]> git.lizzy.rs Git - rust.git/commitdiff
Remove `trait_item_map`, clean up `resolver.with_type_parameter_rib()`.
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>
Sat, 18 Mar 2017 02:10:13 +0000 (02:10 +0000)
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>
Thu, 25 May 2017 05:51:12 +0000 (05:51 +0000)
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/lib.rs

index b7b75f8af73e0cfbe90864db4ec370ec70a9f360..18798962df1beabf71afd46295407f6afc207c7f 100644 (file)
@@ -478,9 +478,10 @@ fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'a>, chi
                     self.define(module, ident, ns, (child.def, ty::Visibility::Public,
                                                     DUMMY_SP, Mark::root()));
 
-                    let has_self = self.session.cstore.associated_item_cloned(child.def.def_id())
-                                       .method_has_self_argument;
-                    self.trait_item_map.insert((def_id, child.name, ns), (child.def, has_self));
+                    if self.session.cstore.associated_item_cloned(child.def.def_id())
+                           .method_has_self_argument {
+                        self.has_self.insert(child.def.def_id());
+                    }
                 }
                 module.populated.set(true);
             }
@@ -773,7 +774,6 @@ fn visit_block(&mut self, block: &'a Block) {
 
     fn visit_trait_item(&mut self, item: &'a TraitItem) {
         let parent = self.resolver.current_module;
-        let def_id = parent.def_id().unwrap();
 
         if let TraitItemKind::Macro(_) = item.node {
             self.visit_invoc(item.id);
@@ -782,16 +782,18 @@ fn visit_trait_item(&mut self, item: &'a TraitItem) {
 
         // Add the item to the trait info.
         let item_def_id = self.resolver.definitions.local_def_id(item.id);
-        let (def, ns, has_self) = match item.node {
-            TraitItemKind::Const(..) => (Def::AssociatedConst(item_def_id), ValueNS, false),
-            TraitItemKind::Method(ref sig, _) =>
-                (Def::Method(item_def_id), ValueNS, sig.decl.has_self()),
-            TraitItemKind::Type(..) => (Def::AssociatedTy(item_def_id), TypeNS, false),
+        let (def, ns) = match item.node {
+            TraitItemKind::Const(..) => (Def::AssociatedConst(item_def_id), ValueNS),
+            TraitItemKind::Method(ref sig, _) => {
+                if sig.decl.has_self() {
+                    self.resolver.has_self.insert(item_def_id);
+                }
+                (Def::Method(item_def_id), ValueNS)
+            }
+            TraitItemKind::Type(..) => (Def::AssociatedTy(item_def_id), TypeNS),
             TraitItemKind::Macro(_) => bug!(),  // handled above
         };
 
-        self.resolver.trait_item_map.insert((def_id, item.ident.name, ns), (def, has_self));
-
         let vis = ty::Visibility::Public;
         self.resolver.define(parent, item.ident, ns, (def, vis, item.span, self.expansion));
 
index 500277e78e61dafc255bc466bcfbc724c22dc99f..6d8ca09935cff3ae4f1139e99bda83b28316578c 100644 (file)
@@ -1111,7 +1111,8 @@ pub struct Resolver<'a> {
 
     prelude: Option<Module<'a>>,
 
-    trait_item_map: FxHashMap<(DefId, Name, Namespace), (Def, bool /* has self */)>,
+    // n.b. This is used only for better diagnostics, not name resolution itself.
+    has_self: FxHashSet<DefId>,
 
     // Names of fields of an item `DefId` accessible with dot syntax.
     // Used for hints during error reporting.
@@ -1134,7 +1135,7 @@ pub struct Resolver<'a> {
     label_ribs: Vec<Rib<'a>>,
 
     // The trait that the current context can refer to.
-    current_trait_ref: Option<(DefId, TraitRef)>,
+    current_trait_ref: Option<(Module<'a>, TraitRef)>,
 
     // The current self type if inside an impl (used for better errors).
     current_self_type: Option<Ty>,
@@ -1337,7 +1338,7 @@ pub fn new(session: &'a Session,
             graph_root: graph_root,
             prelude: None,
 
-            trait_item_map: FxHashMap(),
+            has_self: FxHashSet(),
             field_names: FxHashMap(),
 
             determined_imports: Vec::new(),
@@ -1750,22 +1751,21 @@ fn with_type_parameter_rib<'b, F>(&'b mut self, type_parameters: TypeParameters<
                 let mut function_type_rib = Rib::new(rib_kind);
                 let mut seen_bindings = FxHashMap();
                 for type_parameter in &generics.ty_params {
-                    let name = type_parameter.ident.name;
+                    let ident = type_parameter.ident.unhygienize();
                     debug!("with_type_parameter_rib: {}", type_parameter.id);
 
-                    if seen_bindings.contains_key(&name) {
-                        let span = seen_bindings.get(&name).unwrap();
-                        resolve_error(self,
-                                      type_parameter.span,
-                                      ResolutionError::NameAlreadyUsedInTypeParameterList(name,
-                                                                                          span));
+                    if seen_bindings.contains_key(&ident) {
+                        let span = seen_bindings.get(&ident).unwrap();
+                        let err =
+                            ResolutionError::NameAlreadyUsedInTypeParameterList(ident.name, span);
+                        resolve_error(self, type_parameter.span, err);
                     }
-                    seen_bindings.entry(name).or_insert(type_parameter.span);
+                    seen_bindings.entry(ident).or_insert(type_parameter.span);
 
                     // plain insert (no renaming)
                     let def_id = self.definitions.local_def_id(type_parameter.id);
                     let def = Def::TyParam(def_id);
-                    function_type_rib.bindings.insert(Ident::with_empty_ctxt(name), def);
+                    function_type_rib.bindings.insert(ident, def);
                     self.record_def(type_parameter.id, PathResolution::new(def));
                 }
                 self.ribs[TypeNS].push(function_type_rib);
@@ -1825,11 +1825,20 @@ fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f:
         let mut new_val = None;
         let mut new_id = None;
         if let Some(trait_ref) = opt_trait_ref {
-            let def = self.smart_resolve_path(trait_ref.ref_id, None,
-                                              &trait_ref.path, PathSource::Trait).base_def();
+            let path: Vec<_> = trait_ref.path.segments.iter().map(|seg| seg.identifier).collect();
+            let def = self.smart_resolve_path_fragment(trait_ref.ref_id,
+                                                       None,
+                                                       &path,
+                                                       trait_ref.path.span,
+                                                       trait_ref.path.segments.last().unwrap().span,
+                                                       PathSource::Trait)
+                .base_def();
             if def != Def::Err {
-                new_val = Some((def.def_id(), trait_ref.clone()));
                 new_id = Some(def.def_id());
+                let span = trait_ref.path.span;
+                if let PathResult::Module(module) = self.resolve_path(&path, None, false, span) {
+                    new_val = Some((module, trait_ref.clone()));
+                }
             }
         }
         let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
@@ -1880,7 +1889,7 @@ fn resolve_implementation(&mut self,
                                     ImplItemKind::Const(..) => {
                                         // If this is a trait impl, ensure the const
                                         // exists in trait
-                                        this.check_trait_item(impl_item.ident.name,
+                                        this.check_trait_item(impl_item.ident,
                                                             ValueNS,
                                                             impl_item.span,
                                             |n, s| ResolutionError::ConstNotMemberOfTrait(n, s));
@@ -1889,7 +1898,7 @@ fn resolve_implementation(&mut self,
                                     ImplItemKind::Method(ref sig, _) => {
                                         // If this is a trait impl, ensure the method
                                         // exists in trait
-                                        this.check_trait_item(impl_item.ident.name,
+                                        this.check_trait_item(impl_item.ident,
                                                             ValueNS,
                                                             impl_item.span,
                                             |n, s| ResolutionError::MethodNotMemberOfTrait(n, s));
@@ -1906,7 +1915,7 @@ fn resolve_implementation(&mut self,
                                     ImplItemKind::Type(ref ty) => {
                                         // If this is a trait impl, ensure the type
                                         // exists in trait
-                                        this.check_trait_item(impl_item.ident.name,
+                                        this.check_trait_item(impl_item.ident,
                                                             TypeNS,
                                                             impl_item.span,
                                             |n, s| ResolutionError::TypeNotMemberOfTrait(n, s));
@@ -1924,15 +1933,15 @@ fn resolve_implementation(&mut self,
         });
     }
 
-    fn check_trait_item<F>(&self, name: Name, ns: Namespace, span: Span, err: F)
+    fn check_trait_item<F>(&mut self, ident: Ident, ns: Namespace, span: Span, err: F)
         where F: FnOnce(Name, &str) -> ResolutionError
     {
         // If there is a TraitRef in scope for an impl, then the method must be in the
         // trait.
-        if let Some((did, ref trait_ref)) = self.current_trait_ref {
-            if !self.trait_item_map.contains_key(&(did, name, ns)) {
-                let path_str = path_names_to_string(&trait_ref.path);
-                resolve_error(self, span, err(name, &path_str));
+        if let Some((module, _)) = self.current_trait_ref {
+            if self.resolve_ident_in_module(module, ident, ns, false, false, span).is_err() {
+                let path = &self.current_trait_ref.as_ref().unwrap().1.path;
+                resolve_error(self, span, err(ident.name, &path_names_to_string(path)));
             }
         }
     }
@@ -2302,15 +2311,16 @@ fn smart_resolve_path_fragment(&mut self,
             }
 
             // Try to lookup the name in more relaxed fashion for better error reporting.
-            let name = path.last().unwrap().name;
-            let candidates = this.lookup_import_candidates(name, ns, is_expected);
+            let ident = *path.last().unwrap();
+            let candidates = this.lookup_import_candidates(ident.name, ns, is_expected);
             if !candidates.is_empty() {
                 let mut module_span = this.current_module.span;
                 module_span.hi = module_span.lo;
                 // Report import candidates as help and proceed searching for labels.
                 show_candidates(&mut err, module_span, &candidates, def.is_some());
             } else if is_expected(Def::Enum(DefId::local(CRATE_DEF_INDEX))) {
-                let enum_candidates = this.lookup_import_candidates(name, ns, is_enum_variant);
+                let enum_candidates =
+                    this.lookup_import_candidates(ident.name, ns, is_enum_variant);
                 let mut enum_candidates = enum_candidates.iter()
                     .map(|suggestion| import_candidate_to_paths(&suggestion)).collect::<Vec<_>>();
                 enum_candidates.sort();
@@ -2326,7 +2336,7 @@ fn smart_resolve_path_fragment(&mut self,
                 }
             }
             if path.len() == 1 && this.self_type_is_available(span) {
-                if let Some(candidate) = this.lookup_assoc_candidate(name, ns, is_expected) {
+                if let Some(candidate) = this.lookup_assoc_candidate(ident, ns, is_expected) {
                     let self_is_available = this.self_value_is_available(path[0].ctxt, span);
                     match candidate {
                         AssocSuggestion::Field => {
@@ -2440,7 +2450,7 @@ fn smart_resolve_path_fragment(&mut self,
                 // or `<T>::A::B`. If `B` should be resolved in value namespace then
                 // it needs to be added to the trait map.
                 if ns == ValueNS {
-                    let item_name = path.last().unwrap().name;
+                    let item_name = *path.last().unwrap();
                     let traits = self.get_traits_containing_item(item_name, ns);
                     self.trait_map.insert(id, traits);
                 }
@@ -2819,7 +2829,7 @@ fn with_empty_ribs<T, F>(&mut self, f: F) -> T
     }
 
     fn lookup_assoc_candidate<FilterFn>(&mut self,
-                                        name: Name,
+                                        ident: Ident,
                                         ns: Namespace,
                                         filter_fn: FilterFn)
                                         -> Option<AssocSuggestion>
@@ -2845,7 +2855,7 @@ fn extract_node_id(t: &Ty) -> Option<NodeId> {
                         Def::Struct(did) | Def::Union(did)
                                 if resolution.unresolved_segments() == 0 => {
                             if let Some(field_names) = self.field_names.get(&did) {
-                                if field_names.iter().any(|&field_name| name == field_name) {
+                                if field_names.iter().any(|&field_name| ident.name == field_name) {
                                     return Some(AssocSuggestion::Field);
                                 }
                             }
@@ -2857,10 +2867,12 @@ fn extract_node_id(t: &Ty) -> Option<NodeId> {
         }
 
         // Look for associated items in the current trait.
-        if let Some((trait_did, _)) = self.current_trait_ref {
-            if let Some(&(def, has_self)) = self.trait_item_map.get(&(trait_did, name, ns)) {
+        if let Some((module, _)) = self.current_trait_ref {
+            if let Ok(binding) =
+                    self.resolve_ident_in_module(module, ident, ns, false, false, module.span) {
+                let def = binding.def();
                 if filter_fn(def) {
-                    return Some(if has_self {
+                    return Some(if self.has_self.contains(&def.def_id()) {
                         AssocSuggestion::MethodWithSelf
                     } else {
                         AssocSuggestion::AssocItem
@@ -3081,13 +3093,13 @@ fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
                 // field, we need to add any trait methods we find that match
                 // the field name so that we can do some nice error reporting
                 // later on in typeck.
-                let traits = self.get_traits_containing_item(name.node.name, ValueNS);
+                let traits = self.get_traits_containing_item(name.node, ValueNS);
                 self.trait_map.insert(expr.id, traits);
             }
             ExprKind::MethodCall(name, ..) => {
                 debug!("(recording candidate traits for expr) recording traits for {}",
                        expr.id);
-                let traits = self.get_traits_containing_item(name.node.name, ValueNS);
+                let traits = self.get_traits_containing_item(name.node, ValueNS);
                 self.trait_map.insert(expr.id, traits);
             }
             _ => {
@@ -3096,20 +3108,21 @@ fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
         }
     }
 
-    fn get_traits_containing_item(&mut self, name: Name, ns: Namespace) -> Vec<TraitCandidate> {
-        debug!("(getting traits containing item) looking for '{}'", name);
+    fn get_traits_containing_item(&mut self, ident: Ident, ns: Namespace) -> Vec<TraitCandidate> {
+        debug!("(getting traits containing item) looking for '{}'", ident.name);
 
         let mut found_traits = Vec::new();
         // Look for the current trait.
-        if let Some((trait_def_id, _)) = self.current_trait_ref {
-            if self.trait_item_map.contains_key(&(trait_def_id, name, ns)) {
-                found_traits.push(TraitCandidate { def_id: trait_def_id, import_id: None });
+        if let Some((module, _)) = self.current_trait_ref {
+            if self.resolve_ident_in_module(module, ident, ns, false, false, module.span).is_ok() {
+                let def_id = module.def_id().unwrap();
+                found_traits.push(TraitCandidate { def_id: def_id, import_id: None });
             }
         }
 
         let mut search_module = self.current_module;
         loop {
-            self.get_traits_in_module_containing_item(name, ns, search_module, &mut found_traits);
+            self.get_traits_in_module_containing_item(ident, ns, search_module, &mut found_traits);
             match search_module.kind {
                 ModuleKind::Block(..) => search_module = search_module.parent.unwrap(),
                 _ => break,
@@ -3118,7 +3131,7 @@ fn get_traits_containing_item(&mut self, name: Name, ns: Namespace) -> Vec<Trait
 
         if let Some(prelude) = self.prelude {
             if !search_module.no_implicit_prelude {
-                self.get_traits_in_module_containing_item(name, ns, prelude, &mut found_traits);
+                self.get_traits_in_module_containing_item(ident, ns, prelude, &mut found_traits);
             }
         }
 
@@ -3126,9 +3139,9 @@ fn get_traits_containing_item(&mut self, name: Name, ns: Namespace) -> Vec<Trait
     }
 
     fn get_traits_in_module_containing_item(&mut self,
-                                            name: Name,
+                                            ident: Ident,
                                             ns: Namespace,
-                                            module: Module,
+                                            module: Module<'a>,
                                             found_traits: &mut Vec<TraitCandidate>) {
         let mut traits = module.traits.borrow_mut();
         if traits.is_none() {
@@ -3143,8 +3156,8 @@ fn get_traits_in_module_containing_item(&mut self,
         }
 
         for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
-            let trait_def_id = binding.def().def_id();
-            if self.trait_item_map.contains_key(&(trait_def_id, name, ns)) {
+            let module = binding.module().unwrap();
+            if self.resolve_ident_in_module(module, ident, ns, false, false, module.span).is_ok() {
                 let import_id = match binding.kind {
                     NameBindingKind::Import { directive, .. } => {
                         self.maybe_unused_trait_imports.insert(directive.id);
@@ -3153,6 +3166,7 @@ fn get_traits_in_module_containing_item(&mut self,
                     }
                     _ => None,
                 };
+                let trait_def_id = module.def_id().unwrap();
                 found_traits.push(TraitCandidate { def_id: trait_def_id, import_id: import_id });
             }
         }