diff --git a/Cargo.lock b/Cargo.lock
index 55433a55a18..f230f50212a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3672,7 +3672,6 @@ dependencies = [
 name = "rustc_interface"
 version = "0.0.0"
 dependencies = [
- "libc",
  "libloading",
  "rustc-rayon",
  "rustc-rayon-core",
@@ -3715,7 +3714,6 @@ dependencies = [
  "rustc_ty_utils",
  "smallvec",
  "tracing",
- "winapi",
 ]
 
 [[package]]
@@ -4135,6 +4133,7 @@ name = "rustc_session"
 version = "0.0.0"
 dependencies = [
  "getopts",
+ "libc",
  "rustc_ast",
  "rustc_data_structures",
  "rustc_errors",
@@ -4146,7 +4145,9 @@ dependencies = [
  "rustc_serialize",
  "rustc_span",
  "rustc_target",
+ "smallvec",
  "tracing",
+ "winapi",
 ]
 
 [[package]]
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 6f0a8d0a54c..5a1ad792924 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1123,7 +1123,8 @@ fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) {
         if path.exists() {
             return session_tlib;
         } else {
-            let default_sysroot = filesearch::get_or_default_sysroot();
+            let default_sysroot =
+                filesearch::get_or_default_sysroot().expect("Failed finding sysroot");
             let default_tlib = filesearch::make_target_lib_path(
                 &default_sysroot,
                 sess.opts.target_triple.triple(),
diff --git a/compiler/rustc_error_messages/locales/en-US/passes.ftl b/compiler/rustc_error_messages/locales/en-US/passes.ftl
index 88286c15f9e..5239ff9dc05 100644
--- a/compiler/rustc_error_messages/locales/en-US/passes.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/passes.ftl
@@ -451,8 +451,14 @@ passes_break_inside_async_block =
     .async_block_label = enclosing `async` block
 
 passes_outside_loop =
-    `{$name}` outside of a loop
-    .label = cannot `{$name}` outside of a loop
+    `{$name}` outside of a loop{$is_break ->
+        [true] {" or labeled block"}
+        *[false] {""}
+    }
+    .label = cannot `{$name}` outside of a loop{$is_break ->
+        [true] {" or labeled block"}
+        *[false] {""}
+    }
 
 passes_unlabeled_in_labeled_block =
     unlabeled `{$cf_type}` inside of a labeled block
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 7747ae14a24..9ad1d2bc542 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -1910,6 +1910,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     }
                 }
             }
+
+            // see if we can satisfy using an inherent associated type
+            for impl_ in tcx.inherent_impls(adt_def.did()) {
+                let assoc_ty = tcx.associated_items(impl_).find_by_name_and_kind(
+                    tcx,
+                    assoc_ident,
+                    ty::AssocKind::Type,
+                    *impl_,
+                );
+                if let Some(assoc_ty) = assoc_ty {
+                    let ty = tcx.type_of(assoc_ty.def_id);
+                    return Ok((ty, DefKind::AssocTy, assoc_ty.def_id));
+                }
+            }
         }
 
         // Find the type of the associated item, and the trait where the associated
diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs
index 2b15d4dcd08..8d39fa81165 100644
--- a/compiler/rustc_hir_typeck/src/_match.rs
+++ b/compiler/rustc_hir_typeck/src/_match.rs
@@ -491,11 +491,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     ..
                 } = self.type_var_origin(expected)? else { return None; };
 
-                let sig = *self
-                    .typeck_results
-                    .borrow()
-                    .liberated_fn_sigs()
-                    .get(hir::HirId::make_owner(self.body_id.owner.def_id))?;
+                let sig = self.body_fn_sig()?;
 
                 let substs = sig.output().walk().find_map(|arg| {
                     if let ty::GenericArgKind::Type(ty) = arg.unpack()
diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs
index b706d786b52..80147d90091 100644
--- a/compiler/rustc_hir_typeck/src/check.rs
+++ b/compiler/rustc_hir_typeck/src/check.rs
@@ -31,13 +31,11 @@ pub(super) fn check_fn<'a, 'tcx>(
     fn_id: hir::HirId,
     body: &'tcx hir::Body<'tcx>,
     can_be_generator: Option<hir::Movability>,
-    return_type_pre_known: bool,
 ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
     // Create the function context. This is either derived from scratch or,
     // in the case of closures, based on the outer context.
     let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
     fcx.ps.set(UnsafetyState::function(fn_sig.unsafety, fn_id));
-    fcx.return_type_pre_known = return_type_pre_known;
 
     let tcx = fcx.tcx;
     let hir = tcx.hir();
@@ -51,9 +49,6 @@ pub(super) fn check_fn<'a, 'tcx>(
             decl.output.span(),
             param_env,
         ));
-    // If we replaced declared_ret_ty with infer vars, then we must be inferring
-    // an opaque type, so set a flag so we can improve diagnostics.
-    fcx.return_type_has_opaque = ret_ty != declared_ret_ty;
 
     fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty)));
 
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index 14f6e7d36be..09df50c76b7 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -83,8 +83,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         debug!(?bound_sig, ?liberated_sig);
 
-        let return_type_pre_known = !liberated_sig.output().is_ty_infer();
-
         let generator_types = check_fn(
             self,
             self.param_env.without_const(),
@@ -93,7 +91,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             expr.hir_id,
             body,
             gen,
-            return_type_pre_known,
         )
         .1;
 
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 86597a703e8..e8bf299b037 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -1782,7 +1782,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
             // may occur at the first return expression we see in the closure
             // (if it conflicts with the declared return type). Skip adding a
             // note in this case, since it would be incorrect.
