about summary refs log tree commit diff
path: root/compiler/rustc_resolve
diff options
context:
space:
mode:
authorMatthew Kelly <matthew.kelly2@gmail.com>2022-09-26 19:59:52 -0400
committerMatthew Kelly <matthew.kelly2@gmail.com>2022-09-26 19:59:52 -0400
commit24aab524cbafec7ff8c7cd54ba4f6fb18216c623 (patch)
treeb0fd92c686ed3fe2b3a5a010c0dc32a6a54d3ea1 /compiler/rustc_resolve
parenteda2a401457ba645a32bdc5b9e7e90214e3e4e24 (diff)
parent8b705839cd656d202e920efa8769cbe43a5ee269 (diff)
Merge remote-tracking branch 'origin/master' into mpk/add-long-error-message-for-E0311
Diffstat (limited to 'compiler/rustc_resolve')
-rw-r--r--compiler/rustc_resolve/src/access_levels.rs171
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs50
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs13
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs3
-rw-r--r--compiler/rustc_resolve/src/ident.rs33
-rw-r--r--compiler/rustc_resolve/src/imports.rs60
-rw-r--r--compiler/rustc_resolve/src/late.rs122
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs33
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs105
-rw-r--r--compiler/rustc_resolve/src/lib.rs69
-rw-r--r--compiler/rustc_resolve/src/macros.rs2
11 files changed, 311 insertions, 350 deletions
diff --git a/compiler/rustc_resolve/src/access_levels.rs b/compiler/rustc_resolve/src/access_levels.rs
index 3fba923d9fd..d806441716f 100644
--- a/compiler/rustc_resolve/src/access_levels.rs
+++ b/compiler/rustc_resolve/src/access_levels.rs
@@ -1,25 +1,20 @@
+use crate::NameBinding;
+use crate::NameBindingKind;
+use crate::Resolver;
 use rustc_ast::ast;
 use rustc_ast::visit;
 use rustc_ast::visit::Visitor;
 use rustc_ast::Crate;
 use rustc_ast::EnumDef;
-use rustc_ast::ForeignMod;
 use rustc_ast::NodeId;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::def_id::CRATE_DEF_ID;
 use rustc_middle::middle::privacy::AccessLevel;
-use rustc_middle::ty::Visibility;
+use rustc_middle::ty::DefIdTree;
 use rustc_span::sym;
 
-use crate::imports::ImportKind;
-use crate::BindingKey;
-use crate::NameBinding;
-use crate::NameBindingKind;
-use crate::Resolver;
-
 pub struct AccessLevelsVisitor<'r, 'a> {
     r: &'r mut Resolver<'a>,
-    prev_level: Option<AccessLevel>,
     changed: bool,
 }
 
@@ -28,72 +23,61 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
     /// For now, this doesn't resolve macros (FIXME) and cannot resolve Impl, as we
     /// need access to a TyCtxt for that.
     pub fn compute_access_levels<'c>(r: &'r mut Resolver<'a>, krate: &'c Crate) {
-        let mut visitor =
-            AccessLevelsVisitor { r, changed: false, prev_level: Some(AccessLevel::Public) };
+        let mut visitor = AccessLevelsVisitor { r, changed: false };
 
         visitor.set_access_level_def_id(CRATE_DEF_ID, Some(AccessLevel::Public));
-        visitor.set_exports_access_level(CRATE_DEF_ID);
+        visitor.set_bindings_access_level(CRATE_DEF_ID);
 
         while visitor.changed {
             visitor.reset();
             visit::walk_crate(&mut visitor, krate);
         }
 
-        tracing::info!("resolve::access_levels: {:#?}", r.access_levels);
+        info!("resolve::access_levels: {:#?}", r.access_levels);
     }
 
     fn reset(&mut self) {
         self.changed = false;
-        self.prev_level = Some(AccessLevel::Public);
     }
 
-    /// Update the access level of the exports of the given module accordingly. The module access
+    /// Update the access level of the bindings in the given module accordingly. The module access
     /// level has to be Exported or Public.
     /// This will also follow `use` chains (see PrivacyVisitor::set_import_binding_access_level).
