about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs12
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs27
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs30
-rw-r--r--compiler/rustc_hir/src/def.rs7
-rw-r--r--compiler/rustc_middle/src/query/mod.rs7
-rw-r--r--compiler/rustc_middle/src/ty/context.rs12
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs41
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs8
-rw-r--r--compiler/rustc_mir/src/borrow_check/type_check/input_output.rs28
-rw-r--r--compiler/rustc_mir/src/borrow_check/universal_regions.rs8
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs2
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs2
-rw-r--r--compiler/rustc_resolve/src/late.rs72
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs32
-rw-r--r--compiler/rustc_resolve/src/lib.rs127
-rw-r--r--compiler/rustc_resolve/src/macros.rs12
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs8
-rw-r--r--compiler/rustc_typeck/src/check/compare_method.rs8
-rw-r--r--compiler/rustc_typeck/src/check/upvar.rs26
-rw-r--r--compiler/rustc_typeck/src/check/writeback.rs8
-rw-r--r--config.toml.example8
-rw-r--r--library/alloc/src/collections/btree/node.rs11
-rw-r--r--library/alloc/src/collections/btree/search.rs3
-rw-r--r--library/alloc/src/lib.rs8
-rw-r--r--library/alloc/src/macros.rs8
-rw-r--r--library/core/src/num/nonzero.rs40
-rw-r--r--library/std/src/io/buffered/bufreader.rs14
-rw-r--r--library/std/src/io/buffered/tests.rs12
-rw-r--r--library/std/src/io/mod.rs38
-rw-r--r--src/bootstrap/bootstrap.py15
-rw-r--r--src/bootstrap/check.rs51
-rw-r--r--src/bootstrap/config.rs9
-rw-r--r--src/bootstrap/dist.rs48
-rw-r--r--src/bootstrap/download-ci-llvm-stamp2
-rw-r--r--src/bootstrap/flags.rs6
-rw-r--r--src/bootstrap/native.rs1
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs9
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.rs31
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.stderr26
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.rs26
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.stderr37
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.rs25
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.stderr26
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.rs16
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.stderr26
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.rs15
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr23
-rw-r--r--src/test/ui/const-generics/late-bound-vars/in_closure.rs18
-rw-r--r--src/test/ui/const-generics/late-bound-vars/simple.rs16
-rw-r--r--src/test/ui/hygiene/traits-in-scope.rs53
-rw-r--r--src/test/ui/macros/vec-macro-in-pattern.rs10
-rw-r--r--src/test/ui/macros/vec-macro-in-pattern.stderr10
-rw-r--r--src/test/ui/proc-macro/ambiguous-builtin-attrs.rs6
-rw-r--r--src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr16
-rw-r--r--src/test/ui/suggestions/vec-macro-in-pattern.fixed8
-rw-r--r--src/test/ui/suggestions/vec-macro-in-pattern.rs8
-rw-r--r--src/test/ui/suggestions/vec-macro-in-pattern.stderr16
-rw-r--r--src/test/ui/type/ascription/issue-47666.stderr2
-rw-r--r--src/test/ui/underscore-imports/hygiene.rs10
-rw-r--r--src/test/ui/underscore-imports/hygiene.stderr27
60 files changed, 812 insertions, 399 deletions
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 6c2a871e520..544ef38c12c 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -214,11 +214,7 @@ fn handle_native(name: &str) -> &str {
 }
 
 pub fn target_cpu(sess: &Session) -> &str {
-    let name = match sess.opts.cg.target_cpu {
-        Some(ref s) => &**s,
-        None => &*sess.target.cpu,
-    };
-
+    let name = sess.opts.cg.target_cpu.as_ref().unwrap_or(&sess.target.cpu);
     handle_native(name)
 }
 
@@ -254,8 +250,6 @@ pub fn handle_native_features(sess: &Session) -> Vec<String> {
 }
 
 pub fn tune_cpu(sess: &Session) -> Option<&str> {
-    match sess.opts.debugging_opts.tune_cpu {
-        Some(ref s) => Some(handle_native(&**s)),
-        None => None,
-    }
+    let name = sess.opts.debugging_opts.tune_cpu.as_ref()?;
+    Some(handle_native(name))
 }
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index f47d2ada61a..2ce5fe5ad50 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -29,7 +29,6 @@ use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
 use rustc_session::cgu_reuse_tracker::CguReuse;
 use rustc_session::config::{self, EntryFnType};
-use rustc_session::utils::NativeLibKind;
 use rustc_session::Session;
 use rustc_target::abi::{Align, LayoutOf, VariantIdx};
 
@@ -817,32 +816,6 @@ pub fn provide_both(providers: &mut Providers) {
         }
         tcx.sess.opts.optimize
     };
-
-    providers.dllimport_foreign_items = |tcx, krate| {
-        let module_map = tcx.foreign_modules(krate);
-
-        let dllimports = tcx
-            .native_libraries(krate)
-            .iter()
-            .filter(|lib| {
-                if !matches!(lib.kind, NativeLibKind::Dylib | NativeLibKind::Unspecified) {
-                    return false;
-                }
-                let cfg = match lib.cfg {
-                    Some(ref cfg) => cfg,
-                    None => return true,
-                };
-                attr::cfg_matches(cfg, &tcx.sess.parse_sess, None)
-            })
-            .filter_map(|lib| lib.foreign_module)
-            .map(|id| &module_map[&id])
-            .flat_map(|module| module.foreign_items.iter().cloned())
-            .collect();
-        dllimports
-    };
-
-    providers.is_dllimport_foreign_item =
-        |tcx, def_id| tcx.dllimport_foreign_items(def_id.krate).contains(&def_id);
 }
 
 fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguReuse {
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index 8373304ea91..e8c711cae64 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -56,36 +56,11 @@ crate fn annotate_err_with_kind(
     };
 }
 
