From 7650bd15d5f16130e0ea098dbbc444d2b833c9dd Mon Sep 17 00:00:00 2001
From: Lukas Markeffsky <@>
Date: Fri, 16 Dec 2022 19:39:19 +0100
Subject: [PATCH 01/16] Add cpass to incremental tests

---
 src/tools/compiletest/src/runtest.rs | 50 +++++++++++++++++++---------
 1 file changed, 35 insertions(+), 15 deletions(-)

diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 41c23ff86b25e..ad3d1bddef040 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -278,13 +278,15 @@ impl<'test> TestCx<'test> {
             Incremental => {
                 let revision =
                     self.revision.expect("incremental tests require a list of revisions");
-                if revision.starts_with("rpass") || revision.starts_with("rfail") {
+                if revision.starts_with("cpass")
+                    || revision.starts_with("rpass")
+                    || revision.starts_with("rfail")
+                {
                     true
                 } else if revision.starts_with("cfail") {
-                    // FIXME: would be nice if incremental revs could start with "cpass"
                     pm.is_some()
                 } else {
-                    panic!("revision name must begin with rpass, rfail, or cfail");
+                    panic!("revision name must begin with cpass, rpass, rfail, or cfail");
                 }
             }
             mode => panic!("unimplemented for mode {:?}", mode),
@@ -384,6 +386,20 @@ impl<'test> TestCx<'test> {
         }
     }
 
+    fn run_cpass_test(&self) {
+        let emit_metadata = self.should_emit_metadata(self.pass_mode());
+        let proc_res = self.compile_test(WillExecute::No, emit_metadata);
+
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("compilation failed!", &proc_res);
+        }
+
+        // FIXME(#41968): Move this check to tidy?
+        if !errors::load_errors(&self.testpaths.file, self.revision).is_empty() {
+            self.fatal("compile-pass tests with expected warnings should be moved to ui/");
+        }
+    }
+
     fn run_rpass_test(&self) {
         let emit_metadata = self.should_emit_metadata(self.pass_mode());
         let should_run = self.run_if_enabled();
@@ -393,17 +409,15 @@ impl<'test> TestCx<'test> {
             self.fatal_proc_rec("compilation failed!", &proc_res);
         }
 
+        // FIXME(#41968): Move this check to tidy?
+        if !errors::load_errors(&self.testpaths.file, self.revision).is_empty() {
+            self.fatal("run-pass tests with expected warnings should be moved to ui/");
+        }
+
         if let WillExecute::Disabled = should_run {
             return;
         }
 
-        // FIXME(#41968): Move this check to tidy?
-        let expected_errors = errors::load_errors(&self.testpaths.file, self.revision);
-        assert!(
-            expected_errors.is_empty(),
-            "run-pass tests with expected warnings should be moved to ui/"
-        );
-
         let proc_res = self.exec_compiled_test();
         if !proc_res.status.success() {
             self.fatal_proc_rec("test run failed!", &proc_res);
@@ -2903,10 +2917,11 @@ impl<'test> TestCx<'test> {
     fn run_incremental_test(&self) {
         // Basic plan for a test incremental/foo/bar.rs:
         // - load list of revisions rpass1, cfail2, rpass3
-        //   - each should begin with `rpass`, `cfail`, or `rfail`
-        //   - if `rpass`, expect compile and execution to succeed
+        //   - each should begin with `cpass`, `rpass`, `cfail`, or `rfail`
+        //   - if `cpass`, expect compilation to succeed, don't execute
+        //   - if `rpass`, expect compilation and execution to succeed
         //   - if `cfail`, expect compilation to fail
-        //   - if `rfail`, expect execution to fail
+        //   - if `rfail`, expect compilation to succeed and execution to fail
         // - create a directory build/foo/bar.incremental
         // - compile foo/bar.rs with -C incremental=.../foo/bar.incremental and -C rpass1
         //   - because name of revision starts with "rpass", expect success
@@ -2930,7 +2945,12 @@ impl<'test> TestCx<'test> {
             print!("revision={:?} props={:#?}", revision, self.props);
         }
 
-        if revision.starts_with("rpass") {
+        if revision.starts_with("cpass") {
+            if self.props.should_ice {
+                self.fatal("can only use should-ice in cfail tests");
+            }
+            self.run_cpass_test();
+        } else if revision.starts_with("rpass") {
             if self.props.should_ice {
                 self.fatal("can only use should-ice in cfail tests");
             }
@@ -2943,7 +2963,7 @@ impl<'test> TestCx<'test> {
         } else if revision.starts_with("cfail") {
             self.run_cfail_test();
         } else {
-            self.fatal("revision name must begin with rpass, rfail, or cfail");
+            self.fatal("revision name must begin with cpass, rpass, rfail, or cfail");
         }
     }
 

From 97915ab943001b5a74df4b3e22e7c0a469433fb9 Mon Sep 17 00:00:00 2001
From: Lukas Markeffsky <@>
Date: Fri, 16 Dec 2022 19:42:53 +0100
Subject: [PATCH 02/16] Add note for mismatched types with circular
 dependencies

---
 .../src/infer/error_reporting/mod.rs          | 21 +++++++----
 .../auxiliary/circular-dependencies-aux.rs    | 10 +++++
 tests/incremental/circular-dependencies.rs    | 37 +++++++++++++++++++
 3 files changed, 61 insertions(+), 7 deletions(-)
 create mode 100644 tests/incremental/auxiliary/circular-dependencies-aux.rs
 create mode 100644 tests/incremental/circular-dependencies.rs

diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 8a2b800af0e81..7ce6bd418ebe1 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -613,9 +613,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         }
 
         let report_path_match = |err: &mut Diagnostic, did1: DefId, did2: DefId| {
-            // Only external crates, if either is from a local
-            // module we could have false positives
-            if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate {
+            // Only report definitions from different crates. If both definitions
+            // are from a local module we could have false positives, e.g.
+            // let _ = [{struct Foo; Foo}, {struct Foo; Foo}];
+            if did1.krate != did2.krate {
                 let abs_path =
                     |def_id| AbsolutePathPrinter { tcx: self.tcx }.print_def_path(def_id, &[]);
 
@@ -627,10 +628,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 };
                 if same_path().unwrap_or(false) {
                     let crate_name = self.tcx.crate_name(did1.krate);
-                    err.note(&format!(
-                        "perhaps two different versions of crate `{}` are being used?",
-                        crate_name
-                    ));
+                    let msg = if did1.is_local() || did2.is_local() {
+                        format!(
+                            "the crate `{crate_name}` is compiled multiple times, possibly with different configurations"
+                        )
+                    } else {
+                        format!(
+                            "perhaps two different versions of crate `{crate_name}` are being used?"
+                        )
+                    };
+                    err.note(msg);
                 }
             }
         };
diff --git a/tests/incremental/auxiliary/circular-dependencies-aux.rs b/tests/incremental/auxiliary/circular-dependencies-aux.rs
new file mode 100644
index 0000000000000..0e74eb1b2f263
--- /dev/null
+++ b/tests/incremental/auxiliary/circular-dependencies-aux.rs
@@ -0,0 +1,10 @@
+// edition: 2021
+// compile-flags: --crate-type lib --extern circular_dependencies={{build-base}}/circular-dependencies/libcircular_dependencies.rmeta --emit dep-info,metadata
+
+use circular_dependencies::Foo;
+
+pub fn consume_foo(_: Foo) {}
+
+pub fn produce_foo() -> Foo {
+    Foo
+}
diff --git a/tests/incremental/circular-dependencies.rs b/tests/incremental/circular-dependencies.rs
new file mode 100644
index 0000000000000..10673066a9df0
--- /dev/null
+++ b/tests/incremental/circular-dependencies.rs
@@ -0,0 +1,37 @@
+// ignore-tidy-linelength
+// revisions: cpass1 cfail2
+// edition: 2021
+// [cpass1] compile-flags: --crate-type lib --emit dep-info,metadata
+// [cfail2] aux-build: circular-dependencies-aux.rs
+// [cfail2] compile-flags: --test --extern aux={{build-base}}/circular-dependencies/auxiliary/libcircular_dependencies_aux.rmeta -L dependency={{build-base}}/circular-dependencies
+
+pub struct Foo;
+//[cfail2]~^ NOTE `Foo` is defined in the current crate
+//[cfail2]~| NOTE `Foo` is defined in the current crate
+//[cfail2]~| NOTE `circular_dependencies::Foo` is defined in crate `circular_dependencies`
+//[cfail2]~| NOTE `circular_dependencies::Foo` is defined in crate `circular_dependencies`
+
+pub fn consume_foo(_: Foo) {}
+//[cfail2]~^ NOTE function defined here
+
+pub fn produce_foo() -> Foo {
+    Foo
+}
+
+#[test]
+fn test() {
+    aux::consume_foo(produce_foo());
+    //[cfail2]~^ ERROR mismatched types [E0308]
+    //[cfail2]~| NOTE expected `circular_dependencies::Foo`, found `Foo`
+    //[cfail2]~| NOTE arguments to this function are incorrect
+    //[cfail2]~| NOTE `Foo` and `circular_dependencies::Foo` have similar names, but are actually distinct types
+    //[cfail2]~| NOTE the crate `circular_dependencies` is compiled multiple times, possibly with different configurations
+    //[cfail2]~| NOTE function defined here
+
+    consume_foo(aux::produce_foo());
+    //[cfail2]~^ ERROR mismatched types [E0308]
+    //[cfail2]~| NOTE expected `Foo`, found `circular_dependencies::Foo`
+    //[cfail2]~| NOTE arguments to this function are incorrect
+    //[cfail2]~| NOTE `circular_dependencies::Foo` and `Foo` have similar names, but are actually distinct types
+    //[cfail2]~| NOTE the crate `circular_dependencies` is compiled multiple times, possibly with different configurations
+}

From dfe4c49e9b8f724d43328eee46b733f65d3d5b25 Mon Sep 17 00:00:00 2001
From: Konrad Borowski <konrad@borowski.pw>
Date: Mon, 6 Mar 2023 21:11:01 +0100
Subject: [PATCH 03/16] Use Edition 2021 :pat in matches macro

This makes the macro syntax used in documentation more readable.
---
 library/core/src/macros/mod.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 3b026bc0e0f38..529f62f4d6cd7 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -340,9 +340,9 @@ pub macro debug_assert_matches($($arg:tt)*) {
 #[stable(feature = "matches_macro", since = "1.42.0")]
 #[cfg_attr(not(test), rustc_diagnostic_item = "matches_macro")]
 macro_rules! matches {
-    ($expression:expr, $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => {
+    ($expression:expr, $pattern:pat $(if $guard:expr)? $(,)?) => {
         match $expression {
-            $( $pattern )|+ $( if $guard )? => true,
+            $pattern $(if $guard)? => true,
             _ => false
         }
     };

From c21f1d09de3a6a7bb4952f400919e936032b8ee2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= <tomasz.miasko@gmail.com>
Date: Sat, 11 Mar 2023 00:00:00 +0000
Subject: [PATCH 04/16] read_buf_exact: on error, all read bytes are appended
 to the buffer

Guarantee that when `read_buf_exact` returns, all bytes read will be
appended to the buffer. Including the case when the operations fails.

The motivating use case are operations on a non-blocking reader. When
`read_buf_exact` fails with `ErrorKind::WouldBlock` error, the operation
can be resumed at a later time.
---
 library/std/src/io/mod.rs | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index b2b6d86134b62..4b31c552eedd2 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -823,8 +823,22 @@ pub trait Read {
 
     /// Read the exact number of bytes required to fill `cursor`.
     ///
-    /// This is equivalent to the [`read_exact`](Read::read_exact) method, except that it is passed a [`BorrowedCursor`] rather than `[u8]` to
-    /// allow use with uninitialized buffers.
+    /// This is similar to the [`read_exact`](Read::read_exact) method, except
+    /// that it is passed a [`BorrowedCursor`] rather than `[u8]` to allow use
+    /// with uninitialized buffers.
+    ///
+    /// # Errors
+    ///
+    /// If this function encounters an error of the kind [`ErrorKind::Interrupted`]
+    /// then the error is ignored and the operation will continue.
+    ///
+    /// If this function encounters an "end of file" before completely filling
+    /// the buffer, it returns an error of the kind [`ErrorKind::UnexpectedEof`].
+    ///
+    /// If any other read error is encountered then this function immediately
+    /// returns.
+    ///
+    /// If this function returns an error, all bytes read will be appended to `cursor`.
     #[unstable(feature = "read_buf", issue = "78485")]
     fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> Result<()> {
         while cursor.capacity() > 0 {

From 2df7770d5e8e32728e0add987c65ce8a95fc475d Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume.gomez@huawei.com>
Date: Fri, 10 Mar 2023 22:19:48 +0100
Subject: [PATCH 05/16] Add lint for useless anonymous reexports

---
 compiler/rustc_lint/messages.ftl     |  3 +
 compiler/rustc_lint/src/lib.rs       |  3 +
 compiler/rustc_lint/src/lints.rs     |  7 +++
 compiler/rustc_lint/src/reexports.rs | 82 ++++++++++++++++++++++++++++
 4 files changed, 95 insertions(+)
 create mode 100644 compiler/rustc_lint/src/reexports.rs

diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 68e62c9789aed..1924ae08c3938 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -508,3 +508,6 @@ lint_opaque_hidden_inferred_bound = opaque type `{$ty}` does not satisfy its ass
     .specifically = this associated type bound is unsatisfied for `{$proj_ty}`
 
 lint_opaque_hidden_inferred_bound_sugg = add this bound
+
+lint_useless_anonymous_reexport = useless anonymous re-export
+    .note = only anonymous re-exports of traits are useful, this is {$article} `${desc}`
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index b3578540516d0..c2cc2fcdf551a 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -74,6 +74,7 @@ mod opaque_hidden_inferred_bound;
 mod pass_by_value;
 mod passes;
 mod redundant_semicolon;
+mod reexports;
 mod traits;
 mod types;
 mod unused;
@@ -111,6 +112,7 @@ use noop_method_call::*;
 use opaque_hidden_inferred_bound::*;
 use pass_by_value::*;
 use redundant_semicolon::*;
+use reexports::*;
 use traits::*;
 use types::*;
 use unused::*;
@@ -242,6 +244,7 @@ late_lint_methods!(
             OpaqueHiddenInferredBound: OpaqueHiddenInferredBound,
             MultipleSupertraitUpcastable: MultipleSupertraitUpcastable,
             MapUnitFn: MapUnitFn,
+            UselessAnonymousReexport: UselessAnonymousReexport,
         ]
     ]
 );
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 20ab0af585651..ac73f0830f68b 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1530,3 +1530,10 @@ pub struct UnusedAllocationDiag;
 #[derive(LintDiagnostic)]
 #[diag(lint_unused_allocation_mut)]
 pub struct UnusedAllocationMutDiag;
+
+#[derive(LintDiagnostic)]
+#[diag(lint_useless_anonymous_reexport)]
+pub struct UselessAnonymousReexportDiag {
+    pub article: &'static str,
+    pub desc: &'static str,
+}
diff --git a/compiler/rustc_lint/src/reexports.rs b/compiler/rustc_lint/src/reexports.rs
new file mode 100644
index 0000000000000..8737a57ea0264
--- /dev/null
+++ b/compiler/rustc_lint/src/reexports.rs
@@ -0,0 +1,82 @@
+use crate::lints::UselessAnonymousReexportDiag;
+use crate::{LateContext, LateLintPass, LintContext};
+use rustc_hir::def::DefKind;
+use rustc_hir::def_id::DefId;
+use rustc_hir::{Item, ItemKind, UseKind};
+use rustc_middle::ty::Visibility;
+use rustc_span::symbol::kw;
+use rustc_span::Span;
+
+declare_lint! {
+    /// The `useless_anonymous_reexport` lint checks if anonymous re-exports
+    /// are re-exports of traits.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// #![deny(useless_anonymous_reexport)]
+    ///
+    /// mod sub {
+    ///     pub struct Bar;
+    /// }
+    ///
+    /// pub use self::sub::Bar as _;
+    /// # fn main() {}
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Anonymous re-exports are only useful if it's a re-export of a trait
+    /// in case you want to give access to it. If you re-export any other kind,
+    /// you won't be able to use it since its name won't be accessible.
+    pub USELESS_ANONYMOUS_REEXPORT,
+    Warn,
+    "useless anonymous re-export"
+}
+
+declare_lint_pass!(UselessAnonymousReexport => [USELESS_ANONYMOUS_REEXPORT]);
+
+fn emit_err(cx: &LateContext<'_>, span: Span, def_id: DefId) {
+    let article = cx.tcx.def_descr_article(def_id);
+    let desc = cx.tcx.def_descr(def_id);
+    cx.emit_spanned_lint(
+        USELESS_ANONYMOUS_REEXPORT,
+        span,
+        UselessAnonymousReexportDiag { article, desc },
+    );
+}
+
+impl<'tcx> LateLintPass<'tcx> for UselessAnonymousReexport {
+    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
+        if let ItemKind::Use(path, kind) = item.kind &&
+            !matches!(kind, UseKind::Glob) &&
+            item.ident.name == kw::Underscore &&
+            // We only want re-exports. If it's just a `use X;`, then we ignore it.
+            match cx.tcx.local_visibility(item.owner_id.def_id) {
+                Visibility::Public => true,
+                Visibility::Restricted(level) => {
+                    level != cx.tcx.parent_module_from_def_id(item.owner_id.def_id)
+                }
+            }
+        {
+            for def_id in path.res.iter().filter_map(|r| r.opt_def_id()) {
+                match cx.tcx.def_kind(def_id) {
+                    DefKind::Trait | DefKind::TraitAlias => {}
+                    DefKind::TyAlias => {
+                        let ty = cx.tcx.type_of(def_id);
+                        if !ty.0.is_trait() {
+                            emit_err(cx, item.span, def_id);
+                            break;
+                        }
+                    }
+                    _ => {
+                        emit_err(cx, item.span, def_id);
+                        break;
+                    }
+                }
+            }
+        }
+    }
+}

From ac4ea529801ed087041768f1708637cc8277db49 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume.gomez@huawei.com>
Date: Fri, 10 Mar 2023 22:20:29 +0100
Subject: [PATCH 06/16] Add test for useless_anonymous_reexport lint

---
 compiler/rustc_lint/messages.ftl        |  2 +-
 compiler/rustc_lint/src/lints.rs        |  1 +
 tests/ui/lint/anonymous-reexport.rs     | 16 ++++++++++++++++
 tests/ui/lint/anonymous-reexport.stderr | 20 ++++++++++++++++++++
 4 files changed, 38 insertions(+), 1 deletion(-)
 create mode 100644 tests/ui/lint/anonymous-reexport.rs
 create mode 100644 tests/ui/lint/anonymous-reexport.stderr

diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 1924ae08c3938..c822237413c70 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -510,4 +510,4 @@ lint_opaque_hidden_inferred_bound = opaque type `{$ty}` does not satisfy its ass
 lint_opaque_hidden_inferred_bound_sugg = add this bound
 
 lint_useless_anonymous_reexport = useless anonymous re-export
-    .note = only anonymous re-exports of traits are useful, this is {$article} `${desc}`
+    .note = only anonymous re-exports of traits are useful, this is {$article} `{$desc}`
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index ac73f0830f68b..8d058517118c4 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1533,6 +1533,7 @@ pub struct UnusedAllocationMutDiag;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_useless_anonymous_reexport)]
+#[note]
 pub struct UselessAnonymousReexportDiag {
     pub article: &'static str,
     pub desc: &'static str,
diff --git a/tests/ui/lint/anonymous-reexport.rs b/tests/ui/lint/anonymous-reexport.rs
new file mode 100644
index 0000000000000..380e7792bdd38
--- /dev/null
+++ b/tests/ui/lint/anonymous-reexport.rs
@@ -0,0 +1,16 @@
+#![deny(useless_anonymous_reexport)]
+#![crate_type = "rlib"]
+
+mod my_mod {
+    pub trait Foo {}
+    pub type TyFoo = dyn Foo;
+    pub struct Bar;
+    pub type TyBar = Bar;
+}
+
+pub use self::my_mod::Foo as _;
+pub use self::my_mod::TyFoo as _;
+pub use self::my_mod::Bar as _; //~ ERROR
+pub use self::my_mod::TyBar as _; //~ ERROR
+#[allow(unused_imports)]
+use self::my_mod::TyBar as _;
diff --git a/tests/ui/lint/anonymous-reexport.stderr b/tests/ui/lint/anonymous-reexport.stderr
new file mode 100644
index 0000000000000..fafa855e5fafa
--- /dev/null
+++ b/tests/ui/lint/anonymous-reexport.stderr
@@ -0,0 +1,20 @@
+error: useless anonymous re-export
+  --> $DIR/anonymous-reexport.rs:13:1
+   |
+LL | pub use self::my_mod::Bar as _;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/anonymous-reexport.rs:1:9
+   |
+LL | #![deny(useless_anonymous_reexport)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: useless anonymous re-export
+  --> $DIR/anonymous-reexport.rs:14:1
+   |
+LL | pub use self::my_mod::TyBar as _;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+

From 7b0fa085b093be4cca285441703d91caa216e4dc Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume.gomez@huawei.com>
Date: Sun, 12 Mar 2023 15:23:32 +0100
Subject: [PATCH 07/16] Update failing ui tests

---
 tests/ui/imports/issue-99695-b.fixed    |  2 +-
 tests/ui/imports/issue-99695-b.rs       |  2 +-
 tests/ui/imports/issue-99695.fixed      |  2 +-
 tests/ui/imports/issue-99695.rs         |  2 +-
 tests/ui/lint/anonymous-reexport.rs     |  5 ++++
 tests/ui/lint/anonymous-reexport.stderr | 37 ++++++++++++++++++++++++-
 6 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/tests/ui/imports/issue-99695-b.fixed b/tests/ui/imports/issue-99695-b.fixed
index 0e60c73b67a44..0f688fa282356 100644
--- a/tests/ui/imports/issue-99695-b.fixed
+++ b/tests/ui/imports/issue-99695-b.fixed
@@ -1,5 +1,5 @@
 // run-rustfix
-#![allow(unused, nonstandard_style)]
+#![allow(unused, nonstandard_style, useless_anonymous_reexport)]
 mod m {
 
     mod p {
diff --git a/tests/ui/imports/issue-99695-b.rs b/tests/ui/imports/issue-99695-b.rs
index 031443a1f5df8..b433997e53f6a 100644
--- a/tests/ui/imports/issue-99695-b.rs
+++ b/tests/ui/imports/issue-99695-b.rs
@@ -1,5 +1,5 @@
 // run-rustfix
-#![allow(unused, nonstandard_style)]
+#![allow(unused, nonstandard_style, useless_anonymous_reexport)]
 mod m {
 
     mod p {
diff --git a/tests/ui/imports/issue-99695.fixed b/tests/ui/imports/issue-99695.fixed
index 6bf228b23aad2..17ff409324e34 100644
--- a/tests/ui/imports/issue-99695.fixed
+++ b/tests/ui/imports/issue-99695.fixed
@@ -1,5 +1,5 @@
 // run-rustfix
-#![allow(unused, nonstandard_style)]
+#![allow(unused, nonstandard_style, useless_anonymous_reexport)]
 mod m {
     #[macro_export]
     macro_rules! nu {
diff --git a/tests/ui/imports/issue-99695.rs b/tests/ui/imports/issue-99695.rs
index f7199f1497ab0..b8979bcb7345c 100644
--- a/tests/ui/imports/issue-99695.rs
+++ b/tests/ui/imports/issue-99695.rs
@@ -1,5 +1,5 @@
 // run-rustfix
-#![allow(unused, nonstandard_style)]
+#![allow(unused, nonstandard_style, useless_anonymous_reexport)]
 mod m {
     #[macro_export]
     macro_rules! nu {
diff --git a/tests/ui/lint/anonymous-reexport.rs b/tests/ui/lint/anonymous-reexport.rs
index 380e7792bdd38..5d56ae6f969b5 100644
--- a/tests/ui/lint/anonymous-reexport.rs
+++ b/tests/ui/lint/anonymous-reexport.rs
@@ -12,5 +12,10 @@ pub use self::my_mod::Foo as _;
 pub use self::my_mod::TyFoo as _;
 pub use self::my_mod::Bar as _; //~ ERROR
 pub use self::my_mod::TyBar as _; //~ ERROR
+pub use self::my_mod::{Bar as _}; //~ ERROR
+pub use self::my_mod::{Bar as _, Foo as _}; //~ ERROR
+pub use self::my_mod::{Bar as _, TyBar as _};
+//~^ ERROR
+//~| ERROR
 #[allow(unused_imports)]
 use self::my_mod::TyBar as _;
diff --git a/tests/ui/lint/anonymous-reexport.stderr b/tests/ui/lint/anonymous-reexport.stderr
index fafa855e5fafa..f4f8b41c417a4 100644
--- a/tests/ui/lint/anonymous-reexport.stderr
+++ b/tests/ui/lint/anonymous-reexport.stderr
@@ -4,6 +4,7 @@ error: useless anonymous re-export
 LL | pub use self::my_mod::Bar as _;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
+   = note: only anonymous re-exports of traits are useful, this is a `struct`
 note: the lint level is defined here
   --> $DIR/anonymous-reexport.rs:1:9
    |
@@ -15,6 +16,40 @@ error: useless anonymous re-export
    |
 LL | pub use self::my_mod::TyBar as _;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: only anonymous re-exports of traits are useful, this is a `type alias`
+
+error: useless anonymous re-export
+  --> $DIR/anonymous-reexport.rs:15:24
+   |
+LL | pub use self::my_mod::{Bar as _};
+   |                        ^^^^^^^^
+   |
+   = note: only anonymous re-exports of traits are useful, this is a `struct`
+
+error: useless anonymous re-export
+  --> $DIR/anonymous-reexport.rs:16:24
+   |
+LL | pub use self::my_mod::{Bar as _, Foo as _};
+   |                        ^^^^^^^^
+   |
+   = note: only anonymous re-exports of traits are useful, this is a `struct`
+
+error: useless anonymous re-export
+  --> $DIR/anonymous-reexport.rs:17:24
+   |
+LL | pub use self::my_mod::{Bar as _, TyBar as _};
+   |                        ^^^^^^^^
+   |
+   = note: only anonymous re-exports of traits are useful, this is a `struct`
+
+error: useless anonymous re-export
+  --> $DIR/anonymous-reexport.rs:17:34
+   |
+LL | pub use self::my_mod::{Bar as _, TyBar as _};
+   |                                  ^^^^^^^^^^
+   |
+   = note: only anonymous re-exports of traits are useful, this is a `type alias`
 
-error: aborting due to 2 previous errors
+error: aborting due to 6 previous errors
 

From f663f0946771260ba4a0a24eb24bb5d8ce2fe546 Mon Sep 17 00:00:00 2001
From: est31 <MTest31@outlook.com>
Date: Fri, 10 Mar 2023 10:05:10 +0100
Subject: [PATCH 08/16] Beautify pin! docs

This makes pin docs a little bit less jargon-y and easier to read, by

* splitting up the sentences
* making them less interrupted by punctuation
* turning the footnotes into paragraphs, as they contain useful information
  that shouldn't be hidden in footnotes. Footnotes also interrupt the read flow.
* other improvements and simplifications
---
 library/core/src/pin.rs | 35 +++++++++++++++++++----------------
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index febe57dc90bc7..c4b89a6301965 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -1003,22 +1003,25 @@ impl<P, U> CoerceUnsized<Pin<U>> for Pin<P> where P: CoerceUnsized<U> {}
 #[stable(feature = "pin", since = "1.33.0")]
 impl<P, U> DispatchFromDyn<Pin<U>> for Pin<P> where P: DispatchFromDyn<U> {}
 
-/// Constructs a <code>[Pin]<[&mut] T></code>, by pinning[^1] a `value: T` _locally_[^2].
+/// Constructs a <code>[Pin]<[&mut] T></code>, by pinning a `value: T` locally.
 ///
-/// Unlike [`Box::pin`], this does not involve a heap allocation.
+/// Unlike [`Box::pin`], this does not create a new heap allocation. As explained
+/// below, the element might still end up on the heap however.
 ///
-/// [^1]: If the (type `T` of the) given value does not implement [`Unpin`], then this
-/// effectively pins the `value` in memory, where it will be unable to be moved.
-/// Otherwise, <code>[Pin]<[&mut] T></code> behaves like <code>[&mut] T</code>, and operations such
-/// as [`mem::replace()`][crate::mem::replace] will allow extracting that value, and therefore,
-/// moving it.
-/// See [the `Unpin` section of the `pin` module][self#unpin] for more info.
+/// The local pinning performed by this macro is usually dubbed "stack"-pinning.
+/// Outside of `async` contexts locals do indeed get stored on the stack. In
+/// `async` functions or blocks however, any locals crossing an `.await` point
+/// are part of the state captured by the `Future`, and will use the storage of
+/// those. That storage can either be on the heap or on the stack. Therefore,
+/// local pinning is a more accurate term.
 ///
-/// [^2]: This is usually dubbed "stack"-pinning. And whilst local values are almost always located
-/// in the stack (_e.g._, when within the body of a non-`async` function), the truth is that inside
-/// the body of an `async fn` or block —more generally, the body of a generator— any locals crossing
-/// an `.await` point —a `yield` point— end up being part of the state captured by the `Future` —by
-/// the `Generator`—, and thus will be stored wherever that one is.
+/// If the type of the given value does not implement [`Unpin`], then this macro
+/// pins the value in memory in a way that prevents moves. On the other hand,
+/// if the type does implement [`Unpin`], <code>[Pin]<[&mut] T></code> behaves
+/// like <code>[&mut] T</code>, and operations such as
+/// [`mem::replace()`][crate::mem::replace] or [`mem::take()`](crate::mem::take)
+/// will allow moves of the value.
+/// See [the `Unpin` section of the `pin` module][self#unpin] for details.
 ///
 /// ## Examples
 ///
@@ -1158,9 +1161,9 @@ impl<P, U> DispatchFromDyn<Pin<U>> for Pin<P> where P: DispatchFromDyn<U> {}
 ///
 /// If you really need to return a pinned value, consider using [`Box::pin`] instead.
 ///
-/// On the other hand, pinning to the stack[<sup>2</sup>](#fn2) using [`pin!`] is likely to be
-/// cheaper than pinning into a fresh heap allocation using [`Box::pin`]. Moreover, by virtue of not
-/// even needing an allocator, [`pin!`] is the main non-`unsafe` `#![no_std]`-compatible [`Pin`]
+/// On the other hand, local pinning using [`pin!`] is likely to be cheaper than
+/// pinning into a fresh heap allocation using [`Box::pin`]. Moreover, by virtue of not
+/// requiring an allocator, [`pin!`] is the main non-`unsafe` `#![no_std]`-compatible [`Pin`]
 /// constructor.
 ///
 /// [`Box::pin`]: ../../std/boxed/struct.Box.html#method.pin

From c22f154e3fb6eca7dd1e83575564a5ea44d661bc Mon Sep 17 00:00:00 2001
From: yukang <moorekang@gmail.com>
Date: Fri, 17 Mar 2023 07:59:08 +0800
Subject: [PATCH 09/16] Do not ICE for native_lib without name

---
 compiler/rustc_metadata/src/native_libs.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index d6f68b2e14055..6b6aa78575ae9 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -53,12 +53,13 @@ fn find_bundled_library(
     sess: &Session,
 ) -> Option<Symbol> {
     if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive } = kind
+        && let Some(name) = name
         && sess.crate_types().iter().any(|t| matches!(t, &CrateType::Rlib | CrateType::Staticlib))
         && (sess.opts.unstable_opts.packed_bundled_libs || has_cfg || whole_archive == Some(true))
     {
         let verbatim = verbatim.unwrap_or(false);
         let search_paths = &sess.target_filesearch(PathKind::Native).search_path_dirs();
-        return find_native_static_library(name.unwrap().as_str(), verbatim, search_paths, sess)
+        return find_native_static_library(name.as_str(), verbatim, search_paths, sess)
             .file_name()
             .and_then(|s| s.to_str())
             .map(Symbol::intern);

From 7bc67ef6e02d69023c6fb04c2258beab54ac22b8 Mon Sep 17 00:00:00 2001
From: onestacked <chrisi.schrefl@gmail.com>
Date: Sat, 4 Feb 2023 16:36:26 +0100
Subject: [PATCH 10/16] Make the `Step` implementations const.

---
 library/core/src/iter/range.rs         | 20 ++++++++++++++------
 library/core/src/iter/traits/marker.rs |  3 ++-
 library/core/src/lib.rs                |  1 +
 3 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs
index 78e27d73065aa..dba2b2291ff6e 100644
--- a/library/core/src/iter/range.rs
+++ b/library/core/src/iter/range.rs
@@ -20,7 +20,8 @@ unsafe_impl_trusted_step![char i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usi
 /// The *successor* operation moves towards values that compare greater.
 /// The *predecessor* operation moves towards values that compare lesser.
 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
-pub trait Step: Clone + PartialOrd + Sized {
+#[const_trait]
+pub trait Step: ~const Clone + ~const PartialOrd + Sized {
     /// Returns the number of *successor* steps required to get from `start` to `end`.
     ///
     /// Returns `None` if the number of steps would overflow `usize`
@@ -234,7 +235,8 @@ macro_rules! step_integer_impls {
         $(
             #[allow(unreachable_patterns)]
             #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
-            impl Step for $u_narrower {
+            #[rustc_const_unstable(feature = "const_iter", issue = "92476")]
+            impl const Step for $u_narrower {
                 step_identical_methods!();
 
                 #[inline]
@@ -266,7 +268,8 @@ macro_rules! step_integer_impls {
 
             #[allow(unreachable_patterns)]
             #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
-            impl Step for $i_narrower {
+            #[rustc_const_unstable(feature = "const_iter", issue = "92476")]
+            impl const Step for $i_narrower {
                 step_identical_methods!();
 
                 #[inline]
@@ -330,7 +333,8 @@ macro_rules! step_integer_impls {
         $(
             #[allow(unreachable_patterns)]
             #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
-            impl Step for $u_wider {
+            #[rustc_const_unstable(feature = "const_iter", issue = "92476")]
+            impl const Step for $u_wider {
                 step_identical_methods!();
 
                 #[inline]
@@ -355,7 +359,8 @@ macro_rules! step_integer_impls {
 
             #[allow(unreachable_patterns)]
             #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
-            impl Step for $i_wider {
+            #[rustc_const_unstable(feature = "const_iter", issue = "92476")]
+            impl const Step for $i_wider {
                 step_identical_methods!();
 
                 #[inline]
@@ -405,7 +410,8 @@ step_integer_impls! {
 }
 
 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
-impl Step for char {
+#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
+impl const Step for char {
     #[inline]
     fn steps_between(&start: &char, &end: &char) -> Option<usize> {
         let start = start as u32;
@@ -423,6 +429,7 @@ impl Step for char {
     }
 
     #[inline]
+    #[rustc_allow_const_fn_unstable(const_try)]
     fn forward_checked(start: char, count: usize) -> Option<char> {
         let start = start as u32;
         let mut res = Step::forward_checked(start, count)?;
@@ -439,6 +446,7 @@ impl Step for char {
     }
 
     #[inline]
+    #[rustc_allow_const_fn_unstable(const_try)]
     fn backward_checked(start: char, count: usize) -> Option<char> {
         let start = start as u32;
         let mut res = Step::backward_checked(start, count)?;
diff --git a/library/core/src/iter/traits/marker.rs b/library/core/src/iter/traits/marker.rs
index af02848233d99..c8f60defff771 100644
--- a/library/core/src/iter/traits/marker.rs
+++ b/library/core/src/iter/traits/marker.rs
@@ -86,4 +86,5 @@ pub unsafe trait InPlaceIterable: Iterator {}
 /// for details. Consumers are free to rely on the invariants in unsafe code.
 #[unstable(feature = "trusted_step", issue = "85731")]
 #[rustc_specialization_trait]
-pub unsafe trait TrustedStep: Step {}
+#[const_trait]
+pub unsafe trait TrustedStep: ~const Step {}
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 526232f44ee1e..a8b4b23dc129a 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -126,6 +126,7 @@
 #![feature(const_intrinsic_forget)]
 #![feature(const_ipv4)]
 #![feature(const_ipv6)]
+#![feature(const_iter)]
 #![feature(const_likely)]
 #![feature(const_maybe_uninit_uninit_array)]
 #![feature(const_maybe_uninit_as_mut_ptr)]

From 0dc36fcd5b0bdf07fe1c180c050e0337f1cd3efe Mon Sep 17 00:00:00 2001
From: Ezra Shaw <ezrasure@outlook.com>
Date: Thu, 16 Mar 2023 22:21:59 +1300
Subject: [PATCH 11/16] fix: don't suggest similar method when unstable

---
 compiler/rustc_hir_typeck/src/method/probe.rs |  9 ++++++++
 .../auxiliary/similar-unstable-method.rs      | 13 ++++++++++++
 tests/ui/stability-attribute/issue-109177.rs  | 13 ++++++++++++
 .../stability-attribute/issue-109177.stderr   | 21 +++++++++++++++++++
 4 files changed, 56 insertions(+)
 create mode 100644 tests/ui/stability-attribute/auxiliary/similar-unstable-method.rs
 create mode 100644 tests/ui/stability-attribute/issue-109177.rs
 create mode 100644 tests/ui/stability-attribute/issue-109177.stderr

diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 3254a93034236..79ef2d053fec3 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -1027,6 +1027,15 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                     true
                 }
             })
+            // ensure that we don't suggest unstable methods
+            .filter(|candidate| {
+                // note that `DUMMY_SP` is ok here because it is only used for
+                // suggestions and macro stuff which isn't applicable here.
+                !matches!(
+                    self.tcx.eval_stability(candidate.item.def_id, None, DUMMY_SP, None),
+                    stability::EvalResult::Deny { .. }
+                )
+            })
             .map(|candidate| candidate.item.ident(self.tcx))
             .filter(|&name| set.insert(name))
             .collect();
diff --git a/tests/ui/stability-attribute/auxiliary/similar-unstable-method.rs b/tests/ui/stability-attribute/auxiliary/similar-unstable-method.rs
new file mode 100644
index 0000000000000..8804186ee1a6b
--- /dev/null
+++ b/tests/ui/stability-attribute/auxiliary/similar-unstable-method.rs
@@ -0,0 +1,13 @@
+#![feature(staged_api)]
+#![stable(feature = "libfoo", since = "1.0.0")]
+
+#[unstable(feature = "foo", reason = "...", issue = "none")]
+pub fn foo() {}
+
+#[stable(feature = "libfoo", since = "1.0.0")]
+pub struct Foo;
+
+impl Foo {
+    #[unstable(feature = "foo", reason = "...", issue = "none")]
+    pub fn foo(&self) {}
+}
diff --git a/tests/ui/stability-attribute/issue-109177.rs b/tests/ui/stability-attribute/issue-109177.rs
new file mode 100644
index 0000000000000..6d052779c6d36
--- /dev/null
+++ b/tests/ui/stability-attribute/issue-109177.rs
@@ -0,0 +1,13 @@
+// aux-build: similar-unstable-method.rs
+
+extern crate similar_unstable_method;
+
+fn main() {
+    // FIXME: this function should not suggest the `foo` function.
+    similar_unstable_method::foo1();
+    //~^ ERROR cannot find function `foo1` in crate `similar_unstable_method` [E0425]
+
+    let foo = similar_unstable_method::Foo;
+    foo.foo1();
+    //~^ ERROR no method named `foo1` found for struct `Foo` in the current scope [E0599]
+}
diff --git a/tests/ui/stability-attribute/issue-109177.stderr b/tests/ui/stability-attribute/issue-109177.stderr
new file mode 100644
index 0000000000000..9c2ac591ace05
--- /dev/null
+++ b/tests/ui/stability-attribute/issue-109177.stderr
@@ -0,0 +1,21 @@
+error[E0425]: cannot find function `foo1` in crate `similar_unstable_method`
+  --> $DIR/issue-109177.rs:7:30
+   |
+LL |     similar_unstable_method::foo1();
+   |                              ^^^^ help: a function with a similar name exists: `foo`
+   |
+  ::: $DIR/auxiliary/similar-unstable-method.rs:5:1
+   |
+LL | pub fn foo() {}
+   | ------------ similarly named function `foo` defined here
+
+error[E0599]: no method named `foo1` found for struct `Foo` in the current scope
+  --> $DIR/issue-109177.rs:11:9
+   |
+LL |     foo.foo1();
+   |         ^^^^ method not found in `Foo`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0425, E0599.
+For more information about an error, try `rustc --explain E0425`.

From d1712f49d72c3455abf275f1fb1d5b7653d02e2c Mon Sep 17 00:00:00 2001
From: Gus Caplan <me@gus.host>
Date: Sun, 5 Mar 2023 18:55:30 -0800
Subject: [PATCH 12/16] move default backtrace setting to sys

---
 library/std/src/panic.rs   | 3 +--
 library/std/src/sys/mod.rs | 9 +++++++++
 src/tools/tidy/src/pal.rs  | 1 -
 3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs
index 9fa8f5702a843..c827205f80bd7 100644
--- a/library/std/src/panic.rs
+++ b/library/std/src/panic.rs
@@ -308,8 +308,7 @@ pub fn get_backtrace_style() -> Option<BacktraceStyle> {
                 BacktraceStyle::Short
             }
         })
-        .unwrap_or(if cfg!(target_os = "fuchsia") {
-            // Fuchsia components default to full backtrace.
+        .unwrap_or(if crate::sys::BACKTRACE_DEFAULT {
             BacktraceStyle::Full
         } else {
             BacktraceStyle::Off
diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs
index c080c176a2ace..3864a5195f34b 100644
--- a/library/std/src/sys/mod.rs
+++ b/library/std/src/sys/mod.rs
@@ -76,3 +76,12 @@ cfg_if::cfg_if! {
         pub mod c;
     }
 }
+
+cfg_if::cfg_if! {
+    // Fuchsia components default to full backtrace.
+    if #[cfg(target_os = "fuchsia")] {
+        pub const BACKTRACE_DEFAULT: bool = true;
+    } else {
+        pub const BACKTRACE_DEFAULT: bool = false;
+    }
+}
diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs
index 868579b4b1a8c..6b7b27fd526c3 100644
--- a/src/tools/tidy/src/pal.rs
+++ b/src/tools/tidy/src/pal.rs
@@ -59,7 +59,6 @@ const EXCEPTION_PATHS: &[&str] = &[
     "library/std/src/path.rs",
     "library/std/src/sys_common", // Should only contain abstractions over platforms
     "library/std/src/net/test.rs", // Utility helpers for tests
-    "library/std/src/panic.rs",   // fuchsia-specific panic backtrace handling
     "library/std/src/personality.rs",
     "library/std/src/personality/",
 ];

From 3ae03c7aee740eda1f18ec7c189bc705cfb44964 Mon Sep 17 00:00:00 2001
From: Gus Caplan <me@gus.host>
Date: Fri, 17 Mar 2023 21:00:10 -0700
Subject: [PATCH 13/16] review

---
 library/std/src/panic.rs   | 2 +-
 library/std/src/sys/mod.rs | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs
index c827205f80bd7..345d72ef8678e 100644
--- a/library/std/src/panic.rs
+++ b/library/std/src/panic.rs
@@ -308,7 +308,7 @@ pub fn get_backtrace_style() -> Option<BacktraceStyle> {
                 BacktraceStyle::Short
             }
         })
-        .unwrap_or(if crate::sys::BACKTRACE_DEFAULT {
+        .unwrap_or(if crate::sys::FULL_BACKTRACE_DEFAULT {
             BacktraceStyle::Full
         } else {
             BacktraceStyle::Off
diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs
index 3864a5195f34b..e767b2866cb9b 100644
--- a/library/std/src/sys/mod.rs
+++ b/library/std/src/sys/mod.rs
@@ -80,8 +80,8 @@ cfg_if::cfg_if! {
 cfg_if::cfg_if! {
     // Fuchsia components default to full backtrace.
     if #[cfg(target_os = "fuchsia")] {
-        pub const BACKTRACE_DEFAULT: bool = true;
+        pub const FULL_BACKTRACE_DEFAULT: bool = true;
     } else {
-        pub const BACKTRACE_DEFAULT: bool = false;
+        pub const FULL_BACKTRACE_DEFAULT: bool = false;
     }
 }

From 8a9d6bf4fd540b2a2882193cbd6232b86e5dcd7e Mon Sep 17 00:00:00 2001
From: onestacked <chrisi.schrefl@gmail.com>
Date: Sat, 4 Feb 2023 17:48:46 +0100
Subject: [PATCH 14/16] Mark DoubleEndedIterator as #[const_trait] using
 rustc_do_not_const_check, implement const Iterator and DoubleEndedIterator
 for Range.

---
 library/core/src/iter/range.rs                | 12 ++++---
 library/core/src/iter/traits/double_ended.rs  | 11 +++++-
 library/core/src/iter/traits/iterator.rs      | 13 ++++---
 library/core/src/lib.rs                       |  1 +
 library/core/tests/iter/consts.rs             | 36 +++++++++++++++++++
 library/core/tests/iter/mod.rs                |  2 ++
 library/core/tests/lib.rs                     |  3 ++
 .../ui/typeck/typeck_type_placeholder_item.rs |  1 -
 .../typeck_type_placeholder_item.stderr       | 15 +-------
 9 files changed, 70 insertions(+), 24 deletions(-)
 create mode 100644 library/core/tests/iter/consts.rs

diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs
index dba2b2291ff6e..f19636fba5d95 100644
--- a/library/core/src/iter/range.rs
+++ b/library/core/src/iter/range.rs
@@ -1,4 +1,5 @@
 use crate::convert::TryFrom;
+use crate::marker::Destruct;
 use crate::mem;
 use crate::ops::{self, Try};
 
@@ -522,6 +523,7 @@ macro_rules! range_incl_exact_iter_impl {
 }
 
 /// Specialization implementations for `Range`.
+#[const_trait]
 trait RangeIteratorImpl {
     type Item;
 
@@ -536,7 +538,7 @@ trait RangeIteratorImpl {
     fn spec_advance_back_by(&mut self, n: usize) -> Result<(), usize>;
 }
 
-impl<A: Step> RangeIteratorImpl for ops::Range<A> {
+impl<A: ~const Step + ~const Destruct> const RangeIteratorImpl for ops::Range<A> {
     type Item = A;
 
     #[inline]
@@ -622,7 +624,7 @@ impl<A: Step> RangeIteratorImpl for ops::Range<A> {
     }
 }
 
-impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
+impl<T: ~const TrustedStep + ~const Destruct> const RangeIteratorImpl for ops::Range<T> {
     #[inline]
     fn spec_next(&mut self) -> Option<T> {
         if self.start < self.end {
@@ -710,7 +712,8 @@ impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Step> Iterator for ops::Range<A> {
+#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
+impl<A: ~const Step + ~const Destruct> const Iterator for ops::Range<A> {
     type Item = A;
 
     #[inline]
@@ -820,7 +823,8 @@ range_incl_exact_iter_impl! {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Step> DoubleEndedIterator for ops::Range<A> {
+#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
+impl<A: ~const Step + ~const Destruct> const DoubleEndedIterator for ops::Range<A> {
     #[inline]
     fn next_back(&mut self) -> Option<A> {
         self.spec_next_back()
diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs
index ed23873cdde7c..7a10dea500a96 100644
--- a/library/core/src/iter/traits/double_ended.rs
+++ b/library/core/src/iter/traits/double_ended.rs
@@ -1,3 +1,4 @@
+use crate::marker::Destruct;
 use crate::ops::{ControlFlow, Try};
 
 /// An iterator able to yield elements from both ends.
@@ -37,6 +38,7 @@ use crate::ops::{ControlFlow, Try};
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 #[cfg_attr(not(test), rustc_diagnostic_item = "DoubleEndedIterator")]
+#[const_trait]
 pub trait DoubleEndedIterator: Iterator {
     /// Removes and returns an element from the end of the iterator.
     ///
@@ -131,7 +133,10 @@ pub trait DoubleEndedIterator: Iterator {
     /// [`Err(k)`]: Err
     #[inline]
     #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")]
-    fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), usize>
+    where
+        Self::Item: ~const Destruct,
+    {
         for i in 0..n {
             self.next_back().ok_or(i)?;
         }
@@ -181,6 +186,7 @@ pub trait DoubleEndedIterator: Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iter_nth_back", since = "1.37.0")]
+    #[rustc_do_not_const_check]
     fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
         self.advance_back_by(n).ok()?;
         self.next_back()
@@ -218,6 +224,7 @@ pub trait DoubleEndedIterator: Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iterator_try_fold", since = "1.27.0")]
+    #[rustc_do_not_const_check]
     fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
     where
         Self: Sized,
@@ -289,6 +296,7 @@ pub trait DoubleEndedIterator: Iterator {
     #[doc(alias = "foldr")]
     #[inline]
     #[stable(feature = "iter_rfold", since = "1.27.0")]
+    #[rustc_do_not_const_check]
     fn rfold<B, F>(mut self, init: B, mut f: F) -> B
     where
         Self: Sized,
@@ -344,6 +352,7 @@ pub trait DoubleEndedIterator: Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iter_rfind", since = "1.27.0")]
+    #[rustc_do_not_const_check]
     fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
     where
         Self: Sized,
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index d48760ab3ebfa..6fc86550b63e7 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -1,5 +1,6 @@
 use crate::array;
 use crate::cmp::{self, Ordering};
+use crate::marker::Destruct;
 use crate::ops::{ChangeOutputType, ControlFlow, FromResidual, Residual, Try};
 
 use super::super::try_process;
@@ -336,8 +337,10 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")]
-    #[rustc_do_not_const_check]
-    fn advance_by(&mut self, n: usize) -> Result<(), usize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), usize>
+    where
+        Self::Item: ~const Destruct,
+    {
         for i in 0..n {
             self.next().ok_or(i)?;
         }
@@ -385,8 +388,10 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_do_not_const_check]
-    fn nth(&mut self, n: usize) -> Option<Self::Item> {
+    fn nth(&mut self, n: usize) -> Option<Self::Item>
+    where
+        Self::Item: ~const Destruct,
+    {
         self.advance_by(n).ok()?;
         self.next()
     }
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index a8b4b23dc129a..1076d357070ef 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -123,6 +123,7 @@
 #![feature(const_index_range_slice_index)]
 #![feature(const_inherent_unchecked_arith)]
 #![feature(const_int_unchecked_arith)]
+#![feature(const_intoiterator_identity)]
 #![feature(const_intrinsic_forget)]
 #![feature(const_ipv4)]
 #![feature(const_ipv6)]
diff --git a/library/core/tests/iter/consts.rs b/library/core/tests/iter/consts.rs
new file mode 100644
index 0000000000000..d56687e48c96a
--- /dev/null
+++ b/library/core/tests/iter/consts.rs
@@ -0,0 +1,36 @@
+#[test]
+fn const_manual_iter() {
+    struct S(bool);
+
+    impl const Iterator for S {
+        type Item = ();
+
+        fn next(&mut self) -> Option<Self::Item> {
+            if self.0 == false {
+                self.0 = true;
+                Some(())
+            } else {
+                None
+            }
+        }
+    }
+    const {
+        let mut val = S(false);
+        assert!(val.next().is_some());
+        assert!(val.next().is_none());
+        assert!(val.next().is_none());
+    }
+}
+
+#[test]
+fn const_range() {
+    const {
+        let mut arr = [0; 3];
+        for i in 0..arr.len() {
+            arr[i] = i;
+        }
+        assert!(arr[0] == 0);
+        assert!(arr[1] == 1);
+        assert!(arr[2] == 2);
+    }
+}
diff --git a/library/core/tests/iter/mod.rs b/library/core/tests/iter/mod.rs
index 770b6f7601fa2..cbb18e79e2d43 100644
--- a/library/core/tests/iter/mod.rs
+++ b/library/core/tests/iter/mod.rs
@@ -20,6 +20,8 @@ mod range;
 mod sources;
 mod traits;
 
+mod consts;
+
 use core::cell::Cell;
 use core::convert::TryFrom;
 use core::iter::*;
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index ccb7be68eb1b2..637cc6e9f629b 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -12,8 +12,11 @@
 #![feature(const_caller_location)]
 #![feature(const_cell_into_inner)]
 #![feature(const_convert)]
+#![feature(const_for)]
 #![feature(const_hash)]
 #![feature(const_heap)]
+#![feature(const_intoiterator_identity)]
+#![feature(const_iter)]
 #![feature(const_maybe_uninit_as_mut_ptr)]
 #![feature(const_maybe_uninit_assume_init_read)]
 #![feature(const_nonnull_new)]
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs
index a450dbb82d1bd..e6f7dc410b614 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.rs
+++ b/tests/ui/typeck/typeck_type_placeholder_item.rs
@@ -228,5 +228,4 @@ fn evens_squared(n: usize) -> _ {
 
 const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
 //~^ ERROR the trait bound
-//~| ERROR the trait bound
 //~| ERROR the placeholder
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr
index bc6c9fd077993..9144ab9e3a6bd 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.stderr
+++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr
@@ -437,19 +437,6 @@ LL | fn evens_squared(n: usize) -> _ {
    |                               not allowed in type signatures
    |                               help: replace with an appropriate return type: `impl Iterator<Item = usize>`
 
-error[E0277]: the trait bound `std::ops::Range<{integer}>: Iterator` is not satisfied
-  --> $DIR/typeck_type_placeholder_item.rs:229:22
-   |
-LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
-   |                      ^^^^^^ `std::ops::Range<{integer}>` is not an iterator
-   |
-   = help: the trait `~const Iterator` is not implemented for `std::ops::Range<{integer}>`
-note: the trait `Iterator` is implemented for `std::ops::Range<{integer}>`, but that implementation is not `const`
-  --> $DIR/typeck_type_placeholder_item.rs:229:14
-   |
-LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
-   |              ^^^^^^^
-
 error[E0277]: the trait bound `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>: Iterator` is not satisfied
   --> $DIR/typeck_type_placeholder_item.rs:229:45
    |
@@ -677,7 +664,7 @@ LL |     const D: _ = 42;
    |              not allowed in type signatures
    |              help: replace with the correct type: `i32`
 
-error: aborting due to 73 previous errors
+error: aborting due to 72 previous errors
 
 Some errors have detailed explanations: E0121, E0277, E0282, E0403.
 For more information about an error, try `rustc --explain E0121`.

From 38be6f2cbb586c3fc9c52ca27162323c8bb2f77a Mon Sep 17 00:00:00 2001
From: Camille GILLOT <gillot.camille@gmail.com>
Date: Sat, 18 Mar 2023 18:53:07 +0000
Subject: [PATCH 15/16] Implement FixedSizeEncoding for UnusedGenericParams.

---
 .../src/rmeta/decoder/cstore_impl.rs          | 10 +------
 compiler/rustc_metadata/src/rmeta/encoder.rs  |  4 +--
 compiler/rustc_metadata/src/rmeta/mod.rs      |  2 +-
 compiler/rustc_metadata/src/rmeta/table.rs    | 27 ++++++++++++++++++-
 compiler/rustc_middle/src/ty/instance.rs      | 14 ++++++++++
 5 files changed, 43 insertions(+), 14 deletions(-)

diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index a98433953367b..98eae70b4b708 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -226,15 +226,7 @@ provide! { tcx, def_id, other, cdata,
     lookup_default_body_stability => { table }
     lookup_deprecation_entry => { table }
     params_in_repr => { table }
-    // FIXME: Could be defaulted, but `LazyValue<UnusedGenericParams>` is not `FixedSizeEncoding`..
-    unused_generic_params => {
-        cdata
-            .root
-            .tables
-            .unused_generic_params
-            .get(cdata, def_id.index)
-            .map_or_else(|| ty::UnusedGenericParams::new_all_used(), |lazy| lazy.decode((cdata, tcx)))
-    }
+    unused_generic_params => { cdata.root.tables.unused_generic_params.get(cdata, def_id.index) }
     opt_def_kind => { table_direct }
     impl_parent => { table }
     impl_polarity => { table_direct }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index c778574b2c57b..19745988c5919 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1440,9 +1440,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             let instance =
                 ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id.to_def_id()));
             let unused = tcx.unused_generic_params(instance);
-            if !unused.all_used() {
-                record!(self.tables.unused_generic_params[def_id.to_def_id()] <- unused);
-            }
+            self.tables.unused_generic_params.set(def_id.local_def_index, unused);
         }
 
         // Encode all the deduced parameter attributes for everything that has MIR, even for items
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index e71a1c9810249..6f20ac9e5275f 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -356,6 +356,7 @@ define_tables! {
     inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
     associated_items_for_impl_trait_in_trait: Table<DefIndex, LazyArray<DefId>>,
     opt_rpitit_info: Table<DefIndex, Option<LazyValue<ty::ImplTraitInTraitData>>>,
+    unused_generic_params: Table<DefIndex, UnusedGenericParams>,
 
 - optional:
     attributes: Table<DefIndex, LazyArray<ast::Attribute>>,
@@ -398,7 +399,6 @@ define_tables! {
     trait_def: Table<DefIndex, LazyValue<ty::TraitDef>>,
     trait_item_def_id: Table<DefIndex, RawDefId>,
     expn_that_defined: Table<DefIndex, LazyValue<ExpnId>>,
-    unused_generic_params: Table<DefIndex, LazyValue<UnusedGenericParams>>,
     params_in_repr: Table<DefIndex, LazyValue<BitSet<u32>>>,
     repr_options: Table<DefIndex, LazyValue<ReprOptions>>,
     // `def_keys` and `def_path_hashes` represent a lazy version of a
diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs
index b89d48ec15ae9..364fa74ab7b45 100644
--- a/compiler/rustc_metadata/src/rmeta/table.rs
+++ b/compiler/rustc_metadata/src/rmeta/table.rs
@@ -3,7 +3,7 @@ use crate::rmeta::*;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_hir::def::{CtorKind, CtorOf};
 use rustc_index::vec::Idx;
-use rustc_middle::ty::ParameterizedOverTcx;
+use rustc_middle::ty::{ParameterizedOverTcx, UnusedGenericParams};
 use rustc_serialize::opaque::FileEncoder;
 use rustc_serialize::Encoder as _;
 use rustc_span::hygiene::MacroKind;
@@ -50,6 +50,16 @@ impl IsDefault for DefPathHash {
     }
 }
 
+impl IsDefault for UnusedGenericParams {
+    fn is_default(&self) -> bool {
+        // UnusedGenericParams encodes the *un*usedness as a bitset.
+        // This means that 0 corresponds to all bits used, which is indeed the default.
+        let is_default = self.bits() == 0;
+        debug_assert_eq!(is_default, self.all_used());
+        is_default
+    }
+}
+
 /// Helper trait, for encoding to, and decoding from, a fixed number of bytes.
 /// Used mainly for Lazy positions and lengths.
 /// Unchecked invariant: `Self::default()` should encode as `[0; BYTE_LEN]`,
@@ -271,6 +281,21 @@ impl FixedSizeEncoding for bool {
     }
 }
 
+impl FixedSizeEncoding for UnusedGenericParams {
+    type ByteArray = [u8; 4];
+
+    #[inline]
+    fn from_bytes(b: &[u8; 4]) -> Self {
+        let x: u32 = u32::from_bytes(b);
+        UnusedGenericParams::from_bits(x)
+    }
+
+    #[inline]
+    fn write_to_bytes(self, b: &mut [u8; 4]) {
+        self.bits().write_to_bytes(b);
+    }
+}
+
 // NOTE(eddyb) there could be an impl for `usize`, which would enable a more
 // generic `LazyValue<T>` impl, but in the general case we might not need / want
 // to fit every `usize` in `u32`.
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index f4028a5a9f63a..5fc98f01a5470 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -781,6 +781,12 @@ fn needs_fn_once_adapter_shim(
 #[derive(Debug, Copy, Clone, Eq, PartialEq, Decodable, Encodable, HashStable)]
 pub struct UnusedGenericParams(FiniteBitSet<u32>);
 
+impl Default for UnusedGenericParams {
+    fn default() -> Self {
+        UnusedGenericParams::new_all_used()
+    }
+}
+
 impl UnusedGenericParams {
     pub fn new_all_unused(amount: u32) -> Self {
         let mut bitset = FiniteBitSet::new_empty();
@@ -807,4 +813,12 @@ impl UnusedGenericParams {
     pub fn all_used(&self) -> bool {
         self.0.is_empty()
     }
+
+    pub fn bits(&self) -> u32 {
+        self.0.0
+    }
+
+    pub fn from_bits(bits: u32) -> UnusedGenericParams {
+        UnusedGenericParams(FiniteBitSet(bits))
+    }
 }

From d5558e67ef86bda546eca72778aeeeda24420926 Mon Sep 17 00:00:00 2001
From: yukang <moorekang@gmail.com>
Date: Fri, 17 Mar 2023 09:23:46 +0800
Subject: [PATCH 16/16] The name of NativeLib will be presented

---
 compiler/rustc_codegen_ssa/src/back/link.rs   | 19 +++--
 .../src/back/symbol_export.rs                 |  2 +-
 compiler/rustc_codegen_ssa/src/lib.rs         |  2 +-
 compiler/rustc_metadata/src/native_libs.rs    | 75 +++++++++----------
 compiler/rustc_session/src/cstore.rs          |  7 +-
 compiler/rustc_session/src/utils.rs           |  9 ++-
 tests/ui/linkage-attr/issue-109144.rs         |  4 +
 tests/ui/linkage-attr/issue-109144.stderr     |  9 +++
 8 files changed, 71 insertions(+), 56 deletions(-)
 create mode 100644 tests/ui/linkage-attr/issue-109144.rs
 create mode 100644 tests/ui/linkage-attr/issue-109144.stderr

diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 8aa744ce93531..64742bbb98664 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -358,9 +358,9 @@ fn link_rlib<'a>(
             let (data, _) = create_wrapper_file(sess, b".bundled_lib".to_vec(), &src);
             let wrapper_file = emit_wrapper_file(sess, &data, tmpdir, filename.as_str());
             packed_bundled_libs.push(wrapper_file);
-        } else if let Some(name) = lib.name {
+        } else {
             let path =
-                find_native_static_library(name.as_str(), lib.verbatim, &lib_search_paths, sess);
+                find_native_static_library(lib.name.as_str(), lib.verbatim, &lib_search_paths, sess);
             ab.add_archive(&path, Box::new(|_| false)).unwrap_or_else(|error| {
                 sess.emit_fatal(errors::AddNativeLibrary { library_path: path, error })});
         }
@@ -436,7 +436,7 @@ fn collate_raw_dylibs<'a, 'b>(
     for lib in used_libraries {
         if lib.kind == NativeLibKind::RawDylib {
             let ext = if lib.verbatim { "" } else { ".dll" };
-            let name = format!("{}{}", lib.name.expect("unnamed raw-dylib library"), ext);
+            let name = format!("{}{}", lib.name, ext);
             let imports = dylib_table.entry(name.clone()).or_default();
             for import in &lib.dll_imports {
                 if let Some(old_import) = imports.insert(import.name, import) {
@@ -1294,7 +1294,7 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
         .iter()
         .filter(|l| relevant_lib(sess, l))
         .filter_map(|lib| {
-            let name = lib.name?;
+            let name = lib.name;
             match lib.kind {
                 NativeLibKind::Static { bundle: Some(false), .. }
                 | NativeLibKind::Dylib { .. }
@@ -1315,6 +1315,7 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
                 // These are included, no need to print them
                 NativeLibKind::Static { bundle: None | Some(true), .. }
                 | NativeLibKind::LinkArg
+                | NativeLibKind::WasmImportModule
                 | NativeLibKind::RawDylib => None,
             }
         })
@@ -2273,21 +2274,18 @@ fn add_native_libs_from_crate(
 
     let mut last = (None, NativeLibKind::Unspecified, false);
     for lib in native_libs {
-        let Some(name) = lib.name else {
-            continue;
-        };
         if !relevant_lib(sess, lib) {
             continue;
         }
 
         // Skip if this library is the same as the last.
-        last = if (lib.name, lib.kind, lib.verbatim) == last {
+        last = if (Some(lib.name), lib.kind, lib.verbatim) == last {
             continue;
         } else {
-            (lib.name, lib.kind, lib.verbatim)
+            (Some(lib.name), lib.kind, lib.verbatim)
         };
 
-        let name = name.as_str();
+        let name = lib.name.as_str();
         let verbatim = lib.verbatim;
         match lib.kind {
             NativeLibKind::Static { bundle, whole_archive } => {
@@ -2344,6 +2342,7 @@ fn add_native_libs_from_crate(
             NativeLibKind::RawDylib => {
                 // Handled separately in `linker_with_args`.
             }
+            NativeLibKind::WasmImportModule => {}
             NativeLibKind::LinkArg => {
                 if link_static {
                     cmd.arg(name);
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index 7b58e55dbe84a..18d17b1a0137c 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -595,7 +595,7 @@ fn wasm_import_module_map(tcx: TyCtxt<'_>, cnum: CrateNum) -> FxHashMap<DefId, S
 
     let mut ret = FxHashMap::default();
     for (def_id, lib) in tcx.foreign_modules(cnum).iter() {
-        let module = def_id_to_native_lib.get(&def_id).and_then(|s| s.wasm_import_module);
+        let module = def_id_to_native_lib.get(&def_id).and_then(|s| s.wasm_import_module());
         let Some(module) = module else { continue };
         ret.extend(lib.foreign_items.iter().map(|id| {
             assert_eq!(id.krate, cnum);
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 8e721a84eaf49..81227b04e8a7e 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -118,7 +118,7 @@ bitflags::bitflags! {
 #[derive(Clone, Debug, Encodable, Decodable, HashStable)]
 pub struct NativeLib {
     pub kind: NativeLibKind,
-    pub name: Option<Symbol>,
+    pub name: Symbol,
     pub filename: Option<Symbol>,
     pub cfg: Option<ast::MetaItem>,
     pub verbatim: bool,
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index 6b6aa78575ae9..b855c8e433266 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -46,14 +46,13 @@ pub fn find_native_static_library(
 }
 
 fn find_bundled_library(
-    name: Option<Symbol>,
+    name: Symbol,
     verbatim: Option<bool>,
     kind: NativeLibKind,
     has_cfg: bool,
     sess: &Session,
 ) -> Option<Symbol> {
     if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive } = kind
-        && let Some(name) = name
         && sess.crate_types().iter().any(|t| matches!(t, &CrateType::Rlib | CrateType::Staticlib))
         && (sess.opts.unstable_opts.packed_bundled_libs || has_cfg || whole_archive == Some(true))
     {
@@ -337,10 +336,16 @@ impl<'tcx> Collector<'tcx> {
                 if name.is_some() || kind.is_some() || modifiers.is_some() || cfg.is_some() {
                     sess.emit_err(errors::IncompatibleWasmLink { span });
                 }
-            } else if name.is_none() {
-                sess.emit_err(errors::LinkRequiresName { span: m.span });
             }
 
+            if wasm_import_module.is_some() {
+                (name, kind) = (wasm_import_module, Some(NativeLibKind::WasmImportModule));
+            }
+            let Some((name, name_span)) = name else {
+                sess.emit_err(errors::LinkRequiresName { span: m.span });
+                continue;
+            };
+
             // Do this outside of the loop so that `import_name_type` can be specified before `kind`.
             if let Some((_, span)) = import_name_type {
                 if kind != Some(NativeLibKind::RawDylib) {
@@ -350,8 +355,8 @@ impl<'tcx> Collector<'tcx> {
 
             let dll_imports = match kind {
                 Some(NativeLibKind::RawDylib) => {
-                    if let Some((name, span)) = name && name.as_str().contains('\0') {
-                        sess.emit_err(errors::RawDylibNoNul { span });
+                    if name.as_str().contains('\0') {
+                        sess.emit_err(errors::RawDylibNoNul { span: name_span });
                     }
                     foreign_mod_items
                         .iter()
@@ -390,7 +395,6 @@ impl<'tcx> Collector<'tcx> {
                 }
             };
 
-            let name = name.map(|(name, _)| name);
             let kind = kind.unwrap_or(NativeLibKind::Unspecified);
             let filename = find_bundled_library(name, verbatim, kind, cfg.is_some(), sess);
             self.libs.push(NativeLib {
@@ -399,7 +403,6 @@ impl<'tcx> Collector<'tcx> {
                 kind,
                 cfg,
                 foreign_module: Some(it.owner_id.to_def_id()),
-                wasm_import_module: wasm_import_module.map(|(name, _)| name),
                 verbatim,
                 dll_imports,
             });
@@ -416,11 +419,7 @@ impl<'tcx> Collector<'tcx> {
                 self.tcx.sess.emit_err(errors::LibFrameworkApple);
             }
             if let Some(ref new_name) = lib.new_name {
-                let any_duplicate = self
-                    .libs
-                    .iter()
-                    .filter_map(|lib| lib.name.as_ref())
-                    .any(|n| n.as_str() == lib.name);
+                let any_duplicate = self.libs.iter().any(|n| n.name.as_str() == lib.name);
                 if new_name.is_empty() {
                     self.tcx.sess.emit_err(errors::EmptyRenamingTarget { lib_name: &lib.name });
                 } else if !any_duplicate {
@@ -445,33 +444,28 @@ impl<'tcx> Collector<'tcx> {
             let mut existing = self
                 .libs
                 .drain_filter(|lib| {
-                    if let Some(lib_name) = lib.name {
-                        if lib_name.as_str() == passed_lib.name {
-                            // FIXME: This whole logic is questionable, whether modifiers are
-                            // involved or not, library reordering and kind overriding without
-                            // explicit `:rename` in particular.
-                            if lib.has_modifiers() || passed_lib.has_modifiers() {
-                                match lib.foreign_module {
-                                    Some(def_id) => {
-                                        self.tcx.sess.emit_err(errors::NoLinkModOverride {
-                                            span: Some(self.tcx.def_span(def_id)),
-                                        })
-                                    }
-                                    None => self
-                                        .tcx
-                                        .sess
-                                        .emit_err(errors::NoLinkModOverride { span: None }),
-                                };
-                            }
-                            if passed_lib.kind != NativeLibKind::Unspecified {
-                                lib.kind = passed_lib.kind;
-                            }
-                            if let Some(new_name) = &passed_lib.new_name {
-                                lib.name = Some(Symbol::intern(new_name));
-                            }
-                            lib.verbatim = passed_lib.verbatim;
-                            return true;
+                    if lib.name.as_str() == passed_lib.name {
+                        // FIXME: This whole logic is questionable, whether modifiers are
+                        // involved or not, library reordering and kind overriding without
+                        // explicit `:rename` in particular.
+                        if lib.has_modifiers() || passed_lib.has_modifiers() {
+                            match lib.foreign_module {
+                                Some(def_id) => self.tcx.sess.emit_err(errors::NoLinkModOverride {
+                                    span: Some(self.tcx.def_span(def_id)),
+                                }),
+                                None => {
+                                    self.tcx.sess.emit_err(errors::NoLinkModOverride { span: None })
+                                }
+                            };
+                        }
+                        if passed_lib.kind != NativeLibKind::Unspecified {
+                            lib.kind = passed_lib.kind;
+                        }
+                        if let Some(new_name) = &passed_lib.new_name {
+                            lib.name = Symbol::intern(new_name);
                         }
+                        lib.verbatim = passed_lib.verbatim;
+                        return true;
                     }
                     false
                 })
@@ -479,7 +473,7 @@ impl<'tcx> Collector<'tcx> {
             if existing.is_empty() {
                 // Add if not found
                 let new_name: Option<&str> = passed_lib.new_name.as_deref();
-                let name = Some(Symbol::intern(new_name.unwrap_or(&passed_lib.name)));
+                let name = Symbol::intern(new_name.unwrap_or(&passed_lib.name));
                 let sess = self.tcx.sess;
                 let filename =
                     find_bundled_library(name, passed_lib.verbatim, passed_lib.kind, false, sess);
@@ -489,7 +483,6 @@ impl<'tcx> Collector<'tcx> {
                     kind: passed_lib.kind,
                     cfg: None,
                     foreign_module: None,
-                    wasm_import_module: None,
                     verbatim: passed_lib.verbatim,
                     dll_imports: Vec::new(),
                 });
diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs
index 868ffdf0f1da0..a262c06d91f03 100644
--- a/compiler/rustc_session/src/cstore.rs
+++ b/compiler/rustc_session/src/cstore.rs
@@ -67,12 +67,11 @@ pub enum LinkagePreference {
 #[derive(Debug, Encodable, Decodable, HashStable_Generic)]
 pub struct NativeLib {
     pub kind: NativeLibKind,
-    pub name: Option<Symbol>,
+    pub name: Symbol,
     /// If packed_bundled_libs enabled, actual filename of library is stored.
     pub filename: Option<Symbol>,
     pub cfg: Option<ast::MetaItem>,
     pub foreign_module: Option<DefId>,
-    pub wasm_import_module: Option<Symbol>,
     pub verbatim: Option<bool>,
     pub dll_imports: Vec<DllImport>,
 }
@@ -81,6 +80,10 @@ impl NativeLib {
     pub fn has_modifiers(&self) -> bool {
         self.verbatim.is_some() || self.kind.has_modifiers()
     }
+
+    pub fn wasm_import_module(&self) -> Option<Symbol> {
+        if self.kind == NativeLibKind::WasmImportModule { Some(self.name) } else { None }
+    }
 }
 
 /// Different ways that the PE Format can decorate a symbol name.
diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs
index b996d36a318c5..3b3d4ca5d6b21 100644
--- a/compiler/rustc_session/src/utils.rs
+++ b/compiler/rustc_session/src/utils.rs
@@ -37,6 +37,10 @@ pub enum NativeLibKind {
     /// Argument which is passed to linker, relative order with libraries and other arguments
     /// is preserved
     LinkArg,
+
+    /// Module imported from WebAssembly
+    WasmImportModule,
+
     /// The library kind wasn't specified, `Dylib` is currently used as a default.
     Unspecified,
 }
@@ -50,7 +54,10 @@ impl NativeLibKind {
             NativeLibKind::Dylib { as_needed } | NativeLibKind::Framework { as_needed } => {
                 as_needed.is_some()
             }
-            NativeLibKind::RawDylib | NativeLibKind::Unspecified | NativeLibKind::LinkArg => false,
+            NativeLibKind::RawDylib
+            | NativeLibKind::Unspecified
+            | NativeLibKind::LinkArg
+            | NativeLibKind::WasmImportModule => false,
         }
     }
 
diff --git a/tests/ui/linkage-attr/issue-109144.rs b/tests/ui/linkage-attr/issue-109144.rs
new file mode 100644
index 0000000000000..2f740e5538973
--- /dev/null
+++ b/tests/ui/linkage-attr/issue-109144.rs
@@ -0,0 +1,4 @@
+#![crate_type = "lib"]
+#[link(kind = "static", modifiers = "+whole-archive,+bundle")]
+//~^ ERROR `#[link]` attribute requires a `name = "string"` argument
+extern  {}
diff --git a/tests/ui/linkage-attr/issue-109144.stderr b/tests/ui/linkage-attr/issue-109144.stderr
new file mode 100644
index 0000000000000..33187cfdbb636
--- /dev/null
+++ b/tests/ui/linkage-attr/issue-109144.stderr
@@ -0,0 +1,9 @@
+error[E0459]: `#[link]` attribute requires a `name = "string"` argument
+  --> $DIR/issue-109144.rs:2:1
+   |
+LL | #[link(kind = "static", modifiers = "+whole-archive,+bundle")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `name` argument
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0459`.