Subject: bug#66284: (no subject)

From: [email-masked]
Date: Sat, 30 Sep 2023 17:28:15 -0400

>From 82b31da5a5ea7f65c0d62cd01c761f4ccbfb1ff8 Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
From: Brennan Vincent <[email-masked]>
Date: Sat, 30 Sep 2023 17:01:59 -0400
Subject: [PATCH] * gnu: rust: Introduce rust-next package and various
 intermediates.
To: [email-masked]
X-Fes-Encrypted: true
X-Fes-Ehlo-Domain: localhost

This change introduces intermediate bootstrapping packages rust-1.69, rust-1.70,
rust-1.71, and rust-1.72. It also refactors the code that raises the intermediate
bootstrapping rust-1.67 package into the public "rust" package into a reusable
function so that we can make more such packages. It then uses that function to
create five more packages: rust-next-1.68 through rust-next-1.71, and
rust-next (which is version 1.72.1).

The only one of these that this change exposes publicly is rust-next (i.e.,
rust 1.72.1). This will allow developers who require recent Rust versions to use
Guix to manage their development environment.
---
 .../patches/cargo-failed-install-test.patch   |  16 +
 .../patches/cargo-registry-auth.patch         |  12 +
 gnu/packages/rust.scm                         | 538 ++++++++++++------
 3 files changed, 386 insertions(+), 180 deletions(-)
 create mode 100644 gnu/packages/patches/cargo-failed-install-test.patch
 create mode 100644 gnu/packages/patches/cargo-registry-auth.patch

