]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_resolve/src/late.rs
Auto merge of #90668 - matthiaskrgr:clippy_nov7, r=jyn514
[rust.git] / compiler / rustc_resolve / src / late.rs
index fbb1a868bdefd683103bb3b08196781f2d54606b..e67f7f03516803c0a7cb7ca7acfb57b9f05f4846 100644 (file)
@@ -7,7 +7,7 @@
 
 use RibKind::*;
 
-use crate::{path_names_to_string, BindingError, CrateLint, NameBinding, ToNameBinding};
+use crate::{path_names_to_string, BindingError, CrateLint, LexicalScopeBinding};
 use crate::{Module, ModuleOrUniformRoot, ParentScope, PathResult};
 use crate::{ResolutionError, Resolver, Segment, UseError};
 
 use rustc_hir::def::{self, CtorKind, DefKind, PartialRes, PerNS};
 use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX};
 use rustc_hir::{PrimTy, TraitCandidate};
-use rustc_middle::{bug, span_bug, ty};
+use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
-use rustc_span::source_map::{respan, Spanned};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::Span;
 use smallvec::{smallvec, SmallVec};
-use tracing::debug;
 
+use rustc_span::source_map::{respan, Spanned};
 use std::collections::{hash_map::Entry, BTreeSet};
 use std::mem::{replace, take};
+use tracing::debug;
 
 mod diagnostics;
 crate mod lifetimes;
 
 type Res = def::Res<NodeId>;
 
+type IdentMap<T> = FxHashMap<Ident, T>;
+
+/// Map from the name in a pattern to its binding mode.
+type BindingMap = IdentMap<BindingInfo>;
+
 #[derive(Copy, Clone, Debug)]
 struct BindingInfo {
     span: Span,
@@ -167,8 +172,8 @@ impl RibKind<'_> {
 /// The resolution keeps a separate stack of ribs as it traverses the AST for each namespace. When
 /// resolving, the name is looked up from inside out.
 #[derive(Debug)]
-crate struct Rib<'a, R = &'a NameBinding<'a>> {
-    pub bindings: FxHashMap<Ident, R>,
+crate struct Rib<'a, R = Res> {
+    pub bindings: IdentMap<R>,
     pub kind: RibKind<'a>,
 }
 