-    fn set_exports_access_level(&mut self, module_id: LocalDefId) {
+    fn set_bindings_access_level(&mut self, module_id: LocalDefId) {
         assert!(self.r.module_map.contains_key(&&module_id.to_def_id()));
-
+        let module_level = self.r.access_levels.get_access_level(module_id);
+        if !module_level.is_some() {
+            return;
+        }
         // Set the given binding access level to `AccessLevel::Public` and
         // sets the rest of the `use` chain to `AccessLevel::Exported` until
         // we hit the actual exported item.
         let set_import_binding_access_level =
-            |this: &mut Self, mut binding: &NameBinding<'a>, mut access_level| {
+            |this: &mut Self, mut binding: &NameBinding<'a>, mut access_level, ns| {
                 while let NameBindingKind::Import { binding: nested_binding, import, .. } =
                     binding.kind
                 {
-                    this.set_access_level(import.id, access_level);
-                    if let ImportKind::Single { additional_ids, .. } = import.kind {
-                        this.set_access_level(additional_ids.0, access_level);
-                        this.set_access_level(additional_ids.1, access_level);
-                    }
+                    this.set_access_level(this.r.import_id_for_ns(import, ns), access_level);
 
                     access_level = Some(AccessLevel::Exported);
                     binding = nested_binding;
                 }
             };
 
-        let module_level = self.r.access_levels.map.get(&module_id).copied();
-        assert!(module_level >= Some(AccessLevel::Exported));
-
-        if let Some(exports) = self.r.reexport_map.get(&module_id) {
-            let pub_exports = exports
-                .iter()
-                .filter(|ex| ex.vis == Visibility::Public)
-                .cloned()
-                .collect::<Vec<_>>();
-
-            let module = self.r.get_module(module_id.to_def_id()).unwrap();
-            for export in pub_exports.into_iter() {
-                if let Some(export_def_id) = export.res.opt_def_id().and_then(|id| id.as_local()) {
-                    self.set_access_level_def_id(export_def_id, Some(AccessLevel::Exported));
-                }
-
-                if let Some(ns) = export.res.ns() {
-                    let key = BindingKey { ident: export.ident, ns, disambiguator: 0 };
-                    let name_res = self.r.resolution(module, key);
-                    if let Some(binding) = name_res.borrow().binding() {
-                        set_import_binding_access_level(self, binding, module_level)
-                    }
+        let module = self.r.get_module(module_id.to_def_id()).unwrap();
+        let resolutions = self.r.resolutions(module);
+
+        for (key, name_resolution) in resolutions.borrow().iter() {
+            if let Some(binding) = name_resolution.borrow().binding() && binding.vis.is_public() && !binding.is_ambiguity() {
+                let access_level = match binding.is_import() {
+                    true => {
+                        set_import_binding_access_level(self, binding, module_level, key.ns);
+                        Some(AccessLevel::Exported)
+                    },
+                    false => module_level,
+                };
+                if let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) {
+                    self.set_access_level_def_id(def_id, access_level);
                 }
             }
         }
@@ -114,9 +98,9 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
         def_id: LocalDefId,
         access_level: Option<AccessLevel>,
     ) -> Option<AccessLevel> {
-        let old_level = self.r.access_levels.map.get(&def_id).copied();
+        let old_level = self.r.access_levels.get_access_level(def_id);
         if old_level < access_level {
-            self.r.access_levels.map.insert(def_id, access_level.unwrap());
+            self.r.access_levels.set_access_level(def_id, access_level.unwrap());
             self.changed = true;
             access_level
         } else {
@@ -127,97 +111,59 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
 
 impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> {
     fn visit_item(&mut self, item: &'ast ast::Item) {
-        let inherited_item_level = match item.kind {
+        let def_id = self.r.local_def_id(item.id);
+        // Set access level of nested items.
+        // If it's a mod, also make the visitor walk all of its items
+        match item.kind {
             // Resolved in rustc_privacy when types are available
             ast::ItemKind::Impl(..) => return,
 
-            // Only exported `macro_rules!` items are public, but they always are
-            ast::ItemKind::MacroDef(ref macro_def) if macro_def.macro_rules => {
-                let is_macro_export =
-                    item.attrs.iter().any(|attr| attr.has_name(sym::macro_export));
-                if is_macro_export { Some(AccessLevel::Public) } else { None }
-            }
-
-            // Foreign modules inherit level from parents.
-            ast::ItemKind::ForeignMod(..) => self.prev_level,
-
-            // Other `pub` items inherit levels from parents.
-            ast::ItemKind::ExternCrate(..)
-            | ast::ItemKind::Use(..)
-            | ast::ItemKind::Static(..)
-            | ast::ItemKind::Const(..)
-            | ast::ItemKind::Fn(..)
-            | ast::ItemKind::Mod(..)
-            | ast::ItemKind::GlobalAsm(..)
-            | ast::ItemKind::TyAlias(..)
-            | ast::ItemKind::Enum(..)
-            | ast::ItemKind::Struct(..)
-            | ast::ItemKind::Union(..)
-            | ast::ItemKind::Trait(..)
-            | ast::ItemKind::TraitAlias(..)
-            | ast::ItemKind::MacroDef(..) => {
-                if item.vis.kind.is_pub() {
-                    self.prev_level
-                } else {
-                    None
-                }
-            }
-
             // Should be unreachable at this stage
             ast::ItemKind::MacCall(..) => panic!(
                 "ast::ItemKind::MacCall encountered, this should not anymore appear at this stage"
             ),
-        };
 
-        let access_level = self.set_access_level(item.id, inherited_item_level);
+            // Foreign modules inherit level from parents.
+            ast::ItemKind::ForeignMod(..) => {
+                let parent_level =
+                    self.r.access_levels.get_access_level(self.r.local_parent(def_id));
+                self.set_access_level(item.id, parent_level);
+            }
 
-        // Set access level of nested items.
-        // If it's a mod, also make the visitor walk all of its items
-        match item.kind {
-            ast::ItemKind::Mod(..) => {
-                if access_level.is_some() {
-                    self.set_exports_access_level(self.r.local_def_id(item.id));
+            // Only exported `macro_rules!` items are public, but they always are
+            ast::ItemKind::MacroDef(ref macro_def) if macro_def.macro_rules => {
+                if item.attrs.iter().any(|attr| attr.has_name(sym::macro_export)) {
+                    self.set_access_level(item.id, Some(AccessLevel::Public));
                 }
+            }
 
-                let orig_level = std::mem::replace(&mut self.prev_level, access_level);
+            ast::ItemKind::Mod(..) => {
+                self.set_bindings_access_level(def_id);
                 visit::walk_item(self, item);
-                self.prev_level = orig_level;
             }
 
-            ast::ItemKind::ForeignMod(ForeignMod { ref items, .. }) => {
-                for nested in items {
-                    if nested.vis.kind.is_pub() {
-                        self.set_access_level(nested.id, access_level);
-                    }
-                }
-            }
             ast::ItemKind::Enum(EnumDef { ref variants }, _) => {
+                self.set_bindings_access_level(def_id);
                 for variant in variants {
-                    let variant_level = self.set_access_level(variant.id, access_level);
-                    if let Some(ctor_id) = variant.data.ctor_id() {
-                        self.set_access_level(ctor_id, access_level);
-                    }
-
+                    let variant_def_id = self.r.local_def_id(variant.id);
+                    let variant_level = self.r.access_levels.get_access_level(variant_def_id);
                     for field in variant.data.fields() {
                         self.set_access_level(field.id, variant_level);
                     }
                 }
             }
-            ast::ItemKind::Struct(ref def, _) | ast::ItemKind::Union(ref def, _) => {
-                if let Some(ctor_id) = def.ctor_id() {
-                    self.set_access_level(ctor_id, access_level);
-                }
 
+            ast::ItemKind::Struct(ref def, _) | ast::ItemKind::Union(ref def, _) => {
+                let inherited_level = self.r.access_levels.get_access_level(def_id);
                 for field in def.fields() {
                     if field.vis.kind.is_pub() {
-                        self.set_access_level(field.id, access_level);
+                        self.set_access_level(field.id, inherited_level);
                     }
                 }
             }
-            ast::ItemKind::Trait(ref trait_kind) => {
-                for nested in trait_kind.items.iter() {
-                    self.set_access_level(nested.id, access_level);
-                }
+
+            ast::ItemKind::Trait(..) => {
+                self.set_bindings_access_level(def_id);
             }
 
             ast::ItemKind::ExternCrate(..)
@@ -229,9 +175,6 @@ impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> {
             | ast::ItemKind::TraitAlias(..)
             | ast::ItemKind::MacroDef(..)
             | ast::ItemKind::Fn(..) => return,
-
-            // Unreachable kinds
-            ast::ItemKind::Impl(..) | ast::ItemKind::MacCall(..) => unreachable!(),
         }
     }
 }
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 8f3b6009bd6..81b67b758f7 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -36,28 +36,29 @@ use rustc_span::Span;
 
 use std::cell::Cell;
 use std::ptr;
-use tracing::debug;
 
 type Res = def::Res<NodeId>;
 
-impl<'a> ToNameBinding<'a> for (Module<'a>, ty::Visibility, Span, LocalExpnId) {
+impl<'a, Id: Into<DefId>> ToNameBinding<'a>
+    for (Module<'a>, ty::Visibility<Id>, Span, LocalExpnId)
+{
     fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
         arenas.alloc_name_binding(NameBinding {
             kind: NameBindingKind::Module(self.0),
             ambiguity: None,
-            vis: self.1,
+            vis: self.1.to_def_id(),
             span: self.2,
             expansion: self.3,
         })
     }
 }
 
-impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, LocalExpnId) {
+impl<'a, Id: Into<DefId>> ToNameBinding<'a> for (Res, ty::Visibility<Id>, Span, LocalExpnId) {
     fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
         arenas.alloc_name_binding(NameBinding {
             kind: NameBindingKind::Res(self.0, false),
             ambiguity: None,
-            vis: self.1,
+            vis: self.1.to_def_id(),
             span: self.2,
             expansion: self.3,
         })
@@ -71,7 +72,7 @@ impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, LocalExpnId, IsMacroE
         arenas.alloc_name_binding(NameBinding {
             kind: NameBindingKind::Res(self.0, true),
             ambiguity: None,
-            vis: self.1,
+            vis: self.1.to_def_id(),
             span: self.2,
             expansion: self.3,
         })
@@ -261,7 +262,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                         self.r.visibilities[&def_id.expect_local()]
                     }
                     // Otherwise, the visibility is restricted to the nearest parent `mod` item.
-                    _ => ty::Visibility::Restricted(self.parent_scope.module.nearest_parent_mod()),
+                    _ => ty::Visibility::Restricted(
+                        self.parent_scope.module.nearest_parent_mod().expect_local(),
+                    ),
                 })
             }
             ast::VisibilityKind::Restricted { ref path, id, .. } => {
@@ -312,7 +315,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                             } else {
                                 let vis = ty::Visibility::Restricted(res.def_id());
                                 if self.r.is_accessible_from(vis, parent_scope.module) {
-                                    Ok(vis)
+                                    Ok(vis.expect_local())
                                 } else {
                                     Err(VisResolutionError::AncestorOnly(path.span))
                                 }
@@ -650,7 +653,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                         true,
                         // The whole `use` item
                         item,
-                        ty::Visibility::Restricted(self.parent_scope.module.nearest_parent_mod()),
+                        ty::Visibility::Restricted(
+                            self.parent_scope.module.nearest_parent_mod().expect_local(),
+                        ),
                         root_span,
                     );
                 }
@@ -766,10 +771,10 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                 if let Some(ctor_node_id) = vdata.ctor_id() {
                     // If the structure is marked as non_exhaustive then lower the visibility
                     // to within the crate.
-                    let mut ctor_vis = if vis == ty::Visibility::Public
+                    let mut ctor_vis = if vis.is_public()
                         && self.r.session.contains_name(&item.attrs, sym::non_exhaustive)
                     {
-                        ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id())
+                        ty::Visibility::Restricted(CRATE_DEF_ID)
                     } else {
                         vis
                     };
@@ -786,7 +791,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                         if ctor_vis.is_at_least(field_vis, &*self.r) {
                             ctor_vis = field_vis;
                         }
-                        ret_fields.push(field_vis);
+                        ret_fields.push(field_vis.to_def_id());
                     }
                     let ctor_def_id = self.r.local_def_id(ctor_node_id);
                     let ctor_res = Res::Def(
@@ -796,7 +801,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                     self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion));
                     self.r.visibilities.insert(ctor_def_id, ctor_vis);
 
-                    self.r.struct_constructors.insert(def_id, (ctor_res, ctor_vis, ret_fields));
+                    self.r
+                        .struct_constructors
+                        .insert(def_id, (ctor_res, ctor_vis.to_def_id(), ret_fields));
                 }
             }
 
@@ -868,8 +875,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
         }
         .map(|module| {
             let used = self.process_macro_use_imports(item, module);
-            let binding =
-                (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.r.arenas);
+            let vis = ty::Visibility::<LocalDefId>::Public;
+            let binding = (module, vis, sp, expansion).to_name_binding(self.r.arenas);
             (used, Some(ModuleOrUniformRoot::Module(module)), binding)
         })
         .unwrap_or((true, None, self.r.dummy_binding));
@@ -965,6 +972,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                 | DefKind::TyAlias
                 | DefKind::ForeignTy
                 | DefKind::OpaqueTy
+                | DefKind::ImplTraitPlaceholder
                 | DefKind::TraitAlias
                 | DefKind::AssocTy,
                 _,
@@ -1030,7 +1038,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                 self.insert_field_names(def_id, field_names);
             }
             Res::Def(DefKind::AssocFn, def_id) => {
-                if cstore.fn_has_self_parameter_untracked(def_id) {
+                if cstore.fn_has_self_parameter_untracked(def_id, self.r.session) {
                     self.r.has_self.insert(def_id);
                 }
             }
@@ -1118,7 +1126,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                 root_span: span,
                 span,
                 module_path: Vec::new(),
-                vis: Cell::new(Some(ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id()))),
+                vis: Cell::new(Some(ty::Visibility::Restricted(CRATE_DEF_ID))),
                 used: Cell::new(false),
             })
         };
