From ad7c2b06609c0da21ebdab6e45135cf07290f585 Mon Sep 17 00:00:00 2001
From: Oliver Killane <oliverkillane@gmail.com>
Date: Sun, 5 May 2024 13:54:33 +0100
Subject: [PATCH 1/7] Updated error code explanation

---
 .../src/error_codes/E0582.md                  | 34 +++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/compiler/rustc_error_codes/src/error_codes/E0582.md b/compiler/rustc_error_codes/src/error_codes/E0582.md
index e50cc60ea3302..ea32e4f9f33f1 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0582.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0582.md
@@ -27,6 +27,40 @@ fn bar<F, G>(t: F, u: G)
 fn main() { }
 ```
 
+This error also includes the use of associated types with lifetime parameters.
+```compile_fail,E0582
+trait Foo {
+    type Assoc<'a>;
+}
+
+struct Bar<X, F>
+where
+    X: Foo,
+    F: for<'a> Fn(X::Assoc<'a>) -> &'a i32
+{
+    x: X,
+    f: F
+}
+```
+This is as `Foo::Assoc<'a>` could be implemented by a type that does not use 
+the `'a` parameter, so there is no guarentee that `X::Assoc<'a>` actually uses 
+`'a`.
+
+To fix this we can pass a dummy parameter:
+```
+# trait Foo {
+#     type Assoc<'a>;
+# }
+struct Bar<X, F>
+where
+    X: Foo,
+    F: for<'a> Fn(X::Assoc<'a>, /* dummy */ &'a ()) -> &'a i32
+{
+    x: X,
+    f: F
+}
+```
+
 Note: The examples above used to be (erroneously) accepted by the
 compiler, but this was since corrected. See [issue #33685] for more
 details.

From f3dcf65985dd956595a3f14dcb2a3052daceeb73 Mon Sep 17 00:00:00 2001
From: Oliver Killane <oliverkillane@gmail.com>
Date: Sun, 5 May 2024 14:55:16 +0100
Subject: [PATCH 2/7] fix whitespace

---
 compiler/rustc_error_codes/src/error_codes/E0582.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/compiler/rustc_error_codes/src/error_codes/E0582.md b/compiler/rustc_error_codes/src/error_codes/E0582.md
index ea32e4f9f33f1..31927cd5fe34f 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0582.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0582.md
@@ -42,8 +42,8 @@ where
     f: F
 }
 ```
-This is as `Foo::Assoc<'a>` could be implemented by a type that does not use 
-the `'a` parameter, so there is no guarentee that `X::Assoc<'a>` actually uses 
+This is as `Foo::Assoc<'a>` could be implemented by a type that does not use
+the `'a` parameter, so there is no guarentee that `X::Assoc<'a>` actually uses
 `'a`.
 
 To fix this we can pass a dummy parameter:

From 4db00fe229f08b06feeee552ae53af9f49c25048 Mon Sep 17 00:00:00 2001
From: Luca Barbato <lu_zero@gentoo.org>
Date: Fri, 10 May 2024 16:38:19 +0200
Subject: [PATCH 3/7] Use an helper to move the files

In case the source is not in the same filesystem.
---
 src/bootstrap/src/core/build_steps/dist.rs |  6 ++++--
 src/bootstrap/src/core/download.rs         |  6 +++---
 src/bootstrap/src/utils/helpers.rs         | 15 +++++++++++++++
 src/bootstrap/src/utils/tarball.rs         |  4 ++--
 4 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index 5bc9d7615e2bc..1f006e1453f4b 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -26,7 +26,9 @@ use crate::core::build_steps::tool::{self, Tool};
 use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
 use crate::core::config::TargetSelection;
 use crate::utils::channel::{self, Info};
-use crate::utils::helpers::{exe, is_dylib, output, t, target_supports_cranelift_backend, timeit};
+use crate::utils::helpers::{
+    exe, is_dylib, move_file, output, t, target_supports_cranelift_backend, timeit,
+};
 use crate::utils::tarball::{GeneratedTarball, OverlayKind, Tarball};
 use crate::{Compiler, DependencyType, Mode, LLVM_TOOLS};
 