@@ -493,8 +498,8 @@ fn visit_poly_trait_ref(&mut self, tref: &'ast PolyTraitRef, m: &'ast TraitBound
     }
     fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) {
         match foreign_item.kind {
-            ForeignItemKind::Fn(box FnKind(_, _, ref generics, _))
-            | ForeignItemKind::TyAlias(box TyAliasKind(_, ref generics, ..)) => {
+            ForeignItemKind::Fn(box Fn { ref generics, .. })
+            | ForeignItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
                 self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| {
                     visit::walk_foreign_item(this, foreign_item);
                 });
@@ -562,12 +567,12 @@ fn visit_generics(&mut self, generics: &'ast Generics) {
                 GenericParamKind::Type { .. } => {
                     forward_ty_ban_rib
                         .bindings
-                        .insert(Ident::with_dummy_span(param.ident.name), self.r.dummy_binding);
+                        .insert(Ident::with_dummy_span(param.ident.name), Res::Err);
                 }
                 GenericParamKind::Const { .. } => {
                     forward_const_ban_rib
                         .bindings
-                        .insert(Ident::with_dummy_span(param.ident.name), self.r.dummy_binding);
+                        .insert(Ident::with_dummy_span(param.ident.name), Res::Err);
                 }
                 GenericParamKind::Lifetime => {}
             }
@@ -584,9 +589,7 @@ fn visit_generics(&mut self, generics: &'ast Generics) {
         // such as in the case of `trait Add<Rhs = Self>`.)
         if self.diagnostic_metadata.current_self_item.is_some() {
             // (`Some` if + only if we are in ADT's generics.)
-            forward_ty_ban_rib
-                .bindings
-                .insert(Ident::with_dummy_span(kw::SelfUpper), self.r.dummy_binding);
+            forward_ty_ban_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), Res::Err);
         }
 
         for param in &generics.params {
@@ -734,17 +737,15 @@ fn resolve_ident_in_lexical_scope(
         ns: Namespace,
         record_used_id: Option<NodeId>,
         path_span: Span,
-    ) -> Option<&'a NameBinding<'a>> {
-        self.r
-            .resolve_ident_in_lexical_scope(
-                ident,
-                ns,
-                &self.parent_scope,
-                record_used_id,
-                path_span,
-                &self.ribs[ns],
-            )
-            .ok()
+    ) -> Option<LexicalScopeBinding<'a>> {
+        self.r.resolve_ident_in_lexical_scope(
+            ident,
+            ns,
+            &self.parent_scope,
+            record_used_id,
+            path_span,
+            &self.ribs[ns],
+        )
     }
 
     fn resolve_path(
@@ -902,10 +903,6 @@ fn resolve_adt(&mut self, item: &'ast Item, generics: &'ast Generics) {
     }
 
     fn future_proof_import(&mut self, use_tree: &UseTree) {
-        if !self.should_report_errs() {
-            return;
-        }
-
         let segments = &use_tree.prefix.segments;
         if !segments.is_empty() {
             let ident = segments[0].ident;
@@ -917,42 +914,31 @@ fn future_proof_import(&mut self, use_tree: &UseTree) {
                 UseTreeKind::Simple(..) if segments.len() == 1 => &[TypeNS, ValueNS][..],
                 _ => &[TypeNS],
             };
-
-            let from_ribs = |binding: &NameBinding<'_>| {
-                matches!(
-                    binding.res(),
-                    Res::Local(..)
-                        | Res::SelfTy(..)
-                        | Res::Def(DefKind::TyParam | DefKind::ConstParam, ..)
-                )
-            };
             let report_error = |this: &Self, ns| {
                 let what = if ns == TypeNS { "type parameters" } else { "local variables" };
-                let msg = format!("imports cannot refer to {what}");
-                this.r.session.span_err(ident.span, &msg);
+                if this.should_report_errs() {
+                    this.r
+                        .session
+                        .span_err(ident.span, &format!("imports cannot refer to {}", what));
+                }
             };
 
             for &ns in nss {
-                if let Some(binding) =
-                    self.resolve_ident_in_lexical_scope(ident, ns, None, use_tree.prefix.span)
-                {
-                    if from_ribs(binding) {
+                match self.resolve_ident_in_lexical_scope(ident, ns, None, use_tree.prefix.span) {
+                    Some(LexicalScopeBinding::Res(..)) => {
                         report_error(self, ns);
-                    } else {
+                    }
+                    Some(LexicalScopeBinding::Item(binding)) => {
                         let orig_unusable_binding =
                             replace(&mut self.r.unusable_binding, Some(binding));
-                        if let Some(binding) = self.resolve_ident_in_lexical_scope(
-                            ident,
-                            ns,
-                            None,
-                            use_tree.prefix.span,
-                        ) {
-                            if from_ribs(binding) {
-                                report_error(self, ns);
-                            }
+                        if let Some(LexicalScopeBinding::Res(..)) = self
+                            .resolve_ident_in_lexical_scope(ident, ns, None, use_tree.prefix.span)
+                        {
+                            report_error(self, ns);
                         }
                         self.r.unusable_binding = orig_unusable_binding;
                     }
+                    None => {}
                 }
             }
         } else if let UseTreeKind::Nested(use_trees) = &use_tree.kind {
@@ -967,8 +953,8 @@ fn resolve_item(&mut self, item: &'ast Item) {
         debug!("(resolving item) resolving {} ({:?})", name, item.kind);
 
         match item.kind {
-            ItemKind::TyAlias(box TyAliasKind(_, ref generics, _, _))
-            | ItemKind::Fn(box FnKind(_, _, ref generics, _)) => {
+            ItemKind::TyAlias(box TyAlias { ref generics, .. })
+            | ItemKind::Fn(box Fn { ref generics, .. }) => {
                 self.compute_num_lifetime_params(item.id, generics);
                 self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| {
                     visit::walk_item(this, item)
@@ -982,7 +968,7 @@ fn resolve_item(&mut self, item: &'ast Item) {
                 self.resolve_adt(item, generics);
             }
 
-            ItemKind::Impl(box ImplKind {
+            ItemKind::Impl(box Impl {
                 ref generics,
                 ref of_trait,
                 ref self_ty,
@@ -993,7 +979,7 @@ fn resolve_item(&mut self, item: &'ast Item) {
                 self.resolve_implementation(generics, of_trait, &self_ty, item.id, impl_items);
             }
 
-            ItemKind::Trait(box TraitKind(.., ref generics, ref bounds, ref trait_items)) => {
+            ItemKind::Trait(box Trait { ref generics, ref bounds, ref items, .. }) => {
                 self.compute_num_lifetime_params(item.id, generics);
                 // Create a new rib for the trait-wide type parameters.
                 self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| {
@@ -1008,8 +994,8 @@ fn resolve_item(&mut self, item: &'ast Item) {
                             });
                         };
 
-                        this.with_trait_items(trait_items, |this| {
-                            for item in trait_items {
+                        this.with_trait_items(items, |this| {
+                            for item in items {
                                 match &item.kind {
                                     AssocItemKind::Const(_, ty, default) => {
                                         this.visit_ty(ty);
@@ -1029,10 +1015,10 @@ fn resolve_item(&mut self, item: &'ast Item) {
                                             );
                                         }
                                     }
-                                    AssocItemKind::Fn(box FnKind(_, _, generics, _)) => {
+                                    AssocItemKind::Fn(box Fn { generics, .. }) => {
                                         walk_assoc_item(this, generics, item);
                                     }
-                                    AssocItemKind::TyAlias(box TyAliasKind(_, generics, _, _)) => {
+                                    AssocItemKind::TyAlias(box TyAlias { generics, .. }) => {
                                         walk_assoc_item(this, generics, item);
                                     }
                                     AssocItemKind::MacCall(_) => {
@@ -1149,12 +1135,8 @@ fn with_generic_param_rib<'c, F>(&'c mut self, generics: &'c Generics, kind: Rib
                 _ => unreachable!(),
             };
             let res = Res::Def(def_kind, self.r.local_def_id(param.id).to_def_id());
-            let binding =
-                (res, ty::Visibility::Invisible, param.ident.span, self.parent_scope.expansion)
-                    .to_name_binding(self.r.arenas);
-
             self.r.record_partial_res(param.id, PartialRes::new(res));
-            rib.bindings.insert(ident, binding);
+            rib.bindings.insert(ident, res);
         }
 
         self.ribs[ValueNS].push(function_value_rib);
@@ -1274,12 +1256,10 @@ fn with_optional_trait_ref<T>(
     }
 
     fn with_self_rib_ns(&mut self, ns: Namespace, self_res: Res, f: impl FnOnce(&mut Self)) {
-        let binding = (self_res, ty::Visibility::Invisible, DUMMY_SP, self.parent_scope.expansion)
-            .to_name_binding(self.r.arenas);
         let mut self_type_rib = Rib::new(NormalRibKind);
 
         // Plain insert (no renaming, since types are not currently hygienic)
-        self_type_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), binding);
+        self_type_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), self_res);
         self.ribs[ns].push(self_type_rib);
         f(self);
         self.ribs[ns].pop();
@@ -1358,7 +1338,7 @@ fn resolve_implementation(
                                                 },
                                             );
                                         }
-                                        AssocItemKind::Fn(box FnKind(.., generics, _)) => {
+                                        AssocItemKind::Fn(box Fn { generics, .. }) => {
                                             debug!("resolve_implementation AssocItemKind::Fn");
                                             // We also need a new scope for the impl item type parameters.
                                             this.with_generic_param_rib(
@@ -1383,12 +1363,9 @@ fn resolve_implementation(
                                                 },
                                             );
                                         }
-                                        AssocItemKind::TyAlias(box TyAliasKind(
-                                            _,
-                                            generics,
-                                            _,
-                                            _,
-                                        )) => {
+                                        AssocItemKind::TyAlias(box TyAlias {
+                                            generics, ..
+                                        }) => {
                                             debug!("resolve_implementation AssocItemKind::TyAlias");
                                             // We also need a new scope for the impl item type parameters.
                                             this.with_generic_param_rib(
@@ -1490,7 +1467,7 @@ fn resolve_local(&mut self, local: &'ast Local) {
     /// this is done hygienically. This could arise for a macro
     /// that expands into an or-pattern where one 'x' was from the
     /// user and one 'x' came from the macro.
-    fn binding_mode_map(&mut self, pat: &Pat) -> FxHashMap<Ident, BindingInfo> {
+    fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
         let mut binding_map = FxHashMap::default();
 
         pat.walk(&mut |pat| {
@@ -1523,7 +1500,7 @@ fn is_base_res_local(&self, nid: NodeId) -> bool {
 
     /// Checks that all of the arms in an or-pattern have exactly the
     /// same set of bindings, with the same binding modes for each.
-    fn check_consistent_bindings(&mut self, pats: &[P<Pat>]) -> Vec<FxHashMap<Ident, BindingInfo>> {
+    fn check_consistent_bindings(&mut self, pats: &[P<Pat>]) -> Vec<BindingMap> {
         let mut missing_vars = FxHashMap::default();
         let mut inconsistent_vars = FxHashMap::default();
 
@@ -1665,6 +1642,7 @@ fn resolve_pattern_inner(
                         .try_resolve_as_non_binding(pat_src, pat, bmode, ident, has_sub)
                         .unwrap_or_else(|| self.fresh_binding(ident, pat.id, pat_src, bindings));
                     self.r.record_partial_res(pat.id, PartialRes::new(res));
+                    self.r.record_pat_span(pat.id, pat.span);
                 }
                 PatKind::TupleStruct(ref qself, ref path, ref sub_patterns) => {
                     self.smart_resolve_path(
@@ -1754,24 +1732,18 @@ fn fresh_binding(
         if already_bound_or {
             // `Variant1(a) | Variant2(a)`, ok
             // Reuse definition from the first `a`.
-            self.innermost_rib_bindings(ValueNS)[&ident].res()
+            self.innermost_rib_bindings(ValueNS)[&ident]
         } else {
             let res = Res::Local(pat_id);
             if ident_valid {
                 // A completely fresh binding add to the set if it's valid.
-                let binding =
-                    (res, ty::Visibility::Invisible, ident.span, self.parent_scope.expansion)
-                        .to_name_binding(self.r.arenas);
-                self.innermost_rib_bindings(ValueNS).insert(ident, binding);
+                self.innermost_rib_bindings(ValueNS).insert(ident, res);
             }
             res
         }
     }
 
-    fn innermost_rib_bindings(
-        &mut self,
-        ns: Namespace,
-    ) -> &mut FxHashMap<Ident, &'a NameBinding<'a>> {
+    fn innermost_rib_bindings(&mut self, ns: Namespace) -> &mut IdentMap<Res> {
         &mut self.ribs[ns].last_mut().unwrap().bindings
     }
 
@@ -1788,17 +1760,22 @@ fn try_resolve_as_non_binding(
         // 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 binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, None, pat.span)?;
-        if is_syntactic_ambiguity && binding.is_ambiguity() {
-            // For ambiguous bindings we don't know all their definitions and cannot check
-            // whether they can be shadowed by fresh bindings or not, so force an error.
-            // issues/33118#issuecomment-233962221 (see below) still applies here,
-            // but we have to ignore it for backward compatibility.
-            self.r.record_use(ident, binding, false);
-            return None;
-        }
+        let ls_binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, None, pat.span)?;
+        let (res, binding) = match ls_binding {
+            LexicalScopeBinding::Item(binding)
+                if is_syntactic_ambiguity && binding.is_ambiguity() =>
+            {
+                // For ambiguous bindings we don't know all their definitions and cannot check
+                // whether they can be shadowed by fresh bindings or not, so force an error.
+                // issues/33118#issuecomment-233962221 (see below) still applies here,
+                // but we have to ignore it for backward compatibility.
+                self.r.record_use(ident, binding, false);
+                return None;
+            }
+            LexicalScopeBinding::Item(binding) => (binding.res(), Some(binding)),
+            LexicalScopeBinding::Res(res) => (res, None),
+        };
 
-        let res = binding.res();
         match res {
             Res::SelfCtor(_) // See #70549.
             | Res::Def(
@@ -1806,7 +1783,9 @@ fn try_resolve_as_non_binding(
                 _,
             ) if is_syntactic_ambiguity => {
                 // Disambiguate in favor of a unit struct/variant or constant pattern.
-                self.r.record_use(ident, binding, false);
+                if let Some(binding) = binding {
+                    self.r.record_use(ident, binding, false);
+                }
                 Some(res)
             }
             Res::Def(DefKind::Ctor(..) | DefKind::Const | DefKind::Static, _) => {
@@ -1815,6 +1794,7 @@ fn try_resolve_as_non_binding(
                 // to something unusable as a pattern (e.g., constructor function),
                 // but we still conservatively report an error, see
                 // issues/33118#issuecomment-233962221 for one reason why.
+                let binding = binding.expect("no binding for a ctor or static");
                 self.report_error(
                     ident.span,
                     ResolutionError::BindingShadowsSomethingUnacceptable {
@@ -2054,15 +2034,19 @@ fn smart_resolve_path_fragment(
     }
 
     fn self_type_is_available(&mut self, span: Span) -> bool {
-        let ident = Ident::with_dummy_span(kw::SelfUpper);
-        self.resolve_ident_in_lexical_scope(ident, TypeNS, None, span)
-            .map_or(false, |binding| binding.res() != Res::Err)
+        let binding = self.resolve_ident_in_lexical_scope(
+            Ident::with_dummy_span(kw::SelfUpper),
+            TypeNS,
+            None,
+            span,
+        );
+        if let Some(LexicalScopeBinding::Res(res)) = binding { res != Res::Err } else { false }
     }
 
     fn self_value_is_available(&mut self, self_span: Span, path_span: Span) -> bool {
         let ident = Ident::new(kw::SelfLower, self_span);
-        self.resolve_ident_in_lexical_scope(ident, ValueNS, None, path_span)
-            .map_or(false, |binding| binding.res() != Res::Err)
+        let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, None, path_span);
+        if let Some(LexicalScopeBinding::Res(res)) = binding { res != Res::Err } else { false }
     }
 
     /// A wrapper around [`Resolver::report_error`].