about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_builtin_macros/src/env.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs46
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs22
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs16
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs3
-rw-r--r--compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs2
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs15
-rw-r--r--compiler/rustc_errors/src/lib.rs95
-rw-r--r--compiler/rustc_hir_analysis/src/autoderef.rs2
-rw-r--r--compiler/rustc_lint/messages.ftl10
-rw-r--r--compiler/rustc_lint/src/context.rs24
-rw-r--r--compiler/rustc_lint/src/levels.rs9
-rw-r--r--compiler/rustc_lint/src/lints.rs3
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp9
-rw-r--r--compiler/rustc_middle/src/middle/exported_symbols.rs5
-rw-r--r--compiler/rustc_session/src/config.rs7
-rw-r--r--compiler/rustc_session/src/options.rs3
-rw-r--r--compiler/rustc_span/src/edit_distance.rs28
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalize.rs41
-rw-r--r--compiler/rustc_trait_selection/src/traits/structural_normalize.rs3
-rw-r--r--compiler/stable_mir/src/mir/body.rs33
-rw-r--r--compiler/stable_mir/src/mir/visit.rs24
-rw-r--r--src/doc/unstable-book/src/compiler-flags/env-set.md (renamed from src/doc/unstable-book/src/compiler-flags/env.md)14
-rw-r--r--src/tools/clippy/tests/ui/unknown_clippy_lints.fixed6
-rw-r--r--src/tools/clippy/tests/ui/unknown_clippy_lints.rs4
-rw-r--r--src/tools/clippy/tests/ui/unknown_clippy_lints.stderr20
-rw-r--r--src/tools/miri/src/bin/miri.rs1
-rw-r--r--tests/run-make/no-builtins-lto/Makefile18
-rw-r--r--tests/run-make/no-builtins-lto/filecheck.lto.txt17
-rw-r--r--tests/run-make/no-builtins-lto/foo.rs33
-rw-r--r--tests/run-make/no-builtins-lto/main.rs28
-rw-r--r--tests/run-make/no-builtins-lto/no_builtins.rs13
-rw-r--r--tests/run-make/no-builtins-symbols/Makefile7
-rw-r--r--tests/run-make/no-builtins-symbols/main.rs1
-rw-r--r--tests/run-make/wasm-spurious-import/Makefile (renamed from tests/run-make/wasm-builtins-import/Makefile)0
-rw-r--r--tests/run-make/wasm-spurious-import/main.rs (renamed from tests/run-make/wasm-builtins-import/main.rs)5
-rw-r--r--tests/run-make/wasm-spurious-import/verify.js (renamed from tests/run-make/wasm-builtins-import/verify.js)0
-rw-r--r--tests/ui/coroutine/clone-rpit.next.stderr52
-rw-r--r--tests/ui/coroutine/clone-rpit.rs3
-rw-r--r--tests/ui/extenv/extenv-env-overload.rs2
-rw-r--r--tests/ui/extenv/extenv-env.rs2
-rw-r--r--tests/ui/extenv/extenv-not-env.rs2
-rw-r--r--tests/ui/feature-gates/env-flag.rs2
-rw-r--r--tests/ui/feature-gates/env-flag.stderr2
-rw-r--r--tests/ui/impl-trait/eagerly-reveal-in-local-body.rs13
-rw-r--r--tests/ui/impl-trait/recursive-coroutine-indirect.current.stderr2
-rw-r--r--tests/ui/impl-trait/recursive-coroutine-indirect.next.stderr2
-rw-r--r--tests/ui/impl-trait/recursive-coroutine-indirect.rs4
-rw-r--r--tests/ui/proc-macro/env.rs2
-rw-r--r--tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs9
-rw-r--r--tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr41
-rw-r--r--tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs3
-rw-r--r--tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr16
-rw-r--r--tests/ui/traits/next-solver/alias-bound-unsound.rs6
-rw-r--r--tests/ui/traits/next-solver/alias-bound-unsound.stderr3
-rw-r--r--tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs6
-rw-r--r--tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr21
-rw-r--r--tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs6
-rw-r--r--tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr21
-rw-r--r--tests/ui/treat-err-as-bug/eagerly-emit.rs11
-rw-r--r--tests/ui/treat-err-as-bug/eagerly-emit.stderr28
65 files changed, 500 insertions, 354 deletions
diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs
index 4b3eaf78557..a0fd0e3f9be 100644
--- a/compiler/rustc_builtin_macros/src/env.rs
+++ b/compiler/rustc_builtin_macros/src/env.rs
@@ -18,7 +18,7 @@ fn lookup_env<'cx>(cx: &'cx ExtCtxt<'_>, var: Symbol) -> Option<Symbol> {
     if let Some(value) = cx.sess.opts.logical_env.get(var) {
         return Some(Symbol::intern(value));
     }
-    // If the environment variable was not defined with the `--env` option, we try to retrieve it
+    // If the environment variable was not defined with the `--env-set` option, we try to retrieve it
     // from rustc's environment.
     env::var(var).ok().as_deref().map(Symbol::intern)
 }
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index e9e8ade09b7..42bd8687042 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -60,7 +60,7 @@ fn prepare_lto(
     };
 
     let symbol_filter = &|&(ref name, info): &(String, SymbolExportInfo)| {
-        if info.level.is_below_threshold(export_threshold) || info.used || info.used_compiler {
+        if info.level.is_below_threshold(export_threshold) || info.used {
             Some(CString::new(name.as_str()).unwrap())
         } else {
             None
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index a912ef9e755..27cb0366f17 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -569,6 +569,7 @@ pub(crate) unsafe fn llvm_optimize(
         unroll_loops,
         config.vectorize_slp,
         config.vectorize_loop,
+        config.no_builtins,
         config.emit_lifetime_markers,
         sanitizer_options.as_ref(),
         pgo_gen_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
@@ -677,6 +678,7 @@ pub(crate) unsafe fn codegen(
         unsafe fn with_codegen<'ll, F, R>(
             tm: &'ll llvm::TargetMachine,
             llmod: &'ll llvm::Module,
+            no_builtins: bool,
             f: F,
         ) -> R
         where
@@ -684,7 +686,7 @@ pub(crate) unsafe fn codegen(
         {
             let cpm = llvm::LLVMCreatePassManager();
             llvm::LLVMAddAnalysisPasses(tm, cpm);
-            llvm::LLVMRustAddLibraryInfo(cpm, llmod);
+            llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
             f(cpm)
         }
 
@@ -785,7 +787,7 @@ pub(crate) unsafe fn codegen(
             } else {
                 llmod
             };
-            with_codegen(tm, llmod, |cpm| {
+            with_codegen(tm, llmod, config.no_builtins, |cpm| {
                 write_output_file(
                     dcx,
                     tm,
@@ -820,7 +822,7 @@ pub(crate) unsafe fn codegen(
                     (_, SplitDwarfKind::Split) => Some(dwo_out.as_path()),
                 };
 
-                with_codegen(tm, llmod, |cpm| {
+                with_codegen(tm, llmod, config.no_builtins, |cpm| {
                     write_output_file(
                         dcx,
                         tm,
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index aefca6b34f5..ee73c6b4756 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -2173,8 +2173,13 @@ extern "C" {
         ArgsCstrBuff: *const c_char,
         ArgsCstrBuffLen: usize,
     ) -> *mut TargetMachine;
+
     pub fn LLVMRustDisposeTargetMachine(T: *mut TargetMachine);
-    pub fn LLVMRustAddLibraryInfo<'a>(PM: &PassManager<'a>, M: &'a Module);
+    pub fn LLVMRustAddLibraryInfo<'a>(
+        PM: &PassManager<'a>,
+        M: &'a Module,
+        DisableSimplifyLibCalls: bool,
+    );
     pub fn LLVMRustWriteOutputFile<'a>(
         T: &'a TargetMachine,
         PM: &PassManager<'a>,
@@ -2196,6 +2201,7 @@ extern "C" {
         UnrollLoops: bool,
         SLPVectorize: bool,
         LoopVectorize: bool,
+        DisableSimplifyLibCalls: bool,
         EmitLifetimeMarkers: bool,
         SanitizerOptions: Option<&SanitizerOptions>,
         PGOGenPath: *const c_char,
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 70fda982b01..ace356ab153 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -270,14 +270,8 @@ pub fn each_linked_rlib(
 
     for &cnum in crates {
         match fmts.get(cnum.as_usize() - 1) {
-            Some(&Linkage::NotLinked | &Linkage::Dynamic) => continue,
-            Some(&Linkage::IncludedFromDylib) => {
-                // We always link crate `compiler_builtins` statically. When enabling LTO, we include it as well.
-                if info.compiler_builtins != Some(cnum) {
-                    continue;
-                }
-            }
-            Some(&Linkage::Static) => {}
+            Some(&Linkage::NotLinked | &Linkage::Dynamic | &Linkage::IncludedFromDylib) => continue,
+            Some(_) => {}
             None => return Err(errors::LinkRlibError::MissingFormat),
         }
         let crate_name = info.crate_name[&cnum];
@@ -526,7 +520,8 @@ fn link_staticlib<'a>(
         &codegen_results.crate_info,
         Some(CrateType::Staticlib),
         &mut |cnum, path| {
-            let lto = are_upstream_rust_objects_already_included(sess);
+            let lto = are_upstream_rust_objects_already_included(sess)
+                && !ignored_for_lto(sess, &codegen_results.crate_info, cnum);
 
             let native_libs = codegen_results.crate_info.native_libraries[&cnum].iter();
             let relevant = native_libs.clone().filter(|lib| relevant_lib(sess, lib));
@@ -1277,6 +1272,24 @@ fn link_sanitizer_runtime(
     }
 }
 
+/// Returns a boolean indicating whether the specified crate should be ignored
+/// during LTO.
+///
+/// Crates ignored during LTO are not lumped together in the "massive object
+/// file" that we create and are linked in their normal rlib states. See
+/// comments below for what crates do not participate in LTO.
+///
+/// It's unusual for a crate to not participate in LTO. Typically only
+/// compiler-specific and unstable crates have a reason to not participate in
+/// LTO.
+pub fn ignored_for_lto(sess: &Session, info: &CrateInfo, cnum: CrateNum) -> bool {
+    // If our target enables builtin function lowering in LLVM then the
+    // crates providing these functions don't participate in LTO (e.g.
+    // no_builtins or compiler builtins crates).
+    !sess.target.no_builtins
+        && (info.compiler_builtins == Some(cnum) || info.is_no_builtins.contains(&cnum))
+}
+
 /// This functions tries to determine the appropriate linker (and corresponding LinkerFlavor) to use
 pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
     fn infer_from(
@@ -2742,6 +2755,10 @@ fn rehome_sysroot_lib_dir<'a>(sess: &'a Session, lib_dir: &Path) -> PathBuf {
 // symbols). We must continue to include the rest of the rlib, however, as
 // it may contain static native libraries which must be linked in.
 //
+// (*) Crates marked with `#![no_builtins]` don't participate in LTO and
+// their bytecode wasn't included. The object files in those libraries must
+// still be passed to the linker.
+//
 // Note, however, that if we're not doing LTO we can just pass the rlib
 // blindly to the linker (fast) because it's fine if it's not actually
 // included as we're at the end of the dependency chain.
@@ -2767,7 +2784,9 @@ fn add_static_crate<'a>(
         cmd.link_rlib(&rlib_path);
     };
 
-    if !are_upstream_rust_objects_already_included(sess) {
+    if !are_upstream_rust_objects_already_included(sess)
+        || ignored_for_lto(sess, &codegen_results.crate_info, cnum)
+    {
         link_upstream(cratepath);
         return;
     }
@@ -2781,6 +2800,8 @@ fn add_static_crate<'a>(
         let canonical_name = name.replace('-', "_");
         let upstream_rust_objects_already_included =
             are_upstream_rust_objects_already_included(sess);
+        let is_builtins =
+            sess.target.no_builtins || !codegen_results.crate_info.is_no_builtins.contains(&cnum);
 
         let mut archive = archive_builder_builder.new_archive_builder(sess);
         if let Err(error) = archive.add_archive(
@@ -2797,8 +2818,9 @@ fn add_static_crate<'a>(
 
                 // If we're performing LTO and this is a rust-generated object
                 // file, then we don't need the object file as it's part of the
-                // LTO module.
-                if upstream_rust_objects_already_included && is_rust_object {
+                // LTO module. Note that `#![no_builtins]` is excluded from LTO,
+                // though, so we let that object file slide.
+                if upstream_rust_objects_already_included && is_rust_object && is_builtins {
                     return true;
                 }
 
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index 94841ab7b33..cae7c40c5ad 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -54,8 +54,8 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S
     // export level, however, as they're just implementation details.
     // Down below we'll hardwire all of the symbols to the `Rust` export
     // level instead.
-    let is_compiler_builtins = tcx.is_compiler_builtins(LOCAL_CRATE);
-    let special_runtime_crate = tcx.is_panic_runtime(LOCAL_CRATE) || is_compiler_builtins;
+    let special_runtime_crate =
+        tcx.is_panic_runtime(LOCAL_CRATE) || tcx.is_compiler_builtins(LOCAL_CRATE);
 
     let mut reachable_non_generics: DefIdMap<_> = tcx
         .reachable_set(())
@@ -105,14 +105,8 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S
             }
         })
         .map(|def_id| {
-            let codegen_attrs = tcx.codegen_fn_attrs(def_id.to_def_id());
             // We won't link right if this symbol is stripped during LTO.
             let name = tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())).name;
-            // We have to preserve the symbols of the built-in functions during LTO.
-            let is_builtin_fn = is_compiler_builtins
-                && symbol_export_level(tcx, def_id.to_def_id())
-                    .is_below_threshold(SymbolExportLevel::C)
-                && codegen_attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE);
             let used = name == "rust_eh_personality";
 
             let export_level = if special_runtime_crate {
@@ -120,6 +114,7 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S
             } else {
                 symbol_export_level(tcx, def_id.to_def_id())
             };
+            let codegen_attrs = tcx.codegen_fn_attrs(def_id.to_def_id());
             debug!(
                 "EXPORTED SYMBOL (local): {} ({:?})",
                 tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())),
@@ -139,7 +134,6 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S
                 used: codegen_attrs.flags.contains(CodegenFnAttrFlags::USED)
                     || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)
                     || used,
-                used_compiler: is_builtin_fn,
             };
             (def_id.to_def_id(), info)
         })
@@ -152,7 +146,6 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S
                 level: SymbolExportLevel::C,
                 kind: SymbolExportKind::Data,
                 used: false,
-                used_compiler: false,
             },
         );
     }
@@ -201,7 +194,6 @@ fn exported_symbols_provider_local(
                         level: info.level,
                         kind: SymbolExportKind::Text,
                         used: info.used,
-                        used_compiler: false,
                     },
                 )
             })
@@ -218,7 +210,6 @@ fn exported_symbols_provider_local(
                 level: SymbolExportLevel::C,
                 kind: SymbolExportKind::Text,
                 used: false,
-                used_compiler: false,
             },
         ));
     }
@@ -238,7 +229,6 @@ fn exported_symbols_provider_local(
                     level: SymbolExportLevel::Rust,
                     kind: SymbolExportKind::Text,
                     used: false,
-                    used_compiler: false,
                 },
             ));
         }
