diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index f5c4affdce2..75ccbc92be1 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1616,7 +1616,7 @@ pub enum StrStyle {
     /// A raw string, like `r##"foo"##`.
     ///
     /// The value is the number of `#` symbols used.
-    Raw(u16),
+    Raw(u8),
 }
 
 /// An AST literal.
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index 7df385873c1..2132cdfc001 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -59,9 +59,9 @@ pub enum LitKind {
     Integer,
     Float,
     Str,
-    StrRaw(u16), // raw string delimited by `n` hash symbols
+    StrRaw(u8), // raw string delimited by `n` hash symbols
     ByteStr,
-    ByteStrRaw(u16), // raw byte string delimited by `n` hash symbols
+    ByteStrRaw(u8), // raw byte string delimited by `n` hash symbols
     Err,
 }
 
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index d64f1a05712..9442e0f1a1f 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -618,9 +618,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
     /// Desugar `<expr>.await` into:
     /// ```rust
     /// match ::std::future::IntoFuture::into_future(<expr>) {
-    ///     mut pinned => loop {
+    ///     mut __awaitee => loop {
     ///         match unsafe { ::std::future::Future::poll(
-    ///             <::std::pin::Pin>::new_unchecked(&mut pinned),
+    ///             <::std::pin::Pin>::new_unchecked(&mut __awaitee),
     ///             ::std::future::get_context(task_context),
     ///         ) } {
     ///             ::std::task::Poll::Ready(result) => break result,
@@ -657,21 +657,24 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let expr = self.lower_expr_mut(expr);
         let expr_hir_id = expr.hir_id;
 
-        let pinned_ident = Ident::with_dummy_span(sym::pinned);
-        let (pinned_pat, pinned_pat_hid) =
-            self.pat_ident_binding_mode(span, pinned_ident, hir::BindingAnnotation::Mutable);
+        // Note that the name of this binding must not be changed to something else because
+        // debuggers and debugger extensions expect it to be called `__awaitee`. They use
+        // this name to identify what is being awaited by a suspended async functions.
+        let awaitee_ident = Ident::with_dummy_span(sym::__awaitee);
+        let (awaitee_pat, awaitee_pat_hid) =
+            self.pat_ident_binding_mode(span, awaitee_ident, hir::BindingAnnotation::Mutable);
 
         let task_context_ident = Ident::with_dummy_span(sym::_task_context);
 
         // unsafe {
         //     ::std::future::Future::poll(