@@ -1264,7 +1272,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
             let vis = if is_macro_export {
                 ty::Visibility::Public
             } else {
-                ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id())
+                ty::Visibility::Restricted(CRATE_DEF_ID)
             };
             let binding = (res, vis, span, expansion).to_name_binding(self.r.arenas);
             self.r.set_binding_parent_module(binding, parent_scope.module);
@@ -1295,7 +1303,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                 }
                 _ => self.resolve_visibility(&item.vis),
             };
-            if vis != ty::Visibility::Public {
+            if !vis.is_public() {
                 self.insert_unused_macro(ident, def_id, item.id, &rule_spans);
             }
             self.r.define(module, ident, MacroNS, (res, vis, span, expansion));
@@ -1508,10 +1516,10 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
         self.r.visibilities.insert(def_id, vis);
 
         // If the variant is marked as non_exhaustive then lower the visibility to within the crate.
-        let ctor_vis = if vis == ty::Visibility::Public
+        let ctor_vis = if vis.is_public()
             && self.r.session.contains_name(&variant.attrs, sym::non_exhaustive)
         {
-            ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id())
+            ty::Visibility::Restricted(CRATE_DEF_ID)
         } else {
             vis
         };
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index 66641fb2cb2..7e83f2a7221 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -1,6 +1,5 @@
 use crate::{ImplTraitContext, Resolver};
 use rustc_ast::visit::{self, FnKind};
-use rustc_ast::walk_list;
 use rustc_ast::*;
 use rustc_expand::expand::AstFragment;
 use rustc_hir::def_id::LocalDefId;
@@ -8,7 +7,6 @@ use rustc_hir::definitions::*;
 use rustc_span::hygiene::LocalExpnId;
 use rustc_span::symbol::sym;
 use rustc_span::Span;
-use tracing::debug;
 
 pub(crate) fn collect_definitions(
     resolver: &mut Resolver<'_>,
@@ -149,13 +147,18 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> {
                 self.with_parent(return_impl_trait_id, |this| {
                     this.visit_fn_ret_ty(&sig.decl.output)
                 });
-                let closure_def = self.create_def(closure_id, DefPathData::ClosureExpr, span);
-                self.with_parent(closure_def, |this| walk_list!(this, visit_block, body));
+                // If this async fn has no body (i.e. it's an async fn signature in a trait)
+                // then the closure_def will never be used, and we should avoid generating a
+                // def-id for it.
+                if let Some(body) = body {
+                    let closure_def = self.create_def(closure_id, DefPathData::ClosureExpr, span);
+                    self.with_parent(closure_def, |this| this.visit_block(body));
+                }
                 return;
             }
         }
 
