]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_resolve/lib.rs
resolve: improve/remove allocations
[rust.git] / src / librustc_resolve / lib.rs
index ece0188fa626d15f599f899ef564e5d434bf4386..131b69429c6233f8afbcdb921d779ce2fa510c0c 100644 (file)
@@ -17,6 +17,8 @@
 #![feature(rustc_diagnostic_macros)]
 #![feature(slice_sort_by_cached_key)]
 
+#[macro_use]
+extern crate bitflags;
 #[macro_use]
 extern crate log;
 #[macro_use]
@@ -1012,7 +1014,8 @@ pub struct ModuleData<'a> {
     normal_ancestor_id: DefId,
 
     resolutions: RefCell<FxHashMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>,
-    legacy_macro_resolutions: RefCell<Vec<(Ident, MacroKind, ParentScope<'a>, Option<Def>)>>,
+    legacy_macro_resolutions: RefCell<Vec<(Ident, MacroKind, ParentScope<'a>,
+                                           Option<&'a NameBinding<'a>>)>>,
     macro_resolutions: RefCell<Vec<(Box<[Ident]>, Span)>>,
     builtin_attrs: RefCell<Vec<(Ident, ParentScope<'a>)>>,
 
@@ -1210,10 +1213,6 @@ fn def_ignoring_ambiguity(&self) -> Def {
         }
     }
 
-    fn get_macro<'b: 'a>(&self, resolver: &mut Resolver<'a, 'b>) -> Lrc<SyntaxExtension> {
-        resolver.get_macro(self.def_ignoring_ambiguity())
-    }
-
     // We sometimes need to treat variants as `pub` for backwards compatibility
     fn pseudo_vis(&self) -> ty::Visibility {
         if self.is_variant() && self.def().def_id().is_local() {
@@ -1361,6 +1360,7 @@ pub struct Resolver<'a, 'b: 'a> {
     graph_root: Module<'a>,
 
     prelude: Option<Module<'a>>,
+    pub extern_prelude: FxHashSet<Name>,
 
     /// n.b. This is used only for better diagnostics, not name resolution itself.
     has_self: FxHashSet<DefId>,
@@ -1633,19 +1633,17 @@ fn resolve_hir_path_cb<F>(&mut self, path: &mut hir::Path, is_value: bool, error
                 *def = module.def().unwrap(),
             PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 =>
                 *def = path_res.base_def(),
-            PathResult::NonModule(..) => match self.resolve_path(
-                None,
-                &path,
-                None,
-                true,
-                span,
-                CrateLint::No,
-            ) {
-                PathResult::Failed(span, msg, _) => {
+            PathResult::NonModule(..) =>
+                if let PathResult::Failed(span, msg, _) = self.resolve_path(
+                    None,
+                    &path,
+                    None,
+                    true,
+                    span,
+                    CrateLint::No,
+                ) {
                     error_callback(self, span, ResolutionError::FailedToResolve(&msg));
-                }
-                _ => {}
-            },
+                },
             PathResult::Module(ModuleOrUniformRoot::UniformRoot(_)) |
             PathResult::Indeterminate => unreachable!(),
             PathResult::Failed(span, msg, _) => {
@@ -1677,6 +1675,19 @@ pub fn new(session: &'a Session,
         DefCollector::new(&mut definitions, Mark::root())
             .collect_root(crate_name, session.local_crate_disambiguator());
 
+        let mut extern_prelude: FxHashSet<Name> =
+            session.opts.externs.iter().map(|kv| Symbol::intern(kv.0)).collect();
+
+        if !attr::contains_name(&krate.attrs, "no_core") {
+            extern_prelude.insert(Symbol::intern("core"));
+            if !attr::contains_name(&krate.attrs, "no_std") {
+                extern_prelude.insert(Symbol::intern("std"));
+                if session.rust_2018() {
+                    extern_prelude.insert(Symbol::intern("meta"));
+                }
+            }
+        }
+
         let mut invocations = FxHashMap();
         invocations.insert(Mark::root(),
                            arenas.alloc_invocation_data(InvocationData::root(graph_root)));
@@ -1695,6 +1706,7 @@ pub fn new(session: &'a Session,
             // AST.
             graph_root,
             prelude: None,
+            extern_prelude,
 
             has_self: FxHashSet(),
             field_names: FxHashMap(),
@@ -1967,7 +1979,7 @@ fn resolve_ident_in_lexical_scope(&mut self,
 
         if !module.no_implicit_prelude {
             // `record_used` means that we don't try to load crates during speculative resolution
-            if record_used && ns == TypeNS && self.session.extern_prelude.contains(&ident.name) {
+            if record_used && ns == TypeNS && self.extern_prelude.contains(&ident.name) {
                 let crate_id = self.crate_loader.process_path_extern(ident.name, ident.span);
                 let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
                 self.populate_module_if_necessary(&crate_root);
@@ -2337,7 +2349,7 @@ fn resolve_use_tree(
                     span: prefix.span.to(use_tree.prefix.span),
                 };
 
-                if items.len() == 0 {
+                if items.is_empty() {
                     // Resolve prefix of an import with empty braces (issue #28388).
                     self.smart_resolve_path_with_crate_lint(
                         id,
@@ -2676,7 +2688,7 @@ fn check_consistent_bindings(&mut self, pats: &[P<Pat>]) {
 
                 let map_j = self.binding_mode_map(&q);
                 for (&key, &binding_i) in &map_i {
-                    if map_j.len() == 0 {                   // Account for missing bindings when
+                    if map_j.is_empty() {                   // Account for missing bindings when
                         let binding_error = missing_vars    // map_j has none.
                             .entry(key.name)
                             .or_insert(BindingError {
@@ -2737,9 +2749,8 @@ fn resolve_arm(&mut self, arm: &Arm) {
         // This has to happen *after* we determine which pat_idents are variants
         self.check_consistent_bindings(&arm.pats);
 
-        match arm.guard {
-            Some(ast::Guard::If(ref expr)) => self.visit_expr(expr),
-            _ => {}
+        if let Some(ast::Guard::If(ref expr)) = arm.guard {
+            self.visit_expr(expr)
         }
         self.visit_expr(&arm.body);
 
@@ -2980,14 +2991,14 @@ fn smart_resolve_path_fragment(&mut self,
             // Make the base error.
             let expected = source.descr_expected();
             let path_str = names_to_string(path);
-            let item_str = path[path.len() - 1];
+            let item_str = path.last().unwrap();
             let code = source.error_code(def.is_some());
             let (base_msg, fallback_label, base_span) = if let Some(def) = def {
                 (format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str),
                  format!("not a {}", expected),
                  span)
             } else {
-                let item_span = path[path.len() - 1].span;
+                let item_span = path.last().unwrap().span;
                 let (mod_prefix, mod_str) = if path.len() == 1 {
                     (String::new(), "this scope".to_string())
                 } else if path.len() == 2 && path[0].name == keywords::CrateRoot.name() {
@@ -3010,10 +3021,7 @@ fn smart_resolve_path_fragment(&mut self,
             let mut err = this.session.struct_span_err_with_code(base_span, &base_msg, code);
 
             // Emit help message for fake-self from other languages like `this`(javascript)
-            let fake_self: Vec<Ident> = ["this", "my"].iter().map(
-                |s| Ident::from_str(*s)
-            ).collect();
-            if fake_self.contains(&item_str)
+            if ["this", "my"].contains(&&*item_str.as_str())
                 && this.self_value_is_available(path[0].span, span) {
                 err.span_suggestion_with_applicability(
                     span,
@@ -3354,7 +3362,7 @@ fn type_ascription_suggestion(&self,
                             );
                         }
                         break;
-                    } else if snippet.trim().len() != 0  {
+                    } else if !snippet.trim().is_empty() {
                         debug!("tried to find type ascription `:` token, couldn't find it");
                         break;
                     }
@@ -3664,8 +3672,8 @@ fn resolve_path_with_parent_scope(
                 self.resolve_ident_in_module(module, ident, ns, record_used, path_span)
             } else if opt_ns == Some(MacroNS) {
                 assert!(ns == TypeNS);
-                self.resolve_lexical_macro_path_segment(ident, ns, None, parent_scope, record_used,
-                                                        record_used, path_span).map(|(b, _)| b)
+                self.early_resolve_ident_in_lexical_scope(ident, ns, None, parent_scope,
+                                                          record_used, record_used, path_span)
             } else {
                 let record_used_id =
                     if record_used { crate_lint.node_id().or(Some(CRATE_NODE_ID)) } else { None };
@@ -3916,7 +3924,7 @@ fn adjust_local_def(&mut self,
             }
             _ => {}
         }
-        return def;
+        def
     }
 
     fn lookup_assoc_candidate<FilterFn>(&mut self,
@@ -4019,7 +4027,7 @@ fn lookup_typo_candidate<FilterFn>(&mut self,
                     } else {
                         // Items from the prelude
                         if !module.no_implicit_prelude {
-                            names.extend(self.session.extern_prelude.iter().cloned());
+                            names.extend(self.extern_prelude.iter().cloned());
                             if let Some(prelude) = self.prelude {
                                 add_module_candidates(prelude, &mut names);
                             }
@@ -4366,10 +4374,9 @@ fn lookup_import_candidates_from_module<FilterFn>(&mut self,
         where FilterFn: Fn(Def) -> bool
     {
         let mut candidates = Vec::new();
-        let mut worklist = Vec::new();
         let mut seen_modules = FxHashSet();
         let not_local_module = crate_name != keywords::Crate.ident();
-        worklist.push((start_module, Vec::<ast::PathSegment>::new(), not_local_module));
+        let mut worklist = vec![(start_module, Vec::<ast::PathSegment>::new(), not_local_module)];
 
         while let Some((in_module,
                         path_segments,
@@ -4456,32 +4463,24 @@ fn lookup_import_candidates<FilterFn>(&mut self,
                                           -> Vec<ImportSuggestion>
         where FilterFn: Fn(Def) -> bool
     {
-        let mut suggestions = vec![];
-
-        suggestions.extend(
-            self.lookup_import_candidates_from_module(
-                lookup_name, namespace, self.graph_root, keywords::Crate.ident(), &filter_fn
-            )
-        );
+        let mut suggestions = self.lookup_import_candidates_from_module(
+            lookup_name, namespace, self.graph_root, keywords::Crate.ident(), &filter_fn);
 
         if self.session.rust_2018() {
-            for &name in &self.session.extern_prelude {
+            let extern_prelude_names = self.extern_prelude.clone();
+            for &name in extern_prelude_names.iter() {
                 let ident = Ident::with_empty_ctxt(name);
-                match self.crate_loader.maybe_process_path_extern(name, ident.span) {
-                    Some(crate_id) => {
-                        let crate_root = self.get_module(DefId {
-                            krate: crate_id,
-                            index: CRATE_DEF_INDEX,
-                        });
-                        self.populate_module_if_necessary(&crate_root);
+                if let Some(crate_id) = self.crate_loader.maybe_process_path_extern(name,
+                                                                                    ident.span)
+                {
+                    let crate_root = self.get_module(DefId {
+                        krate: crate_id,
+                        index: CRATE_DEF_INDEX,
+                    });
+                    self.populate_module_if_necessary(&crate_root);
 
-                        suggestions.extend(
-                            self.lookup_import_candidates_from_module(
-                                lookup_name, namespace, crate_root, ident, &filter_fn
-                            )
-                        );
-                    }
-                    None => {}
+                    suggestions.extend(self.lookup_import_candidates_from_module(
+                        lookup_name, namespace, crate_root, ident, &filter_fn));
                 }
             }
         }
@@ -4494,9 +4493,8 @@ fn find_module(&mut self,
                    -> Option<(Module<'a>, ImportSuggestion)>
     {
         let mut result = None;
-        let mut worklist = Vec::new();
         let mut seen_modules = FxHashSet();
-        worklist.push((self.graph_root, Vec::new()));
+        let mut worklist = vec![(self.graph_root, Vec::new())];
 
         while let Some((in_module, path_segments)) = worklist.pop() {
             // abort if the module is already found