-        //         ::std::pin::Pin::new_unchecked(&mut pinned),
+        //         ::std::pin::Pin::new_unchecked(&mut __awaitee),
         //         ::std::future::get_context(task_context),
         //     )
         // }
         let poll_expr = {
-            let pinned = self.expr_ident(span, pinned_ident, pinned_pat_hid);
-            let ref_mut_pinned = self.expr_mut_addr_of(span, pinned);
+            let awaitee = self.expr_ident(span, awaitee_ident, awaitee_pat_hid);
+            let ref_mut_awaitee = self.expr_mut_addr_of(span, awaitee);
             let task_context = if let Some(task_context_hid) = self.task_context {
                 self.expr_ident_mut(span, task_context_ident, task_context_hid)
             } else {
@@ -681,7 +684,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             let new_unchecked = self.expr_call_lang_item_fn_mut(
                 span,
                 hir::LangItem::PinNewUnchecked,
-                arena_vec![self; ref_mut_pinned],
+                arena_vec![self; ref_mut_awaitee],
                 Some(expr_hir_id),
             );
             let get_context = self.expr_call_lang_item_fn_mut(
@@ -782,8 +785,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
             span: self.lower_span(span),
         });
 
-        // mut pinned => loop { ... }
-        let pinned_arm = self.arm(pinned_pat, loop_expr);
+        // mut __awaitee => loop { ... }
+        let awaitee_arm = self.arm(awaitee_pat, loop_expr);
 
         // `match ::std::future::IntoFuture::into_future(<expr>) { ... }`
         let into_future_span = self.mark_span_with_reason(
@@ -799,11 +802,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
         );
 
         // match <into_future_expr> {
-        //     mut pinned => loop { .. }
+        //     mut __awaitee => loop { .. }
         // }
         hir::ExprKind::Match(
             into_future_expr,
-            arena_vec![self; pinned_arm],
+            arena_vec![self; awaitee_arm],
             hir::MatchSource::AwaitDesugar,
         )
     }
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 5b6147c7223..a778d8c5470 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -387,13 +387,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
         if attr.has_name(sym::link) {
             for nested_meta in attr.meta_item_list().unwrap_or_default() {
                 if nested_meta.has_name(sym::modifiers) {
-                    gate_feature_post!(
-                        self,
-                        native_link_modifiers,
-                        nested_meta.span(),
-                        "native link modifiers are experimental"
-                    );
-
                     if let Some(modifiers) = nested_meta.value_str() {
                         for modifier in modifiers.as_str().split(',') {
                             if let Some(modifier) = modifier.strip_prefix(&['+', '-']) {
@@ -412,7 +405,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                                 gate_modifier!(
                                     "bundle" => native_link_modifiers_bundle
                                     "verbatim" => native_link_modifiers_verbatim
-                                    "whole-archive" => native_link_modifiers_whole_archive
                                     "as-needed" => native_link_modifiers_as_needed
                                 );
                             }
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index dbbbbd5ecc0..548ae0e411d 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1844,7 +1844,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
     // This change is somewhat breaking in practice due to local static libraries being linked
     // as whole-archive (#85144), so removing whole-archive may be a pre-requisite.
     if sess.opts.debugging_opts.link_native_libraries {
-        add_local_native_libraries(cmd, sess, codegen_results);
+        add_local_native_libraries(cmd, sess, codegen_results, crate_type);
     }
 
     // Upstream rust libraries and their nobundle static libraries
@@ -2016,6 +2016,16 @@ fn add_order_independent_options(
     add_rpath_args(cmd, sess, codegen_results, out_filename);
 }
 
+// A dylib may reexport symbols from the linked rlib or native static library.
+// Even if some symbol is reexported it's still not necessarily counted as used and may be
+// dropped, at least with `ld`-like ELF linkers. So we have to link some rlibs and static
+// libraries as whole-archive to avoid losing reexported symbols.
+// FIXME: Find a way to mark reexported symbols as used and avoid this use of whole-archive.
+fn default_to_whole_archive(sess: &Session, crate_type: CrateType, cmd: &dyn Linker) -> bool {
+    crate_type == CrateType::Dylib
+        && !(sess.target.limit_rdylib_exports && cmd.exported_symbol_means_used_symbol())
+}
+
 /// # Native library linking
 ///
 /// User-supplied library search paths (-L on the command line). These are the same paths used to
@@ -2029,6 +2039,7 @@ fn add_local_native_libraries(
     cmd: &mut dyn Linker,
     sess: &Session,
     codegen_results: &CodegenResults,
+    crate_type: CrateType,
 ) {
     let filesearch = sess.target_filesearch(PathKind::All);
     for search_path in filesearch.search_paths() {
@@ -2046,14 +2057,18 @@ fn add_local_native_libraries(
         codegen_results.crate_info.used_libraries.iter().filter(|l| relevant_lib(sess, l));
 
     let search_path = OnceCell::new();
-    let mut last = (NativeLibKind::Unspecified, None);
+    let mut last = (None, NativeLibKind::Unspecified, None);
     for lib in relevant_libs {
         let Some(name) = lib.name else {
             continue;
         };
 
         // Skip if this library is the same as the last.
-        last = if (lib.kind, lib.name) == last { continue } else { (lib.kind, lib.name) };
+        last = if (lib.name, lib.kind, lib.verbatim) == last {
+            continue;
+        } else {
+            (lib.name, lib.kind, lib.verbatim)
+        };
 
         let verbatim = lib.verbatim.unwrap_or(false);
         match lib.kind {
@@ -2064,15 +2079,19 @@ fn add_local_native_libraries(
             NativeLibKind::Framework { as_needed } => {
                 cmd.link_framework(name, as_needed.unwrap_or(true))
             }
-            NativeLibKind::Static { bundle: None | Some(true), .. }
-            | NativeLibKind::Static { whole_archive: Some(true), .. } => {
-                cmd.link_whole_staticlib(
-                    name,
-                    verbatim,
-                    &search_path.get_or_init(|| archive_search_paths(sess)),
-                );
+            NativeLibKind::Static { whole_archive, .. } => {
+                if whole_archive == Some(true)
+                    || (whole_archive == None && default_to_whole_archive(sess, crate_type, cmd))
+                {
+                    cmd.link_whole_staticlib(
+                        name,
+                        verbatim,
+                        &search_path.get_or_init(|| archive_search_paths(sess)),
+                    );
+                } else {
+                    cmd.link_staticlib(name, verbatim)
+                }
             }
-            NativeLibKind::Static { .. } => cmd.link_staticlib(name, verbatim),
             NativeLibKind::RawDylib => {
                 // FIXME(#58713): Proper handling for raw dylibs.
                 bug!("raw_dylib feature not yet implemented");
@@ -2197,34 +2216,37 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
                 // external build system already has the native dependencies defined, and it
                 // will provide them to the linker itself.
                 if sess.opts.debugging_opts.link_native_libraries {
-                    let mut last = None;
+                    let mut last = (None, NativeLibKind::Unspecified, None);
                     for lib in &codegen_results.crate_info.native_libraries[&cnum] {
+                        let Some(name) = lib.name else {
+                            continue;
+                        };
                         if !relevant_lib(sess, lib) {
-                            // Skip libraries if they are disabled by `#[link(cfg=...)]`
                             continue;
                         }
 
                         // Skip if this library is the same as the last.
-                        if last == lib.name {
+                        last = if (lib.name, lib.kind, lib.verbatim) == last {
                             continue;
-                        }
+                        } else {
+                            (lib.name, lib.kind, lib.verbatim)
+                        };
 
-                        if let Some(static_lib_name) = lib.name {
-                            if let NativeLibKind::Static { bundle: Some(false), whole_archive } =
-                                lib.kind
+                        if let NativeLibKind::Static { bundle: Some(false), whole_archive } =
+                            lib.kind
+                        {
+                            let verbatim = lib.verbatim.unwrap_or(false);
+                            if whole_archive == Some(true)
+                                || (whole_archive == None
+                                    && default_to_whole_archive(sess, crate_type, cmd))
                             {
-                                let verbatim = lib.verbatim.unwrap_or(false);
-                                if whole_archive == Some(true) {
-                                    cmd.link_whole_staticlib(
-                                        static_lib_name,
-                                        verbatim,
-                                        search_path.get_or_init(|| archive_search_paths(sess)),
-                                    );
-                                } else {
-                                    cmd.link_staticlib(static_lib_name, verbatim);
-                                }
-
-                                last = lib.name;
+                                cmd.link_whole_staticlib(
+                                    name,
+                                    verbatim,
+                                    search_path.get_or_init(|| archive_search_paths(sess)),
+                                );
+                            } else {
+                                cmd.link_staticlib(name, verbatim);
                             }
                         }
                     }
@@ -2282,15 +2304,10 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
         let cratepath = &src.rlib.as_ref().unwrap().0;
 
         let mut link_upstream = |path: &Path| {
-            // If we're creating a dylib, then we need to include the
-            // whole of each object in our archive into that artifact. This is
-            // because a `dylib` can be reused as an intermediate artifact.
-            //
-            // Note, though, that we don't want to include the whole of a
-            // compiler-builtins crate (e.g., compiler-rt) because it'll get
-            // repeatedly linked anyway.
+            // We don't want to include the whole compiler-builtins crate (e.g., compiler-rt)
+            // regardless of the default because it'll get repeatedly linked anyway.
             let path = fix_windows_verbatim_for_gcc(path);
-            if crate_type == CrateType::Dylib
+            if default_to_whole_archive(sess, crate_type, cmd)
                 && codegen_results.crate_info.compiler_builtins != Some(cnum)
             {
                 cmd.link_whole_rlib(&path);
@@ -2401,7 +2418,7 @@ fn add_upstream_native_libraries(
     sess: &Session,
     codegen_results: &CodegenResults,
 ) {
-    let mut last = (NativeLibKind::Unspecified, None);
+    let mut last = (None, NativeLibKind::Unspecified, None);
     for &cnum in &codegen_results.crate_info.used_crates {
         for lib in codegen_results.crate_info.native_libraries[&cnum].iter() {
             let Some(name) = lib.name else {
@@ -2412,7 +2429,11 @@ fn add_upstream_native_libraries(
             }
 
             // Skip if this library is the same as the last.
-            last = if (lib.kind, lib.name) == last { continue } else { (lib.kind, lib.name) };
+            last = if (lib.name, lib.kind, lib.verbatim) == last {
+                continue;
+            } else {
+                (lib.name, lib.kind, lib.verbatim)
+            };
 
             let verbatim = lib.verbatim.unwrap_or(false);
             match lib.kind {
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index a838787381d..3a66bfafaf3 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -186,6 +186,9 @@ pub trait Linker {
     fn no_crt_objects(&mut self);
     fn no_default_libraries(&mut self);
     fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]);
+    fn exported_symbol_means_used_symbol(&self) -> bool {
+        true
+    }
     fn subsystem(&mut self, subsystem: &str);
     fn group_start(&mut self);
     fn group_end(&mut self);
@@ -724,6 +727,10 @@ impl<'a> Linker for GccLinker<'a> {
         }
     }
 
+    fn exported_symbol_means_used_symbol(&self) -> bool {
+        self.sess.target.is_like_windows || self.sess.target.is_like_osx
+    }
+
     fn subsystem(&mut self, subsystem: &str) {
         self.linker_arg("--subsystem");
         self.linker_arg(&subsystem);
@@ -1471,6 +1478,10 @@ impl<'a> Linker for L4Bender<'a> {
         return;
     }
 
+    fn exported_symbol_means_used_symbol(&self) -> bool {
+        false
+    }
+
     fn subsystem(&mut self, subsystem: &str) {
         self.cmd.arg(&format!("--subsystem {}", subsystem));
     }
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index ace0c9df58d..e37251c9c24 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -215,6 +215,10 @@ declare_features! (
     /// Allows patterns with concurrent by-move and by-ref bindings.
     /// For example, you can write `Foo(a, ref b)` where `a` is by-move and `b` is by-ref.
     (accepted, move_ref_pattern, "1.49.0", Some(68354), None),
+    /// Allows specifying modifiers in the link attribute: `#[link(modifiers = "...")]`
+    (accepted, native_link_modifiers, "1.61.0", Some(81490), None),
+    /// Allows specifying the whole-archive link modifier
+    (accepted, native_link_modifiers_whole_archive, "1.61.0", Some(81490), None),
     /// Allows using `#![no_std]`.
     (accepted, no_std, "1.6.0", None, None),
     /// Allows defining identifiers beyond ASCII.
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index feef7295254..28466315c86 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -400,6 +400,8 @@ declare_features! (
     (active, generic_arg_infer, "1.55.0", Some(85077), None),
     /// Allows associated types to be generic, e.g., `type Foo<T>;` (RFC 1598).
     (active, generic_associated_types, "1.23.0", Some(44265), None),
+    /// An extension to the `generic_associated_types` feature, allowing incomplete features.
+    (incomplete, generic_associated_types_extended, "1.61.0", Some(95451), None),
     /// Allows non-trivial generic constants which have to have wfness manually propagated to callers
     (incomplete, generic_const_exprs, "1.56.0", Some(76560), None),
     /// Allows using `..X`, `..=X`, `...X`, and `X..` as a pattern.
@@ -446,16 +448,12 @@ declare_features! (
     (active, must_not_suspend, "1.57.0", Some(83310), None),
     /// Allows using `#[naked]` on functions.
     (active, naked_functions, "1.9.0", Some(32408), None),
-    /// Allows specifying modifiers in the link attribute: `#[link(modifiers = "...")]`
-    (active, native_link_modifiers, "1.53.0", Some(81490), None),
     /// Allows specifying the as-needed link modifier
     (active, native_link_modifiers_as_needed, "1.53.0", Some(81490), None),
     /// Allows specifying the bundle link modifier
     (active, native_link_modifiers_bundle, "1.53.0", Some(81490), None),
     /// Allows specifying the verbatim link modifier
     (active, native_link_modifiers_verbatim, "1.53.0", Some(81490), None),
-    /// Allows specifying the whole-archive link modifier
-    (active, native_link_modifiers_whole_archive, "1.53.0", Some(81490), None),
     /// Allow negative trait implementations.
     (active, negative_impls, "1.44.0", Some(68318), None),
     /// Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more.
diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs
index 5b8300ab530..a41e0374f41 100644
--- a/compiler/rustc_lexer/src/lib.rs
+++ b/compiler/rustc_lexer/src/lib.rs
@@ -161,15 +161,15 @@ pub enum LiteralKind {
     /// "b"abc"", "b"abc"
     ByteStr { terminated: bool },
     /// "r"abc"", "r#"abc"#", "r####"ab"###"c"####", "r#"a"
-    RawStr { n_hashes: u16, err: Option<RawStrError> },
+    RawStr { n_hashes: u8, err: Option<RawStrError> },
     /// "br"abc"", "br#"abc"#", "br####"ab"###"c"####", "br#"a"
-    RawByteStr { n_hashes: u16, err: Option<RawStrError> },
+    RawByteStr { n_hashes: u8, err: Option<RawStrError> },
 }
 
 /// Error produced validating a raw string. Represents cases like:
 /// - `r##~"abcde"##`: `InvalidStarter`
 /// - `r###"abcde"##`: `NoTerminator { expected: 3, found: 2, possible_terminator_offset: Some(11)`
-/// - Too many `#`s (>65535): `TooManyDelimiters`
+/// - Too many `#`s (>255): `TooManyDelimiters`
 // perf note: It doesn't matter that this makes `Token` 36 bytes bigger. See #77629
 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
 pub enum RawStrError {
@@ -178,7 +178,7 @@ pub enum RawStrError {
     /// The string was never terminated. `possible_terminator_offset` is the number of characters after `r` or `br` where they
     /// may have intended to terminate it.
     NoTerminator { expected: usize, found: usize, possible_terminator_offset: Option<usize> },
-    /// More than 65535 `#`s exist.
+    /// More than 255 `#`s exist.
     TooManyDelimiters { found: usize },
 }
 
@@ -698,12 +698,12 @@ impl Cursor<'_> {
     }
 
     /// Eats the double-quoted string and returns `n_hashes` and an error if encountered.
-    fn raw_double_quoted_string(&mut self, prefix_len: usize) -> (u16, Option<RawStrError>) {
+    fn raw_double_quoted_string(&mut self, prefix_len: usize) -> (u8, Option<RawStrError>) {
         // Wrap the actual function to handle the error with too many hashes.
         // This way, it eats the whole raw string.
         let (n_hashes, err) = self.raw_string_unvalidated(prefix_len);
-        // Only up to 65535 `#`s are allowed in raw strings
-        match u16::try_from(n_hashes) {
+        // Only up to 255 `#`s are allowed in raw strings
+        match u8::try_from(n_hashes) {
             Ok(num) => (num, err),
             // We lie about the number of hashes here :P
             Err(_) => (0, Some(RawStrError::TooManyDelimiters { found: n_hashes })),
diff --git a/compiler/rustc_lexer/src/tests.rs b/compiler/rustc_lexer/src/tests.rs
index 548de67449a..07daee06f0f 100644
--- a/compiler/rustc_lexer/src/tests.rs
+++ b/compiler/rustc_lexer/src/tests.rs
@@ -2,7 +2,7 @@ use super::*;
 
 use expect_test::{expect, Expect};
 
-fn check_raw_str(s: &str, expected_hashes: u16, expected_err: Option<RawStrError>) {
+fn check_raw_str(s: &str, expected_hashes: u8, expected_err: Option<RawStrError>) {
     let s = &format!("r{}", s);
     let mut cursor = Cursor::new(s);
     cursor.bump();
@@ -68,13 +68,13 @@ fn test_unterminated_no_pound() {
 
 #[test]
 fn test_too_many_hashes() {
-    let max_count = u16::MAX;
+    let max_count = u8::MAX;
     let mut hashes: String = "#".repeat(max_count.into());
 
-    // Valid number of hashes (65535 = 2^16 - 1), but invalid string.
+    // Valid number of hashes (255 = 2^8 - 1 = u8::MAX), but invalid string.
     check_raw_str(&hashes, max_count, Some(RawStrError::InvalidStarter { bad_char: '\u{0}' }));
 
-    // One more hash sign (65536 = 2^16) becomes too many.
+    // One more hash sign (256 = 2^8) becomes too many.
     hashes.push('#');
     check_raw_str(
         &hashes,
diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs
index 8476c2bfcc4..0324ac3641e 100644
--- a/compiler/rustc_llvm/src/lib.rs
+++ b/compiler/rustc_llvm/src/lib.rs
@@ -1,5 +1,5 @@
 #![feature(nll)]
-#![feature(native_link_modifiers)]
+#![cfg_attr(bootstrap, feature(native_link_modifiers))]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 
 // NOTE: This crate only exists to allow linking on mingw targets.
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index c3a76112391..1cbfb0bd554 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -125,13 +125,18 @@ impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> {
 
             // Do this outside the above loop so we don't depend on modifiers coming
             // after kinds
-            if let Some(item) = items.iter().find(|item| item.has_name(sym::modifiers)) {
+            let mut modifiers_count = 0;
+            for item in items.iter().filter(|item| item.has_name(sym::modifiers)) {
                 if let Some(modifiers) = item.value_str() {
+                    modifiers_count += 1;
                     let span = item.name_value_literal_span().unwrap();
+                    let mut has_duplicate_modifiers = false;
                     for modifier in modifiers.as_str().split(',') {
                         let (modifier, value) = match modifier.strip_prefix(&['+', '-']) {
                             Some(m) => (m, modifier.starts_with('+')),
                             None => {
+                                // Note: this error also excludes the case with empty modifier
+                                // string, like `modifiers = ""`.
                                 sess.span_err(
                                     span,
                                     "invalid linking modifier syntax, expected '+' or '-' prefix \
@@ -143,6 +148,9 @@ impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> {
 
                         match (modifier, &mut lib.kind) {
                             ("bundle", NativeLibKind::Static { bundle, .. }) => {
+                                if bundle.is_some() {
+                                    has_duplicate_modifiers = true;
+                                }
                                 *bundle = Some(value);
                             }
                             ("bundle", _) => {
@@ -153,9 +161,17 @@ impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> {
                                 );
                             }
 
-                            ("verbatim", _) => lib.verbatim = Some(value),
+                            ("verbatim", _) => {
+                                if lib.verbatim.is_some() {
+                                    has_duplicate_modifiers = true;
+                                }
+                                lib.verbatim = Some(value);
+                            }
 
                             ("whole-archive", NativeLibKind::Static { whole_archive, .. }) => {
+                                if whole_archive.is_some() {
+                                    has_duplicate_modifiers = true;
+                                }
                                 *whole_archive = Some(value);
                             }
                             ("whole-archive", _) => {
@@ -168,6 +184,9 @@ impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> {
 
                             ("as-needed", NativeLibKind::Dylib { as_needed })
                             | ("as-needed", NativeLibKind::Framework { as_needed }) => {
+                                if as_needed.is_some() {
+                                    has_duplicate_modifiers = true;
+                                }
                                 *as_needed = Some(value);
                             }
                             ("as-needed", _) => {
@@ -190,12 +209,22 @@ impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> {
                             }
                         }
                     }
+                    if has_duplicate_modifiers {
+                        let msg =
+                            "same modifier is used multiple times in a single `modifiers` argument";
+                        sess.span_err(item.span(), msg);
+                    }
                 } else {
                     let msg = "must be of the form `#[link(modifiers = \"...\")]`";
                     sess.span_err(item.span(), msg);
                 }
             }
 
+            if modifiers_count > 1 {
+                let msg = "multiple `modifiers` arguments in a single `#[link]` attribute";
+                sess.span_err(m.span, msg);
+            }
+
             // In general we require #[link(name = "...")] but we allow
             // #[link(wasm_import_module = "...")] without the `name`.
             let requires_name = kind_specified || lib.wasm_import_module.is_none();
@@ -349,6 +378,15 @@ impl Collector<'_> {
                 .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() {
+                                self.tcx.sess.span_err(
+                                    self.tcx.def_span(lib.foreign_module.unwrap()),
+                                    "overriding linking modifiers from command line is not supported"
+                                );
+                            }
                             if passed_lib.kind != NativeLibKind::Unspecified {
                                 lib.kind = passed_lib.kind;
                             }
diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs
index 388109e6512..075928c889d 100644
--- a/compiler/rustc_middle/src/ty/fold.rs
+++ b/compiler/rustc_middle/src/ty/fold.rs
@@ -1379,3 +1379,50 @@ impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector {
         ControlFlow::CONTINUE
     }
 }
+
+/// Finds the max universe present
+pub struct MaxUniverse {
+    max_universe: ty::UniverseIndex,
+}
+
+impl MaxUniverse {
+    pub fn new() -> Self {
+        MaxUniverse { max_universe: ty::UniverseIndex::ROOT }
+    }
+
+    pub fn max_universe(self) -> ty::UniverseIndex {
+        self.max_universe
+    }
+}
+
+impl<'tcx> TypeVisitor<'tcx> for MaxUniverse {
+    fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
+        if let ty::Placeholder(placeholder) = t.kind() {
+            self.max_universe = ty::UniverseIndex::from_u32(
+                self.max_universe.as_u32().max(placeholder.universe.as_u32()),
+            );
+        }
+
+        t.super_visit_with(self)
+    }
+
+    fn visit_const(&mut self, c: ty::consts::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
+        if let ty::ConstKind::Placeholder(placeholder) = c.val() {
+            self.max_universe = ty::UniverseIndex::from_u32(
+                self.max_universe.as_u32().max(placeholder.universe.as_u32()),
+            );
+        }
+
+        c.super_visit_with(self)
+    }
+
+    fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
+        if let ty::RePlaceholder(placeholder) = *r {
+            self.max_universe = ty::UniverseIndex::from_u32(
+                self.max_universe.as_u32().max(placeholder.universe.as_u32()),
+            );
+        }
+
+        ControlFlow::CONTINUE
+    }
+}
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 92c5d329f6e..5ab412dc777 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -597,15 +597,13 @@ impl<'a> StringReader<'a> {
         }
     }
 
-    /// Note: It was decided to not add a test case, because it would be too big.
-    /// <https://github.com/rust-lang/rust/pull/50296#issuecomment-392135180>
     fn report_too_many_hashes(&self, start: BytePos, found: usize) -> ! {
         self.fatal_span_(
             start,
             self.pos,
             &format!(
                 "too many `#` symbols: raw strings may be delimited \
-                by up to 65535 `#` symbols, but found {}",
+                by up to 255 `#` symbols, but found {}",
                 found
             ),
         )
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 44a2e2bdc85..856436e44db 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -1948,9 +1948,6 @@ fn parse_native_lib_kind(
     kind: &str,
     error_format: ErrorOutputType,
 ) -> (NativeLibKind, Option<bool>) {
-    let is_nightly = nightly_options::match_is_nightly_build(matches);
-    let enable_unstable = nightly_options::is_unstable_enabled(matches);
-
     let (kind, modifiers) = match kind.split_once(':') {
         None => (kind, None),
         Some((kind, modifiers)) => (kind, Some(modifiers)),
@@ -1972,7 +1969,7 @@ fn parse_native_lib_kind(
                     "linking modifier can't be used with library kind `static-nobundle`",
                 )
             }
-            if !is_nightly {
+            if !nightly_options::match_is_nightly_build(matches) {
                 early_error(
                     error_format,
                     "library kind `static-nobundle` are currently unstable and only accepted on \
@@ -1988,23 +1985,7 @@ fn parse_native_lib_kind(
     };
     match modifiers {
         None => (kind, None),
-        Some(modifiers) => {
-            if !is_nightly {
-                early_error(
-                    error_format,
-                    "linking modifiers are currently unstable and only accepted on \
-                the nightly compiler",
-                );
-            }
-            if !enable_unstable {
-                early_error(
-                    error_format,
-                    "linking modifiers are currently unstable, \
-                the `-Z unstable-options` flag must also be passed to use it",
-                )
-            }
-            parse_native_lib_modifiers(kind, modifiers, error_format)
-        }
+        Some(modifiers) => parse_native_lib_modifiers(kind, modifiers, error_format, matches),
     }
 }
 
@@ -2012,7 +1993,23 @@ fn parse_native_lib_modifiers(
     mut kind: NativeLibKind,
     modifiers: &str,
     error_format: ErrorOutputType,
+    matches: &getopts::Matches,
 ) -> (NativeLibKind, Option<bool>) {
+    let report_unstable_modifier = |modifier| {
+        if !nightly_options::is_unstable_enabled(matches) {
+            let why = if nightly_options::match_is_nightly_build(matches) {
+                " and only accepted on the nightly compiler"
+            } else {
+                ", the `-Z unstable-options` flag must also be passed to use it"
+            };
+            early_error(
+                error_format,
+                &format!("{modifier} linking modifier is currently unstable{why}"),
+            )
+        }
+    };
+
+    let mut has_duplicate_modifiers = false;
     let mut verbatim = None;
     for modifier in modifiers.split(',') {
         let (modifier, value) = match modifier.strip_prefix(&['+', '-']) {
@@ -2026,6 +2023,10 @@ fn parse_native_lib_modifiers(
 
         match (modifier, &mut kind) {
             ("bundle", NativeLibKind::Static { bundle, .. }) => {
+                report_unstable_modifier(modifier);
+                if bundle.is_some() {
+                    has_duplicate_modifiers = true;
+                }
                 *bundle = Some(value);
             }
             ("bundle", _) => early_error(
@@ -2034,9 +2035,18 @@ fn parse_native_lib_modifiers(
                     `static` linking kind",
             ),
 
-            ("verbatim", _) => verbatim = Some(value),
+            ("verbatim", _) => {
+                report_unstable_modifier(modifier);
+                if verbatim.is_some() {
+                    has_duplicate_modifiers = true;
+                }
+                verbatim = Some(value);
+            }
 
             ("whole-archive", NativeLibKind::Static { whole_archive, .. }) => {
+                if whole_archive.is_some() {
+                    has_duplicate_modifiers = true;
+                }
                 *whole_archive = Some(value);
             }
             ("whole-archive", _) => early_error(
@@ -2047,6 +2057,10 @@ fn parse_native_lib_modifiers(
 
             ("as-needed", NativeLibKind::Dylib { as_needed })
             | ("as-needed", NativeLibKind::Framework { as_needed }) => {
+                report_unstable_modifier(modifier);
+                if as_needed.is_some() {
+                    has_duplicate_modifiers = true;
+                }
                 *as_needed = Some(value);
             }
             ("as-needed", _) => early_error(
@@ -2055,6 +2069,8 @@ fn parse_native_lib_modifiers(
                     `dylib` and `framework` linking kinds",
             ),
 
+            // Note: this error also excludes the case with empty modifier
+            // string, like `modifiers = ""`.
             _ => early_error(
                 error_format,
                 &format!(
@@ -2064,6 +2080,9 @@ fn parse_native_lib_modifiers(
             ),
         }
     }
+    if has_duplicate_modifiers {
+        report_unstable_modifier("duplicating")
+    }
 
     (kind, verbatim)
 }
diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs
index 281fc887633..c1fd3c7c61b 100644
--- a/compiler/rustc_session/src/cstore.rs
+++ b/compiler/rustc_session/src/cstore.rs
@@ -75,6 +75,12 @@ pub struct NativeLib {
     pub dll_imports: Vec<DllImport>,
 }
 
+impl NativeLib {
+    pub fn has_modifiers(&self) -> bool {
+        self.verbatim.is_some() || self.kind.has_modifiers()
+    }
+}
+
 #[derive(Clone, Debug, Encodable, Decodable, HashStable_Generic)]
 pub struct DllImport {
     pub name: Symbol,
diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs
index a33f94013d2..6a8775bd10b 100644
--- a/compiler/rustc_session/src/utils.rs
+++ b/compiler/rustc_session/src/utils.rs
@@ -43,6 +43,20 @@ pub enum NativeLibKind {
     Unspecified,
 }
 
+impl NativeLibKind {
+    pub fn has_modifiers(&self) -> bool {
+        match self {
+            NativeLibKind::Static { bundle, whole_archive } => {
+                bundle.is_some() || whole_archive.is_some()
+            }
+            NativeLibKind::Dylib { as_needed } | NativeLibKind::Framework { as_needed } => {
+                as_needed.is_some()
+            }
+            NativeLibKind::RawDylib | NativeLibKind::Unspecified => false,
+        }
+    }
+}
+
 rustc_data_structures::impl_stable_hash_via_hash!(NativeLibKind);
 
 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)]
@@ -53,6 +67,12 @@ pub struct NativeLib {
     pub verbatim: Option<bool>,
 }
 
+impl NativeLib {
+    pub fn has_modifiers(&self) -> bool {
+        self.verbatim.is_some() || self.kind.has_modifiers()
+    }
+}
+
 rustc_data_structures::impl_stable_hash_via_hash!(NativeLib);
 
 /// A path that has been canonicalized along with its original, non-canonicalized form
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 84dbad846dd..0bca0a99e15 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -272,6 +272,7 @@ symbols! {
         __D,
         __H,
         __S,
+        __awaitee,
         __try_var,
         _d,
         _e,
@@ -722,6 +723,7 @@ symbols! {
         generators,
         generic_arg_infer,
         generic_associated_types,
+        generic_associated_types_extended,
         generic_const_exprs,
         generic_param_attrs,
         get_context,
@@ -1018,7 +1020,6 @@ symbols! {
         pattern_parentheses,
         phantom_data,
         pin,
-        pinned,
         platform_intrinsics,
         plugin,
         plugin_registrar,
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index 36eddf7784b..d95512bb88f 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -5,6 +5,7 @@ use super::*;
 
 use crate::infer::region_constraints::{Constraint, RegionConstraintData};
 use crate::infer::InferCtxt;
+use crate::traits::project::ProjectAndUnifyResult;
 use rustc_middle::ty::fold::TypeFolder;
 use rustc_middle::ty::{Region, RegionVid, Term};
 
@@ -751,7 +752,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
                     debug!("Projecting and unifying projection predicate {:?}", predicate);
 
                     match project::poly_project_and_unify_type(select, &obligation.with(p)) {
-                        Err(e) => {
+                        ProjectAndUnifyResult::MismatchedProjectionTypes(e) => {
                             debug!(
                                 "evaluate_nested_obligations: Unable to unify predicate \
                                  '{:?}' '{:?}', bailing out",
@@ -759,11 +760,11 @@ impl<'tcx> AutoTraitFinder<'tcx> {
                             );
                             return false;
                         }
-                        Ok(Err(project::InProgress)) => {
+                        ProjectAndUnifyResult::Recursive => {
                             debug!("evaluate_nested_obligations: recursive projection predicate");
                             return false;
                         }
-                        Ok(Ok(Some(v))) => {
+                        ProjectAndUnifyResult::Holds(v) => {
                             // We only care about sub-obligations
                             // when we started out trying to unify
                             // some inference variables. See the comment above
@@ -782,7 +783,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
                                 }
                             }
                         }
-                        Ok(Ok(None)) => {
+                        ProjectAndUnifyResult::FailedNormalization => {
                             // It's ok not to make progress when have no inference variables -
                             // in that case, we were only performing unification to check if an
                             // error occurred (which would indicate that it's impossible for our
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 1b862834467..d0b8b0281c5 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -14,7 +14,7 @@ use rustc_middle::ty::{self, Binder, Const, Ty, TypeFoldable};
 use std::marker::PhantomData;
 
 use super::const_evaluatable;
-use super::project;
+use super::project::{self, ProjectAndUnifyResult};
 use super::select::SelectionContext;
 use super::wf;
 use super::CodeAmbiguity;
@@ -753,8 +753,8 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
         }
 
         match project::poly_project_and_unify_type(self.selcx, &project_obligation) {
-            Ok(Ok(Some(os))) => ProcessResult::Changed(mk_pending(os)),
-            Ok(Ok(None)) => {
+            ProjectAndUnifyResult::Holds(os) => ProcessResult::Changed(mk_pending(os)),
+            ProjectAndUnifyResult::FailedNormalization => {
                 stalled_on.clear();
                 stalled_on.extend(substs_infer_vars(
                     self.selcx,
@@ -763,10 +763,12 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
                 ProcessResult::Unchanged
             }
             // Let the caller handle the recursion
-            Ok(Err(project::InProgress)) => ProcessResult::Changed(mk_pending(vec![
+            ProjectAndUnifyResult::Recursive => ProcessResult::Changed(mk_pending(vec![
                 project_obligation.with(project_obligation.predicate.to_predicate(tcx)),
             ])),
-            Err(e) => ProcessResult::Error(CodeProjectionError(e)),
+            ProjectAndUnifyResult::MismatchedProjectionTypes(e) => {
+                ProcessResult::Error(CodeProjectionError(e))
+            }
         }
     }
 }
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index d4ec677a0b1..2251f992e4d 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -28,7 +28,7 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::LangItem;
 use rustc_infer::infer::resolve::OpportunisticRegionResolver;
 use rustc_middle::traits::select::OverflowError;
-use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
+use rustc_middle::ty::fold::{MaxUniverse, TypeFoldable, TypeFolder};
 use rustc_middle::ty::subst::Subst;
 use rustc_middle::ty::{self, Term, ToPredicate, Ty, TyCtxt};
 use rustc_span::symbol::sym;
@@ -144,6 +144,18 @@ impl<'tcx> ProjectionCandidateSet<'tcx> {
     }
 }
 
+/// Takes the place of a
+/// Result<
+///     Result<Option<Vec<PredicateObligation<'tcx>>>, InProgress>,
+///     MismatchedProjectionTypes<'tcx>,
+/// >
+pub(super) enum ProjectAndUnifyResult<'tcx> {
+    Holds(Vec<PredicateObligation<'tcx>>),
+    FailedNormalization,
+    Recursive,
+    MismatchedProjectionTypes(MismatchedProjectionTypes<'tcx>),
+}
+
 /// Evaluates constraints of the form:
 ///
 ///     for<...> <T as Trait>::U == V
@@ -167,19 +179,47 @@ impl<'tcx> ProjectionCandidateSet<'tcx> {
 pub(super) fn poly_project_and_unify_type<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &PolyProjectionObligation<'tcx>,
-) -> Result<
-    Result<Option<Vec<PredicateObligation<'tcx>>>, InProgress>,
-    MismatchedProjectionTypes<'tcx>,
-> {
+) -> ProjectAndUnifyResult<'tcx> {
     let infcx = selcx.infcx();
-    infcx.commit_if_ok(|_snapshot| {
+    let r = infcx.commit_if_ok(|_snapshot| {
+        let old_universe = infcx.universe();
         let placeholder_predicate =
             infcx.replace_bound_vars_with_placeholders(obligation.predicate);
+        let new_universe = infcx.universe();
 
         let placeholder_obligation = obligation.with(placeholder_predicate);
-        let result = project_and_unify_type(selcx, &placeholder_obligation)?;
-        Ok(result)
-    })
+        match project_and_unify_type(selcx, &placeholder_obligation) {
+            ProjectAndUnifyResult::MismatchedProjectionTypes(e) => Err(e),
+            ProjectAndUnifyResult::Holds(obligations)
+                if old_universe != new_universe
+                    && selcx.tcx().features().generic_associated_types_extended =>
+            {
+                // If the `generic_associated_types_extended` feature is active, then we ignore any
+                // obligations references lifetimes from any universe greater than or equal to the
+                // universe just created. Otherwise, we can end up with something like `for<'a> I: 'a`,
+                // which isn't quite what we want. Ideally, we want either an implied
+                // `for<'a where I: 'a> I: 'a` or we want to "lazily" check these hold when we
+                // substitute concrete regions. There is design work to be done here; until then,
+                // however, this allows experimenting potential GAT features without running into
+                // well-formedness issues.
+                let new_obligations = obligations
+                    .into_iter()
+                    .filter(|obligation| {
+                        let mut visitor = MaxUniverse::new();
+                        obligation.predicate.visit_with(&mut visitor);
+                        visitor.max_universe() < new_universe
+                    })
+                    .collect();
+                Ok(ProjectAndUnifyResult::Holds(new_obligations))
+            }
+            other => Ok(other),
+        }
+    });
+
+    match r {
+        Ok(inner) => inner,
+        Err(err) => ProjectAndUnifyResult::MismatchedProjectionTypes(err),
+    }
 }
 
 /// Evaluates constraints of the form:
@@ -189,15 +229,11 @@ pub(super) fn poly_project_and_unify_type<'cx, 'tcx>(
 /// If successful, this may result in additional obligations.
 ///
 /// See [poly_project_and_unify_type] for an explanation of the return value.
+#[tracing::instrument(level = "debug", skip(selcx))]
 fn project_and_unify_type<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionObligation<'tcx>,
-) -> Result<
-    Result<Option<Vec<PredicateObligation<'tcx>>>, InProgress>,
-    MismatchedProjectionTypes<'tcx>,
-> {
-    debug!(?obligation, "project_and_unify_type");
-
+) -> ProjectAndUnifyResult<'tcx> {
     let mut obligations = vec![];
 
     let infcx = selcx.infcx();
@@ -210,8 +246,8 @@ fn project_and_unify_type<'cx, 'tcx>(
         &mut obligations,
     ) {
         Ok(Some(n)) => n,
-        Ok(None) => return Ok(Ok(None)),
-        Err(InProgress) => return Ok(Err(InProgress)),
+        Ok(None) => return ProjectAndUnifyResult::FailedNormalization,
+        Err(InProgress) => return ProjectAndUnifyResult::Recursive,
     };
     debug!(?normalized, ?obligations, "project_and_unify_type result");
     let actual = obligation.predicate.term;
@@ -231,11 +267,11 @@ fn project_and_unify_type<'cx, 'tcx>(
     match infcx.at(&obligation.cause, obligation.param_env).eq(normalized, actual) {
         Ok(InferOk { obligations: inferred_obligations, value: () }) => {
             obligations.extend(inferred_obligations);
-            Ok(Ok(Some(obligations)))
+            ProjectAndUnifyResult::Holds(obligations)
         }
         Err(err) => {
-            debug!("project_and_unify_type: equating types encountered error {:?}", err);
-            Err(MismatchedProjectionTypes { err })
+            debug!("equating types encountered error {:?}", err);
+            ProjectAndUnifyResult::MismatchedProjectionTypes(MismatchedProjectionTypes { err })
         }
     }
 }
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 42f17721f9b..4f033d45c1f 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -21,6 +21,7 @@ use super::{
 
 use crate::infer::{InferCtxt, InferOk, TypeFreshener};
 use crate::traits::error_reporting::InferCtxtExt;
+use crate::traits::project::ProjectAndUnifyResult;
 use crate::traits::project::ProjectionCacheKeyExt;
 use crate::traits::ProjectionCacheKey;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -525,7 +526,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     let data = bound_predicate.rebind(data);
                     let project_obligation = obligation.with(data);
                     match project::poly_project_and_unify_type(self, &project_obligation) {
-                        Ok(Ok(Some(mut subobligations))) => {
+                        ProjectAndUnifyResult::Holds(mut subobligations) => {
                             'compute_res: {
                                 // If we've previously marked this projection as 'complete', then
                                 // use the final cached result (either `EvaluatedToOk` or
@@ -573,9 +574,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                 res
                             }
                         }
-                        Ok(Ok(None)) => Ok(EvaluatedToAmbig),
-                        Ok(Err(project::InProgress)) => Ok(EvaluatedToRecur),
-                        Err(_) => Ok(EvaluatedToErr),
+                        ProjectAndUnifyResult::FailedNormalization => Ok(EvaluatedToAmbig),
+                        ProjectAndUnifyResult::Recursive => Ok(EvaluatedToRecur),
+                        ProjectAndUnifyResult::MismatchedProjectionTypes(_) => Ok(EvaluatedToErr),
                     }
                 }
 
diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs
index cc6dfb0e330..03c532bb697 100644
--- a/library/alloc/src/vec/into_iter.rs
+++ b/library/alloc/src/vec/into_iter.rs
@@ -8,7 +8,8 @@ use core::iter::{
     FusedIterator, InPlaceIterable, SourceIter, TrustedLen, TrustedRandomAccessNoCoerce,
 };
 use core::marker::PhantomData;
-use core::mem::{self};
+use core::mem::{self, ManuallyDrop};
+use core::ops::Deref;
 use core::ptr::{self, NonNull};
 use core::slice::{self};
 
@@ -32,7 +33,9 @@ pub struct IntoIter<
     pub(super) buf: NonNull<T>,
     pub(super) phantom: PhantomData<T>,
     pub(super) cap: usize,
-    pub(super) alloc: A,
+    // the drop impl reconstructs a RawVec from buf, cap and alloc
+    // to avoid dropping the allocator twice we need to wrap it into ManuallyDrop
+    pub(super) alloc: ManuallyDrop<A>,
     pub(super) ptr: *const T,
     pub(super) end: *const T,
 }
@@ -295,11 +298,11 @@ where
 impl<T: Clone, A: Allocator + Clone> Clone for IntoIter<T, A> {
     #[cfg(not(test))]
     fn clone(&self) -> Self {
-        self.as_slice().to_vec_in(self.alloc.clone()).into_iter()
+        self.as_slice().to_vec_in(self.alloc.deref().clone()).into_iter()
     }
     #[cfg(test)]
     fn clone(&self) -> Self {
-        crate::slice::to_vec(self.as_slice(), self.alloc.clone()).into_iter()
+        crate::slice::to_vec(self.as_slice(), self.alloc.deref().clone()).into_iter()
     }
 }
 
@@ -311,8 +314,8 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for IntoIter<T, A> {
         impl<T, A: Allocator> Drop for DropGuard<'_, T, A> {
             fn drop(&mut self) {
                 unsafe {
-                    // `IntoIter::alloc` is not used anymore after this
-                    let alloc = ptr::read(&self.0.alloc);
+                    // `IntoIter::alloc` is not used anymore after this and will be dropped by RawVec
+                    let alloc = ManuallyDrop::take(&mut self.0.alloc);
                     // RawVec handles deallocation
                     let _ = RawVec::from_raw_parts_in(self.0.buf.as_ptr(), self.0.cap, alloc);
                 }
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 1ca5ee55375..9773ec02337 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -2579,7 +2579,7 @@ impl<T, A: Allocator> IntoIterator for Vec<T, A> {
     fn into_iter(self) -> IntoIter<T, A> {
         unsafe {
             let mut me = ManuallyDrop::new(self);
-            let alloc = ptr::read(me.allocator());
+            let alloc = ManuallyDrop::new(ptr::read(me.allocator()));
             let begin = me.as_mut_ptr();
             let end = if mem::size_of::<T>() == 0 {
                 arith_offset(begin as *const i8, me.len() as isize) as *const T
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index ca0fcc855c7..19e39ebf910 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -1,3 +1,6 @@
+use core::alloc::{Allocator, Layout};
+use core::ptr::NonNull;
+use std::alloc::System;
 use std::assert_matches::assert_matches;
 use std::borrow::Cow;
 use std::cell::Cell;
@@ -991,6 +994,31 @@ fn test_into_iter_advance_by() {
     assert_eq!(i.len(), 0);
 }
 
+#[test]
+fn test_into_iter_drop_allocator() {
+    struct ReferenceCountedAllocator<'a>(DropCounter<'a>);
+
+    unsafe impl Allocator for ReferenceCountedAllocator<'_> {
+        fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, core::alloc::AllocError> {
+            System.allocate(layout)
+        }
+
+        unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
+            System.deallocate(ptr, layout)
+        }
+    }
+
+    let mut drop_count = 0;
+
+    let allocator = ReferenceCountedAllocator(DropCounter { count: &mut drop_count });
+    let _ = Vec::<u32, _>::new_in(allocator);
+    assert_eq!(drop_count, 1);
+
+    let allocator = ReferenceCountedAllocator(DropCounter { count: &mut drop_count });
+    let _ = Vec::<u32, _>::new_in(allocator).into_iter();
+    assert_eq!(drop_count, 2);
+}
+
 #[test]
 fn test_from_iter_specialization() {
     let src: Vec<usize> = vec![0usize; 1];
diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs
index 079626f0fea..82f1e63f4b5 100644
--- a/library/unwind/src/lib.rs
+++ b/library/unwind/src/lib.rs
@@ -1,7 +1,7 @@
 #![no_std]
 #![unstable(feature = "panic_unwind", issue = "32837")]
 #![feature(link_cfg)]
-#![feature(native_link_modifiers)]
+#![cfg_attr(bootstrap, feature(native_link_modifiers))]
 #![feature(native_link_modifiers_bundle)]
 #![feature(nll)]
 #![feature(staged_api)]
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 8f076ad914d..570a61742bc 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -117,6 +117,7 @@ use std::os::unix::fs::symlink as symlink_file;
 use std::os::windows::fs::symlink_file;
 
 use filetime::FileTime;
+use once_cell::sync::OnceCell;
 
 use crate::builder::Kind;
 use crate::config::{LlvmLibunwind, TargetSelection};
@@ -904,7 +905,12 @@ impl Build {
 
     /// Returns the sysroot of the snapshot compiler.
     fn rustc_snapshot_sysroot(&self) -> &Path {
-        self.initial_rustc.parent().unwrap().parent().unwrap()
+        static SYSROOT_CACHE: OnceCell<PathBuf> = once_cell::sync::OnceCell::new();
+        SYSROOT_CACHE.get_or_init(|| {
+            let mut rustc = Command::new(&self.initial_rustc);
+            rustc.args(&["--print", "sysroot"]);
+            output(&mut rustc).trim().into()
+        })
     }
 
     /// Runs a command, printing out nice contextual information if it fails.
diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md
index 3759cb632bb..7838696cc12 100644
--- a/src/doc/rustc/src/command-line-arguments.md
+++ b/src/doc/rustc/src/command-line-arguments.md
@@ -37,6 +37,8 @@ KIND=PATH` where `KIND` may be one of:
 <a id="option-l-link-lib"></a>
 ## `-l`: link the generated crate to a native library
 
+Syntax: `-l [KIND[:MODIFIERS]=]NAME[:RENAME]`.
+
 This flag allows you to specify linking to a specific native library when building
 a crate.
 
@@ -47,7 +49,13 @@ where `KIND` may be one of:
 - `static` — A native static library (such as a `.a` archive).
 - `framework` — A macOS framework.
 
-The kind of library can be specified in a [`#[link]`
+If the kind is specified, then linking modifiers can be attached to it.
+Modifiers are specified as a comma-delimited string with each modifier prefixed with
+either a `+` or `-` to indicate that the modifier is enabled or disabled, respectively.
+The last boolean value specified for a given modifier wins. \
+Example: `-l static:+whole-archive=mylib`.
+
+The kind of library and the modifiers can also be specified in a [`#[link]`
 attribute][link-attribute]. If the kind is not specified in the `link`
 attribute or on the command-line, it will link a dynamic library if available,
 otherwise it will use a static library. If the kind is specified on the
@@ -59,6 +67,22 @@ and `LINK_NAME` is the name of the actual library that will be linked.
 
 [link-attribute]: ../reference/items/external-blocks.html#the-link-attribute
 
+### Linking modifiers: `whole-archive`
+
+This modifier is only compatible with the `static` linking kind.
+Using any other kind will result in a compiler error.
+
+`+whole-archive` means that the static library is linked as a whole archive
+without throwing any object files away.
+
+This modifier translates to `--whole-archive` for `ld`-like linkers,
+to `/WHOLEARCHIVE` for `link.exe`, and to `-force_load` for `ld64`.
+The modifier does nothing for linkers that don't support it.
+
+The default for this modifier is `-whole-archive`. \
+NOTE: The default may currently be different when building dylibs for some targets,
+but it is not guaranteed.
+
 <a id="option-crate-type"></a>
 ## `--crate-type`: a list of types of crates for the compiler to emit
 
diff --git a/src/doc/unstable-book/src/language-features/native-link-modifiers-whole-archive.md b/src/doc/unstable-book/src/language-features/native-link-modifiers-whole-archive.md
deleted file mode 100644
index 4961e88cad1..00000000000
--- a/src/doc/unstable-book/src/language-features/native-link-modifiers-whole-archive.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# `native_link_modifiers_whole_archive`
-
-The tracking issue for this feature is: [#81490]
-
-[#81490]: https://github.com/rust-lang/rust/issues/81490
-
-------------------------
-
-The `native_link_modifiers_whole_archive` feature allows you to use the `whole-archive` modifier.
-
-Only compatible with the `static` linking kind. Using any other kind will result in a compiler error.
-
-`+whole-archive` means that the static library is linked as a whole archive without throwing any object files away.
-
-This modifier translates to `--whole-archive` for `ld`-like linkers, to `/WHOLEARCHIVE` for `link.exe`, and to `-force_load` for `ld64`.
-The modifier does nothing for linkers that don't support it.
-
-The default for this modifier is `-whole-archive`.
diff --git a/src/doc/unstable-book/src/language-features/native-link-modifiers.md b/src/doc/unstable-book/src/language-features/native-link-modifiers.md
deleted file mode 100644
index fc8b5754621..00000000000
--- a/src/doc/unstable-book/src/language-features/native-link-modifiers.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# `native_link_modifiers`
-
-The tracking issue for this feature is: [#81490]
-
-[#81490]: https://github.com/rust-lang/rust/issues/81490
-
-------------------------
-
-The `native_link_modifiers` feature allows you to use the `modifiers` syntax with the `#[link(..)]` attribute.
-
-Modifiers are specified as a comma-delimited string with each modifier prefixed with either a `+` or `-` to indicate that the modifier is enabled or disabled, respectively. The last boolean value specified for a given modifier wins.
diff --git a/src/test/codegen/async-fn-debug-awaitee-field.rs b/src/test/codegen/async-fn-debug-awaitee-field.rs
new file mode 100644
index 00000000000..efb345fa9f3
--- /dev/null
+++ b/src/test/codegen/async-fn-debug-awaitee-field.rs
@@ -0,0 +1,23 @@
+// This test makes sure that the generator field capturing the awaitee in a `.await` expression
+// is called "__awaitee" in debuginfo. This name must not be changed since debuggers and debugger
+// extensions rely on the field having this name.
+
+// ignore-tidy-linelength
+// compile-flags: -C debuginfo=2 --edition=2018
+
+async fn foo() {}
+
+async fn async_fn_test() {
+    foo().await;
+}
+
+// NONMSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}",
+// MSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum$<async_fn_debug_awaitee_field::async_fn_test::async_fn_env$0>",
+// CHECK: [[SUSPEND_STRUCT:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend0", scope: [[GEN]],
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "__awaitee", scope: [[SUSPEND_STRUCT]], {{.*}}, baseType: [[AWAITEE_TYPE:![0-9]*]],
+// NONMSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<async_fn_debug_awaitee_field::foo::{async_fn_env#0}>",
+// MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<enum$<async_fn_debug_awaitee_field::foo::async_fn_env$0> >",
+
+fn main() {
+    let _fn = async_fn_test();
+}
diff --git a/src/test/run-make/native-link-modifier-whole-archive/native_lib_in_src.rs b/src/test/run-make/native-link-modifier-whole-archive/native_lib_in_src.rs
index 373d89b7936..2436c36e6eb 100644
--- a/src/test/run-make/native-link-modifier-whole-archive/native_lib_in_src.rs
+++ b/src/test/run-make/native-link-modifier-whole-archive/native_lib_in_src.rs
@@ -1,6 +1,4 @@
 #![feature(native_link_modifiers_bundle)]
-#![feature(native_link_modifiers_whole_archive)]
-#![feature(native_link_modifiers)]
 
 use std::io::Write;
 
diff --git a/src/test/run-make/raw-dylib-c/lib.rs b/src/test/run-make/raw-dylib-c/lib.rs
index d8e6301f38e..e185c4aec12 100644
--- a/src/test/run-make/raw-dylib-c/lib.rs
+++ b/src/test/run-make/raw-dylib-c/lib.rs
@@ -1,4 +1,4 @@
-#![feature(raw_dylib, native_link_modifiers, native_link_modifiers_verbatim)]
+#![feature(raw_dylib, native_link_modifiers_verbatim)]
 
 #[link(name = "extern_1.dll", kind = "raw-dylib", modifiers = "+verbatim")]
 extern {
diff --git a/src/test/ui/feature-gates/feature-gate-generic_associated_types_extended.rs b/src/test/ui/feature-gates/feature-gate-generic_associated_types_extended.rs
new file mode 100644
index 00000000000..258b8cd35c7
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-generic_associated_types_extended.rs
@@ -0,0 +1,6 @@
+#![feature(generic_associated_types)]
+
+// This feature doesn't *currently* fire on any specific code; it's just a
+// behavior change. Future changes might.
+#[rustc_error] //~ the
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-generic_associated_types_extended.stderr b/src/test/ui/feature-gates/feature-gate-generic_associated_types_extended.stderr
new file mode 100644
index 00000000000..6a5eba38cac
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-generic_associated_types_extended.stderr
@@ -0,0 +1,11 @@
+error[E0658]: the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable
+  --> $DIR/feature-gate-generic_associated_types_extended.rs:5:1
+   |
+LL | #[rustc_error]
+   | ^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-native_link_modifiers.rs b/src/test/ui/feature-gates/feature-gate-native_link_modifiers.rs
deleted file mode 100644
index 2d00aa2a3cf..00000000000
--- a/src/test/ui/feature-gates/feature-gate-native_link_modifiers.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-#[link(name = "foo", modifiers = "")]
-//~^ ERROR: native link modifiers are experimental
-extern "C" {}
-
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-native_link_modifiers.stderr b/src/test/ui/feature-gates/feature-gate-native_link_modifiers.stderr
deleted file mode 100644
index 20a2d6a26fa..00000000000
--- a/src/test/ui/feature-gates/feature-gate-native_link_modifiers.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0658]: native link modifiers are experimental
-  --> $DIR/feature-gate-native_link_modifiers.rs:1:22
-   |
-LL | #[link(name = "foo", modifiers = "")]
-   |                      ^^^^^^^^^^^^^^
-   |
-   = note: see issue #81490 <https://github.com/rust-lang/rust/issues/81490> for more information
-   = help: add `#![feature(native_link_modifiers)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_as_needed.rs b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_as_needed.rs
index 4cf8067592e..fedee812398 100644
--- a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_as_needed.rs
+++ b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_as_needed.rs
@@ -1,6 +1,3 @@
-#![allow(incomplete_features)]
-#![feature(native_link_modifiers)]
-
 #[link(name = "foo", modifiers = "+as-needed")]
 //~^ ERROR: `#[link(modifiers="as-needed")]` is unstable
 extern "C" {}
diff --git a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_as_needed.stderr b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_as_needed.stderr
index 08ce807851b..96750aa6e80 100644
--- a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_as_needed.stderr
+++ b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_as_needed.stderr
@@ -1,5 +1,5 @@
 error[E0658]: `#[link(modifiers="as-needed")]` is unstable
-  --> $DIR/feature-gate-native_link_modifiers_as_needed.rs:4:34
+  --> $DIR/feature-gate-native_link_modifiers_as_needed.rs:1:34
    |
 LL | #[link(name = "foo", modifiers = "+as-needed")]
    |                                  ^^^^^^^^^^^^
diff --git a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle-2.rs b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle-2.rs
index 1b5fa78ee55..e229564950f 100644
--- a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle-2.rs
+++ b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle-2.rs
@@ -1,7 +1,6 @@
 // Test native_link_modifiers_bundle don't need static-nobundle
 // check-pass
 
-#![feature(native_link_modifiers)]
 #![feature(native_link_modifiers_bundle)]
 
 #[link(name = "foo", kind = "static", modifiers = "-bundle")]
diff --git a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle-3.stderr b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle-3.stderr
index 86ccb4e860b..900605c3b37 100644
--- a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle-3.stderr
+++ b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle-3.stderr
@@ -1,2 +1,2 @@
-error: linking modifiers are currently unstable, the `-Z unstable-options` flag must also be passed to use it
+error: bundle linking modifier is currently unstable and only accepted on the nightly compiler
 
diff --git a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle.rs b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle.rs
index b2b1dc28e47..c3c3cff17c4 100644
--- a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle.rs
+++ b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle.rs
@@ -1,6 +1,3 @@
-#![allow(incomplete_features)]
-#![feature(native_link_modifiers)]
-
 #[link(name = "foo", modifiers = "+bundle")]
 //~^ ERROR: `#[link(modifiers="bundle")]` is unstable
 extern "C" {}
diff --git a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle.stderr b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle.stderr
index b3e22b0644a..984b90d9b6c 100644
--- a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle.stderr
+++ b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle.stderr
@@ -1,5 +1,5 @@
 error[E0658]: `#[link(modifiers="bundle")]` is unstable
-  --> $DIR/feature-gate-native_link_modifiers_bundle.rs:4:34
+  --> $DIR/feature-gate-native_link_modifiers_bundle.rs:1:34
    |
 LL | #[link(name = "foo", modifiers = "+bundle")]
    |                                  ^^^^^^^^^
diff --git a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_verbatim.rs b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_verbatim.rs
index 042ce0b3f65..57527be1112 100644
--- a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_verbatim.rs
+++ b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_verbatim.rs
@@ -1,6 +1,3 @@
-#![allow(incomplete_features)]
-#![feature(native_link_modifiers)]
-
 #[link(name = "foo", modifiers = "+verbatim")]
 //~^ ERROR: `#[link(modifiers="verbatim")]` is unstable
 extern "C" {}
diff --git a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_verbatim.stderr b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_verbatim.stderr
index 8159416edfa..5c64c0d21bd 100644
--- a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_verbatim.stderr
+++ b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_verbatim.stderr
@@ -1,5 +1,5 @@
 error[E0658]: `#[link(modifiers="verbatim")]` is unstable
-  --> $DIR/feature-gate-native_link_modifiers_verbatim.rs:4:34
+  --> $DIR/feature-gate-native_link_modifiers_verbatim.rs:1:34
    |
 LL | #[link(name = "foo", modifiers = "+verbatim")]
    |                                  ^^^^^^^^^^^
diff --git a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_whole_archive.rs b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_whole_archive.rs
deleted file mode 100644
index ca801e59114..00000000000
--- a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_whole_archive.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-#![allow(incomplete_features)]
-#![feature(native_link_modifiers)]
-
-#[link(name = "foo", modifiers = "+whole-archive")]
-//~^ ERROR: `#[link(modifiers="whole-archive")]` is unstable
-extern "C" {}
-
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_whole_archive.stderr b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_whole_archive.stderr
deleted file mode 100644
index cacaa789ecb..00000000000
--- a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_whole_archive.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0658]: `#[link(modifiers="whole-archive")]` is unstable
-  --> $DIR/feature-gate-native_link_modifiers_whole_archive.rs:4:34
-   |
-LL | #[link(name = "foo", modifiers = "+whole-archive")]
-   |                                  ^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #81490 <https://github.com/rust-lang/rust/issues/81490> for more information
-   = help: add `#![feature(native_link_modifiers_whole_archive)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/generic-associated-types/extended/lending_iterator.base.nll.stderr b/src/test/ui/generic-associated-types/extended/lending_iterator.base.nll.stderr
new file mode 100644
index 00000000000..3da7794b3d2
--- /dev/null
+++ b/src/test/ui/generic-associated-types/extended/lending_iterator.base.nll.stderr
@@ -0,0 +1,12 @@
+error[E0276]: impl has stricter requirements than trait
+  --> $DIR/lending_iterator.rs:14:45
+   |
+LL |     fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self;
+   |     ------------------------------------------------------------------------ definition of `from_iter` from trait
+...
+LL |     fn from_iter<I: for<'x> LendingIterator<Item<'x> = A>>(mut iter: I) -> Self {
+   |                                             ^^^^^^^^^^^^ impl has extra requirement `I: 'x`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0276`.
diff --git a/src/test/ui/generic-associated-types/extended/lending_iterator.base.stderr b/src/test/ui/generic-associated-types/extended/lending_iterator.base.stderr
new file mode 100644
index 00000000000..c5588b0912b
--- /dev/null
+++ b/src/test/ui/generic-associated-types/extended/lending_iterator.base.stderr
@@ -0,0 +1,26 @@
+error[E0276]: impl has stricter requirements than trait
+  --> $DIR/lending_iterator.rs:14:45
+   |
+LL |     fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self;
+   |     ------------------------------------------------------------------------ definition of `from_iter` from trait
+...
+LL |     fn from_iter<I: for<'x> LendingIterator<Item<'x> = A>>(mut iter: I) -> Self {
+   |                                             ^^^^^^^^^^^^ impl has extra requirement `I: 'x`
+
+error[E0311]: the parameter type `Self` may not live long enough
+  --> $DIR/lending_iterator.rs:35:9
+   |
+LL |         <B as FromLendingIterator<A>>::from_iter(self)
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding an explicit lifetime bound `Self: 'a`...
+   = note: ...so that the type `Self` will meet its required lifetime bounds...
+note: ...that is required by this bound
+  --> $DIR/lending_iterator.rs:10:45
+   |
+LL |     fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self;
+   |                                             ^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0276`.
diff --git a/src/test/ui/generic-associated-types/extended/lending_iterator.rs b/src/test/ui/generic-associated-types/extended/lending_iterator.rs
new file mode 100644
index 00000000000..df11ab21249
--- /dev/null
+++ b/src/test/ui/generic-associated-types/extended/lending_iterator.rs
@@ -0,0 +1,40 @@
+// revisions: base extended
+//[base] check-fail
+//[extended] check-pass
+
+#![feature(generic_associated_types)]
+#![cfg_attr(extended, feature(generic_associated_types_extended))]
+#![cfg_attr(extended, allow(incomplete_features))]
+
+pub trait FromLendingIterator<A>: Sized {
+    fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self;
+}
+
+impl<A> FromLendingIterator<A> for Vec<A> {
+    fn from_iter<I: for<'x> LendingIterator<Item<'x> = A>>(mut iter: I) -> Self {
+        //[base]~^ impl has stricter
+        let mut v = vec![];
+        while let Some(item) = iter.next() {
+            v.push(item);
+        }
+        v
+    }
+}
+
+pub trait LendingIterator {
+    type Item<'z>
+    where
+        Self: 'z;
+    fn next(&mut self) -> Option<Self::Item<'_>>;
+
+    fn collect<A, B: FromLendingIterator<A>>(self) -> B
+    where
+        Self: Sized,
+        Self: for<'q> LendingIterator<Item<'q> = A>,
+    {
+        <B as FromLendingIterator<A>>::from_iter(self)
+        //[base]~^ the parameter type
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/extended/lending_iterator_2.base.stderr b/src/test/ui/generic-associated-types/extended/lending_iterator_2.base.stderr
new file mode 100644
index 00000000000..6c2a624ca11
--- /dev/null
+++ b/src/test/ui/generic-associated-types/extended/lending_iterator_2.base.stderr
@@ -0,0 +1,12 @@
+error[E0276]: impl has stricter requirements than trait
+  --> $DIR/lending_iterator_2.rs:14:45
+   |
+LL |     fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self;
+   |     ------------------------------------------------------------------------ definition of `from_iter` from trait
+...
+LL |     fn from_iter<I: for<'x> LendingIterator<Item<'x> = A>>(mut iter: I) -> Self {
+   |                                             ^^^^^^^^^^^^ impl has extra requirement `I: 'x`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0276`.
diff --git a/src/test/ui/generic-associated-types/extended/lending_iterator_2.rs b/src/test/ui/generic-associated-types/extended/lending_iterator_2.rs
new file mode 100644
index 00000000000..3c4a2184db9
--- /dev/null
+++ b/src/test/ui/generic-associated-types/extended/lending_iterator_2.rs
@@ -0,0 +1,31 @@
+// revisions: base extended
+//[base] check-fail
+//[extended] check-pass
+
+#![feature(generic_associated_types)]
+#![cfg_attr(extended, feature(generic_associated_types_extended))]
+#![cfg_attr(extended, allow(incomplete_features))]
+
+pub trait FromLendingIterator<A>: Sized {
+    fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self;
+}
+
+impl<A> FromLendingIterator<A> for Vec<A> {
+    fn from_iter<I: for<'x> LendingIterator<Item<'x> = A>>(mut iter: I) -> Self {
+        //[base]~^ impl has stricter
+        let mut v = vec![];
+        while let Some(item) = iter.next() {
+            v.push(item);
+        }
+        v
+    }
+}
+
+pub trait LendingIterator {
+    type Item<'a>
+    where
+        Self: 'a;
+    fn next(&mut self) -> Option<Self::Item<'_>>;
+}
+
+fn main() {}
diff --git a/src/test/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs b/src/test/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs
index c3714a38451..b153ef94626 100644
--- a/src/test/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs
+++ b/src/test/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs
@@ -2,9 +2,7 @@
 // build-fail
 // error-pattern: the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs
 
-#![feature(native_link_modifiers)]
 #![feature(native_link_modifiers_bundle)]
-#![feature(native_link_modifiers_whole_archive)]
 
 #[link(name = "mylib", kind = "static", modifiers = "+bundle,+whole-archive")]
 extern "C" { }
diff --git a/src/test/ui/native-library-link-flags/modifiers-override-2.rs b/src/test/ui/native-library-link-flags/modifiers-override-2.rs
new file mode 100644
index 00000000000..333f6786b0f
--- /dev/null
+++ b/src/test/ui/native-library-link-flags/modifiers-override-2.rs
@@ -0,0 +1,3 @@
+// compile-flags:-lstatic:+whole-archive,-whole-archive=foo
+
+fn main() {}
diff --git a/src/test/ui/native-library-link-flags/modifiers-override-2.stderr b/src/test/ui/native-library-link-flags/modifiers-override-2.stderr
new file mode 100644
index 00000000000..9200d7bfb0c
--- /dev/null
+++ b/src/test/ui/native-library-link-flags/modifiers-override-2.stderr
@@ -0,0 +1,2 @@
+error: duplicating linking modifier is currently unstable and only accepted on the nightly compiler
+
diff --git a/src/test/ui/native-library-link-flags/modifiers-override.rs b/src/test/ui/native-library-link-flags/modifiers-override.rs
new file mode 100644
index 00000000000..f6d770559e6
--- /dev/null
+++ b/src/test/ui/native-library-link-flags/modifiers-override.rs
@@ -0,0 +1,17 @@
+// compile-flags:-ldylib:+as-needed=foo -lstatic=bar -Zunstable-options
+
+#![feature(native_link_modifiers_bundle)]
+
+#[link(name = "foo")]
+#[link( //~ ERROR multiple `modifiers` arguments in a single `#[link]` attribute
+    name = "bar",
+    kind = "static",
+    modifiers = "+whole-archive,-whole-archive",
+    //~^ ERROR same modifier is used multiple times in a single `modifiers` argument
+    modifiers = "+bundle"
+)]
+extern "C" {}
+//~^ ERROR overriding linking modifiers from command line is not supported
+//~| ERROR overriding linking modifiers from command line is not supported
+
+fn main() {}
diff --git a/src/test/ui/native-library-link-flags/modifiers-override.stderr b/src/test/ui/native-library-link-flags/modifiers-override.stderr
new file mode 100644
index 00000000000..8644d2382d2
--- /dev/null
+++ b/src/test/ui/native-library-link-flags/modifiers-override.stderr
@@ -0,0 +1,32 @@
+error: same modifier is used multiple times in a single `modifiers` argument
+  --> $DIR/modifiers-override.rs:9:5
+   |
+LL |     modifiers = "+whole-archive,-whole-archive",
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: multiple `modifiers` arguments in a single `#[link]` attribute
+  --> $DIR/modifiers-override.rs:6:1
+   |
+LL | / #[link(
+LL | |     name = "bar",
+LL | |     kind = "static",
+LL | |     modifiers = "+whole-archive,-whole-archive",
+LL | |
+LL | |     modifiers = "+bundle"
+LL | | )]
+   | |__^
+
+error: overriding linking modifiers from command line is not supported
+  --> $DIR/modifiers-override.rs:13:1
+   |
+LL | extern "C" {}
+   | ^^^^^^^^^^^^^
+
+error: overriding linking modifiers from command line is not supported
+  --> $DIR/modifiers-override.rs:13:1
+   |
+LL | extern "C" {}
+   | ^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/clippy_lints/src/regex.rs b/src/tools/clippy/clippy_lints/src/regex.rs
index b6d04334de9..a92097e1d24 100644
--- a/src/tools/clippy/clippy_lints/src/regex.rs
+++ b/src/tools/clippy/clippy_lints/src/regex.rs
@@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for Regex {
 
 #[allow(clippy::cast_possible_truncation)] // truncation very unlikely here
 #[must_use]
-fn str_span(base: Span, c: regex_syntax::ast::Span, offset: u16) -> Span {
+fn str_span(base: Span, c: regex_syntax::ast::Span, offset: u8) -> Span {
     let offset = u32::from(offset);
     let end = base.lo() + BytePos(u32::try_from(c.end.offset).expect("offset too large") + offset);
     let start = base.lo() + BytePos(u32::try_from(c.start.offset).expect("offset too large") + offset);