@@ -2024,7 +2026,7 @@ impl Step for Extended {
             builder.run(&mut cmd);
 
             if !builder.config.dry_run() {
-                t!(fs::rename(exe.join(&filename), distdir(builder).join(&filename)));
+                t!(move_file(exe.join(&filename), distdir(builder).join(&filename)));
             }
         }
     }
diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs
index a074d53aa36e6..60f48c5923e1c 100644
--- a/src/bootstrap/src/core/download.rs
+++ b/src/bootstrap/src/core/download.rs
@@ -12,7 +12,7 @@ use build_helper::ci::CiEnv;
 use build_helper::stage0_parser::VersionMetadata;
 use xz2::bufread::XzDecoder;
 
-use crate::utils::helpers::{check_run, exe, program_out_of_date};
+use crate::utils::helpers::{check_run, exe, move_file, program_out_of_date};
 use crate::{core::build_steps::llvm::detect_llvm_sha, utils::helpers::hex_encode};
 use crate::{t, Config};
 
@@ -209,7 +209,7 @@ impl Config {
             None => panic!("no protocol in {url}"),
         }
         t!(
-            std::fs::rename(&tempfile, dest_path),
+            move_file(&tempfile, dest_path),
             format!("failed to rename {tempfile:?} to {dest_path:?}")
         );
     }
@@ -313,7 +313,7 @@ impl Config {
             if src_path.is_dir() && dst_path.exists() {
                 continue;
             }
-            t!(fs::rename(src_path, dst_path));
+            t!(move_file(src_path, dst_path));
         }
         let dst_dir = dst.join(directory_prefix);
         if dst_dir.exists() {
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index 0d2ff4f951b61..278359cb08e39 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -150,6 +150,21 @@ pub fn symlink_dir(config: &Config, original: &Path, link: &Path) -> io::Result<
     }
 }
 