@@ -251,7 +241,6 @@ fn exported_symbols_provider_local(
                 level: SymbolExportLevel::Rust,
                 kind: SymbolExportKind::Data,
                 used: false,
-                used_compiler: false,
             },
         ))
     }
@@ -271,7 +260,6 @@ fn exported_symbols_provider_local(
                     level: SymbolExportLevel::C,
                     kind: SymbolExportKind::Data,
                     used: false,
-                    used_compiler: false,
                 },
             )
         }));
@@ -297,7 +285,6 @@ fn exported_symbols_provider_local(
                     level: SymbolExportLevel::C,
                     kind: SymbolExportKind::Data,
                     used: false,
-                    used_compiler: false,
                 },
             )
         }));
@@ -315,7 +302,6 @@ fn exported_symbols_provider_local(
                 level: SymbolExportLevel::C,
                 kind: SymbolExportKind::Data,
                 used: true,
-                used_compiler: false,
             },
         ));
     }
@@ -356,7 +342,6 @@ fn exported_symbols_provider_local(
                                 level: SymbolExportLevel::Rust,
                                 kind: SymbolExportKind::Text,
                                 used: false,
-                                used_compiler: false,
                             },
                         ));
                     }
@@ -373,7 +358,6 @@ fn exported_symbols_provider_local(
                             level: SymbolExportLevel::Rust,
                             kind: SymbolExportKind::Text,
                             used: false,
-                            used_compiler: false,
                         },
                     ));
                 }
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 8e835039970..af1c6594446 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -148,12 +148,23 @@ impl ModuleConfig {
 
         let emit_obj = if !should_emit_obj {
             EmitObj::None
-        } else if sess.target.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled() {
+        } else if sess.target.obj_is_bitcode
+            || (sess.opts.cg.linker_plugin_lto.enabled() && !no_builtins)
+        {
             // This case is selected if the target uses objects as bitcode, or
             // if linker plugin LTO is enabled. In the linker plugin LTO case
             // the assumption is that the final link-step will read the bitcode
             // and convert it to object code. This may be done by either the
             // native linker or rustc itself.
+            //
+            // Note, however, that the linker-plugin-lto requested here is
+            // explicitly ignored for `#![no_builtins]` crates. These crates are
+            // specifically ignored by rustc's LTO passes and wouldn't work if
+            // loaded into the linker. These crates define symbols that LLVM
+            // lowers intrinsics to, and these symbol dependencies aren't known
+            // until after codegen. As a result any crate marked
+            // `#![no_builtins]` is assumed to not participate in LTO and
+            // instead goes on to generate object code.
             EmitObj::Bitcode
         } else if need_bitcode_in_object(tcx) {
             EmitObj::ObjectCode(BitcodeSection::Full)
@@ -1023,6 +1034,9 @@ fn start_executing_work<B: ExtraBackendMethods>(
 
     let mut each_linked_rlib_for_lto = Vec::new();
     drop(link::each_linked_rlib(crate_info, None, &mut |cnum, path| {
+        if link::ignored_for_lto(sess, crate_info, cnum) {
+            return;
+        }
         each_linked_rlib_for_lto.push((cnum, path.to_path_buf()));
     }));
 
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 9d1729c4b54..0ad4af968db 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -859,6 +859,7 @@ impl CrateInfo {
             local_crate_name,
             compiler_builtins,
             profiler_runtime: None,
+            is_no_builtins: Default::default(),
             native_libraries: Default::default(),
             used_libraries: tcx.native_libraries(LOCAL_CRATE).iter().map(Into::into).collect(),
             crate_name: Default::default(),
@@ -885,6 +886,9 @@ impl CrateInfo {
             if tcx.is_profiler_runtime(cnum) {
                 info.profiler_runtime = Some(cnum);
             }
+            if tcx.is_no_builtins(cnum) {
+                info.is_no_builtins.insert(cnum);
+            }
         }
 
         // Handle circular dependencies in the standard library.
@@ -892,7 +896,9 @@ impl CrateInfo {
         // If global LTO is enabled then almost everything (*) is glued into a single object file,
         // so this logic is not necessary and can cause issues on some targets (due to weak lang
         // item symbols being "privatized" to that object file), so we disable it.
-        // (*) Native libs are not glued, and we assume that they cannot define weak lang items.
+        // (*) Native libs, and `#[compiler_builtins]` and `#[no_builtins]` crates are not glued,
+        // and we assume that they cannot define weak lang items. This is not currently enforced
+        // by the compiler, but that's ok because all this stuff is unstable anyway.
         let target = &tcx.sess.target;
         if !are_upstream_rust_objects_already_included(tcx.sess) {
             let missing_weak_lang_items: FxHashSet<Symbol> = info
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 0d88df63280..99280fdba7c 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -25,7 +25,7 @@ extern crate tracing;
 extern crate rustc_middle;
 
 use rustc_ast as ast;
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::Lrc;
 use rustc_hir::def_id::CrateNum;
 use rustc_middle::dep_graph::WorkProduct;
@@ -158,6 +158,7 @@ pub struct CrateInfo {
     pub local_crate_name: Symbol,
     pub compiler_builtins: Option<CrateNum>,
     pub profiler_runtime: Option<CrateNum>,
+    pub is_no_builtins: FxHashSet<CrateNum>,
     pub native_libraries: FxHashMap<CrateNum, Vec<NativeLib>>,
     pub crate_name: FxHashMap<CrateNum, Symbol>,
     pub used_libraries: Vec<NativeLib>,
diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
index 980ac310119..648c9118400 100644
--- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
+++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
@@ -85,7 +85,7 @@ fn source_string(file: Lrc<SourceFile>, line: &Line) -> String {
 /// Maps `Diagnostic::Level` to `snippet::AnnotationType`
 fn annotation_type_for_level(level: Level) -> AnnotationType {
     match level {
-        Level::Bug | Level::DelayedBug | Level::Fatal | Level::Error => AnnotationType::Error,
+        Level::Bug | Level::DelayedBug(_) | Level::Fatal | Level::Error => AnnotationType::Error,
         Level::ForceWarning(_) | Level::Warning => AnnotationType::Warning,
         Level::Note | Level::OnceNote => AnnotationType::Note,
         Level::Help | Level::OnceHelp => AnnotationType::Help,
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index d8d6922a1bc..786aced5b4f 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -1,7 +1,7 @@
 use crate::snippet::Style;
 use crate::{
-    CodeSuggestion, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Level, MultiSpan,
-    SubdiagnosticMessage, Substitution, SubstitutionPart, SuggestionStyle,
+    CodeSuggestion, DelayedBugKind, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Level,
+    MultiSpan, SubdiagnosticMessage, Substitution, SubstitutionPart, SuggestionStyle,
 };
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_error_messages::fluent_value_from_str_list_sep_by_and;
@@ -243,12 +243,15 @@ impl Diagnostic {
 
     pub fn is_error(&self) -> bool {
         match self.level {
-            Level::Bug | Level::DelayedBug | Level::Fatal | Level::Error | Level::FailureNote => {
-                true
-            }
+            Level::Bug
+            | Level::DelayedBug(DelayedBugKind::Normal)
+            | Level::Fatal
+            | Level::Error
+            | Level::FailureNote => true,
 
             Level::ForceWarning(_)
             | Level::Warning
+            | Level::DelayedBug(DelayedBugKind::GoodPath)
             | Level::Note
             | Level::OnceNote
             | Level::Help
@@ -318,7 +321,7 @@ impl Diagnostic {
             "downgrade_to_delayed_bug: cannot downgrade {:?} to DelayedBug: not an error",
             self.level
         );
-        self.level = Level::DelayedBug;
+        self.level = Level::DelayedBug(DelayedBugKind::Normal);
     }
 
     /// Appends a labeled span to the diagnostic.
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 404c89ea01b..8c2752af659 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -519,6 +519,12 @@ fn default_track_diagnostic(diag: Diagnostic, f: &mut dyn FnMut(Diagnostic)) {
 pub static TRACK_DIAGNOSTIC: AtomicRef<fn(Diagnostic, &mut dyn FnMut(Diagnostic))> =
     AtomicRef::new(&(default_track_diagnostic as _));
 
+#[derive(Copy, PartialEq, Eq, Clone, Hash, Debug, Encodable, Decodable)]
+pub enum DelayedBugKind {
+    Normal,
+    GoodPath,
+}
+
 #[derive(Copy, Clone, Default)]
 pub struct DiagCtxtFlags {
     /// If false, warning-level lints are suppressed.
@@ -527,6 +533,9 @@ pub struct DiagCtxtFlags {
     /// If Some, the Nth error-level diagnostic is upgraded to bug-level.
     /// (rustc: see `-Z treat-err-as-bug`)
     pub treat_err_as_bug: Option<NonZeroUsize>,
+    /// Eagerly emit delayed bugs as errors, so that the compiler debugger may
+    /// see all of the errors being emitted at once.
+    pub eagerly_emit_delayed_bugs: bool,
     /// Show macro backtraces.
     /// (rustc: see `-Z macro-backtrace`)
     pub macro_backtrace: bool,
@@ -541,8 +550,7 @@ impl Drop for DiagCtxtInner {
         self.emit_stashed_diagnostics();
 
         if !self.has_errors() {
-            let bugs = std::mem::replace(&mut self.span_delayed_bugs, Vec::new());
-            self.flush_delayed(bugs, "no errors encountered even though `span_delayed_bug` issued");
+            self.flush_delayed(DelayedBugKind::Normal)
         }
 
         // FIXME(eddyb) this explains what `good_path_delayed_bugs` are!
@@ -551,11 +559,7 @@ impl Drop for DiagCtxtInner {
         // lints can be `#[allow]`'d, potentially leading to this triggering.
         // Also, "good path" should be replaced with a better naming.
         if !self.has_printed && !self.suppressed_expected_diag && !std::thread::panicking() {
-            let bugs = std::mem::replace(&mut self.good_path_delayed_bugs, Vec::new());
-            self.flush_delayed(
-                bugs,
-                "no warnings or errors encountered even though `good_path_delayed_bugs` issued",
-            );
+            self.flush_delayed(DelayedBugKind::GoodPath);
         }
 
         if self.check_unstable_expect_diagnostics {
@@ -865,7 +869,8 @@ impl DiagCtxt {
         if treat_next_err_as_bug {
             self.bug(msg);
         }
-        DiagnosticBuilder::<ErrorGuaranteed>::new(self, DelayedBug, msg).emit()
+        DiagnosticBuilder::<ErrorGuaranteed>::new(self, DelayedBug(DelayedBugKind::Normal), msg)
+            .emit()
     }
 
     /// Like `delayed_bug`, but takes an additional span.
@@ -882,16 +887,15 @@ impl DiagCtxt {
         if treat_next_err_as_bug {
             self.span_bug(sp, msg);
         }
-        DiagnosticBuilder::<ErrorGuaranteed>::new(self, DelayedBug, msg).with_span(sp).emit()
+        DiagnosticBuilder::<ErrorGuaranteed>::new(self, DelayedBug(DelayedBugKind::Normal), msg)
+            .with_span(sp)
+            .emit()
     }
 
     // FIXME(eddyb) note the comment inside `impl Drop for DiagCtxtInner`, that's
     // where the explanation of what "good path" is (also, it should be renamed).
     pub fn good_path_delayed_bug(&self, msg: impl Into<DiagnosticMessage>) {
-        let mut inner = self.inner.borrow_mut();
-        let diagnostic = Diagnostic::new(DelayedBug, msg);
-        let backtrace = std::backtrace::Backtrace::capture();
-        inner.good_path_delayed_bugs.push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace));
+        DiagnosticBuilder::<()>::new(self, DelayedBug(DelayedBugKind::GoodPath), msg).emit()
     }
 
     #[track_caller]
@@ -1218,9 +1222,7 @@ impl DiagCtxt {
     }
 
     pub fn flush_delayed(&self) {
-        let mut inner = self.inner.borrow_mut();
-        let bugs = std::mem::replace(&mut inner.span_delayed_bugs, Vec::new());
-        inner.flush_delayed(bugs, "no errors encountered even though `span_delayed_bug` issued");
+        self.inner.borrow_mut().flush_delayed(DelayedBugKind::Normal);
     }
 }
 
@@ -1270,17 +1272,30 @@ impl DiagCtxtInner {
             return None;
         }
 
-        if diagnostic.level == DelayedBug {
-            // FIXME(eddyb) this should check for `has_errors` and stop pushing
-            // once *any* errors were emitted (and truncate `span_delayed_bugs`
-            // when an error is first emitted, also), but maybe there's a case
-            // in which that's not sound? otherwise this is really inefficient.
-            let backtrace = std::backtrace::Backtrace::capture();
-            self.span_delayed_bugs
-                .push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace));
+        // FIXME(eddyb) this should check for `has_errors` and stop pushing
+        // once *any* errors were emitted (and truncate `span_delayed_bugs`
+        // when an error is first emitted, also), but maybe there's a case
+        // in which that's not sound? otherwise this is really inefficient.
+        match diagnostic.level {
+            DelayedBug(_) if self.flags.eagerly_emit_delayed_bugs => {
+                diagnostic.level = Error;
+            }
+            DelayedBug(DelayedBugKind::Normal) => {
+                let backtrace = std::backtrace::Backtrace::capture();
+                self.span_delayed_bugs
+                    .push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace));
 
-            #[allow(deprecated)]
-            return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
+                #[allow(deprecated)]
+                return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
+            }
+            DelayedBug(DelayedBugKind::GoodPath) => {
+                let backtrace = std::backtrace::Backtrace::capture();
+                self.good_path_delayed_bugs
+                    .push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace));
+
+                return None;
+            }
+            _ => {}
         }
 
         if diagnostic.has_future_breakage() {
@@ -1396,11 +1411,18 @@ impl DiagCtxtInner {
         self.emit_diagnostic(Diagnostic::new(FailureNote, msg));
     }
 
-    fn flush_delayed(
-        &mut self,
-        bugs: Vec<DelayedDiagnostic>,
-        explanation: impl Into<DiagnosticMessage> + Copy,
-    ) {
+    fn flush_delayed(&mut self, kind: DelayedBugKind) {
+        let (bugs, explanation) = match kind {
+            DelayedBugKind::Normal => (
+                std::mem::take(&mut self.span_delayed_bugs),
+                "no errors encountered even though `span_delayed_bug` issued",
+            ),
+            DelayedBugKind::GoodPath => (
+                std::mem::take(&mut self.good_path_delayed_bugs),
+                "no warnings or errors encountered even though `good_path_delayed_bugs` issued",
+            ),
+        };
+
         if bugs.is_empty() {
             return;
         }
@@ -1433,7 +1455,7 @@ impl DiagCtxtInner {
                 if backtrace || self.ice_file.is_none() { bug.decorate() } else { bug.inner };
 
             // "Undelay" the `DelayedBug`s (into plain `Bug`s).
-            if bug.level != DelayedBug {
+            if !matches!(bug.level, DelayedBug(_)) {
                 // NOTE(eddyb) not panicking here because we're already producing
                 // an ICE, and the more information the merrier.
                 bug.subdiagnostic(InvalidFlushedDelayedDiagnosticLevel {
@@ -1521,8 +1543,9 @@ pub enum Level {
     /// silently dropped. I.e. "expect other errors are emitted" semantics. Useful on code paths
     /// that should only be reached when compiling erroneous code.
     ///
-    /// Its `EmissionGuarantee` is `ErrorGuaranteed`.
-    DelayedBug,
+    /// Its `EmissionGuarantee` is `ErrorGuaranteed` for `Normal` delayed bugs, and `()` for
+    /// `GoodPath` delayed bugs.
+    DelayedBug(DelayedBugKind),
 
     /// An error that causes an immediate abort. Used for things like configuration errors,
     /// internal overflows, some file operation errors.
@@ -1597,7 +1620,7 @@ impl Level {
     fn color(self) -> ColorSpec {
         let mut spec = ColorSpec::new();
         match self {
-            Bug | DelayedBug | Fatal | Error => {
+            Bug | DelayedBug(_) | Fatal | Error => {
                 spec.set_fg(Some(Color::Red)).set_intense(true);
             }
             ForceWarning(_) | Warning => {
@@ -1617,7 +1640,7 @@ impl Level {
 
     pub fn to_str(self) -> &'static str {
         match self {
-            Bug | DelayedBug => "error: internal compiler error",
+            Bug | DelayedBug(_) => "error: internal compiler error",
             Fatal | Error => "error",
             ForceWarning(_) | Warning => "warning",
             Note | OnceNote => "note",
diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs
index 5f599487912..556560945e9 100644
--- a/compiler/rustc_hir_analysis/src/autoderef.rs
+++ b/compiler/rustc_hir_analysis/src/autoderef.rs
@@ -74,7 +74,7 @@ impl<'a, 'tcx> Iterator for Autoderef<'a, 'tcx> {
             // we have some type like `&<Ty as Trait>::Assoc`, since users of
             // autoderef expect this type to have been structurally normalized.
             if self.infcx.next_trait_solver()
-                && let ty::Alias(ty::Projection | ty::Inherent | ty::Weak, _) = ty.kind()
+                && let ty::Alias(..) = ty.kind()
             {
                 let (normalized_ty, obligations) = self.structurally_normalize(ty)?;
                 self.state.obligations.extend(obligations);
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 40e6b1b579f..b6fa2f1f221 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -532,8 +532,14 @@ lint_unknown_gated_lint =
 
 lint_unknown_lint =
     unknown lint: `{$name}`
-    .suggestion = did you mean
-    .help = did you mean: `{$replace}`
+    .suggestion = {$from_rustc ->
+        [true] a lint with a similar name exists in `rustc` lints
+        *[false] did you mean
+    }
+    .help = {$from_rustc ->
+        [true] a lint with a similar name exists in `rustc` lints: `{$replace}`
+        *[false] did you mean: `{$replace}`
+    }
 
 lint_unknown_tool_in_scoped_lint = unknown tool name `{$tool_name}` found in scoped lint: `{$tool_name}::{$lint_name}`
     .help = add `#![register_tool({$tool_name})]` to the crate root
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index d0fd019a8b1..ffd8f1b3c79 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -33,7 +33,7 @@ use rustc_middle::ty::{self, print::Printer, GenericArg, RegisteredTools, Ty, Ty
 use rustc_session::lint::{BuiltinLintDiagnostics, LintExpectationId};
 use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
 use rustc_session::{LintStoreMarker, Session};
-use rustc_span::edit_distance::find_best_match_for_name;
+use rustc_span::edit_distance::find_best_match_for_names;
 use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::Span;
 use rustc_target::abi;
@@ -117,7 +117,7 @@ struct LintGroup {
 pub enum CheckLintNameResult<'a> {
     Ok(&'a [LintId]),
     /// Lint doesn't exist. Potentially contains a suggestion for a correct lint name.
-    NoLint(Option<Symbol>),
+    NoLint(Option<(Symbol, bool)>),
     /// The lint refers to a tool that has not been registered.
     NoTool,
     /// The lint has been renamed to a new name.
@@ -377,7 +377,7 @@ impl LintStore {
                         debug!("lints={:?}", self.by_name.keys().collect::<Vec<_>>());
                         let tool_prefix = format!("{tool_name}::");
                         return if self.by_name.keys().any(|lint| lint.starts_with(&tool_prefix)) {
-                            self.no_lint_suggestion(&complete_name)
+                            self.no_lint_suggestion(&complete_name, tool_name.as_str())
                         } else {
                             // 2. The tool isn't currently running, so no lints will be registered.
                             // To avoid giving a false positive, ignore all unknown lints.
@@ -419,13 +419,14 @@ impl LintStore {
         }
     }
 
-    fn no_lint_suggestion(&self, lint_name: &str) -> CheckLintNameResult<'_> {
+    fn no_lint_suggestion(&self, lint_name: &str, tool_name: &str) -> CheckLintNameResult<'_> {
         let name_lower = lint_name.to_lowercase();
 
         if lint_name.chars().any(char::is_uppercase) && self.find_lints(&name_lower).is_ok() {
             // First check if the lint name is (partly) in upper case instead of lower case...
-            return CheckLintNameResult::NoLint(Some(Symbol::intern(&name_lower)));
+            return CheckLintNameResult::NoLint(Some((Symbol::intern(&name_lower), false)));
         }
+
         // ...if not, search for lints with a similar name
         // Note: find_best_match_for_name depends on the sort order of its input vector.
         // To ensure deterministic output, sort elements of the lint_groups hash map.
@@ -441,7 +442,16 @@ impl LintStore {
         let groups = groups.iter().map(|k| Symbol::intern(k));
         let lints = self.lints.iter().map(|l| Symbol::intern(&l.name_lower()));
         let names: Vec<Symbol> = groups.chain(lints).collect();
-        let suggestion = find_best_match_for_name(&names, Symbol::intern(&name_lower), None);
+        let mut lookups = vec![Symbol::intern(&name_lower)];
+        if let Some(stripped) = name_lower.split("::").last() {
+            lookups.push(Symbol::intern(stripped));
+        }
+        let res = find_best_match_for_names(&names, &lookups, None);
+        let is_rustc = res.map_or_else(
+            || false,
+            |s| name_lower.contains("::") && !s.as_str().starts_with(tool_name),
+        );
+        let suggestion = res.map(|s| (s, is_rustc));
         CheckLintNameResult::NoLint(suggestion)
     }
 
@@ -454,7 +464,7 @@ impl LintStore {
         match self.by_name.get(&complete_name) {
             None => match self.lint_groups.get(&*complete_name) {
                 // Now we are sure, that this lint exists nowhere
-                None => self.no_lint_suggestion(lint_name),
+                None => self.no_lint_suggestion(lint_name, tool_name),
                 Some(LintGroup { lint_ids, depr, .. }) => {
                     // Reaching this would be weird, but let's cover this case anyway
                     if let Some(LintAlias { name, silent }) = depr {
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index 49821437b76..3c2d0c7b205 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -582,8 +582,9 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                 }
                 CheckLintNameResult::NoLint(suggestion) => {
                     let name = lint_name.clone();
-                    let suggestion =
-                        suggestion.map(|replace| UnknownLintSuggestion::WithoutSpan { replace });
+                    let suggestion = suggestion.map(|(replace, from_rustc)| {
+                        UnknownLintSuggestion::WithoutSpan { replace, from_rustc }
+                    });
                     let requested_level = RequestedLevel { level, lint_name };
                     let lint = UnknownLintFromCommandLine { name, suggestion, requested_level };
                     self.emit_lint(UNKNOWN_LINTS, lint);
@@ -990,8 +991,8 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                         } else {
                             name.to_string()
                         };
-                        let suggestion = suggestion.map(|replace| {
-                            UnknownLintSuggestion::WithSpan { suggestion: sp, replace }
+                        let suggestion = suggestion.map(|(replace, from_rustc)| {
+                            UnknownLintSuggestion::WithSpan { suggestion: sp, replace, from_rustc }
                         });
                         let lint = UnknownLint { name, suggestion };
                         self.emit_spanned_lint(UNKNOWN_LINTS, sp.into(), lint);
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index bc9a9d7b745..f370c4392b3 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1050,9 +1050,10 @@ pub enum UnknownLintSuggestion {
         #[primary_span]
         suggestion: Span,
         replace: Symbol,
+        from_rustc: bool,
     },
     #[help(lint_help)]
-    WithoutSpan { replace: Symbol },
+    WithoutSpan { replace: Symbol, from_rustc: bool },
 }
 
 #[derive(LintDiagnostic)]
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 76eb6bfaef7..6114f7c8678 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -531,9 +531,12 @@ extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
 
 // Unfortunately, the LLVM C API doesn't provide a way to create the
 // TargetLibraryInfo pass, so we use this method to do so.
-extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M) {
+extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
+                                       bool DisableSimplifyLibCalls) {
   Triple TargetTriple(unwrap(M)->getTargetTriple());
   TargetLibraryInfoImpl TLII(TargetTriple);
+  if (DisableSimplifyLibCalls)
+    TLII.disableAllFunctions();
   unwrap(PMR)->add(new TargetLibraryInfoWrapperPass(TLII));
 }
 
@@ -700,7 +703,7 @@ LLVMRustOptimize(
     bool IsLinkerPluginLTO,
     bool NoPrepopulatePasses, bool VerifyIR, bool UseThinLTOBuffers,
     bool MergeFunctions, bool UnrollLoops, bool SLPVectorize, bool LoopVectorize,
-    bool EmitLifetimeMarkers,
+    bool DisableSimplifyLibCalls, bool EmitLifetimeMarkers,
     LLVMRustSanitizerOptions *SanitizerOptions,
     const char *PGOGenPath, const char *PGOUsePath,
     bool InstrumentCoverage, const char *InstrProfileOutput,
@@ -800,6 +803,8 @@ LLVMRustOptimize(
 
   Triple TargetTriple(TheModule->getTargetTriple());
   std::unique_ptr<TargetLibraryInfoImpl> TLII(new TargetLibraryInfoImpl(TargetTriple));
+  if (DisableSimplifyLibCalls)
+    TLII->disableAllFunctions();
   FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
 
   PB.registerModuleAnalyses(MAM);
diff --git a/compiler/rustc_middle/src/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs
index 59ce0a14b2a..e30b6b203d7 100644
--- a/compiler/rustc_middle/src/middle/exported_symbols.rs
+++ b/compiler/rustc_middle/src/middle/exported_symbols.rs
@@ -35,12 +35,7 @@ pub enum SymbolExportKind {
 pub struct SymbolExportInfo {
     pub level: SymbolExportLevel,
     pub kind: SymbolExportKind,
-    /// Used to mark these symbols not to be internalized by LTO. These symbols
-    /// are also added to `symbols.o` to avoid circular dependencies when linking.
     pub used: bool,
-    /// Also used to mark these symbols not to be internalized by LTO. But will
-    /// not be added to `symbols.o`. Currently there are only builtin functions.
-    pub used_compiler: bool,
 }
 
 #[derive(Eq, PartialEq, Debug, Copy, Clone, TyEncodable, TyDecodable, HashStable)]
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 61796d7a6ca..20bea153793 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -1146,6 +1146,7 @@ impl UnstableOptions {
         DiagCtxtFlags {
             can_emit_warnings,
             treat_err_as_bug: self.treat_err_as_bug,
+            eagerly_emit_delayed_bugs: self.eagerly_emit_delayed_bugs,
             macro_backtrace: self.macro_backtrace,
             deduplicate_diagnostics: self.deduplicate_diagnostics,
             track_diagnostics: self.track_diagnostics,
@@ -1823,7 +1824,7 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
             "Remap source names in all output (compiler messages and output files)",
             "FROM=TO",
         ),
-        opt::multi("", "env", "Inject an environment variable", "VAR=VALUE"),
+        opt::multi("", "env-set", "Inject an environment variable", "VAR=VALUE"),
     ]);
     opts
 }
@@ -2599,11 +2600,11 @@ fn parse_logical_env(
 ) -> FxIndexMap<String, String> {
     let mut vars = FxIndexMap::default();
 
-    for arg in matches.opt_strs("env") {
+    for arg in matches.opt_strs("env-set") {
         if let Some((name, val)) = arg.split_once('=') {
             vars.insert(name.to_string(), val.to_string());
         } else {
-            early_dcx.early_fatal(format!("`--env`: specify value for variable `{arg}`"));
+            early_dcx.early_fatal(format!("`--env-set`: specify value for variable `{arg}`"));
         }
     }
 
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index c97b18ebd66..2d91a3fbd91 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1583,6 +1583,9 @@ options! {
         "version of DWARF debug information to emit (default: 2 or 4, depending on platform)"),
     dylib_lto: bool = (false, parse_bool, [UNTRACKED],
         "enables LTO for dylib crate type"),
+    eagerly_emit_delayed_bugs: bool = (false, parse_bool, [UNTRACKED],
+        "emit delayed bugs eagerly as errors instead of stashing them and emitting \
+        them only if an error has not been emitted"),
     ehcont_guard: bool = (false, parse_bool, [TRACKED],
         "generate Windows EHCont Guard tables"),
     emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED],
diff --git a/compiler/rustc_span/src/edit_distance.rs b/compiler/rustc_span/src/edit_distance.rs
index 14cb1d6d362..87a0ccbb1a5 100644
--- a/compiler/rustc_span/src/edit_distance.rs
+++ b/compiler/rustc_span/src/edit_distance.rs
@@ -170,6 +170,34 @@ pub fn find_best_match_for_name(
     find_best_match_for_name_impl(false, candidates, lookup, dist)
 }
 
+/// Find the best match for multiple words
+///
+/// This function is intended for use when the desired match would never be
+/// returned due to a substring in `lookup` which is superfluous.
+///
+/// For example, when looking for the closest lint name to `clippy:missing_docs`,
+/// we would find `clippy::erasing_op`, despite `missing_docs` existing and being a better suggestion.
+/// `missing_docs` would have a larger edit distance because it does not contain the `clippy` tool prefix.
+/// In order to find `missing_docs`, this function takes multiple lookup strings, computes the best match
+/// for each and returns the match which had the lowest edit distance. In our example, `clippy:missing_docs` and
+/// `missing_docs` would be `lookups`, enabling `missing_docs` to be the best match, as desired.
+pub fn find_best_match_for_names(
+    candidates: &[Symbol],
+    lookups: &[Symbol],
+    dist: Option<usize>,
+) -> Option<Symbol> {
+    lookups
+        .iter()
+        .map(|s| (s, find_best_match_for_name_impl(false, candidates, *s, dist)))
+        .filter_map(|(s, r)| r.map(|r| (s, r)))
+        .min_by(|(s1, r1), (s2, r2)| {
+            let d1 = edit_distance(s1.as_str(), r1.as_str(), usize::MAX).unwrap();
+            let d2 = edit_distance(s2.as_str(), r2.as_str(), usize::MAX).unwrap();
+            d1.cmp(&d2)
+        })
+        .map(|(_, r)| r)
+}
+
 #[cold]
 fn find_best_match_for_name_impl(
     use_substring_score: bool,
diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs
index 55b79e6fc39..d87cc89954a 100644
--- a/compiler/rustc_trait_selection/src/solve/normalize.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalize.rs
@@ -8,7 +8,7 @@ use rustc_infer::infer::InferCtxt;
 use rustc_infer::traits::TraitEngineExt;
 use rustc_infer::traits::{FulfillmentError, Obligation, TraitEngine};
 use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
-use rustc_middle::traits::{ObligationCause, Reveal};
+use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::{self, AliasTy, Ty, TyCtxt, UniverseIndex};
 use rustc_middle::ty::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
@@ -52,14 +52,16 @@ struct NormalizationFolder<'me, 'tcx> {
 impl<'tcx> NormalizationFolder<'_, 'tcx> {
     fn normalize_alias_ty(
         &mut self,
-        alias: AliasTy<'tcx>,
+        alias_ty: Ty<'tcx>,
     ) -> Result<Ty<'tcx>, Vec<FulfillmentError<'tcx>>> {
+        assert!(matches!(alias_ty.kind(), ty::Alias(..)));
+
         let infcx = self.at.infcx;
         let tcx = infcx.tcx;
         let recursion_limit = tcx.recursion_limit();
         if !recursion_limit.value_within_limit(self.depth) {
             self.at.infcx.err_ctxt().report_overflow_error(
-                &alias.to_ty(tcx),
+                &alias_ty,
                 self.at.cause.span,
                 true,
                 |_| {},
@@ -76,7 +78,11 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> {
             tcx,
             self.at.cause.clone(),
             self.at.param_env,
-            ty::NormalizesTo { alias, term: new_infer_ty.into() },
+            ty::PredicateKind::AliasRelate(
+                alias_ty.into(),
+                new_infer_ty.into(),
+                ty::AliasRelationDirection::Equate,
+            ),
         );
 
         // Do not emit an error if normalization is known to fail but instead
@@ -90,9 +96,12 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> {
                 return Err(errors);
             }
             let ty = infcx.resolve_vars_if_possible(new_infer_ty);
-            ty.try_fold_with(self)?
+
+            // Alias is guaranteed to be fully structurally resolved,
+            // so we can super fold here.
+            ty.try_super_fold_with(self)?
         } else {
-            alias.to_ty(tcx).try_super_fold_with(self)?
+            alias_ty.try_super_fold_with(self)?
         };
 
         self.depth -= 1;
@@ -170,24 +179,18 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for NormalizationFolder<'_, 'tcx> {
     }
 
     fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
-        let reveal = self.at.param_env.reveal();
         let infcx = self.at.infcx;
         debug_assert_eq!(ty, infcx.shallow_resolve(ty));
-        if !needs_normalization(&ty, reveal) {
+        if !ty.has_projections() {
             return Ok(ty);
         }
 
-        // We don't normalize opaque types unless we have
-        // `Reveal::All`, even if we're in the defining scope.
-        let data = match *ty.kind() {
-            ty::Alias(kind, alias_ty) if kind != ty::Opaque || reveal == Reveal::All => alias_ty,
-            _ => return ty.try_super_fold_with(self),
-        };
+        let ty::Alias(..) = *ty.kind() else { return ty.try_super_fold_with(self) };
 
-        if data.has_escaping_bound_vars() {
-            let (data, mapped_regions, mapped_types, mapped_consts) =
-                BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
-            let result = ensure_sufficient_stack(|| self.normalize_alias_ty(data))?;
+        if ty.has_escaping_bound_vars() {
+            let (ty, mapped_regions, mapped_types, mapped_consts) =
+                BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, ty);
+            let result = ensure_sufficient_stack(|| self.normalize_alias_ty(ty))?;
             Ok(PlaceholderReplacer::replace_placeholders(
                 infcx,
                 mapped_regions,
@@ -197,7 +200,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for NormalizationFolder<'_, 'tcx> {
                 result,
             ))
         } else {
-            ensure_sufficient_stack(|| self.normalize_alias_ty(data))
+            ensure_sufficient_stack(|| self.normalize_alias_ty(ty))
         }
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
index e0f9fdc3827..ed5d01d7048 100644
--- a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
@@ -22,8 +22,7 @@ impl<'tcx> StructurallyNormalizeExt<'tcx> for At<'_, 'tcx> {
         assert!(!ty.is_ty_var(), "should have resolved vars before calling");
 
         if self.infcx.next_trait_solver() {
-            // FIXME(-Znext-solver): Should we resolve opaques here?
-            let ty::Alias(ty::Projection | ty::Inherent | ty::Weak, _) = *ty.kind() else {
+            let ty::Alias(..) = *ty.kind() else {
                 return Ok(ty);
             };
 
diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs
index 72227a04bf1..38877f7a77f 100644
--- a/compiler/stable_mir/src/mir/body.rs
+++ b/compiler/stable_mir/src/mir/body.rs
@@ -963,7 +963,7 @@ pub enum PointerCoercion {
     /// Go from a safe fn pointer to an unsafe fn pointer.
     UnsafeFnPointer,
 
-    /// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer.
+    /// Go from a non-capturing closure to a fn pointer or an unsafe fn pointer.
     /// It cannot convert a closure that requires unsafe.
     ClosureFnPointer(Safety),
 
@@ -1037,21 +1037,24 @@ impl Place {
     /// locals from the function body where this place originates from.
     pub fn ty(&self, locals: &[LocalDecl]) -> Result<Ty, Error> {
         let start_ty = locals[self.local].ty;
-        self.projection.iter().fold(Ok(start_ty), |place_ty, elem| {
-            let ty = place_ty?;
-            match elem {
-                ProjectionElem::Deref => Self::deref_ty(ty),
-                ProjectionElem::Field(_idx, fty) => Ok(*fty),
-                ProjectionElem::Index(_) | ProjectionElem::ConstantIndex { .. } => {
-                    Self::index_ty(ty)
-                }
-                ProjectionElem::Subslice { from, to, from_end } => {
-                    Self::subslice_ty(ty, from, to, from_end)
-                }
-                ProjectionElem::Downcast(_) => Ok(ty),
-                ProjectionElem::OpaqueCast(ty) | ProjectionElem::Subtype(ty) => Ok(*ty),
+        self.projection.iter().fold(Ok(start_ty), |place_ty, elem| elem.ty(place_ty?))
+    }
+}
+
+impl ProjectionElem {
+    /// Get the expected type after applying this projection to a given place type.
+    pub fn ty(&self, place_ty: Ty) -> Result<Ty, Error> {
+        let ty = place_ty;
+        match &self {
+            ProjectionElem::Deref => Self::deref_ty(ty),
+            ProjectionElem::Field(_idx, fty) => Ok(*fty),
+            ProjectionElem::Index(_) | ProjectionElem::ConstantIndex { .. } => Self::index_ty(ty),
+            ProjectionElem::Subslice { from, to, from_end } => {
+                Self::subslice_ty(ty, from, to, from_end)
             }
-        })
+            ProjectionElem::Downcast(_) => Ok(ty),
+            ProjectionElem::OpaqueCast(ty) | ProjectionElem::Subtype(ty) => Ok(*ty),
+        }
     }
 
     fn index_ty(ty: Ty) -> Result<Ty, Error> {
diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/stable_mir/src/mir/visit.rs
index ab57ff0f8f5..24296e9e877 100644
--- a/compiler/stable_mir/src/mir/visit.rs
+++ b/compiler/stable_mir/src/mir/visit.rs
@@ -37,7 +37,7 @@
 
 use crate::mir::*;
 use crate::ty::{Const, GenericArgs, Region, Ty};
-use crate::{Opaque, Span};
+use crate::{Error, Opaque, Span};
 
 pub trait MirVisitor {
     fn visit_body(&mut self, body: &Body) {
@@ -76,12 +76,14 @@ pub trait MirVisitor {
         self.super_place(place, ptx, location)
     }
 
-    fn visit_projection_elem(
+    fn visit_projection_elem<'a>(
         &mut self,
+        place_ref: PlaceRef<'a>,
         elem: &ProjectionElem,
         ptx: PlaceContext,
         location: Location,
     ) {
+        let _ = place_ref;
         self.super_projection_elem(elem, ptx, location);
     }
 
@@ -284,8 +286,9 @@ pub trait MirVisitor {
         let _ = ptx;
         self.visit_local(&place.local, ptx, location);
 
-        for elem in &place.projection {
-            self.visit_projection_elem(elem, ptx, location);
+        for (idx, elem) in place.projection.iter().enumerate() {
+            let place_ref = PlaceRef { local: place.local, projection: &place.projection[..idx] };
+            self.visit_projection_elem(place_ref, elem, ptx, location);
         }
     }
 
@@ -453,6 +456,19 @@ impl Location {
     }
 }
 
+/// Reference to a place used to represent a partial projection.
+pub struct PlaceRef<'a> {
+    pub local: Local,
+    pub projection: &'a [ProjectionElem],
+}
+
+impl<'a> PlaceRef<'a> {
+    /// Get the type of this place.
+    pub fn ty(&self, locals: &[LocalDecl]) -> Result<Ty, Error> {
+        self.projection.iter().fold(Ok(locals[self.local].ty), |place_ty, elem| elem.ty(place_ty?))
+    }
+}
+
 /// Information about a place's usage.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 pub struct PlaceContext {
diff --git a/src/doc/unstable-book/src/compiler-flags/env.md b/src/doc/unstable-book/src/compiler-flags/env-set.md
index ac6d7474a9b..e5d7206c3a3 100644
--- a/src/doc/unstable-book/src/compiler-flags/env.md
+++ b/src/doc/unstable-book/src/compiler-flags/env-set.md
@@ -1,4 +1,4 @@
-# `env`
+# `env-set`
 
 The tracking issue for this feature is: [#118372](https://github.com/rust-lang/rust/issues/118372).
 
@@ -11,11 +11,11 @@ from the `proc_macro` crate.
 This information will be stored in the dep-info files. For more information about
 dep-info files, take a look [here](https://doc.rust-lang.org/cargo/guide/build-cache.html#dep-info-files).
 
-When retrieving an environment variable value, the one specified by `--env` will take
+When retrieving an environment variable value, the one specified by `--env-set` will take
 precedence. For example, if you want have `PATH=a` in your environment and pass:
 
 ```bash
-rustc --env PATH=env
+rustc --env-set PATH=env
 ```
 
 Then you will have:
@@ -24,17 +24,17 @@ Then you will have:
 assert_eq!(env!("PATH"), "env");
 ```
 
-It will trigger a new compilation if any of the `--env` argument value is different.
+It will trigger a new compilation if any of the `--env-set` argument value is different.
 So if you first passed:
 
 ```bash
---env A=B --env X=12
+--env-set A=B --env X=12
 ```
 
 and then on next compilation:
 
 ```bash
---env A=B
+--env-set A=B
 ```
 
 `X` value is different (not set) so the code will be re-compiled.
@@ -42,4 +42,4 @@ and then on next compilation:
 Please note that on Windows, environment variables are case insensitive but case
 preserving whereas `rustc`'s environment variables are case sensitive. For example,
 having `Path` in your environment (case insensitive) is different than using
-`rustc --env Path=...` (case sensitive).
+`rustc --env-set Path=...` (case sensitive).
diff --git a/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed b/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed
index cba32ce6b77..c0ccd41c19a 100644
--- a/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed
+++ b/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed
@@ -7,10 +7,12 @@
 #[warn(clippy::if_not_else)]
 #[warn(clippy::unnecessary_cast)]
 #[warn(clippy::useless_transmute)]
-// Shouldn't suggest rustc lint name(`dead_code`)
-#[warn(clippy::eq_op)]
+// Should suggest rustc lint name(`dead_code`)
+#[warn(dead_code)]
 // Shouldn't suggest removed/deprecated clippy lint name(`unused_collect`)
 #[warn(clippy::unused_self)]
 // Shouldn't suggest renamed clippy lint name(`const_static_lifetime`)
 #[warn(clippy::redundant_static_lifetimes)]
+// issue #118183, should report `missing_docs` from rustc lint
+#[warn(missing_docs)]
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/unknown_clippy_lints.rs b/src/tools/clippy/tests/ui/unknown_clippy_lints.rs
index c15d541974f..7a59ad364aa 100644
--- a/src/tools/clippy/tests/ui/unknown_clippy_lints.rs
+++ b/src/tools/clippy/tests/ui/unknown_clippy_lints.rs
@@ -7,10 +7,12 @@
 #[warn(clippy::if_not_els)]
 #[warn(clippy::UNNecsaRy_cAst)]
 #[warn(clippy::useles_transute)]
-// Shouldn't suggest rustc lint name(`dead_code`)
+// Should suggest rustc lint name(`dead_code`)
 #[warn(clippy::dead_cod)]
 // Shouldn't suggest removed/deprecated clippy lint name(`unused_collect`)
 #[warn(clippy::unused_colle)]
 // Shouldn't suggest renamed clippy lint name(`const_static_lifetime`)
 #[warn(clippy::const_static_lifetim)]
+// issue #118183, should report `missing_docs` from rustc lint
+#[warn(clippy::missing_docs)]
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr b/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr
index ee82db31c2c..432c7f72e32 100644
--- a/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr
+++ b/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr
@@ -35,7 +35,12 @@ error: unknown lint: `clippy::dead_cod`
   --> $DIR/unknown_clippy_lints.rs:11:8
    |
 LL | #[warn(clippy::dead_cod)]
-   |        ^^^^^^^^^^^^^^^^ help: did you mean: `clippy::eq_op`
+   |        ^^^^^^^^^^^^^^^^
+   |
+help: a lint with a similar name exists in `rustc` lints
+   |
+LL | #[warn(dead_code)]
+   |        ~~~~~~~~~
 
 error: unknown lint: `clippy::unused_colle`
   --> $DIR/unknown_clippy_lints.rs:13:8
@@ -49,5 +54,16 @@ error: unknown lint: `clippy::const_static_lifetim`
 LL | #[warn(clippy::const_static_lifetim)]
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::redundant_static_lifetimes`
 
-error: aborting due to 8 previous errors
+error: unknown lint: `clippy::missing_docs`
+  --> $DIR/unknown_clippy_lints.rs:17:8
+   |
+LL | #[warn(clippy::missing_docs)]
+   |        ^^^^^^^^^^^^^^^^^^^^
+   |
+help: a lint with a similar name exists in `rustc` lints
+   |
+LL | #[warn(missing_docs)]
+   |        ~~~~~~~~~~~~
+
+error: aborting due to 9 previous errors
 
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index aead55a6996..e8e10f64ad2 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -165,7 +165,6 @@ impl rustc_driver::Callbacks for MiriBeRustCompilerCalls {
                                     level: SymbolExportLevel::C,
                                     kind: SymbolExportKind::Text,
                                     used: false,
-                                    used_compiler: false,
                                 },
                             ))
                         }),
diff --git a/tests/run-make/no-builtins-lto/Makefile b/tests/run-make/no-builtins-lto/Makefile
index c7be4836466..c8f05d9918b 100644
--- a/tests/run-make/no-builtins-lto/Makefile
+++ b/tests/run-make/no-builtins-lto/Makefile
@@ -1,15 +1,9 @@
 include ../tools.mk
 
-# only-x86_64
-
-# We want to check that `no_builtins` is correctly participating in LTO.
-# First, verify that the `foo::foo` symbol can be found when linking.
-# Next, verify that `memcpy` can be customized using `no_builtins` under LTO.
-# Others will use the built-in memcpy.
-
 all:
-	$(RUSTC) -C linker-plugin-lto -C opt-level=2 -C debuginfo=0 foo.rs
-	$(RUSTC) -C linker-plugin-lto -C opt-level=2 -C debuginfo=0 no_builtins.rs
-	$(RUSTC) main.rs -C lto -C opt-level=2 -C debuginfo=0 -C save-temps -C metadata=1 -C codegen-units=1
-	"$(LLVM_BIN_DIR)"/llvm-dis $(TMPDIR)/main.main.*-cgu.0.rcgu.lto.input.bc -o $(TMPDIR)/lto.ll
-	cat "$(TMPDIR)"/lto.ll | "$(LLVM_FILECHECK)" filecheck.lto.txt
+	# Compile a `#![no_builtins]` rlib crate
+	$(RUSTC) no_builtins.rs
+	# Build an executable that depends on that crate using LTO. The no_builtins crate doesn't
+	# participate in LTO, so its rlib must be explicitly linked into the final binary. Verify this by
+	# grepping the linker arguments.
+	$(RUSTC) main.rs -C lto --print link-args | $(CGREP) 'libno_builtins.rlib'
diff --git a/tests/run-make/no-builtins-lto/filecheck.lto.txt b/tests/run-make/no-builtins-lto/filecheck.lto.txt
deleted file mode 100644
index 79dc3a51501..00000000000
--- a/tests/run-make/no-builtins-lto/filecheck.lto.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-CHECK: define{{.*}} void @bar
-CHECK-NEXT: call void @no_builtins
-CHECK-NEXT: call void @llvm.memcpy
-
-CHECK: define{{.*}} i32 @main
-CHECK: call void @bar
-
-CHECK: define{{.*}} void @foo
-CHECK-NEXT: call void @llvm.memcpy
-
-CHECK: define{{.*}} void @no_builtins
-CHECK-SAME: #[[ATTR:[0-9]+]] {
-CHECK: call void @foo
-CHECK-NEXT: call{{.*}} @memcpy
-
-CHECK: attributes #[[ATTR]]
-CHECK-SAME: no-builtins
diff --git a/tests/run-make/no-builtins-lto/foo.rs b/tests/run-make/no-builtins-lto/foo.rs
deleted file mode 100644
index f09ac40b152..00000000000
--- a/tests/run-make/no-builtins-lto/foo.rs
+++ /dev/null
@@ -1,33 +0,0 @@
-#![feature(lang_items, no_core)]
-#![no_std]
-#![no_core]
-#![crate_type = "lib"]
-
-#[inline(never)]
-#[no_mangle]
-pub unsafe fn foo(dest: *mut u8, src: *const u8) {
-    // should call `@llvm.memcpy`.
-    memcpy(dest, src, 1024);
-}
-
-#[no_mangle]
-#[inline(never)]
-pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, _n: usize) -> *mut u8 {
-    *dest = 0;
-    return src as *mut u8;
-}
-
-#[lang = "sized"]
-trait Sized {}
-#[lang = "copy"]
-trait Copy {}
-impl Copy for *mut u8 {}
-impl Copy for *const u8 {}
-
-#[lang = "drop_in_place"]
-#[allow(unconditional_recursion)]
-pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
-    // Code here does not matter - this is replaced by the
-    // real drop glue by the compiler.
-    drop_in_place(to_drop);
-}
diff --git a/tests/run-make/no-builtins-lto/main.rs b/tests/run-make/no-builtins-lto/main.rs
index 4421a2afbce..890c999c8cc 100644
--- a/tests/run-make/no-builtins-lto/main.rs
+++ b/tests/run-make/no-builtins-lto/main.rs
@@ -1,29 +1,3 @@
-#![feature(no_core, start, lang_items)]
-#![no_std]
-// We use `no_core` to reduce the LTO products is small enough.
-#![no_core]
-
 extern crate no_builtins;
-extern crate foo;
-
-#[cfg_attr(unix, link(name = "c"))]
-#[cfg_attr(target_env = "msvc", link(name = "msvcrt"))]
-extern "C" {}
-
-#[start]
-fn main(_: isize, p: *const *const u8) -> isize {
-    // Make sure the symbols are retained.
-    unsafe { bar(*p as *mut u8, *p); }
-    0
-}
-
-#[no_mangle]
-#[inline(never)]
-pub unsafe extern "C" fn bar(dest: *mut u8, src: *const u8) {
-    no_builtins::no_builtins(dest, src);
-    // should call `@llvm.memcpy`
-    foo::memcpy(dest, src, 1024);
-}
 
-#[lang = "eh_personality"]
-fn eh_personality() {}
+fn main() {}
diff --git a/tests/run-make/no-builtins-lto/no_builtins.rs b/tests/run-make/no-builtins-lto/no_builtins.rs
index 33ed68e3aee..5d001031a57 100644
--- a/tests/run-make/no-builtins-lto/no_builtins.rs
+++ b/tests/run-make/no-builtins-lto/no_builtins.rs
@@ -1,15 +1,2 @@
-#![feature(lang_items, no_core)]
-#![no_std]
-#![no_core]
 #![crate_type = "lib"]
 #![no_builtins]
-
-extern crate foo;
-
-#[no_mangle]
-pub unsafe fn no_builtins(dest: *mut u8, src: *const u8) {
-    // There should be no "undefined reference to `foo::foo'".
-    foo::foo(dest, src);
-    // should call `@memcpy` instead of `@llvm.memcpy`.
-    foo::memcpy(dest, src, 1024);
-}
diff --git a/tests/run-make/no-builtins-symbols/Makefile b/tests/run-make/no-builtins-symbols/Makefile
deleted file mode 100644
index 4bb35c1d486..00000000000
--- a/tests/run-make/no-builtins-symbols/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-include ../tools.mk
-
-# only-x86_64-unknown-linux-gnu
-
-all:
-	$(RUSTC) main.rs -o $(TMPDIR)/main
-	[ "$$("$(LLVM_BIN_DIR)"/llvm-nm -U $(TMPDIR)/main | grep -c __fixunssfti)" -eq "0" ]
diff --git a/tests/run-make/no-builtins-symbols/main.rs b/tests/run-make/no-builtins-symbols/main.rs
deleted file mode 100644
index f328e4d9d04..00000000000
--- a/tests/run-make/no-builtins-symbols/main.rs
+++ /dev/null
@@ -1 +0,0 @@
-fn main() {}
diff --git a/tests/run-make/wasm-builtins-import/Makefile b/tests/run-make/wasm-spurious-import/Makefile
index ff9dfeac6d0..ff9dfeac6d0 100644
--- a/tests/run-make/wasm-builtins-import/Makefile
+++ b/tests/run-make/wasm-spurious-import/Makefile
diff --git a/tests/run-make/wasm-builtins-import/main.rs b/tests/run-make/wasm-spurious-import/main.rs
index 5eb99df6ff7..fcbead5e28b 100644
--- a/tests/run-make/wasm-builtins-import/main.rs
+++ b/tests/run-make/wasm-spurious-import/main.rs
@@ -8,8 +8,7 @@ fn my_panic(_info: &core::panic::PanicInfo) -> ! {
 
 #[no_mangle]
 pub fn multer(a: i128, b: i128) -> i128 {
-    // Trigger usage of the __multi3 compiler intrinsic which then leads to an imported function
-    // such as panic or __multi3 (externally defined) in case of a bug. We verify that
-    // no imports exist in our verifier.
+    // Trigger usage of the __multi3 compiler intrinsic which then leads to an imported
+    // panic function in case of a bug. We verify that no imports exist in our verifier.
     a * b
 }
diff --git a/tests/run-make/wasm-builtins-import/verify.js b/tests/run-make/wasm-spurious-import/verify.js
index d3b2101b662..d3b2101b662 100644
--- a/tests/run-make/wasm-builtins-import/verify.js
+++ b/tests/run-make/wasm-spurious-import/verify.js
diff --git a/tests/ui/coroutine/clone-rpit.next.stderr b/tests/ui/coroutine/clone-rpit.next.stderr
new file mode 100644
index 00000000000..2dbdbcc7b05
--- /dev/null
+++ b/tests/ui/coroutine/clone-rpit.next.stderr
@@ -0,0 +1,52 @@
+error[E0391]: cycle detected when type-checking `foo`
+  --> $DIR/clone-rpit.rs:12:1
+   |
+LL | pub fn foo<'a, 'b>() -> impl Clone {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: ...which requires coroutine witness types for `foo::{closure#0}`...
+  --> $DIR/clone-rpit.rs:13:5
+   |
+LL |     move |_: ()| {
+   |     ^^^^^^^^^^^^
+note: ...which requires promoting constants in MIR for `foo::{closure#0}`...
+  --> $DIR/clone-rpit.rs:13:5
+   |
+LL |     move |_: ()| {
+   |     ^^^^^^^^^^^^
+note: ...which requires preparing `foo::{closure#0}` for borrow checking...
+  --> $DIR/clone-rpit.rs:13:5
+   |
+LL |     move |_: ()| {
+   |     ^^^^^^^^^^^^
+note: ...which requires checking if `foo::{closure#0}` contains FFI-unwind calls...
+  --> $DIR/clone-rpit.rs:13:5
+   |
+LL |     move |_: ()| {
+   |     ^^^^^^^^^^^^
+note: ...which requires building MIR for `foo::{closure#0}`...
+  --> $DIR/clone-rpit.rs:13:5
+   |
+LL |     move |_: ()| {
+   |     ^^^^^^^^^^^^
+note: ...which requires match-checking `foo::{closure#0}`...
+  --> $DIR/clone-rpit.rs:13:5
+   |
+LL |     move |_: ()| {
+   |     ^^^^^^^^^^^^
+note: ...which requires type-checking `foo::{closure#0}`...
+  --> $DIR/clone-rpit.rs:13:5
+   |
+LL |     move |_: ()| {
+   |     ^^^^^^^^^^^^
+   = note: ...which again requires type-checking `foo`, completing the cycle
+note: cycle used when computing type of opaque `foo::{opaque#0}`
+  --> $DIR/clone-rpit.rs:12:25
+   |
+LL | pub fn foo<'a, 'b>() -> impl Clone {
+   |                         ^^^^^^^^^^
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/coroutine/clone-rpit.rs b/tests/ui/coroutine/clone-rpit.rs
index cbd28f88fcb..22a553c83d6 100644
--- a/tests/ui/coroutine/clone-rpit.rs
+++ b/tests/ui/coroutine/clone-rpit.rs
@@ -1,6 +1,7 @@
 // revisions: current next
 //[next] compile-flags: -Znext-solver
-// check-pass
+//[current] check-pass
+//[next] known-bug: trait-system-refactor-initiative#82
 
 #![feature(coroutines, coroutine_trait, coroutine_clone)]
 
diff --git a/tests/ui/extenv/extenv-env-overload.rs b/tests/ui/extenv/extenv-env-overload.rs
index b82bb2fe966..8b3b565fe83 100644
--- a/tests/ui/extenv/extenv-env-overload.rs
+++ b/tests/ui/extenv/extenv-env-overload.rs
@@ -1,6 +1,6 @@
 // run-pass
 // rustc-env:MY_VAR=tadam
-// compile-flags: --env MY_VAR=123abc -Zunstable-options
+// compile-flags: --env-set MY_VAR=123abc -Zunstable-options
 
 // This test ensures that variables provided with `--env` take precedence over
 // variables from environment.
diff --git a/tests/ui/extenv/extenv-env.rs b/tests/ui/extenv/extenv-env.rs
index 9fda52b8941..051ea214c1b 100644
--- a/tests/ui/extenv/extenv-env.rs
+++ b/tests/ui/extenv/extenv-env.rs
@@ -1,4 +1,4 @@
-// compile-flags: --env FOO=123abc -Zunstable-options
+// compile-flags: --env-set FOO=123abc -Zunstable-options
 // run-pass
 fn main() {
     assert_eq!(env!("FOO"), "123abc");
diff --git a/tests/ui/extenv/extenv-not-env.rs b/tests/ui/extenv/extenv-not-env.rs
index d6c4a43b003..b0355e073e4 100644
--- a/tests/ui/extenv/extenv-not-env.rs
+++ b/tests/ui/extenv/extenv-not-env.rs
@@ -1,6 +1,6 @@
 // run-pass
 // rustc-env:MY_ENV=/
-// Ensures that variables not defined through `--env` are still available.
+// Ensures that variables not defined through `--env-set` are still available.
 
 fn main() {
     assert!(!env!("MY_ENV").is_empty());
diff --git a/tests/ui/feature-gates/env-flag.rs b/tests/ui/feature-gates/env-flag.rs
index 9dfda2584fb..598773cf3e4 100644
--- a/tests/ui/feature-gates/env-flag.rs
+++ b/tests/ui/feature-gates/env-flag.rs
@@ -1,3 +1,3 @@
-// compile-flags: --env A=B
+// compile-flags: --env-set A=B
 
 fn main() {}
diff --git a/tests/ui/feature-gates/env-flag.stderr b/tests/ui/feature-gates/env-flag.stderr
index 5cb18cef9fb..a9fa1b65ea1 100644
--- a/tests/ui/feature-gates/env-flag.stderr
+++ b/tests/ui/feature-gates/env-flag.stderr
@@ -1,2 +1,2 @@
-error: the `-Z unstable-options` flag must also be passed to enable the flag `env`
+error: the `-Z unstable-options` flag must also be passed to enable the flag `env-set`
 
diff --git a/tests/ui/impl-trait/eagerly-reveal-in-local-body.rs b/tests/ui/impl-trait/eagerly-reveal-in-local-body.rs
new file mode 100644
index 00000000000..a08c2c8765b
--- /dev/null
+++ b/tests/ui/impl-trait/eagerly-reveal-in-local-body.rs
@@ -0,0 +1,13 @@
+// check-pass
+// compile-flags: -Znext-solver
+
+#![feature(type_alias_impl_trait)]
+
+fn main() {
+    type Tait = impl Sized;
+    struct S {
+        i: i32,
+    }
+    let x: Tait = S { i: 0 };
+    println!("{}", x.i);
+}
diff --git a/tests/ui/impl-trait/recursive-coroutine-indirect.current.stderr b/tests/ui/impl-trait/recursive-coroutine-indirect.current.stderr
index 11b3c4ef007..df457c13e70 100644
--- a/tests/ui/impl-trait/recursive-coroutine-indirect.current.stderr
+++ b/tests/ui/impl-trait/recursive-coroutine-indirect.current.stderr
@@ -1,5 +1,5 @@
 error[E0733]: recursion in a coroutine requires boxing
-  --> $DIR/recursive-coroutine-indirect.rs:6:5
+  --> $DIR/recursive-coroutine-indirect.rs:10:5
    |
 LL |     move || {
    |     ^^^^^^^
diff --git a/tests/ui/impl-trait/recursive-coroutine-indirect.next.stderr b/tests/ui/impl-trait/recursive-coroutine-indirect.next.stderr
index 11b3c4ef007..df457c13e70 100644
--- a/tests/ui/impl-trait/recursive-coroutine-indirect.next.stderr
+++ b/tests/ui/impl-trait/recursive-coroutine-indirect.next.stderr
@@ -1,5 +1,5 @@
 error[E0733]: recursion in a coroutine requires boxing
-  --> $DIR/recursive-coroutine-indirect.rs:6:5
+  --> $DIR/recursive-coroutine-indirect.rs:10:5
    |
 LL |     move || {
    |     ^^^^^^^
diff --git a/tests/ui/impl-trait/recursive-coroutine-indirect.rs b/tests/ui/impl-trait/recursive-coroutine-indirect.rs
index 4f8d4d33050..99b6be3358f 100644
--- a/tests/ui/impl-trait/recursive-coroutine-indirect.rs
+++ b/tests/ui/impl-trait/recursive-coroutine-indirect.rs
@@ -1,5 +1,9 @@
 // revisions: current next
 //[next] compile-flags: -Znext-solver
+
+//[next] build-fail
+// Deeply normalizing writeback results of opaques makes this into a post-mono error :(
+
 #![feature(coroutines)]
 #![allow(unconditional_recursion)]
 fn coroutine_hold() -> impl Sized {
diff --git a/tests/ui/proc-macro/env.rs b/tests/ui/proc-macro/env.rs
index 1b1d1873eb3..c0edda4f7df 100644
--- a/tests/ui/proc-macro/env.rs
+++ b/tests/ui/proc-macro/env.rs
@@ -1,7 +1,7 @@
 // aux-build:env.rs
 // run-pass
 // rustc-env: THE_CONST=1
-// compile-flags: -Zunstable-options --env THE_CONST=12 --env ANOTHER=4
+// compile-flags: -Zunstable-options --env-set THE_CONST=12 --env-set ANOTHER=4
 
 #![crate_name = "foo"]
 
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs
index e1e93f79920..01a98a30895 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs
@@ -13,11 +13,8 @@ fn main() {
 }
 
 fn weird0() -> impl Sized + !Sized {}
-//~^ ERROR mismatched types
-//~| ERROR type mismatch resolving `() == impl !Sized + Sized`
+//~^ ERROR type mismatch resolving `() == impl !Sized + Sized`
 fn weird1() -> impl !Sized + Sized {}
-//~^ ERROR mismatched types
-//~| ERROR type mismatch resolving `() == impl !Sized + Sized`
+//~^ ERROR type mismatch resolving `() == impl !Sized + Sized`
 fn weird2() -> impl !Sized {}
-//~^ ERROR mismatched types
-//~| ERROR type mismatch resolving `() == impl !Sized`
+//~^ ERROR type mismatch resolving `() == impl !Sized`
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
index 62792761870..d803e56e817 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
@@ -1,50 +1,17 @@
-error[E0308]: mismatched types
-  --> $DIR/opaque-type-unsatisfied-bound.rs:15:36
-   |
-LL | fn weird0() -> impl Sized + !Sized {}
-   |                ------------------- ^^ types differ
-   |                |
-   |                the expected opaque type
-   |
-   = note: expected opaque type `impl !Sized + Sized`
-                found unit type `()`
-
 error[E0271]: type mismatch resolving `() == impl !Sized + Sized`
   --> $DIR/opaque-type-unsatisfied-bound.rs:15:16
    |
 LL | fn weird0() -> impl Sized + !Sized {}
    |                ^^^^^^^^^^^^^^^^^^^ types differ
 
-error[E0308]: mismatched types
-  --> $DIR/opaque-type-unsatisfied-bound.rs:18:36
-   |
-LL | fn weird1() -> impl !Sized + Sized {}
-   |                ------------------- ^^ types differ
-   |                |
-   |                the expected opaque type
-   |
-   = note: expected opaque type `impl !Sized + Sized`
-                found unit type `()`
-
 error[E0271]: type mismatch resolving `() == impl !Sized + Sized`
-  --> $DIR/opaque-type-unsatisfied-bound.rs:18:16
+  --> $DIR/opaque-type-unsatisfied-bound.rs:17:16
    |
 LL | fn weird1() -> impl !Sized + Sized {}
    |                ^^^^^^^^^^^^^^^^^^^ types differ
 
-error[E0308]: mismatched types
-  --> $DIR/opaque-type-unsatisfied-bound.rs:21:28
-   |
-LL | fn weird2() -> impl !Sized {}
-   |                ----------- ^^ types differ
-   |                |
-   |                the expected opaque type
-   |
-   = note: expected opaque type `impl !Sized`
-                found unit type `()`
-
 error[E0271]: type mismatch resolving `() == impl !Sized`
-  --> $DIR/opaque-type-unsatisfied-bound.rs:21:16
+  --> $DIR/opaque-type-unsatisfied-bound.rs:19:16
    |
 LL | fn weird2() -> impl !Sized {}
    |                ^^^^^^^^^^^ types differ
@@ -63,7 +30,7 @@ note: required by a bound in `consume`
 LL | fn consume(_: impl Trait) {}
    |                    ^^^^^ required by this bound in `consume`
 
-error: aborting due to 7 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0271, E0277, E0308.
+Some errors have detailed explanations: E0271, E0277.
 For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs
index 72bca1a8910..bb2e861a1a7 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs
@@ -3,7 +3,6 @@
 #![feature(negative_bounds, unboxed_closures)]
 
 fn produce() -> impl !Fn<(u32,)> {}
-//~^ ERROR mismatched types
-//~| ERROR type mismatch resolving `() == impl !Fn<(u32,)>`
+//~^ ERROR type mismatch resolving `() == impl !Fn<(u32,)>`
 
 fn main() {}
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
index a4fb4b2b5c4..1fd30410b00 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
@@ -1,21 +1,9 @@
-error[E0308]: mismatched types
-  --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:34
-   |
-LL | fn produce() -> impl !Fn<(u32,)> {}
-   |                 ---------------- ^^ types differ
-   |                 |
-   |                 the expected opaque type
-   |
-   = note: expected opaque type `impl !Fn<(u32,)>`
-                found unit type `()`
-
 error[E0271]: type mismatch resolving `() == impl !Fn<(u32,)>`
   --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17
    |
 LL | fn produce() -> impl !Fn<(u32,)> {}
    |                 ^^^^^^^^^^^^^^^^ types differ
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0271, E0308.
-For more information about an error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/traits/next-solver/alias-bound-unsound.rs b/tests/ui/traits/next-solver/alias-bound-unsound.rs
index 4e279a84a33..8fddbd7ecdc 100644
--- a/tests/ui/traits/next-solver/alias-bound-unsound.rs
+++ b/tests/ui/traits/next-solver/alias-bound-unsound.rs
@@ -23,10 +23,10 @@ fn main() {
     let x = String::from("hello, world");
     drop(<() as Foo>::copy_me(&x));
     //~^ ERROR overflow evaluating the requirement `<() as Foo>::Item: Sized`
-    //~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
-    //~| ERROR overflow evaluating the requirement `<() as Foo>::Item well-formed`
     //~| ERROR overflow evaluating the requirement `String <: <() as Foo>::Item`
+    //~| ERROR overflow evaluating the requirement `<() as Foo>::Item well-formed`
     //~| ERROR overflow evaluating the requirement `&<() as Foo>::Item well-formed`
-    //~| ERROR overflow evaluating the requirement `<() as Foo>::Item normalizes-to _`
+    //~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
+    //~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
     println!("{x}");
 }
diff --git a/tests/ui/traits/next-solver/alias-bound-unsound.stderr b/tests/ui/traits/next-solver/alias-bound-unsound.stderr
index ac3f19b3fe6..874644317eb 100644
--- a/tests/ui/traits/next-solver/alias-bound-unsound.stderr
+++ b/tests/ui/traits/next-solver/alias-bound-unsound.stderr
@@ -52,13 +52,14 @@ LL |     drop(<() as Foo>::copy_me(&x));
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
 
-error[E0275]: overflow evaluating the requirement `<() as Foo>::Item normalizes-to _`
+error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
   --> $DIR/alias-bound-unsound.rs:24:10
    |
 LL |     drop(<() as Foo>::copy_me(&x));
    |          ^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: aborting due to 7 previous errors
 
diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs
index 327ef865de9..71b1502d775 100644
--- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs
+++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs
@@ -13,8 +13,10 @@ fn needs_bar<S: Bar>() {}
 
 fn test<T: Foo1<Assoc1 = <T as Foo2>::Assoc2> + Foo2<Assoc2 = <T as Foo1>::Assoc1>>() {
     needs_bar::<T::Assoc1>();
-    //~^ ERROR overflow evaluating the requirement `<T as Foo1>::Assoc1: Bar`
-    //~| ERROR overflow evaluating the requirement `<T as Foo2>::Assoc2`
+    //~^ ERROR overflow evaluating the requirement `<T as Foo1>::Assoc1 == _`
+    //~| ERROR overflow evaluating the requirement `<T as Foo1>::Assoc1 == _`
+    //~| ERROR overflow evaluating the requirement `<T as Foo1>::Assoc1 == _`
+    //~| ERROR overflow evaluating the requirement `<T as Foo1>::Assoc1: Bar`
 }
 
 fn main() {}
diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr
index eda62b99c44..bad6820f738 100644
--- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr
+++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr
@@ -11,7 +11,7 @@ note: required by a bound in `needs_bar`
 LL | fn needs_bar<S: Bar>() {}
    |                 ^^^ required by this bound in `needs_bar`
 
-error[E0275]: overflow evaluating the requirement `<T as Foo2>::Assoc2`
+error[E0275]: overflow evaluating the requirement `<T as Foo1>::Assoc1 == _`
   --> $DIR/recursive-self-normalization-2.rs:15:5
    |
 LL |     needs_bar::<T::Assoc1>();
@@ -19,6 +19,23 @@ LL |     needs_bar::<T::Assoc1>();
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization_2`)
 
-error: aborting due to 2 previous errors
+error[E0275]: overflow evaluating the requirement `<T as Foo1>::Assoc1 == _`
+  --> $DIR/recursive-self-normalization-2.rs:15:5
+   |
+LL |     needs_bar::<T::Assoc1>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization_2`)
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0275]: overflow evaluating the requirement `<T as Foo1>::Assoc1 == _`
+  --> $DIR/recursive-self-normalization-2.rs:15:17
+   |
+LL |     needs_bar::<T::Assoc1>();
+   |                 ^^^^^^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization_2`)
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs
index f45d208e666..809a6a59ca6 100644
--- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs
+++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs
@@ -9,8 +9,10 @@ fn needs_bar<S: Bar>() {}
 
 fn test<T: Foo<Assoc = <T as Foo>::Assoc>>() {
     needs_bar::<T::Assoc>();
-    //~^ ERROR overflow evaluating the requirement `<T as Foo>::Assoc: Bar`
-    //~| ERROR overflow evaluating the requirement `<T as Foo>::Assoc` [E0275]
+    //~^ ERROR overflow evaluating the requirement `<T as Foo>::Assoc == _`
+    //~| ERROR overflow evaluating the requirement `<T as Foo>::Assoc == _`
+    //~| ERROR overflow evaluating the requirement `<T as Foo>::Assoc == _`
+    //~| ERROR overflow evaluating the requirement `<T as Foo>::Assoc: Bar`
 }
 
 fn main() {}
diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr
index b0a0a69761a..80005d344ba 100644
--- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr
+++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr
@@ -11,7 +11,7 @@ note: required by a bound in `needs_bar`
 LL | fn needs_bar<S: Bar>() {}
    |                 ^^^ required by this bound in `needs_bar`
 
-error[E0275]: overflow evaluating the requirement `<T as Foo>::Assoc`
+error[E0275]: overflow evaluating the requirement `<T as Foo>::Assoc == _`
   --> $DIR/recursive-self-normalization.rs:11:5
    |
 LL |     needs_bar::<T::Assoc>();
@@ -19,6 +19,23 @@ LL |     needs_bar::<T::Assoc>();
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization`)
 
-error: aborting due to 2 previous errors
+error[E0275]: overflow evaluating the requirement `<T as Foo>::Assoc == _`
+  --> $DIR/recursive-self-normalization.rs:11:5
+   |
+LL |     needs_bar::<T::Assoc>();
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization`)
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0275]: overflow evaluating the requirement `<T as Foo>::Assoc == _`
+  --> $DIR/recursive-self-normalization.rs:11:17
+   |
+LL |     needs_bar::<T::Assoc>();
+   |                 ^^^^^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization`)
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/treat-err-as-bug/eagerly-emit.rs b/tests/ui/treat-err-as-bug/eagerly-emit.rs
new file mode 100644
index 00000000000..5f32f5a1d94
--- /dev/null
+++ b/tests/ui/treat-err-as-bug/eagerly-emit.rs
@@ -0,0 +1,11 @@
+// compile-flags: -Zeagerly-emit-delayed-bugs
+
+trait Foo {}
+
+fn main() {}
+
+fn f() -> impl Foo {
+    //~^ ERROR the trait bound `i32: Foo` is not satisfied
+    //~| ERROR `report_selection_error` did not emit an error
+    1i32
+}
diff --git a/tests/ui/treat-err-as-bug/eagerly-emit.stderr b/tests/ui/treat-err-as-bug/eagerly-emit.stderr
new file mode 100644
index 00000000000..3d25741d52d
--- /dev/null
+++ b/tests/ui/treat-err-as-bug/eagerly-emit.stderr
@@ -0,0 +1,28 @@
+error: `report_selection_error` did not emit an error
+  --> $DIR/eagerly-emit.rs:7:11
+   |
+LL | fn f() -> impl Foo {
+   |           ^^^^^^^^
+
+error: trimmed_def_paths constructed but no error emitted; use `DelayDm` for lints or `with_no_trimmed_paths` for debugging
+
+error[E0277]: the trait bound `i32: Foo` is not satisfied
+  --> $DIR/eagerly-emit.rs:7:11
+   |
+LL | fn f() -> impl Foo {
+   |           ^^^^^^^^ the trait `Foo` is not implemented for `i32`
+...
+LL |     1i32
+   |     ---- return type was inferred to be `i32` here
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/eagerly-emit.rs:3:1
+   |
+LL | trait Foo {}
+   | ^^^^^^^^^
+
+error: expected fulfillment errors
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.