-/// Instead of e.g. `vec![a, b, c]` in a pattern context, suggest `[a, b, c]`.
-fn suggest_slice_pat(e: &mut DiagnosticBuilder<'_>, site_span: Span, parser: &Parser<'_>) {
-    let mut suggestion = None;
-    if let Ok(code) = parser.sess.source_map().span_to_snippet(site_span) {
-        if let Some(bang) = code.find('!') {
-            suggestion = Some(code[bang + 1..].to_string());
-        }
-    }
-    if let Some(suggestion) = suggestion {
-        e.span_suggestion(
-            site_span,
-            "use a slice pattern here instead",
-            suggestion,
-            Applicability::MachineApplicable,
-        );
-    } else {
-        e.span_label(site_span, "use a slice pattern here instead");
-    }
-    e.help(
-        "for more information, see https://doc.rust-lang.org/edition-guide/\
-        rust-2018/slice-patterns.html",
-    );
-}
-
 fn emit_frag_parse_err(
     mut e: DiagnosticBuilder<'_>,
     parser: &Parser<'_>,
     orig_parser: &mut Parser<'_>,
     site_span: Span,
-    macro_ident: Ident,
     arm_span: Span,
     kind: AstFragmentKind,
 ) {
@@ -113,9 +88,6 @@ fn emit_frag_parse_err(
         e.span_label(site_span, "in this macro invocation");
     }
     match kind {
-        AstFragmentKind::Pat if macro_ident.name == sym::vec => {
-            suggest_slice_pat(&mut e, site_span, parser);
-        }
         // Try a statement if an expression is wanted but failed and suggest adding `;` to call.
         AstFragmentKind::Expr => match parse_ast_fragment(orig_parser, AstFragmentKind::Stmts) {
             Err(mut err) => err.cancel(),
@@ -143,7 +115,7 @@ impl<'a> ParserAnyMacro<'a> {
         let fragment = match parse_ast_fragment(parser, kind) {
             Ok(f) => f,
             Err(err) => {
-                emit_frag_parse_err(err, parser, snapshot, site_span, macro_ident, arm_span, kind);
+                emit_frag_parse_err(err, parser, snapshot, site_span, arm_span, kind);
                 return kind.dummy(site_span);
             }
         };
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index 4ede9d67b74..a81eb747a33 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -5,6 +5,7 @@ use rustc_ast as ast;
 use rustc_ast::NodeId;
 use rustc_macros::HashStable_Generic;
 use rustc_span::hygiene::MacroKind;
+use rustc_span::Symbol;
 
 use std::array::IntoIter;
 use std::fmt::Debug;
@@ -34,7 +35,7 @@ pub enum CtorKind {
 #[derive(HashStable_Generic)]
 pub enum NonMacroAttrKind {
     /// Single-segment attribute defined by the language (`#[inline]`)
-    Builtin,
+    Builtin(Symbol),
     /// Multi-segment custom attribute living in a "tool module" (`#[rustfmt::skip]`).
     Tool,
     /// Single-segment custom attribute registered by a derive macro (`#[serde(default)]`).
@@ -371,7 +372,7 @@ impl CtorKind {
 impl NonMacroAttrKind {
     pub fn descr(self) -> &'static str {
         match self {
-            NonMacroAttrKind::Builtin => "built-in attribute",
+            NonMacroAttrKind::Builtin(..) => "built-in attribute",
             NonMacroAttrKind::Tool => "tool attribute",
             NonMacroAttrKind::DeriveHelper | NonMacroAttrKind::DeriveHelperCompat => {
                 "derive helper attribute"
@@ -393,7 +394,7 @@ impl NonMacroAttrKind {
             NonMacroAttrKind::Tool
             | NonMacroAttrKind::DeriveHelper
             | NonMacroAttrKind::DeriveHelperCompat => true,
-            NonMacroAttrKind::Builtin | NonMacroAttrKind::Registered => false,
+            NonMacroAttrKind::Builtin(..) | NonMacroAttrKind::Registered => false,
         }
     }
 }
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 9770e67f2d2..00ee7b8ec77 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1281,11 +1281,6 @@ rustc_queries! {
     }
 
     Other {
-        query dllimport_foreign_items(_: CrateNum)
-            -> FxHashSet<DefId> {
-            storage(ArenaCacheSelector<'tcx>)
-            desc { "dllimport_foreign_items" }
-        }
         query is_dllimport_foreign_item(def_id: DefId) -> bool {
             desc { |tcx| "is_dllimport_foreign_item({})", tcx.def_path_str(def_id) }
         }
@@ -1316,7 +1311,7 @@ rustc_queries! {
             desc { "looking up a named region" }
         }
         query is_late_bound_map(_: LocalDefId) ->
-            Option<&'tcx FxHashSet<ItemLocalId>> {
+            Option<(LocalDefId, &'tcx FxHashSet<ItemLocalId>)> {
             desc { "testing if a region is late bound" }
         }
         query object_lifetime_defaults_map(_: LocalDefId)
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index a355242f5ce..1f7dc7bb79d 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -3,6 +3,7 @@
 use crate::arena::Arena;
 use crate::dep_graph::DepGraph;
 use crate::hir::exports::ExportMap;
+use crate::hir::place::Place as HirPlace;
 use crate::ich::{NodeIdHashingMode, StableHashingContext};
 use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
 use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintLevelSource};
@@ -379,7 +380,7 @@ pub struct TypeckResults<'tcx> {
 
     /// Records the reasons that we picked the kind of each closure;
     /// not all closures are present in the map.
-    closure_kind_origins: ItemLocalMap<(Span, Symbol)>,
+    closure_kind_origins: ItemLocalMap<(Span, HirPlace<'tcx>)>,
 
     /// For each fn, records the "liberated" types of its arguments
     /// and return type. Liberated means that all bound regions
@@ -642,11 +643,13 @@ impl<'tcx> TypeckResults<'tcx> {
         self.upvar_capture_map[&upvar_id]
     }
 
-    pub fn closure_kind_origins(&self) -> LocalTableInContext<'_, (Span, Symbol)> {
+    pub fn closure_kind_origins(&self) -> LocalTableInContext<'_, (Span, HirPlace<'tcx>)> {
         LocalTableInContext { hir_owner: self.hir_owner, data: &self.closure_kind_origins }
     }
 
-    pub fn closure_kind_origins_mut(&mut self) -> LocalTableInContextMut<'_, (Span, Symbol)> {
+    pub fn closure_kind_origins_mut(
+        &mut self,
+    ) -> LocalTableInContextMut<'_, (Span, HirPlace<'tcx>)> {
         LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.closure_kind_origins }
     }
 
@@ -2578,7 +2581,8 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     pub fn is_late_bound(self, id: HirId) -> bool {
-        self.is_late_bound_map(id.owner).map_or(false, |set| set.contains(&id.local_id))
+        self.is_late_bound_map(id.owner)
+            .map_or(false, |(owner, set)| owner == id.owner && set.contains(&id.local_id))
     }
 
     pub fn object_lifetime_defaults(self, id: HirId) -> Option<&'tcx [ObjectLifetimeDefault]> {
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 1399fc76e02..b1769b17b42 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -17,7 +17,9 @@ pub use self::IntVarValue::*;
 pub use self::Variance::*;
 
 use crate::hir::exports::ExportMap;
-use crate::hir::place::Place as HirPlace;
+use crate::hir::place::{
+    Place as HirPlace, PlaceBase as HirPlaceBase, ProjectionKind as HirProjectionKind,
+};
 use crate::ich::StableHashingContext;
 use crate::middle::cstore::CrateStoreDyn;
 use crate::middle::resolve_lifetime::ObjectLifetimeDefault;
@@ -734,6 +736,43 @@ pub struct CapturedPlace<'tcx> {
     pub info: CaptureInfo<'tcx>,
 }
 
+pub fn place_to_string_for_capture(tcx: TyCtxt<'tcx>, place: &HirPlace<'tcx>) -> String {
+    let name = match place.base {
+        HirPlaceBase::Upvar(upvar_id) => tcx.hir().name(upvar_id.var_path.hir_id).to_string(),
+        _ => bug!("Capture_information should only contain upvars"),
+    };
+    let mut curr_string = name;
+
+    for (i, proj) in place.projections.iter().enumerate() {
+        match proj.kind {
+            HirProjectionKind::Deref => {
+                curr_string = format!("*{}", curr_string);
+            }
+            HirProjectionKind::Field(idx, variant) => match place.ty_before_projection(i).kind() {
+                ty::Adt(def, ..) => {
+                    curr_string = format!(
+                        "{}.{}",
+                        curr_string,
+                        def.variants[variant].fields[idx as usize].ident.name.as_str()
+                    );
+                }
+                ty::Tuple(_) => {
+                    curr_string = format!("{}.{}", curr_string, idx);
+                }
+                _ => {
+                    bug!(
+                        "Field projection applied to a type other than Adt or Tuple: {:?}.",
+                        place.ty_before_projection(i).kind()
+                    )
+                }
+            },
+            proj => bug!("{:?} unexpected because it isn't captured", proj),
+        }
+    }
+
+    curr_string.to_string()
+}
+
 /// Part of `MinCaptureInformationMap`; describes the capture kind (&, &mut, move)
 /// for a particular capture as well as identifying the part of the source code
 /// that triggered this capture to occur.
diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs
index 4ebc1cdca60..9f97d5c9af7 100644
--- a/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs
@@ -103,7 +103,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         let did = did.expect_local();
                         let hir_id = self.infcx.tcx.hir().local_def_id_to_hir_id(did);
 
-                        if let Some((span, name)) =
+                        if let Some((span, hir_place)) =
                             self.infcx.tcx.typeck(did).closure_kind_origins().get(hir_id)
                         {
                             diag.span_note(
@@ -111,7 +111,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                                 &format!(
                                     "closure cannot be invoked more than once because it moves the \
                                     variable `{}` out of its environment",
-                                    name,
+                                    ty::place_to_string_for_capture(self.infcx.tcx, hir_place)
                                 ),
                             );
                             return;
@@ -127,7 +127,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 let did = did.expect_local();
                 let hir_id = self.infcx.tcx.hir().local_def_id_to_hir_id(did);
 
-                if let Some((span, name)) =
+                if let Some((span, hir_place)) =
                     self.infcx.tcx.typeck(did).closure_kind_origins().get(hir_id)
                 {
                     diag.span_note(
@@ -135,7 +135,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         &format!(
                             "closure cannot be moved more than once as it is not `Copy` due to \
                              moving the variable `{}` out of its environment",
-                            name
+                            ty::place_to_string_for_capture(self.infcx.tcx, hir_place)
                         ),
                     );
                 }
diff --git a/compiler/rustc_mir/src/borrow_check/type_check/input_output.rs b/compiler/rustc_mir/src/borrow_check/type_check/input_output.rs
index b7d22fab3dd..157959b1159 100644
--- a/compiler/rustc_mir/src/borrow_check/type_check/input_output.rs
+++ b/compiler/rustc_mir/src/borrow_check/type_check/input_output.rs
@@ -39,10 +39,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             user_provided_sig = None;
         } else {
             let typeck_results = self.tcx().typeck(mir_def_id);
-            user_provided_sig = match typeck_results.user_provided_sigs.get(&mir_def_id.to_def_id())
-            {
-                None => None,
-                Some(user_provided_poly_sig) => {
+            user_provided_sig = typeck_results.user_provided_sigs.get(&mir_def_id.to_def_id()).map(
+                |user_provided_poly_sig| {
                     // Instantiate the canonicalized variables from
                     // user-provided signature (e.g., the `_` in the code
                     // above) with fresh variables.
@@ -54,18 +52,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     // Replace the bound items in the fn sig with fresh
                     // variables, so that they represent the view from
                     // "inside" the closure.
-                    Some(
-                        self.infcx
-                            .replace_bound_vars_with_fresh_vars(
-                                body.span,
-                                LateBoundRegionConversionTime::FnCall,
-                                poly_sig,
-                            )
-                            .0,
-                    )
-                }
-            }
-        };
+                    self.infcx
+                        .replace_bound_vars_with_fresh_vars(
+                            body.span,
+                            LateBoundRegionConversionTime::FnCall,
+                            poly_sig,
+                        )
+                        .0
+                },
+            );
+        }
 
         debug!(
             "equate_inputs_and_outputs: normalized_input_tys = {:?}, local_decls = {:?}",
diff --git a/compiler/rustc_mir/src/borrow_check/universal_regions.rs b/compiler/rustc_mir/src/borrow_check/universal_regions.rs
index c1a0d9856b7..02d951b70e2 100644
--- a/compiler/rustc_mir/src/borrow_check/universal_regions.rs
+++ b/compiler/rustc_mir/src/borrow_check/universal_regions.rs
@@ -788,13 +788,13 @@ fn for_each_late_bound_region_defined_on<'tcx>(
     fn_def_id: DefId,
     mut f: impl FnMut(ty::Region<'tcx>),
 ) {
-    if let Some(late_bounds) = tcx.is_late_bound_map(fn_def_id.expect_local()) {
-        for late_bound in late_bounds.iter() {
-            let hir_id = HirId { owner: fn_def_id.expect_local(), local_id: *late_bound };
+    if let Some((owner, late_bounds)) = tcx.is_late_bound_map(fn_def_id.expect_local()) {
+        for &late_bound in late_bounds.iter() {
+            let hir_id = HirId { owner, local_id: late_bound };
             let name = tcx.hir().name(hir_id);
             let region_def_id = tcx.hir().local_def_id(hir_id);
             let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion {
-                scope: fn_def_id,
+                scope: owner.to_def_id(),
                 bound_region: ty::BoundRegionKind::BrNamed(region_def_id.to_def_id(), name),
             }));
             f(liberated_region);
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index e96fc185b7e..4ab14c158d3 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -115,7 +115,7 @@ impl<'a> Resolver<'a> {
         self.get_module(parent_id)
     }
 
-    crate fn get_module(&mut self, def_id: DefId) -> Module<'a> {
+    pub fn get_module(&mut self, def_id: DefId) -> Module<'a> {
         // If this is a local module, it will be in `module_map`, no need to recalculate it.
         if let Some(def_id) = def_id.as_local() {
             return self.module_map[&def_id];
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 4f8047ac2df..69fb6870d2c 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -683,7 +683,7 @@ impl<'a> Resolver<'a> {
                     ));
                 }
                 Scope::BuiltinAttrs => {
-                    let res = Res::NonMacroAttr(NonMacroAttrKind::Builtin);
+                    let res = Res::NonMacroAttr(NonMacroAttrKind::Builtin(kw::Empty));
                     if filter_fn(res) {
                         suggestions.extend(
                             BUILTIN_ATTRIBUTES
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 9de35a80061..97e556f5a33 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -14,7 +14,6 @@ use crate::{ResolutionError, Resolver, Segment, UseError};
 use rustc_ast::ptr::P;
 use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
 use rustc_ast::*;
-use rustc_ast::{unwrap_or, walk_list};
 use rustc_ast_lowering::ResolverAstLowering;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::DiagnosticId;
@@ -1911,7 +1910,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                 // it needs to be added to the trait map.
                 if ns == ValueNS {
                     let item_name = path.last().unwrap().ident;
-                    let traits = self.get_traits_containing_item(item_name, ns);
+                    let traits = self.traits_in_scope(item_name, ns);
                     self.r.trait_map.insert(id, traits);
                 }
 
@@ -2371,12 +2370,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                 // field, we need to add any trait methods we find that match
                 // the field name so that we can do some nice error reporting
                 // later on in typeck.
-                let traits = self.get_traits_containing_item(ident, ValueNS);
+                let traits = self.traits_in_scope(ident, ValueNS);
                 self.r.trait_map.insert(expr.id, traits);
             }
             ExprKind::MethodCall(ref segment, ..) => {
                 debug!("(recording candidate traits for expr) recording traits for {}", expr.id);
-                let traits = self.get_traits_containing_item(segment.ident, ValueNS);
+                let traits = self.traits_in_scope(segment.ident, ValueNS);
                 self.r.trait_map.insert(expr.id, traits);
             }
             _ => {
@@ -2385,64 +2384,13 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         }
     }
 
-    fn get_traits_containing_item(
-        &mut self,
-        mut ident: Ident,
-        ns: Namespace,
-    ) -> Vec<TraitCandidate> {
-        debug!("(getting traits containing item) looking for '{}'", ident.name);
-
-        let mut found_traits = Vec::new();
-        // Look for the current trait.
-        if let Some((module, _)) = self.current_trait_ref {
-            if self
-                .r
-                .resolve_ident_in_module(
-                    ModuleOrUniformRoot::Module(module),
-                    ident,
-                    ns,
-                    &self.parent_scope,
-                    false,
-                    module.span,
-                )
-                .is_ok()
-            {
-                let def_id = module.def_id().unwrap();
-                found_traits.push(TraitCandidate { def_id, import_ids: smallvec![] });
-            }
-        }
-
-        ident.span = ident.span.normalize_to_macros_2_0();
-        let mut search_module = self.parent_scope.module;
-        loop {
-            self.r.get_traits_in_module_containing_item(
-                ident,
-                ns,
-                search_module,
-                &mut found_traits,
-                &self.parent_scope,
-            );
-            let mut span_data = ident.span.data();
-            search_module = unwrap_or!(
-                self.r.hygienic_lexical_parent(search_module, &mut span_data.ctxt),
-                break
-            );
-            ident.span = span_data.span();
-        }
-
-        if let Some(prelude) = self.r.prelude {
-            if !search_module.no_implicit_prelude {
-                self.r.get_traits_in_module_containing_item(
-                    ident,
-                    ns,
-                    prelude,
-                    &mut found_traits,
-                    &self.parent_scope,
-                );
-            }
-        }
-
-        found_traits
+    fn traits_in_scope(&mut self, ident: Ident, ns: Namespace) -> Vec<TraitCandidate> {
+        self.r.traits_in_scope(
+            self.current_trait_ref.as_ref().map(|(module, _)| *module),
+            &self.parent_scope,
+            ident.span.ctxt(),
+            Some((ident.name, ns)),
+        )
     }
 }
 
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index aab5c3cf8f5..1be06a44687 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -11,7 +11,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE};
+use rustc_hir::def_id::{CrateNum, DefIdMap, LOCAL_CRATE};
+use rustc_hir::hir_id::ItemLocalId;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::{GenericArg, GenericParam, LifetimeName, Node, ParamName, QPath};
 use rustc_hir::{GenericParamKind, HirIdMap, HirIdSet, LifetimeParamKind};
@@ -20,6 +21,7 @@ use rustc_middle::middle::resolve_lifetime::*;
 use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
+use rustc_span::def_id::{DefId, LocalDefId};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
 use std::borrow::Cow;
@@ -284,7 +286,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
         resolve_lifetimes,
 
         named_region_map: |tcx, id| tcx.resolve_lifetimes(LOCAL_CRATE).defs.get(&id),
-        is_late_bound_map: |tcx, id| tcx.resolve_lifetimes(LOCAL_CRATE).late_bound.get(&id),
+        is_late_bound_map,
         object_lifetime_defaults_map: |tcx, id| {
             tcx.resolve_lifetimes(LOCAL_CRATE).object_lifetime_defaults.get(&id)
         },
@@ -320,6 +322,32 @@ fn resolve_lifetimes(tcx: TyCtxt<'_>, for_krate: CrateNum) -> ResolveLifetimes {
     rl
 }
 
+fn is_late_bound_map<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    def_id: LocalDefId,
+) -> Option<(LocalDefId, &'tcx FxHashSet<ItemLocalId>)> {
+    match tcx.def_kind(def_id) {
+        DefKind::AnonConst => {
+            let mut def_id = tcx
+                .parent(def_id.to_def_id())
+                .unwrap_or_else(|| bug!("anon const or closure without a parent"));
+            // We search for the next outer anon const or fn here
+            // while skipping closures.
+            //
+            // Note that for `AnonConst` we still just recurse until we
+            // find a function body, but who cares :shrug:
+            while tcx.is_closure(def_id) {
+                def_id = tcx
+                    .parent(def_id)
+                    .unwrap_or_else(|| bug!("anon const or closure without a parent"));
+            }
+
+            tcx.is_late_bound_map(def_id.expect_local())
+        }
+        _ => tcx.resolve_lifetimes(LOCAL_CRATE).late_bound.get(&def_id).map(|lt| (def_id, lt)),
+    }
+}
+
 fn krate(tcx: TyCtxt<'_>) -> NamedRegionMap {
     let krate = tcx.hir().krate();
     let mut map = NamedRegionMap {
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index c5b8f7d647c..af534162375 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -44,9 +44,9 @@ use rustc_index::vec::IndexVec;
 use rustc_metadata::creader::{CStore, CrateLoader};
 use rustc_middle::hir::exports::ExportMap;
 use rustc_middle::middle::cstore::{CrateStore, MetadataLoaderDyn};
+use rustc_middle::span_bug;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, DefIdTree, ResolverOutputs};
-use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
 use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
 use rustc_session::Session;
@@ -1477,49 +1477,76 @@ impl<'a> Resolver<'a> {
         self.crate_loader.postprocess(krate);
     }
 
-    fn get_traits_in_module_containing_item(
+    pub fn traits_in_scope(
+        &mut self,
+        current_trait: Option<Module<'a>>,
+        parent_scope: &ParentScope<'a>,
+        ctxt: SyntaxContext,
+        assoc_item: Option<(Symbol, Namespace)>,
+    ) -> Vec<TraitCandidate> {
+        let mut found_traits = Vec::new();
+
+        if let Some(module) = current_trait {
+            if self.trait_may_have_item(Some(module), assoc_item) {
+                let def_id = module.def_id().unwrap();
+                found_traits.push(TraitCandidate { def_id, import_ids: smallvec![] });
+            }
+        }
+
+        self.visit_scopes(ScopeSet::All(TypeNS, false), parent_scope, ctxt, |this, scope, _, _| {
+            match scope {
+                Scope::Module(module) => {
+                    this.traits_in_module(module, assoc_item, &mut found_traits);
+                }
+                Scope::StdLibPrelude => {
+                    if let Some(module) = this.prelude {
+                        this.traits_in_module(module, assoc_item, &mut found_traits);
+                    }
+                }
+                Scope::ExternPrelude | Scope::ToolPrelude | Scope::BuiltinTypes => {}
+                _ => unreachable!(),
+            }
+            None::<()>
+        });
+
+        found_traits
+    }
+
+    fn traits_in_module(
         &mut self,
-        ident: Ident,
-        ns: Namespace,
         module: Module<'a>,
+        assoc_item: Option<(Symbol, Namespace)>,
         found_traits: &mut Vec<TraitCandidate>,
-        parent_scope: &ParentScope<'a>,
     ) {
-        assert!(ns == TypeNS || ns == ValueNS);
         module.ensure_traits(self);
         let traits = module.traits.borrow();
+        for (trait_name, trait_binding) in traits.as_ref().unwrap().iter() {
+            if self.trait_may_have_item(trait_binding.module(), assoc_item) {
+                let def_id = trait_binding.res().def_id();
+                let import_ids = self.find_transitive_imports(&trait_binding.kind, *trait_name);
+                found_traits.push(TraitCandidate { def_id, import_ids });
+            }
+        }
+    }
 
-        for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
-            // Traits have pseudo-modules that can be used to search for the given ident.
-            if let Some(module) = binding.module() {
-                let mut ident = ident;
-                if ident.span.glob_adjust(module.expansion, binding.span).is_none() {
-                    continue;
-                }
-                if self
-                    .resolve_ident_in_module_unadjusted(
-                        ModuleOrUniformRoot::Module(module),
-                        ident,
-                        ns,
-                        parent_scope,
-                        false,
-                        module.span,
-                    )
-                    .is_ok()
-                {
-                    let import_ids = self.find_transitive_imports(&binding.kind, trait_name);
-                    let trait_def_id = module.def_id().unwrap();
-                    found_traits.push(TraitCandidate { def_id: trait_def_id, import_ids });
-                }
-            } else if let Res::Def(DefKind::TraitAlias, _) = binding.res() {
-                // For now, just treat all trait aliases as possible candidates, since we don't
-                // know if the ident is somewhere in the transitive bounds.
-                let import_ids = self.find_transitive_imports(&binding.kind, trait_name);
-                let trait_def_id = binding.res().def_id();
-                found_traits.push(TraitCandidate { def_id: trait_def_id, import_ids });
-            } else {
-                bug!("candidate is not trait or trait alias?")
+    // List of traits in scope is pruned on best effort basis. We reject traits not having an
+    // associated item with the given name and namespace (if specified). This is a conservative
+    // optimization, proper hygienic type-based resolution of associated items is done in typeck.
+    // We don't reject trait aliases (`trait_module == None`) because we don't have access to their
+    // associated items.
+    fn trait_may_have_item(
+        &mut self,
+        trait_module: Option<Module<'a>>,
+        assoc_item: Option<(Symbol, Namespace)>,
+    ) -> bool {
+        match (trait_module, assoc_item) {
+            (Some(trait_module), Some((name, ns))) => {
+                self.resolutions(trait_module).borrow().iter().any(|resolution| {
+                    let (&BindingKey { ident: assoc_ident, ns: assoc_ns, .. }, _) = resolution;
+                    assoc_ns == ns && assoc_ident.name == name
+                })
             }
+            _ => true,
         }
     }
 
@@ -3227,34 +3254,6 @@ impl<'a> Resolver<'a> {
         })
     }
 
-    /// This is equivalent to `get_traits_in_module_containing_item`, but without filtering by the associated item.
-    ///
-    /// This is used by rustdoc for intra-doc links.
-    pub fn traits_in_scope(&mut self, module_id: DefId) -> Vec<TraitCandidate> {
-        let module = self.get_module(module_id);
-        module.ensure_traits(self);
-        let traits = module.traits.borrow();
-        let to_candidate =
-            |this: &mut Self, &(trait_name, binding): &(Ident, &NameBinding<'_>)| TraitCandidate {
-                def_id: binding.res().def_id(),
-                import_ids: this.find_transitive_imports(&binding.kind, trait_name),
-            };
-
-        let mut candidates: Vec<_> =
-            traits.as_ref().unwrap().iter().map(|x| to_candidate(self, x)).collect();
-
-        if let Some(prelude) = self.prelude {
-            if !module.no_implicit_prelude {
-                prelude.ensure_traits(self);
-                candidates.extend(
-                    prelude.traits.borrow().as_ref().unwrap().iter().map(|x| to_candidate(self, x)),
-                );
-            }
-        }
-
-        candidates
-    }
-
     /// Rustdoc uses this to resolve things in a recoverable way. `ResolutionError<'a>`
     /// isn't something that can be returned because it can't be made to live that long,
     /// and also it's a private type. Fortunately rustdoc doesn't need to know the error,
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 5c74094ecd3..5d6120cd310 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -757,7 +757,11 @@ impl<'a> Resolver<'a> {
                     }
                     Scope::BuiltinAttrs => {
                         if is_builtin_attr_name(ident.name) {
-                            ok(Res::NonMacroAttr(NonMacroAttrKind::Builtin), DUMMY_SP, this.arenas)
+                            ok(
+                                Res::NonMacroAttr(NonMacroAttrKind::Builtin(ident.name)),
+                                DUMMY_SP,
+                                this.arenas,
+                            )
                         } else {
                             Err(Determinacy::Determined)
                         }
@@ -810,13 +814,15 @@ impl<'a> Resolver<'a> {
                             // Found another solution, if the first one was "weak", report an error.
                             let (res, innermost_res) = (binding.res(), innermost_binding.res());
                             if res != innermost_res {
-                                let builtin = Res::NonMacroAttr(NonMacroAttrKind::Builtin);
+                                let is_builtin = |res| {
+                                    matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Builtin(..)))
+                                };
                                 let derive_helper_compat =
                                     Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat);
 
                                 let ambiguity_error_kind = if is_import {
                                     Some(AmbiguityKind::Import)
-                                } else if innermost_res == builtin || res == builtin {
+                                } else if is_builtin(innermost_res) || is_builtin(res) {
                                     Some(AmbiguityKind::BuiltinAttr)
                                 } else if innermost_res == derive_helper_compat
                                     || res == derive_helper_compat
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 795cf2e19de..e78ccb35219 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -589,23 +589,23 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                         if let Some(typeck_results) = self.in_progress_typeck_results {
                             let typeck_results = typeck_results.borrow();
                             match (found_kind, typeck_results.closure_kind_origins().get(hir_id)) {
-                                (ty::ClosureKind::FnOnce, Some((span, name))) => {
+                                (ty::ClosureKind::FnOnce, Some((span, place))) => {
                                     err.span_label(
                                         *span,
                                         format!(
                                             "closure is `FnOnce` because it moves the \
                                          variable `{}` out of its environment",
-                                            name
+                                            ty::place_to_string_for_capture(tcx, place)
                                         ),
                                     );
                                 }
-                                (ty::ClosureKind::FnMut, Some((span, name))) => {
+                                (ty::ClosureKind::FnMut, Some((span, place))) => {
                                     err.span_label(
                                         *span,
                                         format!(
                                             "closure is `FnMut` because it mutates the \
                                          variable `{}` here",
-                                            name
+                                            ty::place_to_string_for_capture(tcx, place)
                                         ),
                                     );
                                 }
diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs
index 0036edda36d..d37d6bc4f2d 100644
--- a/compiler/rustc_typeck/src/check/compare_method.rs
+++ b/compiler/rustc_typeck/src/check/compare_method.rs
@@ -365,12 +365,10 @@ fn check_region_bounds_on_impl_item<'tcx>(
         let item_kind = assoc_item_kind_str(impl_m);
         let def_span = tcx.sess.source_map().guess_head_span(span);
         let span = tcx.hir().get_generics(impl_m.def_id).map_or(def_span, |g| g.span);
-        let generics_span = if let Some(sp) = tcx.hir().span_if_local(trait_m.def_id) {
+        let generics_span = tcx.hir().span_if_local(trait_m.def_id).map(|sp| {
             let def_sp = tcx.sess.source_map().guess_head_span(sp);
-            Some(tcx.hir().get_generics(trait_m.def_id).map_or(def_sp, |g| g.span))
-        } else {
-            None
-        };
+            tcx.hir().get_generics(trait_m.def_id).map_or(def_sp, |g| g.span)
+        });
 
         tcx.sess.emit_err(LifetimesOrBoundsMismatchOnTrait {
             span,
diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs
index e8cbefd44ee..feda35daa61 100644
--- a/compiler/rustc_typeck/src/check/upvar.rs
+++ b/compiler/rustc_typeck/src/check/upvar.rs
@@ -176,7 +176,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.demand_eqtype(span, inferred_kind.to_ty(self.tcx), closure_kind_ty);
 
             // If we have an origin, store it.
-            if let Some(origin) = delegate.current_origin {
+            if let Some(origin) = delegate.current_origin.clone() {
+                let origin = if self.tcx.features().capture_disjoint_fields {
+                    origin
+                } else {
+                    // FIXME(project-rfc-2229#26): Once rust-lang#80092 is merged, we should restrict the
+                    // precision of origin as well. Otherwise, this will cause issues when project-rfc-2229#26
+                    // is fixed as we might see Index projections in the origin, which we can't print because
+                    // we don't store enough information.
+                    (origin.0, Place { projections: vec![], ..origin.1 })
+                };
+
                 self.typeck_results
                     .borrow_mut()
                     .closure_kind_origins_mut()
@@ -563,7 +573,7 @@ struct InferBorrowKind<'a, 'tcx> {
 
     // If we modified `current_closure_kind`, this field contains a `Some()` with the
     // variable access that caused us to do so.
-    current_origin: Option<(Span, Symbol)>,
+    current_origin: Option<(Span, Place<'tcx>)>,
 
     /// For each Place that is captured by the closure, we track the minimal kind of
     /// access we need (ref, ref mut, move, etc) and the expression that resulted in such access.
@@ -628,7 +638,7 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
             upvar_id.closure_expr_id,
             ty::ClosureKind::FnOnce,
             usage_span,
-            var_name(tcx, upvar_id.var_path.hir_id),
+            place_with_id.place.clone(),
         );
 
         let capture_info = ty::CaptureInfo {
@@ -720,7 +730,7 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
                 upvar_id.closure_expr_id,
                 ty::ClosureKind::FnMut,
                 tcx.hir().span(diag_expr_id),
-                var_name(tcx, upvar_id.var_path.hir_id),
+                place_with_id.place.clone(),
             );
         }
     }
@@ -765,11 +775,11 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
         closure_id: LocalDefId,
         new_kind: ty::ClosureKind,
         upvar_span: Span,
-        var_name: Symbol,
+        place: Place<'tcx>,
     ) {
         debug!(
-            "adjust_closure_kind(closure_id={:?}, new_kind={:?}, upvar_span={:?}, var_name={})",
-            closure_id, new_kind, upvar_span, var_name
+            "adjust_closure_kind(closure_id={:?}, new_kind={:?}, upvar_span={:?}, place={:?})",
+            closure_id, new_kind, upvar_span, place
         );
 
         // Is this the closure whose kind is currently being inferred?
@@ -797,7 +807,7 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
             | (ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => {
                 // new kind is stronger than the old kind
                 self.current_closure_kind = new_kind;
-                self.current_origin = Some((upvar_span, var_name));
+                self.current_origin = Some((upvar_span, place));
             }
         }
     }
diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs
index 7c9cfe69fc9..6edce62f76b 100644
--- a/compiler/rustc_typeck/src/check/writeback.rs
+++ b/compiler/rustc_typeck/src/check/writeback.rs
@@ -384,9 +384,11 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
         let common_hir_owner = fcx_typeck_results.hir_owner;
 
-        for (&id, &origin) in fcx_typeck_results.closure_kind_origins().iter() {
-            let hir_id = hir::HirId { owner: common_hir_owner, local_id: id };
-            self.typeck_results.closure_kind_origins_mut().insert(hir_id, origin);
+        for (id, origin) in fcx_typeck_results.closure_kind_origins().iter() {
+            let hir_id = hir::HirId { owner: common_hir_owner, local_id: *id };
+            let place_span = origin.0;
+            let place = self.resolve(origin.1.clone(), &place_span);
+            self.typeck_results.closure_kind_origins_mut().insert(hir_id, (place_span, place));
         }
     }
 
diff --git a/config.toml.example b/config.toml.example
index 9e08ce9b27e..55b20adabd0 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -35,9 +35,11 @@ changelog-seen = 2
 # Unless you're developing for a target where Rust CI doesn't build a compiler
 # toolchain or changing LLVM locally, you probably want to set this to true.
 #
-# It's currently false by default due to being newly added; please file bugs if
-# enabling this did not work for you on x86_64-unknown-linux-gnu.
-# Other target triples are currently not supported; see #77084.
+# This is false by default so that distributions don't unexpectedly download
+# LLVM from the internet.
+#
+# All tier 1 targets are currently supported; set this to `"if-supported"` if
+# you are not sure whether you're on a tier 1 target.
 #
 # We also currently only support this when building LLVM for the build triple.
 #
diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs
index 220c98b294c..928c6f9a3a8 100644
--- a/library/alloc/src/collections/btree/node.rs
+++ b/library/alloc/src/collections/btree/node.rs
@@ -184,7 +184,7 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
 
     /// Removes the internal root node, using its first child as the new root node.
     /// As it is intended only to be called when the root node has only one child,
-    /// no cleanup is done on any of the other children.
+    /// no cleanup is done on any of the keys, values and other children.
     /// This decreases the height by 1 and is the opposite of `push_internal_level`.
     ///
     /// Requires exclusive access to the `Root` object but not to the root node;
@@ -225,7 +225,7 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
 ///    - When this is `Owned`, the `NodeRef` acts roughly like `Box<Node>`,
 ///      but does not have a destructor, and must be cleaned up manually.
 ///   Since any `NodeRef` allows navigating through the tree, `BorrowType`
-///   effectively applies to the entire tree, not just the node itself.
+///   effectively applies to the entire tree, not just to the node itself.
 /// - `K` and `V`: These are the types of keys and values stored in the nodes.
 /// - `Type`: This can be `Leaf`, `Internal`, or `LeafOrInternal`. When this is
 ///   `Leaf`, the `NodeRef` points to a leaf node, when this is `Internal` the
@@ -425,7 +425,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
 
 impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
     /// Similar to `ascend`, gets a reference to a node's parent node, but also
-    /// deallocate the current node in the process. This is unsafe because the
+    /// deallocates the current node in the process. This is unsafe because the
     /// current node will still be accessible despite being deallocated.
     pub unsafe fn deallocate_and_ascend(
         self,
@@ -661,7 +661,10 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
     /// Removes a key-value pair from the end of the node and returns the pair.
     /// Also removes the edge that was to the right of that pair and, if the node
     /// is internal, returns the orphaned subtree that this edge owned.
-    fn pop(&mut self) -> (K, V, Option<Root<K, V>>) {
+    ///
+    /// # Safety
+    /// The node must not be empty.
+    unsafe fn pop(&mut self) -> (K, V, Option<Root<K, V>>) {
         debug_assert!(self.len() > 0);
 
         let idx = self.len() - 1;
diff --git a/library/alloc/src/collections/btree/search.rs b/library/alloc/src/collections/btree/search.rs
index ed7f95fe632..efe94ef175c 100644
--- a/library/alloc/src/collections/btree/search.rs
+++ b/library/alloc/src/collections/btree/search.rs
@@ -12,8 +12,7 @@ pub enum SearchResult<BorrowType, K, V, FoundType, GoDownType> {
 
 /// Looks up a given key in a (sub)tree headed by the given node, recursively.
 /// Returns a `Found` with the handle of the matching KV, if any. Otherwise,
-/// returns a `GoDown` with the handle of the possible leaf edge where the key
-/// belongs.
+/// returns a `GoDown` with the handle of the leaf edge where the key belongs.
 ///
 /// The result is meaningful only if the tree is ordered by key, like the tree
 /// in a `BTreeMap` is.
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index d0bfa038aa1..14a10aac061 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -140,6 +140,7 @@
 #![feature(type_alias_impl_trait)]
 #![feature(associated_type_bounds)]
 #![feature(slice_group_by)]
+#![feature(decl_macro)]
 // Allow testing this library
 
 #[cfg(test)]
@@ -193,4 +194,11 @@ mod std {
 #[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")]
 pub mod __export {
     pub use core::format_args;
+
+    /// Force AST node to an expression to improve diagnostics in pattern position.
+    #[rustc_macro_transparency = "semitransparent"]
+    #[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")]
+    pub macro force_expr($e:expr) {
+        $e
+    }
 }
diff --git a/library/alloc/src/macros.rs b/library/alloc/src/macros.rs
index 7d4eff6185d..3a46763c3f6 100644
--- a/library/alloc/src/macros.rs
+++ b/library/alloc/src/macros.rs
@@ -37,16 +37,16 @@
 #[cfg(not(test))]
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow_internal_unstable(box_syntax)]
+#[allow_internal_unstable(box_syntax, liballoc_internals)]
 macro_rules! vec {
     () => (
-        $crate::vec::Vec::new()
+        $crate::__export::force_expr!($crate::vec::Vec::new())
     );
     ($elem:expr; $n:expr) => (
-        $crate::vec::from_elem($elem, $n)
+        $crate::__export::force_expr!($crate::vec::from_elem($elem, $n))
     );
     ($($x:expr),+ $(,)?) => (
-        <[_]>::into_vec(box [$($x),+])
+        $crate::__export::force_expr!(<[_]>::into_vec(box [$($x),+]))
     );
 }
 
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index ba8918b192f..111feb7dbec 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -286,3 +286,43 @@ nonzero_integers_div! {
     NonZeroU128(u128);
     NonZeroUsize(usize);
 }
+
+macro_rules! nonzero_unsigned_is_power_of_two {
+    ( $( $Ty: ident )+ ) => {
+        $(
+            impl $Ty {
+
+                /// Returns `true` if and only if `self == (1 << k)` for some `k`.
+                ///
+                /// On many architectures, this function can perform better than `is_power_of_two()`
+                /// on the underlying integer type, as special handling of zero can be avoided.
+                ///
+                /// # Examples
+                ///
+                /// Basic usage:
+                ///
+                /// ```
+                /// #![feature(nonzero_is_power_of_two)]
+                ///
+                #[doc = concat!("let eight = std::num::", stringify!($Ty), "::new(8).unwrap();")]
+                /// assert!(eight.is_power_of_two());
+                #[doc = concat!("let ten = std::num::", stringify!($Ty), "::new(10).unwrap();")]
+                /// assert!(!ten.is_power_of_two());
+                /// ```
+                #[unstable(feature = "nonzero_is_power_of_two", issue = "81106")]
+                #[inline]
+                pub const fn is_power_of_two(self) -> bool {
+                    // LLVM 11 normalizes `unchecked_sub(x, 1) & x == 0` to the implementation seen here.
+                    // On the basic x86-64 target, this saves 3 instructions for the zero check.
+                    // On x86_64 with BMI1, being nonzero lets it codegen to `BLSR`, which saves an instruction
+                    // compared to the `POPCNT` implementation on the underlying integer type.
+
+                    intrinsics::ctpop(self.get()) < 2
+                }
+
+            }
+        )+
+    }
+}
+
+nonzero_unsigned_is_power_of_two! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize }
diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs
index 16c18d6e146..8bae3da1273 100644
--- a/library/std/src/io/buffered/bufreader.rs
+++ b/library/std/src/io/buffered/bufreader.rs
@@ -271,6 +271,20 @@ impl<R: Read> Read for BufReader<R> {
         Ok(nread)
     }
 
+    // Small read_exacts from a BufReader are extremely common when used with a deserializer.
+    // The default implementation calls read in a loop, which results in surprisingly poor code
+    // generation for the common path where the buffer has enough bytes to fill the passed-in
+    // buffer.
+    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
+        if self.buffer().len() >= buf.len() {
+            buf.copy_from_slice(&self.buffer()[..buf.len()]);
+            self.consume(buf.len());
+            return Ok(());
+        }
+
+        crate::io::default_read_exact(self, buf)
+    }
+
     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         let total_len = bufs.iter().map(|b| b.len()).sum::<usize>();
         if self.pos == self.cap && total_len >= self.buf.len() {
diff --git a/library/std/src/io/buffered/tests.rs b/library/std/src/io/buffered/tests.rs
index 66a64f667ba..f6c2b499567 100644
--- a/library/std/src/io/buffered/tests.rs
+++ b/library/std/src/io/buffered/tests.rs
@@ -444,6 +444,18 @@ fn bench_buffered_reader(b: &mut test::Bencher) {
 }
 
 #[bench]
+fn bench_buffered_reader_small_reads(b: &mut test::Bencher) {
+    let data = (0..u8::MAX).cycle().take(1024 * 4).collect::<Vec<_>>();
+    b.iter(|| {
+        let mut reader = BufReader::new(&data[..]);
+        let mut buf = [0u8; 4];
+        for _ in 0..1024 {
+            reader.read_exact(&mut buf).unwrap();
+        }
+    });
+}
+
+#[bench]
 fn bench_buffered_writer(b: &mut test::Bencher) {
     b.iter(|| BufWriter::new(io::sink()));
 }
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 3f5b7c0b29b..c87a56586c6 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -416,6 +416,25 @@ where
     write(buf)
 }
 
+pub(crate) fn default_read_exact<R: Read + ?Sized>(this: &mut R, mut buf: &mut [u8]) -> Result<()> {
+    while !buf.is_empty() {
+        match this.read(buf) {
+            Ok(0) => break,
+            Ok(n) => {
+                let tmp = buf;
+                buf = &mut tmp[n..];
+            }
+            Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
+            Err(e) => return Err(e),
+        }
+    }
+    if !buf.is_empty() {
+        Err(Error::new(ErrorKind::UnexpectedEof, "failed to fill whole buffer"))
+    } else {
+        Ok(())
+    }
+}
+
 /// The `Read` trait allows for reading bytes from a source.
 ///
 /// Implementors of the `Read` trait are called 'readers'.
@@ -766,23 +785,8 @@ pub trait Read {
     /// }
     /// ```
     #[stable(feature = "read_exact", since = "1.6.0")]
-    fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<()> {
-        while !buf.is_empty() {
-            match self.read(buf) {
-                Ok(0) => break,
-                Ok(n) => {
-                    let tmp = buf;
-                    buf = &mut tmp[n..];
-                }
-                Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
-                Err(e) => return Err(e),
-            }
-        }
-        if !buf.is_empty() {
-            Err(Error::new(ErrorKind::UnexpectedEof, "failed to fill whole buffer"))
-        } else {
-            Ok(())
-        }
+    fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
+        default_read_exact(self, buf)
     }
 
     /// Creates a "by reference" adaptor for this instance of `Read`.
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 6d2d7bbbef9..5350c9eefe7 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -465,8 +465,21 @@ class RustBuild(object):
 
     def downloading_llvm(self):
         opt = self.get_toml('download-ci-llvm', 'llvm')
+        # This is currently all tier 1 targets (since others may not have CI
+        # artifacts)
+        # https://doc.rust-lang.org/rustc/platform-support.html#tier-1
+        supported_platforms = [
+            "aarch64-unknown-linux-gnu",
+            "i686-pc-windows-gnu",
+            "i686-pc-windows-msvc",
+            "i686-unknown-linux-gnu",
+            "x86_64-unknown-linux-gnu",
+            "x86_64-apple-darwin",
+            "x86_64-pc-windows-gnu",
+            "x86_64-pc-windows-msvc",
+        ]
         return opt == "true" \
-            or (opt == "if-available" and self.build == "x86_64-unknown-linux-gnu")
+            or (opt == "if-available" and self.build in supported_platforms)
 
     def _download_stage0_helper(self, filename, pattern, tarball_suffix, date=None):
         if date is None:
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 72a979338a5..c19bb536ce8 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -73,7 +73,7 @@ impl Step for Std {
 
     fn run(self, builder: &Builder<'_>) {
         let target = self.target;
-        let compiler = builder.compiler(0, builder.config.build);
+        let compiler = builder.compiler(builder.top_stage, builder.config.build);
 
         let mut cargo = builder.cargo(
             compiler,
@@ -84,7 +84,10 @@ impl Step for Std {
         );
         std_cargo(builder, target, compiler.stage, &mut cargo);
 
-        builder.info(&format!("Checking std artifacts ({} -> {})", &compiler.host, target));
+        builder.info(&format!(
+            "Checking stage{} std artifacts ({} -> {})",
+            builder.top_stage, &compiler.host, target
+        ));
         run_cargo(
             builder,
             cargo,
@@ -94,9 +97,13 @@ impl Step for Std {
             true,
         );
 
-        let libdir = builder.sysroot_libdir(compiler, target);
-        let hostdir = builder.sysroot_libdir(compiler, compiler.host);
-        add_to_sysroot(&builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
+        // We skip populating the sysroot in non-zero stage because that'll lead
+        // to rlib/rmeta conflicts if std gets built during this session.
+        if compiler.stage == 0 {
+            let libdir = builder.sysroot_libdir(compiler, target);
+            let hostdir = builder.sysroot_libdir(compiler, compiler.host);
+            add_to_sysroot(&builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
+        }
 
         // Then run cargo again, once we've put the rmeta files for the library
         // crates into the sysroot. This is needed because e.g., core's tests
@@ -124,8 +131,8 @@ impl Step for Std {
             }
 
             builder.info(&format!(
-                "Checking std test/bench/example targets ({} -> {})",
-                &compiler.host, target
+                "Checking stage{} std test/bench/example targets ({} -> {})",
+                builder.top_stage, &compiler.host, target
             ));
             run_cargo(
                 builder,
@@ -163,10 +170,20 @@ impl Step for Rustc {
     /// the `compiler` targeting the `target` architecture. The artifacts
     /// created will also be linked into the sysroot directory.
     fn run(self, builder: &Builder<'_>) {
-        let compiler = builder.compiler(0, builder.config.build);
+        let compiler = builder.compiler(builder.top_stage, builder.config.build);
         let target = self.target;
 
-        builder.ensure(Std { target });
+        if compiler.stage != 0 {
+            // If we're not in stage 0, then we won't have a std from the beta
+            // compiler around. That means we need to make sure there's one in
+            // the sysroot for the compiler to find. Otherwise, we're going to
+            // fail when building crates that need to generate code (e.g., build
+            // scripts and their dependencies).
+            builder.ensure(crate::compile::Std { target: compiler.host, compiler });
+            builder.ensure(crate::compile::Std { target, compiler });
+        } else {
+            builder.ensure(Std { target });
+        }
 
         let mut cargo = builder.cargo(
             compiler,
@@ -187,7 +204,10 @@ impl Step for Rustc {
             cargo.arg("-p").arg(krate.name);
         }
 
-        builder.info(&format!("Checking compiler artifacts ({} -> {})", &compiler.host, target));
+        builder.info(&format!(
+            "Checking stage{} compiler artifacts ({} -> {})",
+            builder.top_stage, &compiler.host, target
+        ));
         run_cargo(
             builder,
             cargo,
@@ -225,7 +245,7 @@ impl Step for CodegenBackend {
     }
 
     fn run(self, builder: &Builder<'_>) {
-        let compiler = builder.compiler(0, builder.config.build);
+        let compiler = builder.compiler(builder.top_stage, builder.config.build);
         let target = self.target;
         let backend = self.backend;
 
@@ -244,8 +264,8 @@ impl Step for CodegenBackend {
         rustc_cargo_env(builder, &mut cargo, target);
 
         builder.info(&format!(
-            "Checking {} artifacts ({} -> {})",
-            backend, &compiler.host.triple, target.triple
+            "Checking stage{} {} artifacts ({} -> {})",
+            builder.top_stage, backend, &compiler.host.triple, target.triple
         ));
 
         run_cargo(
@@ -280,7 +300,7 @@ macro_rules! tool_check_step {
             }
 
             fn run(self, builder: &Builder<'_>) {
-                let compiler = builder.compiler(0, builder.config.build);
+                let compiler = builder.compiler(builder.top_stage, builder.config.build);
                 let target = self.target;
 
                 builder.ensure(Rustc { target });
@@ -301,7 +321,8 @@ macro_rules! tool_check_step {
                 }
 
                 builder.info(&format!(
-                    "Checking {} artifacts ({} -> {})",
+                    "Checking stage{} {} artifacts ({} -> {})",
+                    builder.top_stage,
                     stringify!($name).to_lowercase(),
                     &compiler.host.triple,
                     target.triple
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index f4d89a89c14..ec1308ab82b 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -377,6 +377,7 @@ struct Build {
     configure_args: Option<Vec<String>>,
     local_rebuild: Option<bool>,
     print_step_timings: Option<bool>,
+    check_stage: Option<u32>,
     doc_stage: Option<u32>,
     build_stage: Option<u32>,
     test_stage: Option<u32>,
@@ -676,6 +677,7 @@ impl Config {
 
         // See https://github.com/rust-lang/compiler-team/issues/326
         config.stage = match config.cmd {
+            Subcommand::Check { .. } => flags.stage.or(build.check_stage).unwrap_or(0),
             Subcommand::Doc { .. } => flags.stage.or(build.doc_stage).unwrap_or(0),
             Subcommand::Build { .. } => flags.stage.or(build.build_stage).unwrap_or(1),
             Subcommand::Test { .. } => flags.stage.or(build.test_stage).unwrap_or(1),
@@ -685,7 +687,6 @@ impl Config {
             // These are all bootstrap tools, which don't depend on the compiler.
             // The stage we pass shouldn't matter, but use 0 just in case.
             Subcommand::Clean { .. }
-            | Subcommand::Check { .. }
             | Subcommand::Clippy { .. }
             | Subcommand::Fix { .. }
             | Subcommand::Run { .. }
@@ -816,8 +817,10 @@ impl Config {
                 check_ci_llvm!(llvm.allow_old_toolchain);
                 check_ci_llvm!(llvm.polly);
 
-                // CI-built LLVM is shared
-                config.llvm_link_shared = true;
+                // CI-built LLVM can be either dynamic or static.
+                let ci_llvm = config.out.join(&*config.build.triple).join("ci-llvm");
+                let link_type = t!(std::fs::read_to_string(ci_llvm.join("link-type.txt")));
+                config.llvm_link_shared = link_type == "dynamic";
             }
 
             if config.llvm_thin_lto {
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index e2c2e19b0bc..af9c0fb04bc 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -1800,19 +1800,11 @@ fn add_env(builder: &Builder<'_>, cmd: &mut Command, target: TargetSelection) {
     }
 }
 
-/// Maybe add libLLVM.so to the given destination lib-dir. It will only have
-/// been built if LLVM tools are linked dynamically.
+/// Maybe add LLVM object files to the given destination lib-dir. Allows either static or dynamic linking.
 ///
-/// Note: This function does not yet support Windows, but we also don't support
-///       linking LLVM tools dynamically on Windows yet.
-fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir: &Path) {
-    if !builder.config.llvm_link_shared {
-        // We do not need to copy LLVM files into the sysroot if it is not
-        // dynamically linked; it is already included into librustc_llvm
-        // statically.
-        return;
-    }
 
+/// Returns whether the files were actually copied.
+fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir: &Path) -> bool {
     if let Some(config) = builder.config.target_config.get(&target) {
         if config.llvm_config.is_some() && !builder.config.llvm_from_ci {
             // If the LLVM was externally provided, then we don't currently copy
@@ -1828,7 +1820,7 @@ fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir
             //
             // If the LLVM is coming from ourselves (just from CI) though, we
             // still want to install it, as it otherwise won't be available.
-            return;
+            return false;
         }
     }
 
@@ -1837,31 +1829,48 @@ fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir
     // clear why this is the case, though. llvm-config will emit the versioned
     // paths and we don't want those in the sysroot (as we're expecting
     // unversioned paths).
-    if target.contains("apple-darwin") {
+    if target.contains("apple-darwin") && builder.config.llvm_link_shared {
         let src_libdir = builder.llvm_out(target).join("lib");
         let llvm_dylib_path = src_libdir.join("libLLVM.dylib");
         if llvm_dylib_path.exists() {
             builder.install(&llvm_dylib_path, dst_libdir, 0o644);
         }
+        !builder.config.dry_run
     } else if let Ok(llvm_config) = crate::native::prebuilt_llvm_config(builder, target) {
-        let files = output(Command::new(llvm_config).arg("--libfiles"));
-        for file in files.lines() {
+        let mut cmd = Command::new(llvm_config);
+        cmd.arg("--libfiles");
+        builder.verbose(&format!("running {:?}", cmd));
+        let files = output(&mut cmd);
+        for file in files.trim_end().split(' ') {
             builder.install(Path::new(file), dst_libdir, 0o644);
         }
+        !builder.config.dry_run
+    } else {
+        false
     }
 }
 
 /// Maybe add libLLVM.so to the target lib-dir for linking.
 pub fn maybe_install_llvm_target(builder: &Builder<'_>, target: TargetSelection, sysroot: &Path) {
     let dst_libdir = sysroot.join("lib/rustlib").join(&*target.triple).join("lib");
-    maybe_install_llvm(builder, target, &dst_libdir);
+    // We do not need to copy LLVM files into the sysroot if it is not
+    // dynamically linked; it is already included into librustc_llvm
+    // statically.
+    if builder.config.llvm_link_shared {
+        maybe_install_llvm(builder, target, &dst_libdir);
+    }
 }
 
 /// Maybe add libLLVM.so to the runtime lib-dir for rustc itself.
 pub fn maybe_install_llvm_runtime(builder: &Builder<'_>, target: TargetSelection, sysroot: &Path) {
     let dst_libdir =
         sysroot.join(builder.sysroot_libdir_relative(Compiler { stage: 1, host: target }));
-    maybe_install_llvm(builder, target, &dst_libdir);
+    // We do not need to copy LLVM files into the sysroot if it is not
+    // dynamically linked; it is already included into librustc_llvm
+    // statically.
+    if builder.config.llvm_link_shared {
+        maybe_install_llvm(builder, target, &dst_libdir);
+    }
 }
 
 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
@@ -1973,7 +1982,10 @@ impl Step for RustDev {
         // `$ORIGIN/../lib` can find it. It may also be used as a dependency
         // of `rustc-dev` to support the inherited `-lLLVM` when using the
         // compiler libraries.
-        maybe_install_llvm(builder, target, &tarball.image_dir().join("lib"));
+        let dst_libdir = tarball.image_dir().join("lib");
+        maybe_install_llvm(builder, target, &dst_libdir);
+        let link_type = if builder.config.llvm_link_shared { "dynamic" } else { "static" };
+        t!(std::fs::write(tarball.image_dir().join("link-type.txt"), link_type), dst_libdir);
 
         Some(tarball.generate())
     }
diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp
index b29ecd65401..fb5b058cb4d 100644
--- a/src/bootstrap/download-ci-llvm-stamp
+++ b/src/bootstrap/download-ci-llvm-stamp
@@ -1,4 +1,4 @@
 Change this file to make users of the `download-ci-llvm` configuration download
 a new version of LLVM from CI, even if the LLVM submodule hasn’t changed.
 
-Last change is for: https://github.com/rust-lang/rust/pull/80087
+Last change is for: https://github.com/rust-lang/rust/pull/80932
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index d6a45f1c170..55062e11e02 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -614,14 +614,10 @@ Arguments:
         };
 
         if let Subcommand::Check { .. } = &cmd {
-            if matches.opt_str("stage").is_some() {
-                println!("--stage not supported for x.py check, always treated as stage 0");
-                process::exit(1);
-            }
             if matches.opt_str("keep-stage").is_some()
                 || matches.opt_str("keep-stage-std").is_some()
             {
-                println!("--keep-stage not supported for x.py check, only one stage available");
+                println!("--keep-stage not yet supported for x.py check");
                 process::exit(1);
             }
         }
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index 6412df3fd90..609ac8b3669 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -171,7 +171,6 @@ impl Step for Llvm {
             .define("LLVM_TARGETS_TO_BUILD", llvm_targets)
             .define("LLVM_EXPERIMENTAL_TARGETS_TO_BUILD", llvm_exp_targets)
             .define("LLVM_INCLUDE_EXAMPLES", "OFF")
-            .define("LLVM_INCLUDE_TESTS", "OFF")
             .define("LLVM_INCLUDE_DOCS", "OFF")
             .define("LLVM_INCLUDE_BENCHMARKS", "OFF")
             .define("LLVM_ENABLE_TERMINFO", "OFF")
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 708d7710058..280984088a9 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -19,7 +19,7 @@ use rustc_session::lint::{
     builtin::{BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS},
     Lint,
 };
-use rustc_span::hygiene::MacroKind;
+use rustc_span::hygiene::{MacroKind, SyntaxContext};
 use rustc_span::symbol::Ident;
 use rustc_span::symbol::Symbol;
 use rustc_span::DUMMY_SP;
@@ -770,7 +770,12 @@ fn traits_implemented_by(cx: &DocContext<'_>, type_: DefId, module: DefId) -> Fx
     let mut cache = cx.module_trait_cache.borrow_mut();
     let in_scope_traits = cache.entry(module).or_insert_with(|| {
         cx.enter_resolver(|resolver| {
-            resolver.traits_in_scope(module).into_iter().map(|candidate| candidate.def_id).collect()
+            let parent_scope = &ParentScope::module(resolver.get_module(module), resolver);
+            resolver
+                .traits_in_scope(None, parent_scope, SyntaxContext::root(), None)
+                .into_iter()
+                .map(|candidate| candidate.def_id)
+                .collect()
         })
     });
 
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.rs
new file mode 100644
index 00000000000..2916d8c794f
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.rs
@@ -0,0 +1,31 @@
+#![feature(capture_disjoint_fields)]
+//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+//~| `#[warn(incomplete_features)]` on by default
+//~| see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+
+// Check that precise paths are being reported back in the error message.
+
+
+enum MultiVariant {
+    Point(i32, i32),
+    Meta(i32)
+}
+
+fn main() {
+    let mut point = MultiVariant::Point(10, -10,);
+
+    let mut meta = MultiVariant::Meta(1);
+
+    let c = || {
+        if let MultiVariant::Point(ref mut x, _) = point {
+            *x += 1;
+        }
+
+        if let MultiVariant::Meta(ref mut v) = meta {
+            *v += 1;
+        }
+    };
+
+    let a = c;
+    let b = c; //~ ERROR use of moved value: `c` [E0382]
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.stderr
new file mode 100644
index 00000000000..de0bfe3bd76
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.stderr
@@ -0,0 +1,26 @@
+warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/closure-origin-multi-variant-diagnostics.rs:1:12
+   |
+LL | #![feature(capture_disjoint_fields)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
+
+error[E0382]: use of moved value: `c`
+  --> $DIR/closure-origin-multi-variant-diagnostics.rs:30:13
+   |
+LL |     let a = c;
+   |             - value moved here
+LL |     let b = c;
+   |             ^ value used here after move
+   |
+note: closure cannot be moved more than once as it is not `Copy` due to moving the variable `point.0` out of its environment
+  --> $DIR/closure-origin-multi-variant-diagnostics.rs:20:52
+   |
+LL |         if let MultiVariant::Point(ref mut x, _) = point {
+   |                                                    ^^^^^
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.rs
new file mode 100644
index 00000000000..8486f03f2eb
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.rs
@@ -0,0 +1,26 @@
+#![feature(capture_disjoint_fields)]
+//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+//~| `#[warn(incomplete_features)]` on by default
+//~| see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+
+// Check that precise paths are being reported back in the error message.
+
+enum SingleVariant {
+    Point(i32, i32),
+}
+
+fn main() {
+    let mut point = SingleVariant::Point(10, -10);
+
+    let c = || {
+        // FIXME(project-rfc-2229#24): Change this to be a destructure pattern
+        // once this is fixed, to remove the warning.
+        if let SingleVariant::Point(ref mut x, _) = point {
+            //~^ WARNING: irrefutable if-let pattern
+            *x += 1;
+        }
+    };
+
+    let b = c;
+    let a = c; //~ ERROR use of moved value: `c` [E0382]
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.stderr
new file mode 100644
index 00000000000..ad66f6d7ffc
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.stderr
@@ -0,0 +1,37 @@
+warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/closure-origin-single-variant-diagnostics.rs:1:12
+   |
+LL | #![feature(capture_disjoint_fields)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
+
+warning: irrefutable if-let pattern
+  --> $DIR/closure-origin-single-variant-diagnostics.rs:18:9
+   |
+LL | /         if let SingleVariant::Point(ref mut x, _) = point {
+LL | |
+LL | |             *x += 1;
+LL | |         }
+   | |_________^
+   |
+   = note: `#[warn(irrefutable_let_patterns)]` on by default
+
+error[E0382]: use of moved value: `c`
+  --> $DIR/closure-origin-single-variant-diagnostics.rs:25:13
+   |
+LL |     let b = c;
+   |             - value moved here
+LL |     let a = c;
+   |             ^ value used here after move
+   |
+note: closure cannot be moved more than once as it is not `Copy` due to moving the variable `point.0` out of its environment
+  --> $DIR/closure-origin-single-variant-diagnostics.rs:18:53
+   |
+LL |         if let SingleVariant::Point(ref mut x, _) = point {
+   |                                                     ^^^^^
+
+error: aborting due to previous error; 2 warnings emitted
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.rs
new file mode 100644
index 00000000000..103890f1f35
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.rs
@@ -0,0 +1,25 @@
+#![feature(capture_disjoint_fields)]
+//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+//~| `#[warn(incomplete_features)]` on by default
+//~| see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+
+// Check that precise paths are being reported back in the error message.
+
+struct Y {
+    y: X
+}
+
+struct X {
+    a: u32,
+    b: u32,
+}
+
+fn main() {
+    let mut x = Y { y: X { a: 5, b: 0 } };
+    let hello = || {
+        x.y.a += 1;
+    };
+
+    let b = hello;
+    let c = hello; //~ ERROR use of moved value: `hello` [E0382]
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.stderr
new file mode 100644
index 00000000000..474d77b7cd2
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.stderr
@@ -0,0 +1,26 @@
+warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/closure-origin-struct-diagnostics.rs:1:12
+   |
+LL | #![feature(capture_disjoint_fields)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
+
+error[E0382]: use of moved value: `hello`
+  --> $DIR/closure-origin-struct-diagnostics.rs:24:13
+   |
+LL |     let b = hello;
+   |             ----- value moved here
+LL |     let c = hello;
+   |             ^^^^^ value used here after move
+   |
+note: closure cannot be moved more than once as it is not `Copy` due to moving the variable `x.y.a` out of its environment
+  --> $DIR/closure-origin-struct-diagnostics.rs:20:9
+   |
+LL |         x.y.a += 1;
+   |         ^^^^^
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.rs
new file mode 100644
index 00000000000..6b078d2329c
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.rs
@@ -0,0 +1,16 @@
+#![feature(capture_disjoint_fields)]
+//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+//~| `#[warn(incomplete_features)]` on by default
+//~| see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+
+// Check that precise paths are being reported back in the error message.
+
+fn main() {
+    let mut x = (5, 0);
+    let hello = || {
+        x.0 += 1;
+    };
+
+    let b = hello;
+    let c = hello; //~ ERROR use of moved value: `hello` [E0382]
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.stderr
new file mode 100644
index 00000000000..716728e96ec
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.stderr
@@ -0,0 +1,26 @@
+warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/closure-origin-tuple-diagnostics-1.rs:1:12
+   |
+LL | #![feature(capture_disjoint_fields)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
+
+error[E0382]: use of moved value: `hello`
+  --> $DIR/closure-origin-tuple-diagnostics-1.rs:15:13
+   |
+LL |     let b = hello;
+   |             ----- value moved here
+LL |     let c = hello;
+   |             ^^^^^ value used here after move
+   |
+note: closure cannot be moved more than once as it is not `Copy` due to moving the variable `x.0` out of its environment
+  --> $DIR/closure-origin-tuple-diagnostics-1.rs:11:9
+   |
+LL |         x.0 += 1;
+   |         ^^^
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.rs
new file mode 100644
index 00000000000..0638db60769
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.rs
@@ -0,0 +1,15 @@
+#![feature(capture_disjoint_fields)]
+//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+//~| `#[warn(incomplete_features)]` on by default
+//~| see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+struct S(String, String);
+
+fn expect_fn<F: Fn()>(_f: F) {}
+
+fn main() {
+    let s = S(format!("s"), format!("s"));
+    let c = || { //~ ERROR expected a closure that implements the `Fn`
+        let s = s.1;
+    };
+    expect_fn(c);
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr
new file mode 100644
index 00000000000..77eb2a94ffb
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr
@@ -0,0 +1,23 @@
+warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/closure-origin-tuple-diagnostics.rs:1:12
+   |
+LL | #![feature(capture_disjoint_fields)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
+
+error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
+  --> $DIR/closure-origin-tuple-diagnostics.rs:11:13
+   |
+LL |     let c = || {
+   |             ^^ this closure implements `FnOnce`, not `Fn`
+LL |         let s = s.1;
+   |                 --- closure is `FnOnce` because it moves the variable `s.1` out of its environment
+LL |     };
+LL |     expect_fn(c);
+   |     --------- the requirement to implement `Fn` derives from here
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0525`.
diff --git a/src/test/ui/const-generics/late-bound-vars/in_closure.rs b/src/test/ui/const-generics/late-bound-vars/in_closure.rs
new file mode 100644
index 00000000000..0aaeaffb4cb
--- /dev/null
+++ b/src/test/ui/const-generics/late-bound-vars/in_closure.rs
@@ -0,0 +1,18 @@
+// run-pass
+#![feature(const_generics)]
+#![allow(incomplete_features)]
+
+const fn inner<'a>() -> usize where &'a (): Sized {
+    3
+}
+
+fn test<'a>() {
+    let _ = || {
+        let _: [u8; inner::<'a>()];
+        let _ = [0; inner::<'a>()];
+    };
+}
+
+fn main() {
+    test();
+}
diff --git a/src/test/ui/const-generics/late-bound-vars/simple.rs b/src/test/ui/const-generics/late-bound-vars/simple.rs
new file mode 100644
index 00000000000..2c411a3bdc5
--- /dev/null
+++ b/src/test/ui/const-generics/late-bound-vars/simple.rs
@@ -0,0 +1,16 @@
+// run-pass
+#![feature(const_generics)]
+#![allow(incomplete_features)]
+
+const fn inner<'a>() -> usize where &'a (): Sized {
+    3
+}
+
+fn test<'a>() {
+    let _: [u8; inner::<'a>()];
+    let _ = [0; inner::<'a>()];
+}
+
+fn main() {
+    test();
+}
diff --git a/src/test/ui/hygiene/traits-in-scope.rs b/src/test/ui/hygiene/traits-in-scope.rs
new file mode 100644
index 00000000000..548bb226b71
--- /dev/null
+++ b/src/test/ui/hygiene/traits-in-scope.rs
@@ -0,0 +1,53 @@
+// Macros with def-site hygiene still bring traits into scope.
+// It is not clear whether this is desirable behavior or not.
+// It is also not clear how to prevent it if it is not desirable.
+
+// check-pass
+
+#![feature(decl_macro)]
+#![feature(trait_alias)]
+
+mod traits {
+    pub trait Trait1 {
+        fn simple_import(&self) {}
+    }
+    pub trait Trait2 {
+        fn renamed_import(&self) {}
+    }
+    pub trait Trait3 {
+        fn underscore_import(&self) {}
+    }
+    pub trait Trait4 {
+        fn trait_alias(&self) {}
+    }
+
+    impl Trait1 for () {}
+    impl Trait2 for () {}
+    impl Trait3 for () {}
+    impl Trait4 for () {}
+}
+
+macro m1() {
+    use traits::Trait1;
+}
+macro m2() {
+    use traits::Trait2 as Alias;
+}
+macro m3() {
+    use traits::Trait3 as _;
+}
+macro m4() {
+    trait Alias = traits::Trait4;
+}
+
+fn main() {
+    m1!();
+    m2!();
+    m3!();
+    m4!();
+
+    ().simple_import();
+    ().renamed_import();
+    ().underscore_import();
+    ().trait_alias();
+}
diff --git a/src/test/ui/macros/vec-macro-in-pattern.rs b/src/test/ui/macros/vec-macro-in-pattern.rs
new file mode 100644
index 00000000000..ce4298b8bb3
--- /dev/null
+++ b/src/test/ui/macros/vec-macro-in-pattern.rs
@@ -0,0 +1,10 @@
+// This is a regression test for #61933
+// Verify that the vec![] macro may not be used in patterns
+// and that the resulting diagnostic is actually helpful.
+
+fn main() {
+    match Some(vec![42]) {
+        Some(vec![43]) => {} //~ ERROR arbitrary expressions aren't allowed in patterns
+        _ => {}
+    }
+}
diff --git a/src/test/ui/macros/vec-macro-in-pattern.stderr b/src/test/ui/macros/vec-macro-in-pattern.stderr
new file mode 100644
index 00000000000..3dabebfdaa2
--- /dev/null
+++ b/src/test/ui/macros/vec-macro-in-pattern.stderr
@@ -0,0 +1,10 @@
+error: arbitrary expressions aren't allowed in patterns
+  --> $DIR/vec-macro-in-pattern.rs:7:14
+   |
+LL |         Some(vec![43]) => {}
+   |              ^^^^^^^^
+   |
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs b/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs
index 142efb3c6cd..5f45f6892d2 100644
--- a/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs
+++ b/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs
@@ -1,5 +1,5 @@
+// edition:2018
 // aux-build:builtin-attrs.rs
-
 #![feature(decl_macro)] //~ ERROR `feature` is ambiguous
 
 extern crate builtin_attrs;
@@ -31,3 +31,7 @@ fn main() {
     Bench;
     NonExistent; //~ ERROR cannot find value `NonExistent` in this scope
 }
+
+use deny as allow;
+#[allow(unused)] //~ ERROR `allow` is ambiguous (built-in attribute vs any other name)
+fn builtin_renamed() {}
diff --git a/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr b/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr
index 276ee1cfd35..dfd60dc92cc 100644
--- a/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr
+++ b/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr
@@ -60,6 +60,20 @@ LL | use builtin_attrs::*;
    |     ^^^^^^^^^^^^^^^^
    = help: use `crate::repr` to refer to this attribute macro unambiguously
 
+error[E0659]: `allow` is ambiguous (built-in attribute vs any other name)
+  --> $DIR/ambiguous-builtin-attrs.rs:36:3
+   |
+LL | #[allow(unused)]
+   |   ^^^^^ ambiguous name
+   |
+   = note: `allow` could refer to a built-in attribute
+note: `allow` could also refer to the built-in attribute imported here
+  --> $DIR/ambiguous-builtin-attrs.rs:35:5
+   |
+LL | use deny as allow;
+   |     ^^^^^^^^^^^^^
+   = help: use `crate::allow` to refer to this built-in attribute unambiguously
+
 error[E0659]: `feature` is ambiguous (built-in attribute vs any other name)
   --> $DIR/ambiguous-builtin-attrs.rs:3:4
    |
@@ -80,7 +94,7 @@ error[E0517]: attribute should be applied to a struct, enum, or union
 LL | fn non_macro_expanded_location<#[repr(C)] T>() {
    |                                       ^   - not a struct, enum, or union
 
-error: aborting due to 7 previous errors
+error: aborting due to 8 previous errors
 
 Some errors have detailed explanations: E0425, E0517, E0659.
 For more information about an error, try `rustc --explain E0425`.
diff --git a/src/test/ui/suggestions/vec-macro-in-pattern.fixed b/src/test/ui/suggestions/vec-macro-in-pattern.fixed
deleted file mode 100644
index e1695d6820a..00000000000
--- a/src/test/ui/suggestions/vec-macro-in-pattern.fixed
+++ /dev/null
@@ -1,8 +0,0 @@
-// run-rustfix
-fn main() {
-    // everything after `.as_ref` should be suggested
-    match Some(vec![3]).as_ref().map(|v| v.as_slice()) {
-        Some([_x]) => (), //~ ERROR unexpected `(` after qualified path
-        _ => (),
-    }
-}
diff --git a/src/test/ui/suggestions/vec-macro-in-pattern.rs b/src/test/ui/suggestions/vec-macro-in-pattern.rs
deleted file mode 100644
index 4843629fbcf..00000000000
--- a/src/test/ui/suggestions/vec-macro-in-pattern.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-// run-rustfix
-fn main() {
-    // everything after `.as_ref` should be suggested
-    match Some(vec![3]).as_ref().map(|v| v.as_slice()) {
-        Some(vec![_x]) => (), //~ ERROR unexpected `(` after qualified path
-        _ => (),
-    }
-}
diff --git a/src/test/ui/suggestions/vec-macro-in-pattern.stderr b/src/test/ui/suggestions/vec-macro-in-pattern.stderr
deleted file mode 100644
index f9d0464ac88..00000000000
--- a/src/test/ui/suggestions/vec-macro-in-pattern.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error: unexpected `(` after qualified path
-  --> $DIR/vec-macro-in-pattern.rs:5:14
-   |
-LL |         Some(vec![_x]) => (),
-   |              ^^^^^^^^
-   |              |
-   |              unexpected `(` after qualified path
-   |              the qualified path
-   |              in this macro invocation
-   |              help: use a slice pattern here instead: `[_x]`
-   |
-   = help: for more information, see https://doc.rust-lang.org/edition-guide/rust-2018/slice-patterns.html
-   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/type/ascription/issue-47666.stderr b/src/test/ui/type/ascription/issue-47666.stderr
index ba393ff1a20..755eec23c2e 100644
--- a/src/test/ui/type/ascription/issue-47666.stderr
+++ b/src/test/ui/type/ascription/issue-47666.stderr
@@ -1,4 +1,4 @@
-error: expected type, found reserved keyword `box`
+error: expected type, found `<[_]>::into_vec(box [0, 1])`
   --> $DIR/issue-47666.rs:3:25
    |
 LL |     let _ = Option:Some(vec![0, 1]);
diff --git a/src/test/ui/underscore-imports/hygiene.rs b/src/test/ui/underscore-imports/hygiene.rs
index a254f6eaa59..c4db6524538 100644
--- a/src/test/ui/underscore-imports/hygiene.rs
+++ b/src/test/ui/underscore-imports/hygiene.rs
@@ -1,5 +1,6 @@
-// Make sure that underscore imports have the same hygiene considerations as
-// other imports.
+// Make sure that underscore imports have the same hygiene considerations as other imports.
+
+// check-pass
 
 #![feature(decl_macro)]
 
@@ -7,7 +8,6 @@ mod x {
     pub use std::ops::Deref as _;
 }
 
-
 macro glob_import() {
     pub use crate::x::*;
 }
@@ -35,6 +35,6 @@ fn main() {
     use crate::z::*;
     glob_import!();
     underscore_import!();
-    (&()).deref();              //~ ERROR no method named `deref`
-    (&mut ()).deref_mut();      //~ ERROR no method named `deref_mut`
+    (&()).deref();
+    (&mut ()).deref_mut();
 }
diff --git a/src/test/ui/underscore-imports/hygiene.stderr b/src/test/ui/underscore-imports/hygiene.stderr
deleted file mode 100644
index 29836137860..00000000000
--- a/src/test/ui/underscore-imports/hygiene.stderr
+++ /dev/null
@@ -1,27 +0,0 @@
-error[E0599]: no method named `deref` found for reference `&()` in the current scope
-  --> $DIR/hygiene.rs:38:11
-   |
-LL |     (&()).deref();
-   |           ^^^^^ method not found in `&()`
-   |
-   = help: items from traits can only be used if the trait is in scope
-help: the following trait is implemented but not in scope; perhaps add a `use` for it:
-   |
-LL | use std::ops::Deref;
-   |
-
-error[E0599]: no method named `deref_mut` found for mutable reference `&mut ()` in the current scope
-  --> $DIR/hygiene.rs:39:15
-   |
-LL |     (&mut ()).deref_mut();
-   |               ^^^^^^^^^ method not found in `&mut ()`
-   |
-   = help: items from traits can only be used if the trait is in scope
-help: the following trait is implemented but not in scope; perhaps add a `use` for it:
-   |
-LL | use std::ops::DerefMut;
-   |
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0599`.