+/// Rename a file if from and to are in the same filesystem or
+/// copy and remove the file otherwise
+pub fn move_file<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> {
+    match fs::rename(&from, &to) {
+        // FIXME: Once `ErrorKind::CrossesDevices` is stabilized use
+        // if e.kind() == io::ErrorKind::CrossesDevices {
+        #[cfg(unix)]
+        Err(e) if e.raw_os_error() == Some(libc::EXDEV) => {
+            std::fs::copy(&from, &to)?;
+            std::fs::remove_file(&from)
+        }
+        r => r,
+    }
+}
+
 pub fn forcing_clang_based_tests() -> bool {
     if let Some(var) = env::var_os("RUSTBUILD_FORCE_CLANG_BASED_TESTS") {
         match &var.to_string_lossy().to_lowercase()[..] {
diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs
index 2a950e669b923..57cdf7473a191 100644
--- a/src/bootstrap/src/utils/tarball.rs
+++ b/src/bootstrap/src/utils/tarball.rs
@@ -13,7 +13,7 @@ use std::{
 use crate::core::builder::Builder;
 use crate::core::{build_steps::dist::distdir, builder::Kind};
 use crate::utils::channel;
-use crate::utils::helpers::t;
+use crate::utils::helpers::{move_file, t};
 
 #[derive(Copy, Clone)]
 pub(crate) enum OverlayKind {
@@ -284,7 +284,7 @@ impl<'a> Tarball<'a> {
         // name, not "image". We rename the image directory just before passing
         // into rust-installer.
         let dest = self.temp_dir.join(self.package_name());
-        t!(std::fs::rename(&self.image_dir, &dest));
+        t!(move_file(&self.image_dir, &dest));
 
         self.run(|this, cmd| {
             let distdir = distdir(this.builder);

From fe8f66e4bcbe36e7e4b21943661ff23b5369c64b Mon Sep 17 00:00:00 2001
From: Jules Bertholet <julesbertholet@quoi.xyz>
Date: Mon, 13 May 2024 13:32:31 -0400
Subject: [PATCH 4/7] `rustc_hir_typeck`: Account for `skipped_ref_pats` in
 `expr_use_visitor`

Fixes #125058
---
 .../rustc_hir_typeck/src/expr_use_visitor.rs  | 12 +++++++++-
 .../pattern/skipped-ref-pats-issue-125058.rs  | 18 ++++++++++++++
 .../skipped-ref-pats-issue-125058.stderr      | 24 +++++++++++++++++++
 3 files changed, 53 insertions(+), 1 deletion(-)
 create mode 100644 tests/ui/pattern/skipped-ref-pats-issue-125058.rs
 create mode 100644 tests/ui/pattern/skipped-ref-pats-issue-125058.stderr

diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index 1864c7e6ef82d..89f62577506fd 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -18,12 +18,12 @@ use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, Res};
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::{HirId, PatKind};
-use rustc_middle::{bug, span_bug};
 use rustc_middle::hir::place::ProjectionKind;
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::{
     self, adjustment, AdtKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt as _,
 };
+use rustc_middle::{bug, span_bug};
 use rustc_span::{ErrorGuaranteed, Span};
 use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
 use rustc_trait_selection::infer::InferCtxtExt;
@@ -1181,6 +1181,10 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
                 debug!("pat_ty(pat={:?}) found adjusted ty `{:?}`", pat, first_ty);
                 return Ok(*first_ty);
             }
+        } else if let PatKind::Ref(subpat, _) = pat.kind
+            && self.cx.typeck_results().skipped_ref_pats().contains(pat.hir_id)
+        {
+            return self.pat_ty_adjusted(subpat);
         }
 
         self.pat_ty_unadjusted(pat)
@@ -1712,6 +1716,12 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
                 self.cat_pattern(place_with_id, subpat, op)?;
             }
 
+            PatKind::Ref(subpat, _)
+                if self.cx.typeck_results().skipped_ref_pats().contains(pat.hir_id) =>
+            {
+                self.cat_pattern(place_with_id, subpat, op)?;
+            }
+
             PatKind::Box(subpat) | PatKind::Ref(subpat, _) => {
                 // box p1, &p1, &mut p1. we can ignore the mutability of
                 // PatKind::Ref since that information is already contained
diff --git a/tests/ui/pattern/skipped-ref-pats-issue-125058.rs b/tests/ui/pattern/skipped-ref-pats-issue-125058.rs
new file mode 100644
index 0000000000000..b733e5fda0a26
--- /dev/null
+++ b/tests/ui/pattern/skipped-ref-pats-issue-125058.rs
@@ -0,0 +1,18 @@
+//@ run-pass
+//@ edition: 2024
+//@ compile-flags: -Zunstable-options
+
+#![allow(incomplete_features)]
+#![feature(ref_pat_eat_one_layer_2024)]
+
+struct Foo;
+//~^ WARN struct `Foo` is never constructed
+
+fn main() {
+    || {
+        //~^ WARN unused closure that must be used
+        if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
+            let _: u32 = x;
+        }
+    };
+}
diff --git a/tests/ui/pattern/skipped-ref-pats-issue-125058.stderr b/tests/ui/pattern/skipped-ref-pats-issue-125058.stderr
new file mode 100644
index 0000000000000..cee1cc673c7e6
--- /dev/null
+++ b/tests/ui/pattern/skipped-ref-pats-issue-125058.stderr
@@ -0,0 +1,24 @@
+warning: struct `Foo` is never constructed
+  --> $DIR/skipped-ref-pats-issue-125058.rs:8:8
+   |
+LL | struct Foo;
+   |        ^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: unused closure that must be used
+  --> $DIR/skipped-ref-pats-issue-125058.rs:12:5
+   |
+LL | /     || {
+LL | |
+LL | |         if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
+LL | |             let _: u32 = x;
+LL | |         }
+LL | |     };
+   | |_____^
+   |
+   = note: closures are lazy and do nothing unless called
+   = note: `#[warn(unused_must_use)]` on by default
+
+warning: 2 warnings emitted
+

From 1f5837ae2506d5439b31195b7fcf784b9ee90d2b Mon Sep 17 00:00:00 2001
From: Oneirical <manchot@videotron.ca>
Date: Sat, 11 May 2024 17:20:31 -0400
Subject: [PATCH 5/7] rewrite c-link-to-rust-staticlib

---
 .../tidy/src/allowed_run_make_makefiles.txt   |  1 -
 .../c-link-to-rust-staticlib/Makefile         | 16 ---------------
 .../c-link-to-rust-staticlib/rmake.rs         | 20 +++++++++++++++++++
 3 files changed, 20 insertions(+), 17 deletions(-)
 delete mode 100644 tests/run-make/c-link-to-rust-staticlib/Makefile
 create mode 100644 tests/run-make/c-link-to-rust-staticlib/rmake.rs

diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index 5f68f779c4eb0..37acd768593eb 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -8,7 +8,6 @@ run-make/branch-protection-check-IBT/Makefile
 run-make/c-dynamic-dylib/Makefile
 run-make/c-dynamic-rlib/Makefile
 run-make/c-link-to-rust-dylib/Makefile
-run-make/c-link-to-rust-staticlib/Makefile
 run-make/c-static-dylib/Makefile
 run-make/c-static-rlib/Makefile
 run-make/c-unwind-abi-catch-lib-panic/Makefile
diff --git a/tests/run-make/c-link-to-rust-staticlib/Makefile b/tests/run-make/c-link-to-rust-staticlib/Makefile
deleted file mode 100644
index d36cc421c468a..0000000000000
--- a/tests/run-make/c-link-to-rust-staticlib/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-# This test checks that C linking with Rust does not encounter any errors, with static libraries.
-# See https://github.com/rust-lang/rust/issues/10434
-
-# ignore-cross-compile
-include ../tools.mk
-
-# ignore-freebsd
-# FIXME
-
-all:
-	$(RUSTC) foo.rs
-	$(CC) bar.c $(call STATICLIB,foo) $(call OUT_EXE,bar) \
-		$(EXTRACFLAGS) $(EXTRACXXFLAGS)
-	$(call RUN,bar)
-	rm $(call STATICLIB,foo)
-	$(call RUN,bar)
diff --git a/tests/run-make/c-link-to-rust-staticlib/rmake.rs b/tests/run-make/c-link-to-rust-staticlib/rmake.rs
new file mode 100644
index 0000000000000..d73ca413777d2
--- /dev/null
+++ b/tests/run-make/c-link-to-rust-staticlib/rmake.rs
@@ -0,0 +1,20 @@
+// This test checks that C linking with Rust does not encounter any errors, with a static library.
+// See https://github.com/rust-lang/rust/issues/10434
+
+//@ ignore-cross-compile
+
+use run_make_support::{cc, extra_c_flags, extra_cxx_flags, run, rustc, static_lib};
+use std::fs;
+
+fn main() {
+    rustc().input("foo.rs").run();
+    cc().input("bar.c")
+        .input(static_lib("foo"))
+        .out_exe("bar")
+        .args(&extra_c_flags())
+        .args(&extra_cxx_flags())
+        .run();
+    run("bar");
+    fs::remove_file(static_lib("foo"));
+    run("bar");
+}

From b1e5e5161a2ef27852aab40cf3472187bdda5fee Mon Sep 17 00:00:00 2001
From: Julien <96022417+Oneirical@users.noreply.github.com>
Date: Tue, 14 May 2024 16:43:39 -0400
Subject: [PATCH 6/7] remove cxx_flags

---
 tests/run-make/c-link-to-rust-staticlib/rmake.rs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tests/run-make/c-link-to-rust-staticlib/rmake.rs b/tests/run-make/c-link-to-rust-staticlib/rmake.rs
index d73ca413777d2..762d7953a9a0f 100644
--- a/tests/run-make/c-link-to-rust-staticlib/rmake.rs
+++ b/tests/run-make/c-link-to-rust-staticlib/rmake.rs
@@ -3,7 +3,7 @@
 
 //@ ignore-cross-compile
 
-use run_make_support::{cc, extra_c_flags, extra_cxx_flags, run, rustc, static_lib};
+use run_make_support::{cc, extra_c_flags, run, rustc, static_lib};
 use std::fs;
 
 fn main() {
@@ -12,7 +12,6 @@ fn main() {
         .input(static_lib("foo"))
         .out_exe("bar")
         .args(&extra_c_flags())
-        .args(&extra_cxx_flags())
         .run();
     run("bar");
     fs::remove_file(static_lib("foo"));

From 1f61cc3078ce6bcca8095778310f73fc45f7193e Mon Sep 17 00:00:00 2001
From: Oneirical <manchot@videotron.ca>
Date: Mon, 13 May 2024 23:30:50 -0400
Subject: [PATCH 7/7] port no-cdylib-as-rdylib test

---
 .../tidy/src/allowed_run_make_makefiles.txt      |  1 -
 tests/run-make/no-cdylib-as-rdylib/Makefile      | 16 ----------------
 tests/run-make/no-cdylib-as-rdylib/rmake.rs      | 16 ++++++++++++++++
 3 files changed, 16 insertions(+), 17 deletions(-)
 delete mode 100644 tests/run-make/no-cdylib-as-rdylib/Makefile
 create mode 100644 tests/run-make/no-cdylib-as-rdylib/rmake.rs

diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index d742368292035..fc2ba589d2442 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -185,7 +185,6 @@ run-make/native-link-modifier-whole-archive/Makefile
 run-make/no-alloc-shim/Makefile
 run-make/no-builtins-attribute/Makefile
 run-make/no-builtins-lto/Makefile
-run-make/no-cdylib-as-rdylib/Makefile
 run-make/no-duplicate-libs/Makefile
 run-make/no-intermediate-extras/Makefile
 run-make/obey-crate-type-flag/Makefile
diff --git a/tests/run-make/no-cdylib-as-rdylib/Makefile b/tests/run-make/no-cdylib-as-rdylib/Makefile
deleted file mode 100644
index 4d2be0aea913d..0000000000000
--- a/tests/run-make/no-cdylib-as-rdylib/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-# Test that rustc will not attempt to link against a cdylib as if
-# it is a rust dylib when an rlib for the same crate is available.
-# Previously rustc didn't actually check if any further formats of
-# a crate which has been loaded are of the same version and if
-# they are actually valid. This caused a cdylib to be interpreted
-# as rust dylib as soon as the corresponding rlib was loaded. As
-# cdylibs don't export any rust symbols, linking would fail if
-# rustc decides to link against the cdylib rather than the rlib.
-
-all:
-	$(RUSTC) bar.rs --crate-type=rlib --crate-type=cdylib
-	$(RUSTC) foo.rs -C prefer-dynamic
-	$(call RUN,foo)
diff --git a/tests/run-make/no-cdylib-as-rdylib/rmake.rs b/tests/run-make/no-cdylib-as-rdylib/rmake.rs
new file mode 100644
index 0000000000000..42e89df6c2b61
--- /dev/null
+++ b/tests/run-make/no-cdylib-as-rdylib/rmake.rs
@@ -0,0 +1,16 @@
+// This test produces an rlib and a cdylib from bar.rs.
+// Then, foo.rs attempts to link to the bar library.
+// If the test passes, that means rustc favored the rlib and ignored the cdylib.
+// If the test fails, that is because the cdylib was picked, which does not export
+// any Rust symbols.
+// See https://github.com/rust-lang/rust/pull/113695
+
+//@ ignore-cross-compile
+
+use run_make_support::{run, rustc};
+
+fn main() {
+    rustc().input("bar.rs").crate_type("rlib").crate_type("cdylib").run();
+    rustc().input("foo.rs").arg("-Cprefer-dynamic").run();
+    run("foo");
+}