-        visit::walk_fn(self, fn_kind, span);
+        visit::walk_fn(self, fn_kind);
     }
 
     fn visit_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId, _nested: bool) {
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 2d15b1b0a1b..ab71fa0bc1d 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -25,7 +25,6 @@ use rustc_span::lev_distance::find_best_match_for_name;
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{BytePos, Span};
-use tracing::debug;
 
 use crate::imports::{Import, ImportKind, ImportResolver};
 use crate::late::{PatternSource, Rib};
@@ -1394,7 +1393,7 @@ impl<'a> Resolver<'a> {
 
         // If only some candidates are accessible, take just them
         if !candidates.iter().all(|v: &ImportSuggestion| !v.accessible) {
-            candidates = candidates.into_iter().filter(|x| x.accessible).collect();
+            candidates.retain(|x| x.accessible)
         }
 
         candidates
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 2afba94d793..2287aa1eb25 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -6,6 +6,7 @@ use rustc_middle::bug;
 use rustc_middle::ty;
 use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK;
 use rustc_session::lint::BuiltinLintDiagnostics;
+use rustc_span::def_id::LocalDefId;
 use rustc_span::edition::Edition;
 use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext};
 use rustc_span::symbol::{kw, Ident};
@@ -26,6 +27,8 @@ use Determinacy::*;
 use Namespace::*;
 use RibKind::*;
 
+type Visibility = ty::Visibility<LocalDefId>;
+
 impl<'a> Resolver<'a> {
     /// A generic scope visitor.
     /// Visits scopes in order to resolve some identifier in them or perform other actions.
@@ -273,7 +276,7 @@ impl<'a> Resolver<'a> {
     ///
     /// Invariant: This must only be called during main resolution, not during
     /// import resolution.
-    #[tracing::instrument(level = "debug", skip(self, ribs))]
+    #[instrument(level = "debug", skip(self, ribs))]
     pub(crate) fn resolve_ident_in_lexical_scope(
         &mut self,
         mut ident: Ident,
@@ -367,7 +370,7 @@ impl<'a> Resolver<'a> {
     /// expansion and import resolution (perhaps they can be merged in the future).
     /// The function is used for resolving initial segments of macro paths (e.g., `foo` in
     /// `foo::bar!(); or `foo!();`) and also for import paths on 2018 edition.
-    #[tracing::instrument(level = "debug", skip(self, scope_set))]
+    #[instrument(level = "debug", skip(self, scope_set))]
     pub(crate) fn early_resolve_ident_in_lexical_scope(
         &mut self,
         orig_ident: Ident,
@@ -424,8 +427,7 @@ impl<'a> Resolver<'a> {
                 let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt));
                 let ok = |res, span, arenas| {
                     Ok((
-                        (res, ty::Visibility::Public, span, LocalExpnId::ROOT)
-                            .to_name_binding(arenas),
+                        (res, Visibility::Public, span, LocalExpnId::ROOT).to_name_binding(arenas),
                         Flags::empty(),
                     ))
                 };
@@ -438,7 +440,7 @@ impl<'a> Resolver<'a> {
                         {
                             let binding = (
                                 Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
-                                ty::Visibility::Public,
+                                Visibility::Public,
                                 attr.span,
                                 expn_id,
                             )
@@ -708,7 +710,7 @@ impl<'a> Resolver<'a> {
         Err(Determinacy::determined(determinacy == Determinacy::Determined || force))
     }
 
-    #[tracing::instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self))]
     pub(crate) fn maybe_resolve_ident_in_module(
         &mut self,
         module: ModuleOrUniformRoot<'a>,
@@ -720,7 +722,7 @@ impl<'a> Resolver<'a> {
             .map_err(|(determinacy, _)| determinacy)
     }
 
-    #[tracing::instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self))]
     pub(crate) fn resolve_ident_in_module(
         &mut self,
         module: ModuleOrUniformRoot<'a>,
@@ -734,7 +736,7 @@ impl<'a> Resolver<'a> {
             .map_err(|(determinacy, _)| determinacy)
     }
 
-    #[tracing::instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn resolve_ident_in_module_ext(
         &mut self,
         module: ModuleOrUniformRoot<'a>,
@@ -772,7 +774,7 @@ impl<'a> Resolver<'a> {
         )
     }
 
-    #[tracing::instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn resolve_ident_in_module_unadjusted(
         &mut self,
         module: ModuleOrUniformRoot<'a>,
@@ -796,7 +798,7 @@ impl<'a> Resolver<'a> {
 
     /// Attempts to resolve `ident` in namespaces `ns` of `module`.
     /// Invariant: if `finalize` is `Some`, expansion and import resolution must be complete.
-    #[tracing::instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn resolve_ident_in_module_unadjusted_ext(
         &mut self,
         module: ModuleOrUniformRoot<'a>,
@@ -841,9 +843,8 @@ impl<'a> Resolver<'a> {
                 if ns == TypeNS {
                     if ident.name == kw::Crate || ident.name == kw::DollarCrate {
                         let module = self.resolve_crate_root(ident);
-                        let binding =
-                            (module, ty::Visibility::Public, module.span, LocalExpnId::ROOT)
-                                .to_name_binding(self.arenas);
+                        let binding = (module, Visibility::Public, module.span, LocalExpnId::ROOT)
+                            .to_name_binding(self.arenas);
                         return Ok(binding);
                     } else if ident.name == kw::Super || ident.name == kw::SelfLower {
                         // FIXME: Implement these with renaming requirements so that e.g.
@@ -1059,7 +1060,7 @@ impl<'a> Resolver<'a> {
     }
 
     /// Validate a local resolution (from ribs).
-    #[tracing::instrument(level = "debug", skip(self, all_ribs))]
+    #[instrument(level = "debug", skip(self, all_ribs))]
     fn validate_res_from_ribs(
         &mut self,
         rib_index: usize,
@@ -1294,7 +1295,7 @@ impl<'a> Resolver<'a> {
         res
     }
 
-    #[tracing::instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self))]
     pub(crate) fn maybe_resolve_path(
         &mut self,
         path: &[Segment],
@@ -1304,7 +1305,7 @@ impl<'a> Resolver<'a> {
         self.resolve_path_with_ribs(path, opt_ns, parent_scope, None, None, None)
     }
 
-    #[tracing::instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self))]
     pub(crate) fn resolve_path(
         &mut self,
         path: &[Segment],
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index c2491c6ebde..5bdb4274781 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -2,7 +2,7 @@
 
 use crate::diagnostics::Suggestion;
 use crate::Determinacy::{self, *};
-use crate::Namespace::{MacroNS, TypeNS};
+use crate::Namespace::{self, *};
 use crate::{module_to_string, names_to_string};
 use crate::{AmbiguityKind, BindingKey, ModuleKind, ResolutionError, Resolver, Segment};
 use crate::{Finalize, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet};
@@ -23,8 +23,6 @@ use rustc_span::lev_distance::find_best_match_for_name;
 use rustc_span::symbol::{kw, Ident, Symbol};
 use rustc_span::Span;
 
-use tracing::*;
-
 use std::cell::Cell;
 use std::{mem, ptr};
 
@@ -216,7 +214,7 @@ impl<'a> Resolver<'a> {
         binding: &'a NameBinding<'a>,
         import: &'a Import<'a>,
     ) -> &'a NameBinding<'a> {
-        let import_vis = import.expect_vis();
+        let import_vis = import.expect_vis().to_def_id();
         let vis = if binding.vis.is_at_least(import_vis, self)
             || pub_use_of_private_extern_crate_hack(import, binding)
         {
@@ -229,7 +227,7 @@ impl<'a> Resolver<'a> {
             if vis == import_vis
                 || max_vis.get().map_or(true, |max_vis| vis.is_at_least(max_vis, self))
             {
-                max_vis.set(Some(vis))
+                max_vis.set(Some(vis.expect_local()))
             }
         }
 
@@ -373,6 +371,31 @@ impl<'a> Resolver<'a> {
             self.used_imports.insert(import.id);
         }
     }
+
+    /// Take primary and additional node IDs from an import and select one that corresponds to the
+    /// given namespace. The logic must match the corresponding logic from `fn lower_use_tree` that
+    /// assigns resolutons to IDs.
+    pub(crate) fn import_id_for_ns(&self, import: &Import<'_>, ns: Namespace) -> NodeId {
+        if let ImportKind::Single { additional_ids: (id1, id2), .. } = import.kind {
+            if let Some(resolutions) = self.import_res_map.get(&import.id) {
+                assert!(resolutions[ns].is_some(), "incorrectly finalized import");
+                return match ns {
+                    TypeNS => import.id,
+                    ValueNS => match resolutions.type_ns {
+                        Some(_) => id1,
+                        None => import.id,
+                    },
+                    MacroNS => match (resolutions.type_ns, resolutions.value_ns) {
+                        (Some(_), Some(_)) => id2,
+                        (Some(_), None) | (None, Some(_)) => id1,
+                        (None, None) => import.id,
+                    },
+                };
+            }
+        }
+
+        import.id
+    }
 }
 
 /// An error that may be transformed into a diagnostic later. Used to combine multiple unresolved
@@ -1135,24 +1158,15 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
         if let Some(def_id) = module.opt_def_id() {
             let mut reexports = Vec::new();
 
-            module.for_each_child(self.r, |_, ident, _, binding| {
-                // FIXME: Consider changing the binding inserted by `#[macro_export] macro_rules`
-                // into the crate root to actual `NameBindingKind::Import`.
-                if binding.is_import()
-                    || matches!(binding.kind, NameBindingKind::Res(_, _is_macro_export @ true))
-                {
-                    let res = binding.res().expect_non_local();
-                    // Ambiguous imports are treated as errors at this point and are
-                    // not exposed to other crates (see #36837 for more details).
-                    if res != def::Res::Err && !binding.is_ambiguity() {
-                        reexports.push(ModChild {
-                            ident,
-                            res,
-                            vis: binding.vis,
-                            span: binding.span,
-                            macro_rules: false,
-                        });
-                    }
+            module.for_each_child(self.r, |this, ident, _, binding| {
+                if let Some(res) = this.is_reexport(binding) {
+                    reexports.push(ModChild {
+                        ident,
+                        res,
+                        vis: binding.vis,
+                        span: binding.span,
+                        macro_rules: false,
+                    });
                 }
             });
 
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 693ec86616e..558db003867 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -20,7 +20,7 @@ use rustc_errors::DiagnosticId;
 use rustc_hir::def::Namespace::{self, *};
 use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, PartialRes, PerNS};
 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
-use rustc_hir::{PrimTy, TraitCandidate};
+use rustc_hir::{BindingAnnotation, PrimTy, TraitCandidate};
 use rustc_middle::middle::resolve_lifetime::Set1;
 use rustc_middle::ty::DefIdTree;
 use rustc_middle::{bug, span_bug};
@@ -32,7 +32,6 @@ use smallvec::{smallvec, SmallVec};
 use rustc_span::source_map::{respan, Spanned};
 use std::collections::{hash_map::Entry, BTreeSet};
 use std::mem::{replace, take};
-use tracing::debug;
 
 mod diagnostics;
 pub(crate) mod lifetimes;
@@ -51,7 +50,7 @@ use diagnostics::{
 #[derive(Copy, Clone, Debug)]
 struct BindingInfo {
     span: Span,
-    binding_mode: BindingMode,
+    annotation: BindingAnnotation,
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
@@ -806,7 +805,12 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
                             sig.decl.has_self(),
                             sig.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)),
                             &sig.decl.output,
-                        )
+                        );
+
+                        this.record_lifetime_params_for_async(
+                            fn_id,
+                            sig.header.asyncness.opt_return_id(),
+                        );
                     },
                 );
                 return;
@@ -848,41 +852,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
                             },
                         );
 
-                        // Construct the list of in-scope lifetime parameters for async lowering.
-                        // We include all lifetime parameters, either named or "Fresh".
-                        // The order of those parameters does not matter, as long as it is
-                        // deterministic.
-                        if let Some(async_node_id) = async_node_id {
-                            let mut extra_lifetime_params = this
-                                .r
-                                .extra_lifetime_params_map
-                                .get(&fn_id)
-                                .cloned()
-                                .unwrap_or_default();
-                            for rib in this.lifetime_ribs.iter().rev() {
-                                extra_lifetime_params.extend(
-                                    rib.bindings
-                                        .iter()
-                                        .map(|(&ident, &(node_id, res))| (ident, node_id, res)),
-                                );
-                                match rib.kind {
-                                    LifetimeRibKind::Item => break,
-                                    LifetimeRibKind::AnonymousCreateParameter {
-                                        binder, ..
-                                    } => {
-                                        if let Some(earlier_fresh) =
-                                            this.r.extra_lifetime_params_map.get(&binder)
-                                        {
-                                            extra_lifetime_params.extend(earlier_fresh);
-                                        }
-                                    }
-                                    _ => {}
-                                }
-                            }
-                            this.r
-                                .extra_lifetime_params_map
-                                .insert(async_node_id, extra_lifetime_params);
-                        }
+                        this.record_lifetime_params_for_async(fn_id, async_node_id);
 
                         if let Some(body) = body {
                             // Ignore errors in function bodies if this is rustdoc
@@ -1031,7 +1001,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
         if let Some(ref gen_args) = constraint.gen_args {
             // Forbid anonymous lifetimes in GAT parameters until proper semantics are decided.
             self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
-                this.visit_generic_args(gen_args.span(), gen_args)
+                this.visit_generic_args(gen_args)
             });
         }
         match constraint.kind {
@@ -1045,10 +1015,10 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
         }
     }
 
-    fn visit_path_segment(&mut self, path_span: Span, path_segment: &'ast PathSegment) {
+    fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) {
         if let Some(ref args) = path_segment.args {
             match &**args {
-                GenericArgs::AngleBracketed(..) => visit::walk_generic_args(self, path_span, args),
+                GenericArgs::AngleBracketed(..) => visit::walk_generic_args(self, args),
                 GenericArgs::Parenthesized(p_args) => {
                     // Probe the lifetime ribs to know how to behave.
                     for rib in self.lifetime_ribs.iter().rev() {
@@ -1079,7 +1049,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
                             // We have nowhere to introduce generics.  Code is malformed,
                             // so use regular lifetime resolution to avoid spurious errors.
                             LifetimeRibKind::Item | LifetimeRibKind::Generics { .. } => {
-                                visit::walk_generic_args(self, path_span, args);
+                                visit::walk_generic_args(self, args);
                                 break;
                             }
                             LifetimeRibKind::AnonymousCreateParameter { .. }
@@ -1390,7 +1360,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         })
     }
 
-    #[tracing::instrument(level = "debug", skip(self, work))]
+    #[instrument(level = "debug", skip(self, work))]
     fn with_lifetime_rib<T>(
         &mut self,
         kind: LifetimeRibKind,
@@ -1404,7 +1374,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         ret
     }
 
-    #[tracing::instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn resolve_lifetime(&mut self, lifetime: &'ast Lifetime, use_ctxt: visit::LifetimeCtxt) {
         let ident = lifetime.ident;
 
@@ -1508,7 +1478,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         self.record_lifetime_res(lifetime.id, LifetimeRes::Error, LifetimeElisionCandidate::Named);
     }
 
-    #[tracing::instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn resolve_anonymous_lifetime(&mut self, lifetime: &Lifetime, elided: bool) {
         debug_assert_eq!(lifetime.ident.name, kw::UnderscoreLifetime);
 
@@ -1573,7 +1543,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         self.report_missing_lifetime_specifiers(vec![missing_lifetime], None);
     }
 
-    #[tracing::instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn resolve_elided_lifetime(&mut self, anchor_id: NodeId, span: Span) {
         let id = self.r.next_node_id();
         let lt = Lifetime { id, ident: Ident::new(kw::UnderscoreLifetime, span) };
@@ -1586,7 +1556,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         self.resolve_anonymous_lifetime(&lt, true);
     }
 
-    #[tracing::instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn create_fresh_lifetime(&mut self, id: NodeId, ident: Ident, binder: NodeId) -> LifetimeRes {
         debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
         debug!(?ident.span);
@@ -1604,7 +1574,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         res
     }
 
-    #[tracing::instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn resolve_elided_lifetimes_in_path(
         &mut self,
         path_id: NodeId,
@@ -1804,7 +1774,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         }
     }
 
-    #[tracing::instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn record_lifetime_res(
         &mut self,
         id: NodeId,
@@ -1827,7 +1797,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         }
     }
 
-    #[tracing::instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn record_lifetime_param(&mut self, id: NodeId, res: LifetimeRes) {
         if let Some(prev_res) = self.r.lifetimes_res_map.insert(id, res) {
             panic!(
@@ -1838,7 +1808,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
     }
 
     /// Perform resolution of a function signature, accounting for lifetime elision.
-    #[tracing::instrument(level = "debug", skip(self, inputs))]
+    #[instrument(level = "debug", skip(self, inputs))]
     fn resolve_fn_signature(
         &mut self,
         fn_id: NodeId,
@@ -2866,10 +2836,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
 
         pat.walk(&mut |pat| {
             match pat.kind {
-                PatKind::Ident(binding_mode, ident, ref sub_pat)
+                PatKind::Ident(annotation, ident, ref sub_pat)
                     if sub_pat.is_some() || self.is_base_res_local(pat.id) =>
                 {
-                    binding_map.insert(ident, BindingInfo { span: ident.span, binding_mode });
+                    binding_map.insert(ident, BindingInfo { span: ident.span, annotation });
                 }
                 PatKind::Or(ref ps) => {
                     // Check the consistency of this or-pattern and
@@ -2926,7 +2896,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                         binding_error.target.insert(pat_outer.span);
                     }
                     Some(binding_outer) => {
-                        if binding_outer.binding_mode != binding_inner.binding_mode {
+                        if binding_outer.annotation != binding_inner.annotation {
                             // The binding modes in the outer and inner bindings differ.
                             inconsistent_vars
                                 .entry(name)
@@ -3147,14 +3117,14 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
     fn try_resolve_as_non_binding(
         &mut self,
         pat_src: PatternSource,
-        bm: BindingMode,
+        ann: BindingAnnotation,
         ident: Ident,
         has_sub: bool,
     ) -> Option<Res> {
         // An immutable (no `mut`) by-value (no `ref`) binding pattern without
         // a sub pattern (no `@ $pat`) is syntactically ambiguous as it could
         // also be interpreted as a path to e.g. a constant, variant, etc.
-        let is_syntactic_ambiguity = !has_sub && bm == BindingMode::ByValue(Mutability::Not);
+        let is_syntactic_ambiguity = !has_sub && ann == BindingAnnotation::NONE;
 
         let ls_binding = self.maybe_resolve_ident_in_lexical_scope(ident, ValueNS)?;
         let (res, binding) = match ls_binding {
@@ -3268,11 +3238,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         source: PathSource<'ast>,
         finalize: Finalize,
     ) -> PartialRes {
-        tracing::debug!(
+        debug!(
             "smart_resolve_path_fragment(qself={:?}, path={:?}, finalize={:?})",
-            qself,
-            path,
-            finalize,
+            qself, path, finalize,
         );
         let ns = source.namespace();
 
@@ -3801,7 +3769,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                 for argument in arguments {
                     self.resolve_expr(argument, None);
                 }
-                self.visit_path_segment(expr.span, segment);
+                self.visit_path_segment(segment);
             }
 
             ExprKind::Call(ref callee, ref arguments) => {
@@ -3929,6 +3897,36 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             Some((ident.name, ns)),
         )
     }
+
+    /// Construct the list of in-scope lifetime parameters for async lowering.
+    /// We include all lifetime parameters, either named or "Fresh".
+    /// The order of those parameters does not matter, as long as it is
+    /// deterministic.
+    fn record_lifetime_params_for_async(
+        &mut self,
+        fn_id: NodeId,
+        async_node_id: Option<(NodeId, Span)>,
+    ) {
+        if let Some((async_node_id, _)) = async_node_id {
+            let mut extra_lifetime_params =
+                self.r.extra_lifetime_params_map.get(&fn_id).cloned().unwrap_or_default();
+            for rib in self.lifetime_ribs.iter().rev() {
+                extra_lifetime_params.extend(
+                    rib.bindings.iter().map(|(&ident, &(node_id, res))| (ident, node_id, res)),
+                );
+                match rib.kind {
+                    LifetimeRibKind::Item => break,
+                    LifetimeRibKind::AnonymousCreateParameter { binder, .. } => {
+                        if let Some(earlier_fresh) = self.r.extra_lifetime_params_map.get(&binder) {
+                            extra_lifetime_params.extend(earlier_fresh);
+                        }
+                    }
+                    _ => {}
+                }
+            }
+            self.r.extra_lifetime_params_map.insert(async_node_id, extra_lifetime_params);
+        }
+    }
 }
 
 struct LifetimeCountVisitor<'a, 'b> {
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index d41edea6a25..3c276a9ada9 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -33,8 +33,6 @@ use rustc_span::{BytePos, Span};
 use std::iter;
 use std::ops::Deref;
 
-use tracing::debug;
-
 type Res = def::Res<ast::NodeId>;
 
 /// A field or associated item from self type suggested in case of resolution failure.
@@ -175,7 +173,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                 span,
                 span_label: match res {
                     Res::Def(kind, def_id) if kind == DefKind::TyParam => {
-                        self.def_span(def_id).map(|span| (span, "found this type pararmeter"))
+                        self.def_span(def_id).map(|span| (span, "found this type parameter"))
                     }
                     _ => None,
                 },
@@ -619,9 +617,9 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                         .filter(|&sp| sp != base_error.span)
                         .collect();
 
-                    let start_span = bounds.iter().map(|bound| bound.span()).next().unwrap();
+                    let start_span = bounds[0].span();
                     // `end_span` is the end of the poly trait ref (Foo + 'baz + Bar><)
-                    let end_span = bounds.iter().map(|bound| bound.span()).last().unwrap();
+                    let end_span = bounds.last().unwrap().span();
                     // `last_bound_span` is the last bound of the poly trait ref (Foo + >'baz< + Bar)
                     let last_bound_span = spans.last().cloned().unwrap();
                     let mut multi_span: MultiSpan = spans.clone().into();
@@ -1792,7 +1790,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                 }
             };
 
-            let mut suggestable_variants = variants
+            let suggestable_variants = variants
                 .iter()
                 .filter(|(_, def_id, kind)| !needs_placeholder(*def_id, *kind))
                 .map(|(variant, _, kind)| (path_names_to_string(variant), kind))
@@ -1802,8 +1800,9 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                     CtorKind::Fictive => format!("({} {{}})", variant),
                 })
                 .collect::<Vec<_>>();
+            let no_suggestable_variant = suggestable_variants.is_empty();
 
-            if !suggestable_variants.is_empty() {
+            if !no_suggestable_variant {
                 let msg = if suggestable_variants.len() == 1 {
                     "you might have meant to use the following enum variant"
                 } else {
@@ -1813,7 +1812,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                 err.span_suggestions(
                     span,
                     msg,
-                    suggestable_variants.drain(..),
+                    suggestable_variants.into_iter(),
                     Applicability::MaybeIncorrect,
                 );
             }
@@ -1830,15 +1829,15 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                 .collect::<Vec<_>>();
 
             if !suggestable_variants_with_placeholders.is_empty() {
-                let msg = match (
-                    suggestable_variants.is_empty(),
-                    suggestable_variants_with_placeholders.len(),
-                ) {
-                    (true, 1) => "the following enum variant is available",
-                    (true, _) => "the following enum variants are available",
-                    (false, 1) => "alternatively, the following enum variant is available",
-                    (false, _) => "alternatively, the following enum variants are also available",
-                };
+                let msg =
+                    match (no_suggestable_variant, suggestable_variants_with_placeholders.len()) {
+                        (true, 1) => "the following enum variant is available",
+                        (true, _) => "the following enum variants are available",
+                        (false, 1) => "alternatively, the following enum variant is available",
+                        (false, _) => {
+                            "alternatively, the following enum variants are also available"
+                        }
+                    };
 
                 err.span_suggestions(
                     span,
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index 6ea976a5900..9fb1af20ac9 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -278,7 +278,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
 /// lifetimes into a single binder.) This requires us to resolve the
 /// *trait definition* of `Sub`; basically just enough lifetime information
 /// to look at the supertraits.
-#[tracing::instrument(level = "debug", skip(tcx))]
+#[instrument(level = "debug", skip(tcx))]
 fn resolve_lifetimes_trait_definition(
     tcx: TyCtxt<'_>,
     local_def_id: LocalDefId,
@@ -289,7 +289,7 @@ fn resolve_lifetimes_trait_definition(
 /// Computes the `ResolveLifetimes` map that contains data for an entire `Item`.
 /// You should not read the result of this query directly, but rather use
 /// `named_region_map`, `is_late_bound_map`, etc.
-#[tracing::instrument(level = "debug", skip(tcx))]
+#[instrument(level = "debug", skip(tcx))]
 fn resolve_lifetimes(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> ResolveLifetimes {
     convert_named_region_map(do_resolve(tcx, local_def_id, false))
 }
@@ -339,24 +339,25 @@ fn convert_named_region_map(named_region_map: NamedRegionMap) -> ResolveLifetime
 /// This allows us to avoid cycles. Importantly, if we ask for lifetimes for lifetimes that have an owner
 /// other than the trait itself (like the trait methods or associated types), then we just use the regular
 /// `resolve_lifetimes`.
-fn resolve_lifetimes_for<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx ResolveLifetimes {
-    let item_id = item_for(tcx, def_id);
-    if item_id == def_id {
-        let item = tcx.hir().item(hir::ItemId { def_id: item_id });
+fn resolve_lifetimes_for<'tcx>(tcx: TyCtxt<'tcx>, def_id: hir::OwnerId) -> &'tcx ResolveLifetimes {
+    let item_id = item_for(tcx, def_id.def_id);
+    let local_def_id = item_id.def_id.def_id;
+    if item_id.def_id == def_id {
+        let item = tcx.hir().item(item_id);
         match item.kind {
-            hir::ItemKind::Trait(..) => tcx.resolve_lifetimes_trait_definition(item_id),
-            _ => tcx.resolve_lifetimes(item_id),
+            hir::ItemKind::Trait(..) => tcx.resolve_lifetimes_trait_definition(local_def_id),
+            _ => tcx.resolve_lifetimes(local_def_id),
         }
     } else {
-        tcx.resolve_lifetimes(item_id)
+        tcx.resolve_lifetimes(local_def_id)
     }
 }
 
 /// Finds the `Item` that contains the given `LocalDefId`
-fn item_for(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> LocalDefId {
+fn item_for(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> hir::ItemId {
     match tcx.hir().find_by_def_id(local_def_id) {
         Some(Node::Item(item)) => {
-            return item.def_id;
+            return item.item_id();
         }
         _ => {}
     }
@@ -366,7 +367,7 @@ fn item_for(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> LocalDefId {
         loop {
             let node = parent_iter.next().map(|n| n.1);
             match node {
-                Some(hir::Node::Item(item)) => break item.def_id,
+                Some(hir::Node::Item(item)) => break item.item_id(),
                 Some(hir::Node::Crate(_)) | None => bug!("Called `item_for` on an Item."),
                 _ => {}
             }
@@ -525,6 +526,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
         }
     }
 
+    #[instrument(level = "debug", skip(self))]
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
         match &item.kind {
             hir::ItemKind::Impl(hir::Impl { of_trait, .. }) => {
@@ -565,13 +567,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                 // their owner, we can keep going until we find the Item that owns that. We then
                 // conservatively add all resolved lifetimes. Otherwise we run into problems in
                 // cases like `type Foo<'a> = impl Bar<As = impl Baz + 'a>`.
-                for (_hir_id, node) in
-                    self.tcx.hir().parent_iter(self.tcx.hir().local_def_id_to_hir_id(item.def_id))
-                {
+                for (_hir_id, node) in self.tcx.hir().parent_iter(item.def_id.into()) {
                     match node {
                         hir::Node::Item(parent_item) => {
-                            let resolved_lifetimes: &ResolveLifetimes =
-                                self.tcx.resolve_lifetimes(item_for(self.tcx, parent_item.def_id));
+                            let resolved_lifetimes: &ResolveLifetimes = self.tcx.resolve_lifetimes(
+                                item_for(self.tcx, parent_item.def_id.def_id).def_id.def_id,
+                            );
                             // We need to add *all* deps, since opaque tys may want them from *us*
                             for (&owner, defs) in resolved_lifetimes.defs.iter() {
                                 defs.iter().for_each(|(&local_id, region)| {
@@ -647,7 +648,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
         }
     }
 
-    #[tracing::instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
         match ty.kind {
             hir::TyKind::BareFn(ref c) => {
@@ -681,7 +682,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                 let scope = Scope::TraitRefBoundary { s: self.scope };
                 self.with(scope, |this| {
                     for bound in bounds {
-                        this.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None);
+                        this.visit_poly_trait_ref(bound);
                     }
                 });
                 match lifetime.name {
@@ -714,7 +715,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                 };
                 self.with(scope, |this| this.visit_ty(&mt.ty));
             }
-            hir::TyKind::OpaqueDef(item_id, lifetimes) => {
+            hir::TyKind::OpaqueDef(item_id, lifetimes, _in_trait) => {
                 // Resolve the lifetimes in the bounds to the lifetime defs in the generics.
                 // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
                 // `type MyAnonTy<'b> = impl MyTrait<'b>;`
@@ -839,6 +840,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
         }
     }
 
+    #[instrument(level = "debug", skip(self))]
     fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
         use self::hir::TraitItemKind::*;
         match trait_item.kind {
@@ -888,6 +890,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
         }
     }
 
+    #[instrument(level = "debug", skip(self))]
     fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
         use self::hir::ImplItemKind::*;
         match impl_item.kind {
@@ -930,7 +933,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
         }
     }
 
-    #[tracing::instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
         match lifetime_ref.name {
             hir::LifetimeName::Static => self.insert_lifetime(lifetime_ref, Region::Static),
@@ -1102,11 +1105,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
         }
     }
 
-    fn visit_poly_trait_ref(
-        &mut self,
-        trait_ref: &'tcx hir::PolyTraitRef<'tcx>,
-        _modifier: hir::TraitBoundModifier,
-    ) {
+    fn visit_poly_trait_ref(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) {
         debug!("visit_poly_trait_ref(trait_ref={:?})", trait_ref);
 
         let (mut binders, scope_type) = self.poly_trait_ref_binder_info();
@@ -1148,21 +1147,18 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
     }
 }
 
-fn object_lifetime_default<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    param_def_id: DefId,
-) -> Option<ObjectLifetimeDefault> {
+fn object_lifetime_default<'tcx>(tcx: TyCtxt<'tcx>, param_def_id: DefId) -> ObjectLifetimeDefault {
+    debug_assert_eq!(tcx.def_kind(param_def_id), DefKind::TyParam);
     let param_def_id = param_def_id.expect_local();
     let parent_def_id = tcx.local_parent(param_def_id);
-    let generics = tcx.hir().get_generics(parent_def_id)?;
+    let generics = tcx.hir().get_generics(parent_def_id).unwrap();
     let param_hir_id = tcx.local_def_id_to_hir_id(param_def_id);
-    let param = generics.params.iter().find(|p| p.hir_id == param_hir_id)?;
+    let param = generics.params.iter().find(|p| p.hir_id == param_hir_id).unwrap();
 
     // Scan the bounds and where-clauses on parameters to extract bounds
     // of the form `T:'a` so as to determine the `ObjectLifetimeDefault`
     // for each type parameter.
     match param.kind {
-        GenericParamKind::Lifetime { .. } => None,
         GenericParamKind::Type { .. } => {
             let mut set = Set1::Empty;
 
@@ -1181,21 +1177,17 @@ fn object_lifetime_default<'tcx>(
                 }
             }
 
-            Some(match set {
+            match set {
                 Set1::Empty => ObjectLifetimeDefault::Empty,
                 Set1::One(hir::LifetimeName::Static) => ObjectLifetimeDefault::Static,
                 Set1::One(hir::LifetimeName::Param(param_def_id, _)) => {
                     ObjectLifetimeDefault::Param(param_def_id.to_def_id())
                 }
                 _ => ObjectLifetimeDefault::Ambiguous,
-            })
+            }
         }
-        GenericParamKind::Const { .. } => {
-            // Generic consts don't impose any constraints.
-            //
-            // We still store a dummy value here to allow generic parameters
-            // in an arbitrary order.
-            Some(ObjectLifetimeDefault::Empty)
+        _ => {
+            bug!("object_lifetime_default_raw must only be called on a type parameter")
         }
     }
 }
@@ -1212,7 +1204,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             scope: &wrap_scope,
             trait_definition_only: self.trait_definition_only,
         };
-        let span = tracing::debug_span!("scope", scope = ?TruncatedScopeDebug(&this.scope));
+        let span = debug_span!("scope", scope = ?TruncatedScopeDebug(&this.scope));
         {
             let _enter = span.enter();
             f(&mut this);
@@ -1287,7 +1279,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         self.with(scope, walk);
     }
 
-    #[tracing::instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn resolve_lifetime_ref(
         &mut self,
         region_def_id: LocalDefId,
@@ -1323,7 +1315,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                     // regular fns.
                     if let Some(hir::PredicateOrigin::ImplTrait) = where_bound_origin
                         && let hir::LifetimeName::Param(_, hir::ParamName::Fresh) = lifetime_ref.name
-                        && let hir::IsAsync::NotAsync = self.tcx.asyncness(lifetime_ref.hir_id.owner)
+                        && let hir::IsAsync::NotAsync = self.tcx.asyncness(lifetime_ref.hir_id.owner.def_id)
                         && !self.tcx.features().anonymous_lifetime_in_impl_trait
                     {
                         rustc_session::parse::feature_err(
@@ -1368,7 +1360,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             return;
         }
 
-        // We may fail to resolve higher-ranked lifetimes that are mentionned by APIT.
+        // We may fail to resolve higher-ranked lifetimes that are mentioned by APIT.
         // AST-based resolution does not care for impl-trait desugaring, which are the
         // responibility of lowering.  This may create a mismatch between the resolution
         // AST found (`region_def_id`) which points to HRTB, and what HIR allows.
@@ -1409,7 +1401,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         );
     }
 
-    #[tracing::instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn visit_segment_args(
         &mut self,
         res: Res,
@@ -1512,7 +1504,20 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             generics
                 .params
                 .iter()
-                .filter_map(|param| self.tcx.object_lifetime_default(param.def_id))
+                .filter_map(|param| {
+                    match self.tcx.def_kind(param.def_id) {
+                        // Generic consts don't impose any constraints.
+                        //
+                        // We still store a dummy value here to allow generic parameters
+                        // in an arbitrary order.
+                        DefKind::ConstParam => Some(ObjectLifetimeDefault::Empty),
+                        DefKind::TyParam => Some(self.tcx.object_lifetime_default(param.def_id)),
+                        // We may also get a `Trait` or `TraitAlias` because of how generics `Self` parameter
+                        // works.  Ignore it because it can't have a meaningful lifetime default.
+                        DefKind::LifetimeParam | DefKind::Trait | DefKind::TraitAlias => None,
+                        dk => bug!("unexpected def_kind {:?}", dk),
+                    }
+                })
                 .map(set_to_region)
                 .collect()
         });
@@ -1659,7 +1664,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         }
     }
 
-    #[tracing::instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn visit_fn_like_elision(
         &mut self,
         inputs: &'tcx [hir::Ty<'tcx>],
@@ -1707,7 +1712,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         self.insert_lifetime(lifetime_ref, lifetime.shifted(late_depth));
     }
 
-    #[tracing::instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) {
         debug!(
             node = ?self.tcx.hir().node_to_string(lifetime_ref.hir_id),
@@ -1818,7 +1823,7 @@ fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet<
                     // is, those would be potentially inputs to
                     // projections
                     if let Some(last_segment) = path.segments.last() {
-                        self.visit_path_segment(path.span, last_segment);
+                        self.visit_path_segment(last_segment);
                     }
                 }
 
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 66090c96d1e..583030b0e50 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -12,7 +12,6 @@
 #![feature(if_let_guard)]
 #![feature(iter_intersperse)]
 #![feature(let_chains)]
-#![feature(let_else)]
 #![feature(never_type)]
 #![recursion_limit = "256"]
 #![allow(rustdoc::private_intra_doc_links)]
@@ -57,8 +56,7 @@ use rustc_span::{Span, DUMMY_SP};
 use smallvec::{smallvec, SmallVec};
 use std::cell::{Cell, RefCell};
 use std::collections::BTreeSet;
-use std::{cmp, fmt, ptr};
-use tracing::debug;
+use std::{fmt, ptr};
 
 use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion};
 use imports::{Import, ImportKind, ImportResolver, NameResolution};
@@ -164,7 +162,6 @@ enum ImplTraitContext {
     Universal(LocalDefId),
 }
 
-#[derive(Eq)]
 struct BindingError {
     name: Symbol,
     origin: BTreeSet<Span>,
@@ -172,24 +169,6 @@ struct BindingError {
     could_be_path: bool,
 }
 
-impl PartialOrd for BindingError {
-    fn partial_cmp(&self, other: &BindingError) -> Option<cmp::Ordering> {
-        Some(self.cmp(other))
-    }
-}
-
-impl PartialEq for BindingError {
-    fn eq(&self, other: &BindingError) -> bool {
-        self.name == other.name
-    }
-}
-
-impl Ord for BindingError {
-    fn cmp(&self, other: &BindingError) -> cmp::Ordering {
-        self.name.cmp(&other.name)
-    }
-}
-
 enum ResolutionError<'a> {
     /// Error E0401: can't use type or const parameters from outer function.
     GenericParamsFromOuterFunction(Res, HasGenericParams),
@@ -649,7 +628,7 @@ pub struct NameBinding<'a> {
     ambiguity: Option<(&'a NameBinding<'a>, AmbiguityKind)>,
     expansion: LocalExpnId,
     span: Span,
-    vis: ty::Visibility,
+    vis: ty::Visibility<DefId>,
 }
 
 pub trait ToNameBinding<'a> {
@@ -846,7 +825,7 @@ impl<'a> NameBinding<'a> {
     }
 }
 
-#[derive(Debug, Default, Clone)]
+#[derive(Default, Clone)]
 pub struct ExternPreludeEntry<'a> {
     extern_crate_item: Option<&'a NameBinding<'a>>,
     pub introduced_by_item: bool,
@@ -912,11 +891,6 @@ pub struct Resolver<'a> {
     label_res_map: NodeMap<NodeId>,
     /// Resolutions for lifetimes.
     lifetimes_res_map: NodeMap<LifetimeRes>,
-    /// Mapping from generics `def_id`s to TAIT generics `def_id`s.
-    /// For each captured lifetime (e.g., 'a), we create a new lifetime parameter that is a generic
-    /// defined on the TAIT, so we have type Foo<'a1> = ... and we establish a mapping in this
-    /// field from the original parameter 'a to the new parameter 'a1.
-    generics_def_id_map: Vec<FxHashMap<LocalDefId, LocalDefId>>,
     /// Lifetime parameters that lowering will have to introduce.
     extra_lifetime_params_map: NodeMap<Vec<(Ident, NodeId, LifetimeRes)>>,
 
@@ -1018,7 +992,7 @@ pub struct Resolver<'a> {
     /// Table for mapping struct IDs into struct constructor IDs,
     /// it's not used during normal resolution, only for better error reporting.
     /// Also includes of list of each fields visibility
-    struct_constructors: DefIdMap<(Res, ty::Visibility, Vec<ty::Visibility>)>,
+    struct_constructors: DefIdMap<(Res, ty::Visibility<DefId>, Vec<ty::Visibility<DefId>>)>,
 
     /// Features enabled for this crate.
     active_features: FxHashSet<Symbol>,
@@ -1279,7 +1253,6 @@ impl<'a> Resolver<'a> {
             import_res_map: Default::default(),
             label_res_map: Default::default(),
             lifetimes_res_map: Default::default(),
-            generics_def_id_map: Vec::new(),
             extra_lifetime_params_map: Default::default(),
             extern_crate_map: Default::default(),
             reexport_map: FxHashMap::default(),
@@ -1446,7 +1419,6 @@ impl<'a> Resolver<'a> {
             import_res_map: self.import_res_map,
             label_res_map: self.label_res_map,
             lifetimes_res_map: self.lifetimes_res_map,
-            generics_def_id_map: self.generics_def_id_map,
             extra_lifetime_params_map: self.extra_lifetime_params_map,
             next_node_id: self.next_node_id,
             node_id_to_def_id: self.node_id_to_def_id,
@@ -1491,7 +1463,6 @@ impl<'a> Resolver<'a> {
             import_res_map: self.import_res_map.clone(),
             label_res_map: self.label_res_map.clone(),
             lifetimes_res_map: self.lifetimes_res_map.clone(),
-            generics_def_id_map: self.generics_def_id_map.clone(),
             extra_lifetime_params_map: self.extra_lifetime_params_map.clone(),
             next_node_id: self.next_node_id.clone(),
             node_id_to_def_id: self.node_id_to_def_id.clone(),
@@ -1817,7 +1788,11 @@ impl<'a> Resolver<'a> {
         self.pat_span_map.insert(node, span);
     }
 
-    fn is_accessible_from(&self, vis: ty::Visibility, module: Module<'a>) -> bool {
+    fn is_accessible_from(
+        &self,
+        vis: ty::Visibility<impl Into<DefId>>,
+        module: Module<'a>,
+    ) -> bool {
         vis.is_accessible_from(module.nearest_parent_mod(), self)
     }
 
@@ -1871,10 +1846,8 @@ impl<'a> Resolver<'a> {
                     self.crate_loader.maybe_process_path_extern(ident.name)?
                 };
                 let crate_root = self.expect_module(crate_id.as_def_id());
-                Some(
-                    (crate_root, ty::Visibility::Public, DUMMY_SP, LocalExpnId::ROOT)
-                        .to_name_binding(self.arenas),
-                )
+                let vis = ty::Visibility::<LocalDefId>::Public;
+                Some((crate_root, vis, DUMMY_SP, LocalExpnId::ROOT).to_name_binding(self.arenas))
             }
         })
     }
@@ -1991,7 +1964,7 @@ impl<'a> Resolver<'a> {
                         _ => panic!("invalid arg index"),
                     }
                 }
-                // Cache the lookup to avoid parsing attributes for an iterm multiple times.
+                // Cache the lookup to avoid parsing attributes for an item multiple times.
                 self.legacy_const_generic_args.insert(def_id, Some(ret.clone()));
                 return Some(ret);
             }
@@ -2021,6 +1994,24 @@ impl<'a> Resolver<'a> {
         }
         self.main_def = Some(MainDefinition { res, is_import, span });
     }
+
+    // Items that go to reexport table encoded to metadata and visible through it to other crates.
+    fn is_reexport(&self, binding: &NameBinding<'a>) -> Option<def::Res<!>> {
+        // FIXME: Consider changing the binding inserted by `#[macro_export] macro_rules`
+        // into the crate root to actual `NameBindingKind::Import`.
+        if binding.is_import()
+            || matches!(binding.kind, NameBindingKind::Res(_, _is_macro_export @ true))
+        {
+            let res = binding.res().expect_non_local();
+            // Ambiguous imports are treated as errors at this point and are
+            // not exposed to other crates (see #36837 for more details).
+            if res != def::Res::Err && !binding.is_ambiguity() {
+                return Some(res);
+            }
+        }
+
+        return None;
+    }
 }
 
 fn names_to_string(names: &[Symbol]) -> String {
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 0c428aa6cc0..dafa10e9e00 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -441,7 +441,7 @@ impl<'a> ResolverExpand for Resolver<'a> {
                 }
                 PathResult::Indeterminate => indeterminate = true,
                 // We can only be sure that a path doesn't exist after having tested all the
-                // posibilities, only at that time we can return false.
+                // possibilities, only at that time we can return false.
                 PathResult::Failed { .. } => {}
                 PathResult::Module(_) => panic!("unexpected path resolution"),
             }