]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_resolve/lib.rs
rustc: replace Res in hir::Upvar with only Local/Upvar data.
[rust.git] / src / librustc_resolve / lib.rs
index c4a4dd306055bb92db05298eebe2bba46db2ef20..67ed6a773056bd7cb0a4f42312dc5ff1df611df1 100644 (file)
@@ -43,7 +43,7 @@
 use syntax::ext::base::SyntaxExtension;
 use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
 use syntax::ext::base::MacroKind;
-use syntax::symbol::{Symbol, keywords, sym};
+use syntax::symbol::{Symbol, kw, sym};
 use syntax::util::lev_distance::find_best_match_for_name;
 
 use syntax::visit::{self, FnKind, Visitor};
@@ -589,7 +589,7 @@ fn is_expected(self, res: Res) -> bool {
                 | Res::Def(DefKind::Trait, _)
                 | Res::Def(DefKind::TraitAlias, _)
                 | Res::Def(DefKind::TyAlias, _)
-                | Res::Def(DefKind::AssociatedTy, _)
+                | Res::Def(DefKind::AssocTy, _)
                 | Res::PrimTy(..)
                 | Res::Def(DefKind::TyParam, _)
                 | Res::SelfTy(..)
@@ -615,14 +615,14 @@ fn is_expected(self, res: Res) -> bool {
                 | Res::Upvar(..)
                 | Res::Def(DefKind::Fn, _)
                 | Res::Def(DefKind::Method, _)
-                | Res::Def(DefKind::AssociatedConst, _)
+                | Res::Def(DefKind::AssocConst, _)
                 | Res::SelfCtor(..)
                 | Res::Def(DefKind::ConstParam, _) => true,
                 _ => false,
             },
             PathSource::Pat => match res {
                 Res::Def(DefKind::Ctor(_, CtorKind::Const), _) |
-                Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssociatedConst, _) |
+                Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) |
                 Res::SelfCtor(..) => true,
                 _ => false,
             },