diff --git a/gnu/packages/patches/cargo-failed-install-test.patch b/gnu/packages/patches/cargo-failed-install-test.patch
new file mode 100644
index 0000000000..d687346243
--- /dev/null
+++ b/gnu/packages/patches/cargo-failed-install-test.patch
@@ -0,0 +1,16 @@
+diff --git a/tests/testsuite/install.rs b/tests/testsuite/install.rs
+index 0c7fc5037..8cd6222a0 100644
+--- a/src/tools/cargo/tests/testsuite/install.rs
++++ b/src/tools/cargo/tests/testsuite/install.rs
+@@ -2276,7 +2276,9 @@ fn failed_install_retains_temp_directory() {
+ 
+     // Find the path in the output.
+     let start = stderr.find("found at `").unwrap() + 10;
+-    let end = stderr[start..].find('.').unwrap() - 1;
+-    let path = Path::new(&stderr[start..(end + start)]);
++    let end = stderr[start..].trim_end_matches(r"`.
++To reuse those artifacts with a future compilation, set the environment variable `CARGO_TARGET_DIR` to that path.
++");
++    let path = Path::new(end);
+     assert!(path.exists());
+     assert!(path.join("release/deps").exists());
diff --git a/gnu/packages/patches/cargo-registry-auth.patch b/gnu/packages/patches/cargo-registry-auth.patch
new file mode 100644
index 0000000000..914db3a21d
--- /dev/null
+++ b/gnu/packages/patches/cargo-registry-auth.patch
@@ -0,0 +1,12 @@
+diff --git a/tests/testsuite/registry_auth.rs b/tests/testsuite/registry_auth.rs
+index 97cdf6748..36d579823 100644
+--- a/src/tools/cargo/tests/testsuite/registry_auth.rs
++++ b/src/tools/cargo/tests/testsuite/registry_auth.rs
+@@ -585,6 +585,6 @@ note: Waiting [..]
+     // 5. /api/v1/crates/new
+     // 6. config.json for the "wait for publish"
+     // 7. /index/3/f/foo for the "wait for publish"
+-    assert_eq!(authorizations.len(), 7);
++    assert!(authorizations.len() >= 7);
+     assert!(!log.contains("a-unique_token"));
+ }
diff --git a/gnu/packages/rust.scm b/gnu/packages/rust.scm
index 38db41549a..11af172a42 100644
--- a/gnu/packages/rust.scm
+++ b/gnu/packages/rust.scm
@@ -16,6 +16,7 @@
 ;;; Copyright © 2022 Zheng Junjie <[email-masked]>
 ;;; Copyright © 2022 Jim Newsome <[email-masked]>
 ;;; Copyright © 2022 Mark H Weaver <[email-masked]>
+;;; Copyright © 2023 Brennan Vincent <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -703,194 +704,371 @@ (define rust-1.67
                              (replace "llvm" llvm-15))))))
 
 (define rust-1.68
-  (rust-bootstrapped-package
-   rust-1.67 "1.68.2" "15ifyd5jj8rd979dkakp887hgmhndr68pqaqvd2hqkfdywirqcwk"))
+  (let ((base-rust (rust-bootstrapped-package
+                    rust-1.67 "1.68.2" "15ifyd5jj8rd979dkakp887hgmhndr68pqaqvd2hqkfdywirqcwk")))
+    (package
+      (inherit base-rust)
+      (arguments
+       (substitute-keyword-arguments (package-arguments base-rust)
+         ((#:validate-runpath? _) #f))))))
 
-;;; Note: Only the latest version of Rust is supported and tested.  The
-;;; intermediate rusts are built for bootstrapping purposes and should not
-;;; be relied upon.  This is to ease maintenance and reduce the time
-;;; required to build the full Rust bootstrap chain.
-;;;
-;;; Here we take the latest included Rust, make it public, and re-enable tests
-;;; and extra components such as rustfmt.
-(define-public rust
-  (let ((base-rust rust-1.68))
+(define rust-1.69
+  (let ((base-rust (rust-bootstrapped-package
+                    rust-1.68 "1.69.0" "03zn7kx5bi5mdfsqfccj4h8gd6abm7spj0kjsfxwlv5dcwc9f1gv")))
+    (package
+      (inherit base-rust)
+      (source
+       (origin
+         (inherit (package-source base-rust))
+         (snippet
+          '(begin
+             (for-each delete-file-recursively
+                       '("src/llvm-project"
+                         "vendor/tikv-jemalloc-sys/jemalloc"))
+             ;; find . -not -type d -executable -exec file {} \+ | grep ELF
+             ;; returns nothing.
+
+             ;; Also remove the bundled (mostly Windows) libraries.
+             (for-each delete-file
+                       (find-files "vendor" ".*\\.(a|dll|exe|lib)$")))))))))
+
+(define (assemble-rustix-outline-asm-phase . dirs)
+  `(lambda _
+     (let* ((system (or ,(%current-target-system)
+                        ,(%current-system)))
+            (arch
+             (match system
+               ("x86_64-linux"   "x86_64")
+               ("i686-linux"     "x86")
+               ("armhf-linux"    "arm")
+               ("aarch64-linux"  "aarch64")
+               ("mips64el-linux" "mips64")
+               ("riscv64-linux"  "riscv64")
+               (_                (let ((dash (string-index system #\-)))
+                                   (substring system 0 dash))))))
+       (for-each
+        (lambda (dir)
+          (with-directory-excursion dir
+            (invoke "gcc" "-c" (format #f "~a.s" arch))
+            (invoke "ar" "r"
+                    (format #f "debug/librustix_outline_~a.a" arch)
+                    (format #f "~a.o" arch))
+            (invoke "ar" "r"
+                    (format #f "release/librustix_outline_~a.a" arch)
+                    (format #f "~a.o" arch))))
+        ',dirs))))
+
+(define rust-1.70
+  (let ((base-rust (rust-bootstrapped-package
+                    rust-1.69 "1.70.0" "0z6j7d0ni0rmfznv0w3mrf882m11kyh51g2bxkj40l3s1c0axgxj")))
     (package
       (inherit base-rust)
-      (outputs (cons "rustfmt" (package-outputs base-rust)))
       (arguments
        (substitute-keyword-arguments (package-arguments base-rust)
-         ((#:tests? _ #f)
-          (not (%current-target-system)))
          ((#:phases phases)
           `(modify-phases ,phases
-             (add-after 'unpack 'relax-gdb-auto-load-safe-path
-               ;; Allow GDB to load binaries from any location, otherwise the
-               ;; gdbinfo tests fail.  This is only useful when testing with a
-               ;; GDB version newer than 8.2.
-               (lambda _
-                 (setenv "HOME" (getcwd))
-                 (with-output-to-file (string-append (getenv "HOME") "/.gdbinit")
-                   (lambda _
-                     (format #t "set auto-load safe-path /~%")))
-                 ;; Do not launch gdb with '-nx' which causes it to not execute
-                 ;; any init file.
-                 (substitute* "src/tools/compiletest/src/runtest.rs"
-                   (("\"-nx\".as_ref\\(\\), ")
-                    ""))))
-             (add-after 'unpack 'patch-cargo-env-shebang
-               (lambda _
-                 (substitute* '("src/tools/cargo/tests/testsuite/build.rs"
-                                "src/tools/cargo/tests/testsuite/fix.rs")
-                   ;; The cargo *_wrapper tests set RUSTC.*WRAPPER environment
-                   ;; variable which points to /usr/bin/env.  Since it's not a
-                   ;; shebang, it needs to be manually patched.
-                   (("/usr/bin/env")
-                    (which "env")))))
-             (add-after 'unpack 'disable-tests-requiring-git
-               (lambda _
-                 (substitute* "src/tools/cargo/tests/testsuite/new.rs"
-                   (("fn author_prefers_cargo")
-                    "#[ignore]\nfn author_prefers_cargo")
-                   (("fn finds_author_git")
-                    "#[ignore]\nfn finds_author_git")
-                   (("fn finds_local_author_git")
-                    "#[ignore]\nfn finds_local_author_git"))))
-             (add-after 'unpack 'disable-tests-requiring-mercurial
-               (lambda _
-                 (substitute*
-                   "src/tools/cargo/tests/testsuite/init/simple_hg_ignore_exists/mod.rs"
-                   (("fn simple_hg_ignore_exists")
-                    "#[ignore]\nfn simple_hg_ignore_exists"))
-                 (substitute*
-                   "src/tools/cargo/tests/testsuite/init/mercurial_autodetect/mod.rs"
-                   (("fn mercurial_autodetect")
-                    "#[ignore]\nfn mercurial_autodetect"))))
-             (add-after 'unpack 'disable-tests-broken-on-aarch64
-               (lambda _
-                 (with-directory-excursion "src/tools/cargo/tests/testsuite/"
-                   (substitute* "build_script_extra_link_arg.rs"
-                     (("^fn build_script_extra_link_arg_bin_single" m)
-                      (string-append "#[ignore]\n" m)))
-                   (substitute* "build_script.rs"
-                     (("^fn env_test" m)
-                      (string-append "#[ignore]\n" m)))
-                   (substitute* "collisions.rs"
-                     (("^fn collision_doc_profile_split" m)
-                      (string-append "#[ignore]\n" m)))
-                   (substitute* "concurrent.rs"
-                     (("^fn no_deadlock_with_git_dependencies" m)
-                      (string-append "#[ignore]\n" m)))
-                   (substitute* "features2.rs"
-                     (("^fn dep_with_optional_host_deps_activated" m)
-                      (string-append "#[ignore]\n" m))))))
-             (add-after 'unpack 'patch-command-exec-tests
-               ;; This test suite includes some tests that the stdlib's
-               ;; `Command` execution properly handles in situations where
-               ;; the environment or PATH variable are empty, but this fails
-               ;; since we don't have `echo` available at its usual FHS
-               ;; location.
-               (lambda _
-                 (substitute* (match (find-files "." "^command-exec.rs$")
-                                ((file) file))
-                   (("Command::new\\(\"echo\"\\)")
-                    (format #f "Command::new(~s)" (which "echo"))))))
-             (add-after 'unpack 'patch-command-uid-gid-test
-               (lambda _
-                 (substitute* (match (find-files "." "^command-uid-gid.rs$")
-                                ((file) file))
-                   (("/bin/sh")
-                    (which "sh")))))
-             (add-after 'unpack 'skip-shebang-tests
-               ;; This test make sure that the parser behaves properly when a
-               ;; source file starts with a shebang. Unfortunately, the
-               ;; patch-shebangs phase changes the meaning of these edge-cases.
-               ;; We skip the test since it's drastically unlikely Guix's
-               ;; packaging will introduce a bug here.
-               (lambda _
-                 (delete-file "tests/ui/parser/shebang/sneaky-attrib.rs")))
-             (add-after 'unpack 'patch-process-tests
-               (lambda* (#:key inputs #:allow-other-keys)
-                 (let ((bash (assoc-ref inputs "bash")))
-                   (substitute* "library/std/src/process/tests.rs"
-                     (("\"/bin/sh\"")
-                      (string-append "\"" bash "/bin/sh\"")))
-                   ;; The three tests which are known to fail upstream on QEMU
-                   ;; emulation on aarch64 and riscv64 also fail on x86_64 in Guix's
-                   ;; build system. Skip them on all builds.
-                   (substitute* "library/std/src/sys/unix/process/process_common/tests.rs"
-                     (("target_arch = \"arm\",") "target_os = \"linux\",")))))
-             (add-after 'unpack 'disable-interrupt-tests
+             ;; Rustix ships with some bundled assembly-language
+             ;; libraries. We strip the pre-assembled versions from
+             ;; the sources, so regenerate them here.
+             (add-after 'configure 'assemble-rustix-outline-asm
+               ,(assemble-rustix-outline-asm-phase
+                 "vendor/rustix-0.36.5/src/backend/linux_raw/arch/outline/"
+                 "vendor/rustix/src/backend/linux_raw/arch/outline/")))))))))
+
+(define rust-1.71
+  (let ((base-rust (rust-bootstrapped-package
+                    rust-1.70 "1.71.0" "15jc0d13cmrh2xvpkyyvsbwgn3w4klqiwf2wlgzfp22mvjmy8rx6")))
+    (package
+      (inherit base-rust)
+      (arguments
+       (substitute-keyword-arguments (package-arguments base-rust)
+         ((#:phases phases)
+          `(modify-phases ,phases
+             (replace 'patch-cargo-checksums
                (lambda _
-                 ;; This test hangs in the build container; disable it.
-                 (substitute* (match (find-files "." "^freshness.rs$")
-                                ((file) file))
-                   (("fn linking_interrupted")
-                    "#[ignore]\nfn linking_interrupted"))
-                 ;; Likewise for the ctrl_c_kills_everyone test.
-                 (substitute* (match (find-files "." "^death.rs$")
-                                ((file) file))
-                   (("fn ctrl_c_kills_everyone")
-                    "#[ignore]\nfn ctrl_c_kills_everyone"))))
-             (add-after 'unpack 'adjust-rpath-values
-               ;; This adds %output:out to rpath, allowing us to install utilities in
-               ;; different outputs while reusing the shared libraries.
-               (lambda* (#:key outputs #:allow-other-keys)
-                 (let ((out (assoc-ref outputs "out")))
-                   (substitute* "src/bootstrap/builder.rs"
-                      ((" = rpath.*" all)
-                       (string-append all
-                                      "                "
-                                      "rustflags.arg(\"-Clink-args=-Wl,-rpath="
-                                      out "/lib\");\n"))))))
-             (add-after 'configure 'add-gdb-to-config
-               (lambda* (#:key inputs #:allow-other-keys)
-                 (let ((gdb (assoc-ref inputs "gdb")))
-                   (substitute* "config.toml"
-                     (("^python =.*" all)
-                      (string-append all
-                                     "gdb = \"" gdb "/bin/gdb\"\n"))))))
-             (replace 'build
-               ;; Phase overridden to also build rustfmt.
-               (lambda* (#:key parallel-build? #:allow-other-keys)
-                 (let ((job-spec (string-append
-                                  "-j" (if parallel-build?
-                                           (number->string (parallel-job-count))
-                                           "1"))))
-                   (invoke "./x.py" job-spec "build"
-                           "library/std" ;rustc
-                           "src/tools/cargo"
-                           "src/tools/rustfmt"))))
-             (replace 'check
-               ;; Phase overridden to also test rustfmt.
-               (lambda* (#:key tests? parallel-build? #:allow-other-keys)
-                 (when tests?
-                   (let ((job-spec (string-append
-                                    "-j" (if parallel-build?
-                                             (number->string (parallel-job-count))
-                                             "1"))))
-                     (invoke "./x.py" job-spec "test" "-vv"
-                             "library/std"
-                             "src/tools/cargo"
-                             "src/tools/rustfmt")))))
-             (replace 'install
-               ;; Phase overridden to also install rustfmt.
-               (lambda* (#:key outputs #:allow-other-keys)
-                 (invoke "./x.py" "install")
-                 (substitute* "config.toml"
-                   ;; Adjust the prefix to the 'cargo' output.
-                   (("prefix = \"[^\"]*\"")
-                    (format #f "prefix = ~s" (assoc-ref outputs "cargo"))))
-                 (invoke "./x.py" "install" "cargo")
-                 (substitute* "config.toml"
-                   ;; Adjust the prefix to the 'rustfmt' output.
-                   (("prefix = \"[^\"]*\"")
-                    (format #f "prefix = ~s" (assoc-ref outputs "rustfmt"))))
-                 (invoke "./x.py" "install" "rustfmt")))))))
-      ;; Add test inputs.
-      (native-inputs (cons* `("gdb" ,gdb/pinned)
-                            `("procps" ,procps)
-                            (package-native-inputs base-rust))))))
+                 (substitute* '("Cargo.lock"
+                                "src/bootstrap/Cargo.lock"
+                                "src/tools/rust-analyzer/Cargo.lock"
+                                "src/tools/cargo/Cargo.lock")
+                   (("(checksum = )\".*\"" all name)
+                    (string-append name "\"" ,%cargo-reference-hash "\"")))
+                 (generate-all-checksums "vendor")))
+             (replace 'assemble-rustix-outline-asm
+               ,(assemble-rustix-outline-asm-phase
+                 "vendor/rustix-0.37.6/src/backend/linux_raw/arch/outline/"
+                 "vendor/rustix-0.37.7/src/backend/linux_raw/arch/outline/"
+                 "vendor/rustix/src/backend/linux_raw/arch/outline/")))))))))
+
+(define rust-1.72
+  (let ((base-rust (rust-bootstrapped-package
+                    rust-1.71 "1.72.1" "15gqd1jzhnc16a7gjmav4x1v83jjbzyjh1gvcdfvpkajd9gq8j3z")))
+    (package
+     (inherit base-rust)
+     (arguments
+      (substitute-keyword-arguments
+       (package-arguments base-rust)
+       ((#:phases phases)
+        `(modify-phases
+          ,phases
+          (replace 'assemble-rustix-outline-asm
+               ,(assemble-rustix-outline-asm-phase
+                 "vendor/rustix-0.37.6/src/backend/linux_raw/arch/outline/"
+                 "vendor/rustix-0.37.11/src/backend/linux_raw/arch/outline/"
+                 "vendor/rustix-0.37.20/src/backend/linux_raw/arch/outline/")))))))))
+
+(define public-rust-1.67-phase-mods
+  '((add-after 'unpack 'relax-gdb-auto-load-safe-path
+      ;; Allow GDB to load binaries from any location, otherwise the
+      ;; gdbinfo tests fail.  This is only useful when testing with a
+      ;; GDB version newer than 8.2.
+      (lambda _
+        (setenv "HOME" (getcwd))
+        (with-output-to-file (string-append (getenv "HOME") "/.gdbinit")
+          (lambda _
+            (format #t "set auto-load safe-path /~%")))
+        ;; Do not launch gdb with '-nx' which causes it to not execute
+        ;; any init file.
+        (substitute* "src/tools/compiletest/src/runtest.rs"
+          (("\"-nx\".as_ref\\(\\), ")
+           ""))))
+    (add-after 'unpack 'patch-cargo-env-shebang
+      (lambda _
+        (substitute* '("src/tools/cargo/tests/testsuite/build.rs"
+                       "src/tools/cargo/tests/testsuite/fix.rs")
+          ;; The cargo *_wrapper tests set RUSTC.*WRAPPER environment
+          ;; variable which points to /usr/bin/env.  Since it's not a
+          ;; shebang, it needs to be manually patched.
+          (("/usr/bin/env")
+           (which "env")))))
+    (add-after 'unpack 'disable-tests-requiring-git
+      (lambda _
+        (substitute* "src/tools/cargo/tests/testsuite/new.rs"
+          (("fn author_prefers_cargo")
+           "#[ignore]\nfn author_prefers_cargo")
+          (("fn finds_author_git")
+           "#[ignore]\nfn finds_author_git")
+          (("fn finds_local_author_git")
+           "#[ignore]\nfn finds_local_author_git"))))
+    (add-after 'unpack 'disable-tests-requiring-mercurial
+      (lambda _
+        (substitute*
+            "src/tools/cargo/tests/testsuite/init/simple_hg_ignore_exists/mod.rs"
+          (("fn simple_hg_ignore_exists")
+           "#[ignore]\nfn simple_hg_ignore_exists"))
+        (substitute*
+            "src/tools/cargo/tests/testsuite/init/mercurial_autodetect/mod.rs"
+          (("fn mercurial_autodetect")
+           "#[ignore]\nfn mercurial_autodetect"))))
+    (add-after 'unpack 'disable-tests-broken-on-aarch64
+      (lambda _
+        (with-directory-excursion "src/tools/cargo/tests/testsuite/"
+          (substitute* "build_script_extra_link_arg.rs"
+            (("^fn build_script_extra_link_arg_bin_single" m)
+             (string-append "#[ignore]\n" m)))
+          (substitute* "build_script.rs"
+            (("^fn env_test" m)
+             (string-append "#[ignore]\n" m)))
+          (substitute* "collisions.rs"
+            (("^fn collision_doc_profile_split" m)
+             (string-append "#[ignore]\n" m)))
+          (substitute* "concurrent.rs"
+            (("^fn no_deadlock_with_git_dependencies" m)
+             (string-append "#[ignore]\n" m)))
+          (substitute* "features2.rs"
+            (("^fn dep_with_optional_host_deps_activated" m)
+             (string-append "#[ignore]\n" m))))))
+    (add-after 'unpack 'patch-command-exec-tests
+      ;; This test suite includes some tests that the stdlib's
+      ;; `Command` execution properly handles in situations where
+      ;; the environment or PATH variable are empty, but this fails
+      ;; since we don't have `echo` available at its usual FHS
+      ;; location.
+      (lambda _
+        (substitute* (match (find-files "." "^command-exec.rs$")
+                       ((file) file))
+          (("Command::new\\(\"echo\"\\)")
+           (format #f "Command::new(~s)" (which "echo"))))))
+    (add-after 'unpack 'patch-command-uid-gid-test
+      (lambda _
+        (substitute* (match (find-files "." "^command-uid-gid.rs$")
+                       ((file) file))
+          (("/bin/sh")
+           (which "sh")))))
+    (add-after 'unpack 'skip-shebang-tests
+      ;; This test make sure that the parser behaves properly when a
+      ;; source file starts with a shebang. Unfortunately, the
+      ;; patch-shebangs phase changes the meaning of these edge-cases.
+      ;; We skip the test since it's drastically unlikely Guix's
+      ;; packaging will introduce a bug here.
+      (lambda _
+        (delete-file "src/test/ui/parser/shebang/sneaky-attrib.rs")))
+    (add-after 'unpack 'patch-process-tests
+      (lambda* (#:key inputs #:allow-other-keys)
+        (let ((bash (assoc-ref inputs "bash")))
+          (substitute* "library/std/src/process/tests.rs"
+            (("\"/bin/sh\"")
+             (string-append "\"" bash "/bin/sh\"")))
+          ;; The three tests which are known to fail upstream on QEMU
+          ;; emulation on aarch64 and riscv64 also fail on x86_64 in Guix's
+          ;; build system. Skip them on all builds.
+          (substitute* "library/std/src/sys/unix/process/process_common/tests.rs"
+            (("target_arch = \"arm\",") "target_os = \"linux\",")))))
+    (add-after 'unpack 'disable-interrupt-tests
+      (lambda _
+        ;; This test hangs in the build container; disable it.
+        (substitute* (match (find-files "." "^freshness.rs$")
+                       ((file) file))
+          (("fn linking_interrupted")
+           "#[ignore]\nfn linking_interrupted"))
+        ;; Likewise for the ctrl_c_kills_everyone test.
+        (substitute* (match (find-files "." "^death.rs$")
+                       ((file) file))
+          (("fn ctrl_c_kills_everyone")
+           "#[ignore]\nfn ctrl_c_kills_everyone"))))
+    (add-after 'configure 'add-gdb-to-config
+      (lambda* (#:key inputs #:allow-other-keys)
+        (let ((gdb (assoc-ref inputs "gdb")))
+          (substitute* "config.toml"
+            (("^python =.*" all)
+             (string-append all
+                            "gdb = \"" gdb "/bin/gdb\"\n"))))))
+    (replace 'build
+      ;; Phase overridden to also build rustfmt.
+      (lambda* (#:key parallel-build? #:allow-other-keys)
+        (let ((job-spec (string-append
+                         "-j" (if parallel-build?
+                                  (number->string (parallel-job-count))
+                                  "1"))))
+          (invoke "./x.py" job-spec "build"
+                  "library/std" ;rustc
+                  "src/tools/cargo"
+                  "src/tools/rustfmt"))))
+    (replace 'check
+      ;; Phase overridden to also test rustfmt.
+      (lambda* (#:key tests? parallel-build? #:allow-other-keys)
+        (when tests?
+          (let ((job-spec (string-append
+                           "-j" (if parallel-build?
+                                    (number->string (parallel-job-count))
+                                    "1"))))
+            (invoke "./x.py" job-spec "test" "-vv"
+                    "library/std"
+                    "src/tools/cargo"
+                    "src/tools/rustfmt")))))
+    (replace 'install
+      ;; Phase overridden to also install rustfmt.
+      (lambda* (#:key outputs #:allow-other-keys)
+        (invoke "./x.py" "install")
+        (substitute* "config.toml"
+          ;; Adjust the prefix to the 'cargo' output.
+          (("prefix = \"[^\"]*\"")
+           (format #f "prefix = ~s" (assoc-ref outputs "cargo"))))
+        (invoke "./x.py" "install" "cargo")
+        (substitute* "config.toml"
+          ;; Adjust the prefix to the 'rustfmt' output.
+          (("prefix = \"[^\"]*\"")
+           (format #f "prefix = ~s" (assoc-ref outputs "rustfmt"))))
+        (invoke "./x.py" "install" "rustfmt")))))
+
+;;; Here we take a given version of Rust and re-enable tests
+;;; and extra components such as rustfmt.
+;;;
+;;; This function was designed for Rust 1.67. Future versions of Rust may require
+;;; further overriding and customization.
+(define* (mk-public-rust
+          base-rust
+          #:optional (phase-mods public-rust-1.67-phase-mods))
+  (package
+    (inherit base-rust)
+    (outputs (cons "rustfmt" (package-outputs base-rust)))
+    (arguments
+     (substitute-keyword-arguments (package-arguments base-rust)
+       ((#:tests? _ #f)
+        (not (%current-target-system)))
+       ((#:phases phases)
+        `(modify-phases ,phases
+           ,@phase-mods))))
+    ;; Add test inputs.
+    (native-inputs (cons* `("gdb" ,gdb/pinned)
+                          `("procps" ,procps)
+                          (package-native-inputs base-rust)))))
+
+;;; Note: Only the version 1.67 of Rust is supported and tested.  The
+;;; intermediate rusts are built for bootstrapping purposes and should not
+;;; be relied upon.  This is to ease maintenance and reduce the time
+;;; required to build the full Rust bootstrap chain.
+(define-public rust
+  (mk-public-rust rust-1.67))
+
+(define public-rust-1.68-phase-mods
+  (append public-rust-1.67-phase-mods
+          '((replace 'skip-shebang-tests
+              (lambda _
+                (delete-file "tests/ui/parser/shebang/sneaky-attrib.rs"))))))
+
+(define rust-next-1.68
+  (mk-public-rust rust-1.68 public-rust-1.68-phase-mods))
+
+(define public-rust-1.69-phase-mods
+  (append public-rust-1.68-phase-mods
+          '((replace 'disable-tests-requiring-mercurial
+              (lambda _
+                (substitute*
+                    "src/tools/cargo/tests/testsuite/init/simple_hg_ignore_exists/mod.rs"
+                  (("fn case")
+                   "#[ignore]\nfn case"))
+                (substitute*
+                    "src/tools/cargo/tests/testsuite/init/mercurial_autodetect/mod.rs"
+                  (("fn case")
+                   "#[ignore]\nfn case")))))))
+
+(define rust-next-1.69
+  (mk-public-rust rust-1.69 public-rust-1.69-phase-mods))
+
+(define public-rust-1.70-phase-mods
+  (append public-rust-1.69-phase-mods
+          '((add-after 'disable-tests-requiring-git 'disable-more-tests-requiring-git
+               (lambda _                 
+                 (substitute* "src/tools/cargo/tests/testsuite/git.rs"
+                   (("fn fetch_downloads_with_git2_first_then_with_gitoxide_and_vice_versa")
+                    "#[ignore]\nfn fetch_downloads_with_git2_first_then_with_gitoxide_and_vice_versa")))))))
+
+(define rust-next-1.70
+  (mk-public-rust rust-1.70 public-rust-1.70-phase-mods))
+
+(define public-rust-1.71-phase-mods
+  (append public-rust-1.70-phase-mods
+          '((add-after 'disable-more-tests-requiring-git 'disable-even-more-tests-requiring-git
+              (lambda _
+                (delete-file "src/tools/cargo/tests/testsuite/git_shallow.rs")
+                (substitute* "src/tools/cargo/tests/testsuite/main.rs"
+                  (("mod git_shallow;")
+                   ""))
+                (substitute* "src/tools/cargo/tests/testsuite/offline.rs"
+                  (("fn gitoxide_cargo_compile_offline_with_cached_git_dep_shallow_dep")
+                   "#[ignore]\nfn gitoxide_cargo_compile_offline_with_cached_git_dep_shallow_dep"))
+                (substitute* "src/tools/cargo/tests/testsuite/patch.rs"
+                  (("fn gitoxide_clones_shallow_old_git_patch")
+                   "#[ignore]\nfn gitoxide_clones_shallow_old_git_patch")))))))
+
+(define rust-next-1.71
+  (mk-public-rust rust-1.71 public-rust-1.71-phase-mods))
+
+(define public-rust-1.72-phase-mods
+  public-rust-1.71-phase-mods)
+
+(define-public rust-next
+  (let ((base-rust (mk-public-rust rust-1.72 public-rust-1.72-phase-mods)))
+    (package
+     (inherit base-rust)
+     (source
+      (origin
+       (inherit (package-source base-rust))
+       (patches (search-patches
+                 "cargo-registry-auth.patch"
+                 "cargo-failed-install-test.patch"))
+       (patch-flags '("-p1"))))
+     (name "rust-next"))))
 
 (define-public rust-src-1.64
   (hidden-package

base-commit: 9f41aa021f982b3fc23927e2988c59329acdc8fc
-- 
2.41.0