-            && !fcx.return_type_pre_known
+            && let Some(fn_sig) = fcx.body_fn_sig()
+            && fn_sig.output().is_ty_var()
         {
             err.span_note(
                 sp,
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 9fde62a81a1..682dbab56bc 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -220,7 +220,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Hide the outer diverging and has_errors flags.
         let old_diverges = self.diverges.replace(Diverges::Maybe);
-        let old_has_errors = self.has_errors.replace(false);
 
         let ty = ensure_sufficient_stack(|| match &expr.kind {
             hir::ExprKind::Path(
@@ -259,7 +258,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Combine the diverging and has_error flags.
         self.diverges.set(self.diverges.get() | old_diverges);
-        self.has_errors.set(self.has_errors.get() | old_has_errors);
 
         debug!("type of {} is...", self.tcx.hir().node_to_string(expr.hir_id));
         debug!("... {:?}, expected is {:?}", ty, expected);
@@ -840,7 +838,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return_expr_ty,
         );
 
-        if self.return_type_has_opaque {
+        if let Some(fn_sig) = self.body_fn_sig()
+            && fn_sig.output().has_opaque_types()
+        {
             // Point any obligations that were registered due to opaque type
             // inference at the return expression.
             self.select_obligations_where_possible(false, |errors| {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 7c22eaf18f8..7563c543d3f 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -143,7 +143,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.typeck_results.borrow_mut().node_types_mut().insert(id, ty);
 
         if ty.references_error() {
-            self.has_errors.set(true);
             self.set_tainted_by_errors();
         }
     }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 8e0fcb56c7f..e1955d838f2 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1334,7 +1334,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Hide the outer diverging and `has_errors` flags.
         let old_diverges = self.diverges.replace(Diverges::Maybe);
-        let old_has_errors = self.has_errors.replace(false);
 
         match stmt.kind {
             hir::StmtKind::Local(l) => {
@@ -1364,7 +1363,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Combine the diverging and `has_error` flags.
         self.diverges.set(self.diverges.get() | old_diverges);
-        self.has_errors.set(self.has_errors.get() | old_has_errors);
     }
 
     pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
@@ -1544,11 +1542,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.diverges.set(prev_diverges);
         }
 
-        let mut ty = ctxt.coerce.unwrap().complete(self);
-
-        if self.has_errors.get() || ty.references_error() {
-            ty = self.tcx.ty_error()
-        }
+        let ty = ctxt.coerce.unwrap().complete(self);
 
         self.write_ty(blk.hir_id, ty);
 
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index c36c01e1b46..72388baa261 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -112,21 +112,9 @@ pub struct FnCtxt<'a, 'tcx> {
     /// the diverges flag is set to something other than `Maybe`.
     pub(super) diverges: Cell<Diverges>,
 
-    /// Whether any child nodes have any type errors.
-    pub(super) has_errors: Cell<bool>,
-
     pub(super) enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
 
     pub(super) inh: &'a Inherited<'tcx>,
-
-    /// True if the function or closure's return type is known before
-    /// entering the function/closure, i.e. if the return type is
-    /// either given explicitly or inferred from, say, an `Fn*` trait
-    /// bound. Used for diagnostic purposes only.
-    pub(super) return_type_pre_known: bool,
-
-    /// True if the return type has an Opaque type
-    pub(super) return_type_has_opaque: bool,
 }
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -145,14 +133,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             resume_yield_tys: None,
             ps: Cell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
             diverges: Cell::new(Diverges::Maybe),
-            has_errors: Cell::new(false),
             enclosing_breakables: RefCell::new(EnclosingBreakables {
                 stack: Vec::new(),
                 by_id: Default::default(),
             }),
             inh,
-            return_type_pre_known: true,
-            return_type_has_opaque: false,
         }
     }
 
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 4db9c56f98f..e3b3fb499b1 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -22,6 +22,14 @@ use rustc_trait_selection::traits::error_reporting::DefIdOrName;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
+    pub(crate) fn body_fn_sig(&self) -> Option<ty::FnSig<'tcx>> {
+        self.typeck_results
+            .borrow()
+            .liberated_fn_sigs()
+            .get(self.tcx.hir().get_parent_node(self.body_id))
+            .copied()
+    }
+
     pub(in super::super) fn suggest_semicolon_at_end(&self, span: Span, err: &mut Diagnostic) {
         err.span_suggestion_short(
             span.shrink_to_hi(),
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 959c5486645..d1762598a52 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -250,7 +250,7 @@ fn typeck_with_fallback<'tcx>(
                 param_env,
                 fn_sig,
             );
-            check_fn(&inh, param_env, fn_sig, decl, id, body, None, true).0
+            check_fn(&inh, param_env, fn_sig, decl, id, body, None).0
         } else {
             let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
             let expected_type = body_ty
diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml
index 6a4c5b4d373..2e526733df9 100644
--- a/compiler/rustc_interface/Cargo.toml
+++ b/compiler/rustc_interface/Cargo.toml
@@ -48,12 +48,6 @@ rustc_resolve = { path = "../rustc_resolve" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
 rustc_ty_utils = { path = "../rustc_ty_utils" }
 
-[target.'cfg(unix)'.dependencies]
-libc = "0.2"
-
-[target.'cfg(windows)'.dependencies]
-winapi = { version = "0.3", features = ["libloaderapi"] }
-
 [dev-dependencies]
 rustc_target = { path = "../rustc_target" }
 
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 519b8a7fc7c..62ee72f9883 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -9,6 +9,7 @@ use rustc_session as session;
 use rustc_session::config::CheckCfg;
 use rustc_session::config::{self, CrateType};
 use rustc_session::config::{ErrorOutputType, Input, OutputFilenames};
+use rustc_session::filesearch::sysroot_candidates;
 use rustc_session::lint::{self, BuiltinLintDiagnostics, LintBuffer};
 use rustc_session::parse::CrateConfig;
 use rustc_session::{early_error, filesearch, output, Session};
@@ -78,7 +79,7 @@ pub fn create_session(
 
     let bundle = match rustc_errors::fluent_bundle(
         sopts.maybe_sysroot.clone(),
-        sysroot_candidates(),
+        sysroot_candidates().to_vec(),
         sopts.unstable_opts.translate_lang.clone(),
         sopts.unstable_opts.translate_additional_ftl.as_deref(),
         sopts.unstable_opts.translate_directionality_markers,
@@ -273,100 +274,6 @@ fn get_rustc_path_inner(bin_path: &str) -> Option<PathBuf> {
     })
 }
 
-fn sysroot_candidates() -> Vec<PathBuf> {
-    let target = session::config::host_triple();
-    let mut sysroot_candidates = vec![filesearch::get_or_default_sysroot()];
-    let path = current_dll_path().and_then(|s| s.canonicalize().ok());
-    if let Some(dll) = path {
-        // use `parent` twice to chop off the file name and then also the
-        // directory containing the dll which should be either `lib` or `bin`.
-        if let Some(path) = dll.parent().and_then(|p| p.parent()) {
-            // The original `path` pointed at the `rustc_driver` crate's dll.
-            // Now that dll should only be in one of two locations. The first is
-            // in the compiler's libdir, for example `$sysroot/lib/*.dll`. The
-            // other is the target's libdir, for example
-            // `$sysroot/lib/rustlib/$target/lib/*.dll`.
-            //
-            // We don't know which, so let's assume that if our `path` above
-            // ends in `$target` we *could* be in the target libdir, and always
-            // assume that we may be in the main libdir.
-            sysroot_candidates.push(path.to_owned());
-
-            if path.ends_with(target) {
-                sysroot_candidates.extend(
-                    path.parent() // chop off `$target`
-                        .and_then(|p| p.parent()) // chop off `rustlib`
-                        .and_then(|p| p.parent()) // chop off `lib`
-                        .map(|s| s.to_owned()),
-                );
-            }
-        }
-    }
-
-    return sysroot_candidates;
-
-    #[cfg(unix)]
-    fn current_dll_path() -> Option<PathBuf> {
-        use std::ffi::{CStr, OsStr};
-        use std::os::unix::prelude::*;
-
-        unsafe {
-            let addr = current_dll_path as usize as *mut _;
-            let mut info = mem::zeroed();
-            if libc::dladdr(addr, &mut info) == 0 {
-                info!("dladdr failed");
-                return None;
-            }
-            if info.dli_fname.is_null() {
-                info!("dladdr returned null pointer");
-                return None;
-            }
-            let bytes = CStr::from_ptr(info.dli_fname).to_bytes();
-            let os = OsStr::from_bytes(bytes);
-            Some(PathBuf::from(os))
-        }
-    }
-
-    #[cfg(windows)]
-    fn current_dll_path() -> Option<PathBuf> {
-        use std::ffi::OsString;
-        use std::io;
-        use std::os::windows::prelude::*;
-        use std::ptr;
-
-        use winapi::um::libloaderapi::{
-            GetModuleFileNameW, GetModuleHandleExW, GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
-        };
-
-        unsafe {
-            let mut module = ptr::null_mut();
-            let r = GetModuleHandleExW(
-                GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
-                current_dll_path as usize as *mut _,
-                &mut module,
-            );
-            if r == 0 {
-                info!("GetModuleHandleExW failed: {}", io::Error::last_os_error());
-                return None;
-            }
-            let mut space = Vec::with_capacity(1024);
-            let r = GetModuleFileNameW(module, space.as_mut_ptr(), space.capacity() as u32);
-            if r == 0 {
-                info!("GetModuleFileNameW failed: {}", io::Error::last_os_error());
-                return None;
-            }
-            let r = r as usize;
-            if r >= space.capacity() {
-                info!("our buffer was too small? {}", io::Error::last_os_error());
-                return None;
-            }
-            space.set_len(r);
-            let os = OsString::from_wide(&space);
-            Some(PathBuf::from(os))
-        }
-    }
-}
-
 fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> MakeBackendFn {
     // For now we only allow this function to be called once as it'll dlopen a
     // few things, which seems to work best if we only do that once. In
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index d8bed700f52..1dbf0d642e2 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -956,6 +956,7 @@ pub struct OutsideLoop<'a> {
     #[label]
     pub span: Span,
     pub name: &'a str,
+    pub is_break: bool,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs
index 077194ec687..b4cf19e4a34 100644
--- a/compiler/rustc_passes/src/loops.rs
+++ b/compiler/rustc_passes/src/loops.rs
@@ -193,7 +193,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
                 self.sess.emit_err(BreakInsideAsyncBlock { span, closure_span, name });
             }
             Normal | AnonConst => {
-                self.sess.emit_err(OutsideLoop { span, name });
+                self.sess.emit_err(OutsideLoop { span, name, is_break: name == "break" });
             }
         }
     }
diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml
index 6b1eaa4d399..a052f293341 100644
--- a/compiler/rustc_session/Cargo.toml
+++ b/compiler/rustc_session/Cargo.toml
@@ -17,3 +17,10 @@ rustc_span = { path = "../rustc_span" }
 rustc_fs_util = { path = "../rustc_fs_util" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_lint_defs = { path = "../rustc_lint_defs" }
+smallvec = "1.8.1"
+
+[target.'cfg(unix)'.dependencies]
+libc = "0.2"
+
+[target.'cfg(windows)'.dependencies]
+winapi = { version = "0.3", features = ["libloaderapi"] }
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index b8ad18c64dc..aece29ca0cb 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2447,7 +2447,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
     let sysroot = match &sysroot_opt {
         Some(s) => s,
         None => {
-            tmp_buf = crate::filesearch::get_or_default_sysroot();
+            tmp_buf = crate::filesearch::get_or_default_sysroot().expect("Failed finding sysroot");
             &tmp_buf
         }
     };
diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs
index e8edb38f503..1b66773be6f 100644
--- a/compiler/rustc_session/src/filesearch.rs
+++ b/compiler/rustc_session/src/filesearch.rs
@@ -1,5 +1,6 @@
 //! A module for searching for libraries
 
+use smallvec::{smallvec, SmallVec};
 use std::env;
 use std::fs;
 use std::iter::FromIterator;
@@ -62,9 +63,99 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
     PathBuf::from_iter([sysroot, Path::new(&rustlib_path), Path::new("lib")])
 }
 
+#[cfg(unix)]
+fn current_dll_path() -> Result<PathBuf, String> {
+    use std::ffi::{CStr, OsStr};
+    use std::os::unix::prelude::*;
+
+    unsafe {
+        let addr = current_dll_path as usize as *mut _;
+        let mut info = std::mem::zeroed();
+        if libc::dladdr(addr, &mut info) == 0 {
+            return Err("dladdr failed".into());
+        }
+        if info.dli_fname.is_null() {
+            return Err("dladdr returned null pointer".into());
+        }
+        let bytes = CStr::from_ptr(info.dli_fname).to_bytes();
+        let os = OsStr::from_bytes(bytes);
+        Ok(PathBuf::from(os))
+    }
+}
+
+#[cfg(windows)]
+fn current_dll_path() -> Result<PathBuf, String> {
+    use std::ffi::OsString;
+    use std::io;
+    use std::os::windows::prelude::*;
+    use std::ptr;
+
+    use winapi::um::libloaderapi::{
+        GetModuleFileNameW, GetModuleHandleExW, GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+    };
+
+    unsafe {
+        let mut module = ptr::null_mut();
+        let r = GetModuleHandleExW(
+            GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+            current_dll_path as usize as *mut _,
+            &mut module,
+        );
+        if r == 0 {
+            return Err(format!("GetModuleHandleExW failed: {}", io::Error::last_os_error()));
+        }
+        let mut space = Vec::with_capacity(1024);
+        let r = GetModuleFileNameW(module, space.as_mut_ptr(), space.capacity() as u32);
+        if r == 0 {
+            return Err(format!("GetModuleFileNameW failed: {}", io::Error::last_os_error()));
+        }
+        let r = r as usize;
+        if r >= space.capacity() {
+            return Err(format!("our buffer was too small? {}", io::Error::last_os_error()));
+        }
+        space.set_len(r);
+        let os = OsString::from_wide(&space);
+        Ok(PathBuf::from(os))
+    }
+}
+
+pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> {
+    let target = crate::config::host_triple();
+    let mut sysroot_candidates: SmallVec<[PathBuf; 2]> =
+        smallvec![get_or_default_sysroot().expect("Failed finding sysroot")];
+    let path = current_dll_path().and_then(|s| Ok(s.canonicalize().map_err(|e| e.to_string())?));
+    if let Ok(dll) = path {
+        // use `parent` twice to chop off the file name and then also the
+        // directory containing the dll which should be either `lib` or `bin`.
+        if let Some(path) = dll.parent().and_then(|p| p.parent()) {
+            // The original `path` pointed at the `rustc_driver` crate's dll.
+            // Now that dll should only be in one of two locations. The first is
+            // in the compiler's libdir, for example `$sysroot/lib/*.dll`. The
+            // other is the target's libdir, for example
+            // `$sysroot/lib/rustlib/$target/lib/*.dll`.
+            //
+            // We don't know which, so let's assume that if our `path` above
+            // ends in `$target` we *could* be in the target libdir, and always
+            // assume that we may be in the main libdir.
+            sysroot_candidates.push(path.to_owned());
+
+            if path.ends_with(target) {
+                sysroot_candidates.extend(
+                    path.parent() // chop off `$target`
+                        .and_then(|p| p.parent()) // chop off `rustlib`
+                        .and_then(|p| p.parent()) // chop off `lib`
+                        .map(|s| s.to_owned()),
+                );
+            }
+        }
+    }
+
+    return sysroot_candidates;
+}
+
 /// This function checks if sysroot is found using env::args().next(), and if it
-/// is not found, uses env::current_exe() to imply sysroot.
-pub fn get_or_default_sysroot() -> PathBuf {
+/// is not found, finds sysroot from current rustc_driver dll.
+pub fn get_or_default_sysroot() -> Result<PathBuf, String> {
     // Follow symlinks.  If the resolved path is relative, make it absolute.
     fn canonicalize(path: PathBuf) -> PathBuf {
         let path = fs::canonicalize(&path).unwrap_or(path);
@@ -74,17 +165,32 @@ pub fn get_or_default_sysroot() -> PathBuf {
         fix_windows_verbatim_for_gcc(&path)
     }
 
-    // Use env::current_exe() to get the path of the executable following
-    // symlinks/canonicalizing components.
-    fn from_current_exe() -> PathBuf {
-        match env::current_exe() {
-            Ok(exe) => {
-                let mut p = canonicalize(exe);
-                p.pop();
-                p.pop();
-                p
-            }
-            Err(e) => panic!("failed to get current_exe: {e}"),
+    fn default_from_rustc_driver_dll() -> Result<PathBuf, String> {
+        let dll = current_dll_path().and_then(|s| Ok(canonicalize(s)))?;
+
+        // `dll` will be in one of the following two:
+        // - compiler's libdir: $sysroot/lib/*.dll
+        // - target's libdir: $sysroot/lib/rustlib/$target/lib/*.dll
+        //
+        // use `parent` twice to chop off the file name and then also the
+        // directory containing the dll
+        let dir = dll.parent().and_then(|p| p.parent()).ok_or(format!(
+            "Could not move 2 levels upper using `parent()` on {}",
+            dll.display()
+        ))?;
+
+        // if `dir` points target's dir, move up to the sysroot
+        if dir.ends_with(crate::config::host_triple()) {
+            dir.parent() // chop off `$target`
+                .and_then(|p| p.parent()) // chop off `rustlib`
+                .and_then(|p| p.parent()) // chop off `lib`
+                .map(|s| s.to_owned())
+                .ok_or(format!(
+                    "Could not move 3 levels upper using `parent()` on {}",
+                    dir.display()
+                ))
+        } else {
+            Ok(dir.to_owned())
         }
     }
 
@@ -118,7 +224,5 @@ pub fn get_or_default_sysroot() -> PathBuf {
         }
     }
 
-    // Check if sysroot is found using env::args().next(), and if is not found,
-    // use env::current_exe() to imply sysroot.
-    from_env_args_next().unwrap_or_else(from_current_exe)
+    Ok(from_env_args_next().unwrap_or(default_from_rustc_driver_dll()?))
 }
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index ec0a5b9d0d8..10352198357 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -1309,7 +1309,7 @@ pub fn build_session(
 
     let sysroot = match &sopts.maybe_sysroot {
         Some(sysroot) => sysroot.clone(),
-        None => filesearch::get_or_default_sysroot(),
+        None => filesearch::get_or_default_sysroot().expect("Failed finding sysroot"),
     };
 
     let target_cfg = config::build_target_config(&sopts, target_override, &sysroot);
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 7bf32cb0d98..e6a11218139 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -1856,7 +1856,7 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
 /// }
 /// ```
 ///
-/// Coverting in the other direction from a `&mut T`
+/// Converting in the other direction from a `&mut T`
 /// to an `&UnsafeCell<T>` is allowed:
 ///
 /// ```rust
diff --git a/library/core/src/error.md b/library/core/src/error.md
index 891abebbfd3..78808d489b2 100644
--- a/library/core/src/error.md
+++ b/library/core/src/error.md
@@ -46,7 +46,7 @@ These functions are equivalent, they either return the inner value if the
 `Result` is `Ok` or panic if the `Result` is `Err` printing the inner error
 as the source. The only difference between them is that with `expect` you
 provide a panic error message to be printed alongside the source, whereas
-`unwrap` has a default message indicating only that you unwraped an `Err`.
+`unwrap` has a default message indicating only that you unwrapped an `Err`.
 
 Of the two, `expect` is generally preferred since its `msg` field allows you
 to convey your intent and assumptions which makes tracking down the source
diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs
index 3dd5b12507f..dafcd876744 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -275,7 +275,7 @@ impl f32 {
     /// This result is not an element of the function's codomain, but it is the
     /// closest floating point number in the real numbers and thus fulfills the
     /// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)`
-    /// approximatively.
+    /// approximately.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs
index 31351a87978..77048f9a28f 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -275,7 +275,7 @@ impl f64 {
     /// This result is not an element of the function's codomain, but it is the
     /// closest floating point number in the real numbers and thus fulfills the
     /// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)`
-    /// approximatively.
+    /// approximately.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs
index fc2dc42833d..81461de4f72 100644
--- a/library/std/src/sys/windows/c.rs
+++ b/library/std/src/sys/windows/c.rs
@@ -363,7 +363,7 @@ impl IO_STATUS_BLOCK {
 
 pub type LPOVERLAPPED_COMPLETION_ROUTINE = unsafe extern "system" fn(
     dwErrorCode: DWORD,
-    dwNumberOfBytesTransfered: DWORD,
+    dwNumberOfBytesTransferred: DWORD,
     lpOverlapped: *mut OVERLAPPED,
 );
 
diff --git a/library/std/src/sys/windows/pipe.rs b/library/std/src/sys/windows/pipe.rs
index 013c776c476..9f26acc4520 100644
--- a/library/std/src/sys/windows/pipe.rs
+++ b/library/std/src/sys/windows/pipe.rs
@@ -324,17 +324,18 @@ impl AnonPipe {
         let mut async_result: Option<AsyncResult> = None;
         struct AsyncResult {
             error: u32,
-            transfered: u32,
+            transferred: u32,
         }
 
         // STEP 3: The callback.
         unsafe extern "system" fn callback(
             dwErrorCode: u32,
-            dwNumberOfBytesTransfered: u32,
+            dwNumberOfBytesTransferred: u32,
             lpOverlapped: *mut c::OVERLAPPED,
         ) {
             // Set `async_result` using a pointer smuggled through `hEvent`.
-            let result = AsyncResult { error: dwErrorCode, transfered: dwNumberOfBytesTransfered };
+            let result =
+                AsyncResult { error: dwErrorCode, transferred: dwNumberOfBytesTransferred };
             *(*lpOverlapped).hEvent.cast::<Option<AsyncResult>>() = Some(result);
         }
 
@@ -365,7 +366,7 @@ impl AnonPipe {
         // STEP 4: Return the result.
         // `async_result` is always `Some` at this point
         match result.error {
-            c::ERROR_SUCCESS => Ok(result.transfered as usize),
+            c::ERROR_SUCCESS => Ok(result.transferred as usize),
             error => Err(io::Error::from_raw_os_error(error as _)),
         }
     }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 8d38f2df0d8..16e2d9a3cfc 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1381,7 +1381,8 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
                 ty::Projection(proj) => Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id),
                 // Rustdoc handles `ty::Error`s by turning them into `Type::Infer`s.
                 ty::Error(_) => return Type::Infer,
-                _ => bug!("clean: expected associated type, found `{:?}`", ty),
+                // Otherwise, this is an inherent associated type.
+                _ => return clean_middle_ty(ty, cx, None),
             };
             let trait_ = clean_path(&hir::Path { span, res, segments: &[] }, cx);
             register_res(cx, trait_.res);
diff --git a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs
index e58bba64058..94ea0e93bf6 100644
--- a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs
+++ b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs
@@ -1,3 +1,4 @@
+// check-pass
 // This test ensures that rustdoc does not panic on inherented associated types
 // that are referred to without fully-qualified syntax.
 
@@ -9,8 +10,4 @@ pub struct Struct;
 impl Struct {
     pub type AssocTy = usize;
     pub const AssocConst: Self::AssocTy = 42;
-    //~^ ERROR ambiguous associated type
-    //~| HELP use fully-qualified syntax
-    //~| ERROR ambiguous associated type
-    //~| HELP use fully-qualified syntax
 }
diff --git a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr
deleted file mode 100644
index b963b722f66..00000000000
--- a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0223]: ambiguous associated type
-  --> $DIR/ambiguous-inherent-assoc-ty.rs:11:27
-   |
-LL |     pub const AssocConst: Self::AssocTy = 42;
-   |                           ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<Struct as Trait>::AssocTy`
-
-error[E0223]: ambiguous associated type
-  --> $DIR/ambiguous-inherent-assoc-ty.rs:11:27
-   |
-LL |     pub const AssocConst: Self::AssocTy = 42;
-   |                           ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<Struct as Trait>::AssocTy`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0223`.
diff --git a/src/test/ui/array-slice-vec/array-break-length.stderr b/src/test/ui/array-slice-vec/array-break-length.stderr
index 93f1c238bcc..2df7b6d7f63 100644
--- a/src/test/ui/array-slice-vec/array-break-length.stderr
+++ b/src/test/ui/array-slice-vec/array-break-length.stderr
@@ -1,8 +1,8 @@
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
   --> $DIR/array-break-length.rs:3:17
    |
 LL |         |_: [_; break]| {}
-   |                 ^^^^^ cannot `break` outside of a loop
+   |                 ^^^^^ cannot `break` outside of a loop or labeled block
 
 error[E0268]: `continue` outside of a loop
   --> $DIR/array-break-length.rs:7:17
diff --git a/src/test/ui/assoc-inherent.rs b/src/test/ui/assoc-inherent.rs
deleted file mode 100644
index c579c962ffc..00000000000
--- a/src/test/ui/assoc-inherent.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-// Test that inherent associated types work with
-// inherent_associated_types feature gate.
-
-#![feature(inherent_associated_types)]
-#![allow(incomplete_features)]
-
-struct Foo;
-
-impl Foo {
-    type Bar = isize;
-}
-
-impl Foo {
-    type Baz; //~ ERROR associated type in `impl` without body
-}
-
-fn main() {
-    let x : Foo::Bar; //~ERROR ambiguous associated type
-    x = 0isize;
-}
diff --git a/src/test/ui/assoc-inherent.stderr b/src/test/ui/assoc-inherent.stderr
deleted file mode 100644
index b703453fa03..00000000000
--- a/src/test/ui/assoc-inherent.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error: associated type in `impl` without body
-  --> $DIR/assoc-inherent.rs:14:5
-   |
-LL |     type Baz;
-   |     ^^^^^^^^-
-   |             |
-   |             help: provide a definition for the type: `= <type>;`
-
-error[E0223]: ambiguous associated type
-  --> $DIR/assoc-inherent.rs:18:13
-   |
-LL |     let x : Foo::Bar;
-   |             ^^^^^^^^ help: use fully-qualified syntax: `<Foo as Trait>::Bar`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0223`.
diff --git a/src/test/ui/associated-inherent-types/assoc-inherent-no-body.rs b/src/test/ui/associated-inherent-types/assoc-inherent-no-body.rs
new file mode 100644
index 00000000000..71f65b92eae
--- /dev/null
+++ b/src/test/ui/associated-inherent-types/assoc-inherent-no-body.rs
@@ -0,0 +1,10 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct Foo;
+
+impl Foo {
+    type Baz; //~ ERROR associated type in `impl` without body
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-inherent-types/assoc-inherent-no-body.stderr b/src/test/ui/associated-inherent-types/assoc-inherent-no-body.stderr
new file mode 100644
index 00000000000..387a5658da3
--- /dev/null
+++ b/src/test/ui/associated-inherent-types/assoc-inherent-no-body.stderr
@@ -0,0 +1,10 @@
+error: associated type in `impl` without body
+  --> $DIR/assoc-inherent-no-body.rs:7:5
+   |
+LL |     type Baz;
+   |     ^^^^^^^^-
+   |             |
+   |             help: provide a definition for the type: `= <type>;`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/associated-inherent-types/assoc-inherent-use.rs b/src/test/ui/associated-inherent-types/assoc-inherent-use.rs
new file mode 100644
index 00000000000..7ae425e2aaa
--- /dev/null
+++ b/src/test/ui/associated-inherent-types/assoc-inherent-use.rs
@@ -0,0 +1,14 @@
+// check-pass
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct Foo;
+
+impl Foo {
+    type Bar = isize;
+}
+
+fn main() {
+    let x: Foo::Bar;
+    x = 0isize;
+}
diff --git a/src/test/ui/closures/closure-array-break-length.stderr b/src/test/ui/closures/closure-array-break-length.stderr
index 2b8ab9bfc44..7e0b0027a6f 100644
--- a/src/test/ui/closures/closure-array-break-length.stderr
+++ b/src/test/ui/closures/closure-array-break-length.stderr
@@ -10,11 +10,11 @@ error[E0268]: `continue` outside of a loop
 LL |     while |_: [_; continue]| {} {}
    |                   ^^^^^^^^ cannot `continue` outside of a loop
 
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
   --> $DIR/closure-array-break-length.rs:6:19
    |
 LL |     while |_: [_; break]| {} {}
-   |                   ^^^^^ cannot `break` outside of a loop
+   |                   ^^^^^ cannot `break` outside of a loop or labeled block
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/error-codes/E0268.stderr b/src/test/ui/error-codes/E0268.stderr
index c926f9e4874..6422e8a9490 100644
--- a/src/test/ui/error-codes/E0268.stderr
+++ b/src/test/ui/error-codes/E0268.stderr
@@ -1,8 +1,8 @@
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
   --> $DIR/E0268.rs:2:5
    |
 LL |     break;
-   |     ^^^^^ cannot `break` outside of a loop
+   |     ^^^^^ cannot `break` outside of a loop or labeled block
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0767.rs b/src/test/ui/error-codes/E0767.rs
index 6c6cb746e6c..14215d36a38 100644
--- a/src/test/ui/error-codes/E0767.rs
+++ b/src/test/ui/error-codes/E0767.rs
@@ -1,6 +1,7 @@
-fn main () {
+fn main() {
     'a: loop {
         || {
+            //~^ ERROR mismatched types
             loop { break 'a; } //~ ERROR E0767
         }
     }
diff --git a/src/test/ui/error-codes/E0767.stderr b/src/test/ui/error-codes/E0767.stderr
index 2429823306b..ee85247301c 100644
--- a/src/test/ui/error-codes/E0767.stderr
+++ b/src/test/ui/error-codes/E0767.stderr
@@ -1,14 +1,27 @@
 error[E0767]: use of unreachable label `'a`
-  --> $DIR/E0767.rs:4:26
+  --> $DIR/E0767.rs:5:26
    |
 LL |     'a: loop {
    |     -- unreachable label defined here
-LL |         || {
+...
 LL |             loop { break 'a; }
    |                          ^^ unreachable label `'a`
    |
    = note: labels are unreachable through functions, closures, async blocks and modules
 
-error: aborting due to previous error
+error[E0308]: mismatched types
+  --> $DIR/E0767.rs:3:9
+   |
+LL | /         || {
+LL | |
+LL | |             loop { break 'a; }
+LL | |         }
+   | |_________^ expected `()`, found closure
+   |
+   = note: expected unit type `()`
+                found closure `[closure@$DIR/E0767.rs:3:9: 3:11]`
 
-For more information about this error, try `rustc --explain E0767`.
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0767.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/for-loop-while/break-outside-loop.stderr b/src/test/ui/for-loop-while/break-outside-loop.stderr
index 287bf9af62e..9092f34df35 100644
--- a/src/test/ui/for-loop-while/break-outside-loop.stderr
+++ b/src/test/ui/for-loop-while/break-outside-loop.stderr
@@ -9,11 +9,11 @@ LL |             break 'lab;
    |
    = note: labels are unreachable through functions, closures, async blocks and modules
 
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
   --> $DIR/break-outside-loop.rs:10:15
    |
 LL |     let pth = break;
-   |               ^^^^^ cannot `break` outside of a loop
+   |               ^^^^^ cannot `break` outside of a loop or labeled block
 
 error[E0268]: `continue` outside of a loop
   --> $DIR/break-outside-loop.rs:11:17
@@ -38,11 +38,11 @@ LL |             if cond() { break }
 LL |             if cond() { continue }
    |                         ^^^^^^^^ cannot `continue` inside of a closure
 
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
   --> $DIR/break-outside-loop.rs:24:25
    |
 LL |     let unconstrained = break;
-   |                         ^^^^^ cannot `break` outside of a loop
+   |                         ^^^^^ cannot `break` outside of a loop or labeled block
 
 error[E0267]: `break` inside of a closure
   --> $DIR/break-outside-loop.rs:30:13
diff --git a/src/test/ui/issues/issue-28105.stderr b/src/test/ui/issues/issue-28105.stderr
index 42ed838d7c0..f450256f3ec 100644
--- a/src/test/ui/issues/issue-28105.stderr
+++ b/src/test/ui/issues/issue-28105.stderr
@@ -4,11 +4,11 @@ error[E0268]: `continue` outside of a loop
 LL |     continue
    |     ^^^^^^^^ cannot `continue` outside of a loop
 
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
   --> $DIR/issue-28105.rs:6:5
    |
 LL |     break
-   |     ^^^^^ cannot `break` outside of a loop
+   |     ^^^^^ cannot `break` outside of a loop or labeled block
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-43162.stderr b/src/test/ui/issues/issue-43162.stderr
index a443db40732..40d9200058e 100644
--- a/src/test/ui/issues/issue-43162.stderr
+++ b/src/test/ui/issues/issue-43162.stderr
@@ -1,14 +1,14 @@
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
   --> $DIR/issue-43162.rs:3:5
    |
 LL |     break true;
-   |     ^^^^^^^^^^ cannot `break` outside of a loop
+   |     ^^^^^^^^^^ cannot `break` outside of a loop or labeled block
 
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
   --> $DIR/issue-43162.rs:7:5
    |
 LL |     break {};
-   |     ^^^^^^^^ cannot `break` outside of a loop
+   |     ^^^^^^^^ cannot `break` outside of a loop or labeled block
 
 error[E0308]: mismatched types
   --> $DIR/issue-43162.rs:1:13
diff --git a/src/test/ui/issues/issue-50576.stderr b/src/test/ui/issues/issue-50576.stderr
index 9fea1411080..4ec22fde910 100644
--- a/src/test/ui/issues/issue-50576.stderr
+++ b/src/test/ui/issues/issue-50576.stderr
@@ -4,17 +4,17 @@ error[E0426]: use of undeclared label `'L`
 LL |     |bool: [u8; break 'L]| 0;
    |                       ^^ undeclared label `'L`
 
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
   --> $DIR/issue-50576.rs:2:17
    |
 LL |     |bool: [u8; break 'L]| 0;
-   |                 ^^^^^^^^ cannot `break` outside of a loop
+   |                 ^^^^^^^^ cannot `break` outside of a loop or labeled block
 
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
   --> $DIR/issue-50576.rs:5:16
    |
 LL |     Vec::<[u8; break]>::new();
-   |                ^^^^^ cannot `break` outside of a loop
+   |                ^^^^^ cannot `break` outside of a loop or labeled block
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/issues/issue-50581.stderr b/src/test/ui/issues/issue-50581.stderr
index 35d6fc49ced..07b6df072cb 100644
--- a/src/test/ui/issues/issue-50581.stderr
+++ b/src/test/ui/issues/issue-50581.stderr
@@ -1,8 +1,8 @@
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
   --> $DIR/issue-50581.rs:2:14
    |
 LL |     |_: [u8; break]| ();
-   |              ^^^^^ cannot `break` outside of a loop
+   |              ^^^^^ cannot `break` outside of a loop or labeled block
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-83048.rs b/src/test/ui/issues/issue-83048.rs
index 520ae974398..8e4fb6eae9d 100644
--- a/src/test/ui/issues/issue-83048.rs
+++ b/src/test/ui/issues/issue-83048.rs
@@ -1,5 +1,5 @@
 // compile-flags: -Z unpretty=thir-tree
 
 pub fn main() {
-    break; //~ ERROR: `break` outside of a loop [E0268]
+    break; //~ ERROR: `break` outside of a loop or labeled block [E0268]
 }
diff --git a/src/test/ui/issues/issue-83048.stderr b/src/test/ui/issues/issue-83048.stderr
index 62d67d75844..dade9e46950 100644
--- a/src/test/ui/issues/issue-83048.stderr
+++ b/src/test/ui/issues/issue-83048.stderr
@@ -1,8 +1,8 @@
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
   --> $DIR/issue-83048.rs:4:5
    |
 LL |     break;
-   |     ^^^^^ cannot `break` outside of a loop
+   |     ^^^^^ cannot `break` outside of a loop or labeled block
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/resolve/resolve-self-in-impl.stderr b/src/test/ui/resolve/resolve-self-in-impl.stderr
index 9f9ed68898f..b3042d41346 100644
--- a/src/test/ui/resolve/resolve-self-in-impl.stderr
+++ b/src/test/ui/resolve/resolve-self-in-impl.stderr
@@ -1,19 +1,3 @@
-error: `Self` is not valid in the self type of an impl block
-  --> $DIR/resolve-self-in-impl.rs:14:13
-   |
-LL | impl Tr for Self {}
-   |             ^^^^
-   |
-   = note: replace `Self` with a different type
-
-error: `Self` is not valid in the self type of an impl block
-  --> $DIR/resolve-self-in-impl.rs:15:15
-   |
-LL | impl Tr for S<Self> {}
-   |               ^^^^
-   |
-   = note: replace `Self` with a different type
-
 error: `Self` is not valid in the self type of an impl block
   --> $DIR/resolve-self-in-impl.rs:16:6
    |
@@ -38,6 +22,22 @@ LL | impl (Self, Self) {}
    |
    = note: replace `Self` with a different type
 
+error: `Self` is not valid in the self type of an impl block
+  --> $DIR/resolve-self-in-impl.rs:14:13
+   |
+LL | impl Tr for Self {}
+   |             ^^^^
+   |
+   = note: replace `Self` with a different type
+
+error: `Self` is not valid in the self type of an impl block
+  --> $DIR/resolve-self-in-impl.rs:15:15
+   |
+LL | impl Tr for S<Self> {}
+   |               ^^^^
+   |
+   = note: replace `Self` with a different type
+
 error[E0391]: cycle detected when computing trait implemented by `<impl at $DIR/resolve-self-in-impl.rs:19:1: 19:23>`
   --> $DIR/resolve-self-in-impl.rs:19:1
    |
diff --git a/src/test/ui/track-diagnostics/track.stderr b/src/test/ui/track-diagnostics/track.stderr
index ba26cf7c745..8256c1f5f0f 100644
--- a/src/test/ui/track-diagnostics/track.stderr
+++ b/src/test/ui/track-diagnostics/track.stderr
@@ -5,11 +5,11 @@ LL |     break rust
    |           ^^^^ not found in this scope
 -Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC
 
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
   --> $DIR/track.rs:LL:CC
    |
 LL |     break rust
-   |     ^^^^^^^^^^ cannot `break` outside of a loop
+   |     ^^^^^^^^^^ cannot `break` outside of a loop or labeled block
 -Ztrack-diagnostics: created at compiler/rustc_passes/src/loops.rs:LL:CC
 
 error: internal compiler error: It looks like you're trying to break rust; would you like some ICE?
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index ae54b2078a6..f24d3507823 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -23,8 +23,8 @@ use std::borrow::Cow;
 use std::env;
 use std::ops::Deref;
 use std::panic;
-use std::path::{Path, PathBuf};
-use std::process::{exit, Command};
+use std::path::Path;
+use std::process::exit;
 use std::sync::LazyLock;
 
 /// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If
@@ -210,17 +210,6 @@ fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
     interface::try_print_query_stack(&handler, num_frames);
 }
 
-fn toolchain_path(home: Option<String>, toolchain: Option<String>) -> Option<PathBuf> {
-    home.and_then(|home| {
-        toolchain.map(|toolchain| {
-            let mut path = PathBuf::from(home);
-            path.push("toolchains");
-            path.push(toolchain);
-            path
-        })
-    })
-}
-
 #[allow(clippy::too_many_lines)]
 pub fn main() {
     rustc_driver::init_rustc_env_logger();
@@ -228,51 +217,6 @@ pub fn main() {
     exit(rustc_driver::catch_with_exit_code(move || {
         let mut orig_args: Vec<String> = env::args().collect();
 
-        // Get the sysroot, looking from most specific to this invocation to the least:
-        // - command line
-        // - runtime environment
-        //    - SYSROOT
-        //    - RUSTUP_HOME, MULTIRUST_HOME, RUSTUP_TOOLCHAIN, MULTIRUST_TOOLCHAIN
-        // - sysroot from rustc in the path
-        // - compile-time environment
-        //    - SYSROOT
-        //    - RUSTUP_HOME, MULTIRUST_HOME, RUSTUP_TOOLCHAIN, MULTIRUST_TOOLCHAIN
-        let sys_root_arg = arg_value(&orig_args, "--sysroot", |_| true);
-        let have_sys_root_arg = sys_root_arg.is_some();
-        let sys_root = sys_root_arg
-            .map(PathBuf::from)
-            .or_else(|| std::env::var("SYSROOT").ok().map(PathBuf::from))
-            .or_else(|| {
-                let home = std::env::var("RUSTUP_HOME")
-                    .or_else(|_| std::env::var("MULTIRUST_HOME"))
-                    .ok();
-                let toolchain = std::env::var("RUSTUP_TOOLCHAIN")
-                    .or_else(|_| std::env::var("MULTIRUST_TOOLCHAIN"))
-                    .ok();
-                toolchain_path(home, toolchain)
-            })
-            .or_else(|| {
-                Command::new("rustc")
-                    .arg("--print")
-                    .arg("sysroot")
-                    .output()
-                    .ok()
-                    .and_then(|out| String::from_utf8(out.stdout).ok())
-                    .map(|s| PathBuf::from(s.trim()))
-            })
-            .or_else(|| option_env!("SYSROOT").map(PathBuf::from))
-            .or_else(|| {
-                let home = option_env!("RUSTUP_HOME")
-                    .or(option_env!("MULTIRUST_HOME"))
-                    .map(ToString::to_string);
-                let toolchain = option_env!("RUSTUP_TOOLCHAIN")
-                    .or(option_env!("MULTIRUST_TOOLCHAIN"))
-                    .map(ToString::to_string);
-                toolchain_path(home, toolchain)
-            })
-            .map(|pb| pb.to_string_lossy().to_string())
-            .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust");
-
         // make "clippy-driver --rustc" work like a subcommand that passes further args to "rustc"
         // for example `clippy-driver --rustc --version` will print the rustc version that clippy-driver
         // uses
@@ -280,13 +224,7 @@ pub fn main() {
             orig_args.remove(pos);
             orig_args[0] = "rustc".to_string();
 
-            // if we call "rustc", we need to pass --sysroot here as well
-            let mut args: Vec<String> = orig_args.clone();
-            if !have_sys_root_arg {
-                args.extend(vec!["--sysroot".into(), sys_root]);
-            };
-
-            return rustc_driver::RunCompiler::new(&args, &mut DefaultCallbacks).run();
+            return rustc_driver::RunCompiler::new(&orig_args, &mut DefaultCallbacks).run();
         }
 
         if orig_args.iter().any(|a| a == "--version" || a == "-V") {
@@ -309,14 +247,6 @@ pub fn main() {
             exit(0);
         }
 
-        // this conditional check for the --sysroot flag is there so users can call
-        // `clippy_driver` directly
-        // without having to pass --sysroot or anything
-        let mut args: Vec<String> = orig_args.clone();
-        if !have_sys_root_arg {
-            args.extend(vec!["--sysroot".into(), sys_root]);
-        };
-
         let mut no_deps = false;
         let clippy_args_var = env::var("CLIPPY_ARGS").ok();
         let clippy_args = clippy_args_var
@@ -345,10 +275,11 @@ pub fn main() {
 
         let clippy_enabled = !cap_lints_allow && (!no_deps || in_primary_package);
         if clippy_enabled {
+            let mut args: Vec<String> = orig_args.clone();
             args.extend(clippy_args);
             rustc_driver::RunCompiler::new(&args, &mut ClippyCallbacks { clippy_args_var }).run()
         } else {
-            rustc_driver::RunCompiler::new(&args, &mut RustcCallbacks { clippy_args_var }).run()
+            rustc_driver::RunCompiler::new(&orig_args, &mut RustcCallbacks { clippy_args_var }).run()
         }
     }))
 }
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index bd01ea655dd..e673ea67dbc 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -216,76 +216,28 @@ fn init_late_loggers(tcx: TyCtxt<'_>) {
     }
 }
 
-/// Returns the "default sysroot" that Miri will use for host things if no `--sysroot` flag is set.
-/// Should be a compile-time constant.
-fn host_sysroot() -> Option<String> {
-    if option_env!("RUSTC_STAGE").is_some() {
-        // This is being built as part of rustc, and gets shipped with rustup.
-        // We can rely on the sysroot computation in librustc_session.
-        return None;
-    }
-    // For builds outside rustc, we need to ensure that we got a sysroot
-    // that gets used as a default.  The sysroot computation in librustc_session would
-    // end up somewhere in the build dir (see `get_or_default_sysroot`).
-    // Taken from PR <https://github.com/Manishearth/rust-clippy/pull/911>.
-    let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
-    let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
-    Some(match (home, toolchain) {
-        (Some(home), Some(toolchain)) => {
-            // Check that at runtime, we are still in this toolchain (if there is any toolchain).
-            if let Some(toolchain_runtime) =
-                env::var_os("RUSTUP_TOOLCHAIN").or_else(|| env::var_os("MULTIRUST_TOOLCHAIN"))
-            {
-                if toolchain_runtime != toolchain {
-                    show_error!(
-                        "This Miri got built with local toolchain `{toolchain}`, but now is being run under a different toolchain. \n\
-                        Make sure to run Miri in the toolchain it got built with, e.g. via `cargo +{toolchain} miri`."
-                    )
-                }
-            }
-            format!("{home}/toolchains/{toolchain}")
-        }
-        _ => option_env!("RUST_SYSROOT")
-            .unwrap_or_else(|| {
-                show_error!(
-                    "To build Miri without rustup, set the `RUST_SYSROOT` env var at build time",
-                )
-            })
-            .to_owned(),
-    })
-}
-
 /// Execute a compiler with the given CLI arguments and callbacks.
 fn run_compiler(
     mut args: Vec<String>,
     target_crate: bool,
     callbacks: &mut (dyn rustc_driver::Callbacks + Send),
 ) -> ! {
-    // Make sure we use the right default sysroot. The default sysroot is wrong,
-    // because `get_or_default_sysroot` in `librustc_session` bases that on `current_exe`.
-    //
-    // Make sure we always call `host_sysroot` as that also does some sanity-checks
-    // of the environment we were built in and whether it matches what we are running in.
-    let host_default_sysroot = host_sysroot();
-    // Now see if we even need to set something.
-    let sysroot_flag = "--sysroot";
-    if !args.iter().any(|e| e == sysroot_flag) {
-        // No sysroot was set, let's see if we have a custom default we want to configure.
-        let default_sysroot = if target_crate {
+    if target_crate {
+        // Miri needs a custom sysroot for target crates.
+        // If no `--sysroot` is given, the `MIRI_SYSROOT` env var is consulted to find where
+        // that sysroot lives, and that is passed to rustc.
+        let sysroot_flag = "--sysroot";
+        if !args.iter().any(|e| e == sysroot_flag) {
             // Using the built-in default here would be plain wrong, so we *require*
             // the env var to make sure things make sense.
-            Some(env::var("MIRI_SYSROOT").unwrap_or_else(|_| {
+            let miri_sysroot = env::var("MIRI_SYSROOT").unwrap_or_else(|_| {
                 show_error!(
                     "Miri was invoked in 'target' mode without `MIRI_SYSROOT` or `--sysroot` being set"
-                )
-            }))
-        } else {
-            host_default_sysroot
-        };
-        if let Some(sysroot) = default_sysroot {
-            // We need to overwrite the default that librustc_session would compute.
+                    )
+            });
+
             args.push(sysroot_flag.to_owned());
-            args.push(sysroot);
+            args.push(miri_sysroot);
         }
     }