@@ -635,14 +635,14 @@ fn is_expected(self, res: Res) -> bool {
                 | Res::Def(DefKind::Union, _)
                 | Res::Def(DefKind::Variant, _)
                 | Res::Def(DefKind::TyAlias, _)
-                | Res::Def(DefKind::AssociatedTy, _)
+                | Res::Def(DefKind::AssocTy, _)
                 | Res::SelfTy(..) => true,
                 _ => false,
             },
             PathSource::TraitItem(ns) => match res {
-                Res::Def(DefKind::AssociatedConst, _)
+                Res::Def(DefKind::AssocConst, _)
                 | Res::Def(DefKind::Method, _) if ns == ValueNS => true,
-                Res::Def(DefKind::AssociatedTy, _) if ns == TypeNS => true,
+                Res::Def(DefKind::AssocTy, _) if ns == TypeNS => true,
                 _ => false,
             },
             PathSource::Visibility => match res {
@@ -762,7 +762,7 @@ fn visit_mod(
                 ItemKind::Use(..) => {
                     // don't suggest placing a use before the prelude
                     // import or other generated ones
-                    if item.span.ctxt().outer().expn_info().is_none() {
+                    if item.span.ctxt().outer_expn_info().is_none() {
                         self.span = Some(item.span.shrink_to_lo());
                         self.found_use = true;
                         return;
@@ -772,7 +772,7 @@ fn visit_mod(
                 ItemKind::ExternCrate(_) => {}
                 // but place them before the first other item
                 _ => if self.span.map_or(true, |span| item.span < span ) {
-                    if item.span.ctxt().outer().expn_info().is_none() {
+                    if item.span.ctxt().outer_expn_info().is_none() {
                         // don't insert between attributes and an item
                         if item.attrs.is_empty() {
                             self.span = Some(item.span.shrink_to_lo());
@@ -820,7 +820,7 @@ fn visit_ty(&mut self, ty: &'tcx Ty) {
                 self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type);
             }
             TyKind::ImplicitSelf => {
-                let self_ty = keywords::SelfUpper.ident();
+                let self_ty = Ident::with_empty_ctxt(kw::SelfUpper);
                 let res = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, Some(ty.id), ty.span)
                               .map_or(Res::Err, |d| d.res());
                 self.record_partial_res(ty.id, PartialRes::new(res));
@@ -860,7 +860,7 @@ fn visit_fn(&mut self,
             FnKind::ItemFn(_, ref header, ..) =>
                 (FnItemRibKind, &header.asyncness.node),
             FnKind::Method(_, ref sig, _, _) =>
-                (TraitOrImplItemRibKind, &sig.header.asyncness.node),
+                (AssocItemRibKind, &sig.header.asyncness.node),
             FnKind::Closure(_) =>
                 // Async closures aren't resolved through `visit_fn`-- they're
                 // processed separately
@@ -1033,7 +1033,7 @@ enum RibKind<'a> {
     /// methods or associated types. Allow references to ty params that impl or trait
     /// binds. Disallow any other upvars (including other ty params that are
     /// upvars).
-    TraitOrImplItemRibKind,
+    AssocItemRibKind,
 
     /// We passed through a function definition. Disallow upvars.
     /// Permit only those const parameters that are specified in the function's generics.
@@ -1511,9 +1511,9 @@ fn is_glob_import(&self) -> bool {
 
     fn is_importable(&self) -> bool {
         match self.res() {
-            Res::Def(DefKind::AssociatedConst, _)
+            Res::Def(DefKind::AssocConst, _)
             | Res::Def(DefKind::Method, _)
-            | Res::Def(DefKind::AssociatedTy, _) => false,
+            | Res::Def(DefKind::AssocTy, _) => false,
             _ => true,
         }
     }
@@ -1817,18 +1817,17 @@ fn resolve_str_path(
         is_value: bool
     ) -> hir::Path {
         let root = if crate_root.is_some() {
-            keywords::PathRoot
+            kw::PathRoot
         } else {
-            keywords::Crate
+            kw::Crate
         };
-        let segments = iter::once(root.ident())
+        let segments = iter::once(Ident::with_empty_ctxt(root))
             .chain(
                 crate_root.into_iter()
                     .chain(components.iter().cloned())
                     .map(Ident::with_empty_ctxt)
             ).map(|i| self.new_ast_path_segment(i)).collect::<Vec<_>>();
 
-
         let path = ast::Path {
             span,
             segments,
@@ -1866,7 +1865,7 @@ pub fn resolve_str_path_error(&mut self, span: Span, path_str: &str, is_value: b
         let path = if path_str.starts_with("::") {
             ast::Path {
                 span,
-                segments: iter::once(keywords::PathRoot.ident())
+                segments: iter::once(Ident::with_empty_ctxt(kw::PathRoot))
                     .chain({
                         path_str.split("::").skip(1).map(Ident::from_str)
                     })
@@ -1961,7 +1960,7 @@ pub fn new(session: &'a Session,
         let root_module_kind = ModuleKind::Def(
             DefKind::Mod,
             root_def_id,
-            keywords::Invalid.name(),
+            kw::Invalid,
         );
         let graph_root = arenas.alloc_module(ModuleData {
             no_implicit_prelude: attr::contains_name(&krate.attrs, sym::no_implicit_prelude),
@@ -2187,10 +2186,10 @@ fn resolve_ident_in_lexical_scope(&mut self,
                                       path_span: Span)
                                       -> Option<LexicalScopeBinding<'a>> {
         assert!(ns == TypeNS  || ns == ValueNS);
-        if ident.name == keywords::Invalid.name() {
+        if ident.name == kw::Invalid {
             return Some(LexicalScopeBinding::Res(Res::Err));
         }
-        ident.span = if ident.name == keywords::SelfUpper.name() {
+        ident.span = if ident.name == kw::SelfUpper {
             // FIXME(jseyfried) improve `Self` hygiene
             ident.span.with_ctxt(SyntaxContext::empty())
         } else if ns == TypeNS {
@@ -2309,7 +2308,7 @@ fn resolve_ident_in_lexical_scope(&mut self,
 
     fn hygienic_lexical_parent(&mut self, module: Module<'a>, span: &mut Span)
                                -> Option<Module<'a>> {
-        if !module.expansion.is_descendant_of(span.ctxt().outer()) {
+        if !module.expansion.outer_is_descendant_of(span.ctxt()) {
             return Some(self.macro_def_scope(span.remove_mark()));
         }
 
@@ -2345,7 +2344,7 @@ fn hygienic_lexical_parent_with_compatibility_fallback(&mut self, module: Module
             module.expansion.is_descendant_of(parent.expansion) {
                 // The macro is a proc macro derive
                 if module.expansion.looks_like_proc_macro_derive() {
-                    if parent.expansion.is_descendant_of(span.ctxt().outer()) {
+                    if parent.expansion.outer_is_descendant_of(span.ctxt()) {
                         *poisoned = Some(node_id);
                         return module.parent;
                     }
@@ -2405,7 +2404,7 @@ fn resolve_ident_in_module_ext(
 
     fn resolve_crate_root(&mut self, ident: Ident) -> Module<'a> {
         let mut ctxt = ident.span.ctxt();
-        let mark = if ident.name == keywords::DollarCrate.name() {
+        let mark = if ident.name == kw::DollarCrate {
             // When resolving `$crate` from a `macro_rules!` invoked in a `macro`,
             // we don't want to pretend that the `macro_rules!` definition is in the `macro`
             // as described in `SyntaxContext::apply_mark`, so we ignore prepended modern marks.
@@ -2613,7 +2612,7 @@ fn resolve_item(&mut self, item: &Item) {
 
                         for trait_item in trait_items {
                             let generic_params = HasGenericParams(&trait_item.generics,
-                                                                    TraitOrImplItemRibKind);
+                                                                    AssocItemRibKind);
                             this.with_generic_param_rib(generic_params, |this| {
                                 match trait_item.node {
                                     TraitItemKind::Const(ref ty, ref default) => {
@@ -2851,7 +2850,7 @@ fn with_self_rib<F>(&mut self, self_res: Res, f: F)
         let mut self_type_rib = Rib::new(NormalRibKind);
 
         // Plain insert (no renaming, since types are not currently hygienic)
-        self_type_rib.bindings.insert(keywords::SelfUpper.ident(), self_res);
+        self_type_rib.bindings.insert(Ident::with_empty_ctxt(kw::SelfUpper), self_res);
         self.ribs[TypeNS].push(self_type_rib);
         f(self);
         self.ribs[TypeNS].pop();
@@ -2862,7 +2861,7 @@ fn with_self_struct_ctor_rib<F>(&mut self, impl_id: DefId, f: F)
     {
         let self_res = Res::SelfCtor(impl_id);
         let mut self_type_rib = Rib::new(NormalRibKind);
-        self_type_rib.bindings.insert(keywords::SelfUpper.ident(), self_res);
+        self_type_rib.bindings.insert(Ident::with_empty_ctxt(kw::SelfUpper), self_res);
         self.ribs[ValueNS].push(self_type_rib);
         f(self);
         self.ribs[ValueNS].pop();
@@ -2900,7 +2899,7 @@ fn resolve_implementation(&mut self,
 
                                     // We also need a new scope for the impl item type parameters.
                                     let generic_params = HasGenericParams(&impl_item.generics,
-                                                                          TraitOrImplItemRibKind);
+                                                                          AssocItemRibKind);
                                     this.with_generic_param_rib(generic_params, |this| {
                                         use self::ResolutionError::*;
                                         match impl_item.node {
@@ -3199,7 +3198,7 @@ fn fresh_binding(&mut self,
             }
             None => {
                 // A completely fresh binding, add to the lists if it's valid.
-                if ident.name != keywords::Invalid.name() {
+                if ident.name != kw::Invalid {
                     bindings.insert(ident, outer_pat_id);
                     self.ribs[ValueNS].last_mut().unwrap().bindings.insert(ident, res);
                 }
@@ -3494,13 +3493,13 @@ fn type_ascription_suggestion(
     }
 
     fn self_type_is_available(&mut self, span: Span) -> bool {
-        let binding = self.resolve_ident_in_lexical_scope(keywords::SelfUpper.ident(),
+        let binding = self.resolve_ident_in_lexical_scope(Ident::with_empty_ctxt(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(keywords::SelfLower.name(), self_span);
+        let ident = Ident::new(kw::SelfLower, self_span);
         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 }
     }
@@ -3657,8 +3656,8 @@ fn resolve_qpath(
         };
 
         if path.len() > 1 && !global_by_default && result.base_res() != Res::Err &&
-           path[0].ident.name != keywords::PathRoot.name() &&
-           path[0].ident.name != keywords::DollarCrate.name() {
+           path[0].ident.name != kw::PathRoot &&
+           path[0].ident.name != kw::DollarCrate {
             let unqualified_result = {
                 match self.resolve_path_without_parent_scope(
                     &[*path.last().unwrap()],
@@ -3739,11 +3738,11 @@ fn resolve_path(
             let name = ident.name;
 
             allow_super &= ns == TypeNS &&
-                (name == keywords::SelfLower.name() ||
-                 name == keywords::Super.name());
+                (name == kw::SelfLower ||
+                 name == kw::Super);
 
             if ns == TypeNS {
-                if allow_super && name == keywords::Super.name() {
+                if allow_super && name == kw::Super {
                     let mut ctxt = ident.span.ctxt().modern();
                     let self_module = match i {
                         0 => Some(self.resolve_self(&mut ctxt, self.current_module)),
@@ -3768,25 +3767,25 @@ fn resolve_path(
                     };
                 }
                 if i == 0 {
-                    if name == keywords::SelfLower.name() {
+                    if name == kw::SelfLower {
                         let mut ctxt = ident.span.ctxt().modern();
                         module = Some(ModuleOrUniformRoot::Module(
                             self.resolve_self(&mut ctxt, self.current_module)));
                         continue;
                     }
-                    if name == keywords::PathRoot.name() && ident.span.rust_2018() {
+                    if name == kw::PathRoot && ident.span.rust_2018() {
                         module = Some(ModuleOrUniformRoot::ExternPrelude);
                         continue;
                     }
-                    if name == keywords::PathRoot.name() &&
+                    if name == kw::PathRoot &&
                        ident.span.rust_2015() && self.session.rust_2018() {
                         // `::a::b` from 2015 macro on 2018 global edition
                         module = Some(ModuleOrUniformRoot::CrateRootAndExternPrelude);
                         continue;
                     }
-                    if name == keywords::PathRoot.name() ||
-                       name == keywords::Crate.name() ||
-                       name == keywords::DollarCrate.name() {
+                    if name == kw::PathRoot ||
+                       name == kw::Crate ||
+                       name == kw::DollarCrate {
                         // `::a::b`, `crate::a::b` or `$crate::a::b`
                         module = Some(ModuleOrUniformRoot::Module(
                             self.resolve_crate_root(ident)));
@@ -3797,12 +3796,12 @@ fn resolve_path(
 
             // Report special messages for path segment keywords in wrong positions.
             if ident.is_path_segment_keyword() && i != 0 {
-                let name_str = if name == keywords::PathRoot.name() {
+                let name_str = if name == kw::PathRoot {
                     "crate root".to_string()
                 } else {
                     format!("`{}`", name)
                 };
-                let label = if i == 1 && path[0].ident.name == keywords::PathRoot.name() {
+                let label = if i == 1 && path[0].ident.name == kw::PathRoot {
                     format!("global paths cannot start with {}", name_str)
                 } else {
                     format!("{} in paths can only be used in start position", name_str)
@@ -3971,13 +3970,13 @@ fn lint_if_path_starts_with_module(
 
         // We're only interested in `use` paths which should start with
         // `{{root}}` currently.
-        if first_name != keywords::PathRoot.name() {
+        if first_name != kw::PathRoot {
             return
         }
 
         match path.get(1) {
             // If this import looks like `crate::...` it's already good
-            Some(Segment { ident, .. }) if ident.name == keywords::Crate.name() => return,
+            Some(Segment { ident, .. }) if ident.name == kw::Crate => return,
             // Otherwise go below to see if it's an extern crate
             Some(_) => {}
             // If the path has length one (and it's `PathRoot` most likely)
@@ -4041,7 +4040,7 @@ fn adjust_local_res(&mut self,
             Res::Upvar(..) => {
                 span_bug!(span, "unexpected {:?} in bindings", res)
             }
-            Res::Local(node_id) => {
+            Res::Local(var_id) => {
                 use ResolutionError::*;
                 let mut res_err = None;
 
@@ -4052,30 +4051,34 @@ fn adjust_local_res(&mut self,
                             // Nothing to do. Continue.
                         }
                         ClosureRibKind(function_id) => {
-                            let prev_res = res;
+                            let parent = match res {
+                                Res::Upvar(_, i, closure) => Some((closure, i)),
+                                _ => None,
+                            };
 
                             let seen = self.upvars_seen
                                            .entry(function_id)
                                            .or_default();
-                            if let Some(&index) = seen.get(&node_id) {
-                                res = Res::Upvar(node_id, index, function_id);
+                            if let Some(&index) = seen.get(&var_id) {
+                                res = Res::Upvar(var_id, index, function_id);
                                 continue;
                             }
                             let vec = self.upvars
                                           .entry(function_id)
                                           .or_default();
                             let depth = vec.len();
-                            res = Res::Upvar(node_id, depth, function_id);
+                            res = Res::Upvar(var_id, depth, function_id);
 
                             if record_used {
                                 vec.push(Upvar {
-                                    res: prev_res,
+                                    var_id,
+                                    parent,
                                     span,
                                 });
-                                seen.insert(node_id, depth);
+                                seen.insert(var_id, depth);
                             }
                         }
-                        ItemRibKind | FnItemRibKind | TraitOrImplItemRibKind => {
+                        ItemRibKind | FnItemRibKind | AssocItemRibKind => {
                             // This was an attempt to access an upvar inside a
                             // named function item. This is not allowed, so we
                             // report an error.
@@ -4104,7 +4107,7 @@ fn adjust_local_res(&mut self,
             Res::Def(DefKind::TyParam, _) | Res::SelfTy(..) => {
                 for rib in ribs {
                     match rib.kind {
-                        NormalRibKind | TraitOrImplItemRibKind | ClosureRibKind(..) |
+                        NormalRibKind | AssocItemRibKind | ClosureRibKind(..) |
                         ModuleRibKind(..) | MacroDefinition(..) | ForwardTyParamBanRibKind |
                         ConstantItemRibKind | TyParamAsConstParamTy => {
                             // Nothing to do. Continue.
@@ -4670,7 +4673,7 @@ fn lookup_import_candidates_from_module<FilterFn>(&mut self,
     {
         let mut candidates = Vec::new();
         let mut seen_modules = FxHashSet::default();
-        let not_local_module = crate_name != keywords::Crate.ident();
+        let not_local_module = crate_name.name != kw::Crate;
         let mut worklist = vec![(start_module, Vec::<ast::PathSegment>::new(), not_local_module)];
 
         while let Some((in_module,
@@ -4764,7 +4767,8 @@ fn lookup_import_candidates<FilterFn>(&mut self,
         where FilterFn: Fn(Res) -> bool
     {
         let mut suggestions = self.lookup_import_candidates_from_module(
-            lookup_ident, namespace, self.graph_root, keywords::Crate.ident(), &filter_fn);
+            lookup_ident, namespace, self.graph_root, Ident::with_empty_ctxt(kw::Crate), &filter_fn
+        );
 
         if lookup_ident.span.rust_2018() {
             let extern_prelude_names = self.extern_prelude.clone();
@@ -4883,7 +4887,7 @@ fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility {
                 } else {
                     let ctxt = ident.span.ctxt();
                     Some(Segment::from_ident(Ident::new(
-                        keywords::PathRoot.name(), path.span.shrink_to_lo().with_ctxt(ctxt)
+                        kw::PathRoot, path.span.shrink_to_lo().with_ctxt(ctxt)
                     )))
                 };
 
@@ -5352,17 +5356,17 @@ fn extern_prelude_get(&mut self, ident: Ident, speculative: bool)
 }
 
 fn is_self_type(path: &[Segment], namespace: Namespace) -> bool {
-    namespace == TypeNS && path.len() == 1 && path[0].ident.name == keywords::SelfUpper.name()
+    namespace == TypeNS && path.len() == 1 && path[0].ident.name == kw::SelfUpper
 }
 
 fn is_self_value(path: &[Segment], namespace: Namespace) -> bool {
-    namespace == ValueNS && path.len() == 1 && path[0].ident.name == keywords::SelfLower.name()
+    namespace == ValueNS && path.len() == 1 && path[0].ident.name == kw::SelfLower
 }
 
 fn names_to_string(idents: &[Ident]) -> String {
     let mut result = String::new();
     for (i, ident) in idents.iter()
-                            .filter(|ident| ident.name != keywords::PathRoot.name())
+                            .filter(|ident| ident.name != kw::PathRoot)
                             .enumerate() {
         if i > 0 {
             result.push_str("::");