about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-05-04 17:22:00 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-05-04 17:22:00 +0300
commit7da9250fb51e71ecd3dbb4c760c24e836ed3530f (patch)
tree5cfdf5d81bc7515770a171bba307ab3c0ec7f047
parent85ddd1dc587615a0dc76cef80ff7d88a1b4bc28e (diff)
Remove `Res::Label`
Paths can never resolve to labels
-rw-r--r--src/librustc/hir/def.rs4
-rw-r--r--src/librustc/hir/lowering.rs5
-rw-r--r--src/librustc_resolve/lib.rs35
-rw-r--r--src/librustc_save_analysis/lib.rs1
-rw-r--r--src/librustc_save_analysis/sig.rs2
5 files changed, 24 insertions, 23 deletions
diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs
index 87af450451e..0719eb701a9 100644
--- a/src/librustc/hir/def.rs
+++ b/src/librustc/hir/def.rs
@@ -142,7 +142,6 @@ pub enum Res<Id = hir::HirId> {
     Upvar(Id,           // `HirId` of closed over local
           usize,        // index in the `freevars` list of the closure
           ast::NodeId), // expr node that creates the closure
-    Label(ast::NodeId),
 
     // Macro namespace
     NonMacroAttr(NonMacroAttrKind), // e.g., `#[inline]` or `#[rustfmt::skip]`
@@ -349,7 +348,6 @@ impl<Id> Res<Id> {
 
             Res::Local(..) |
             Res::Upvar(..) |
-            Res::Label(..)  |
             Res::PrimTy(..) |
             Res::SelfTy(..) |
             Res::SelfCtor(..) |
@@ -377,7 +375,6 @@ impl<Id> Res<Id> {
             Res::PrimTy(..) => "builtin type",
             Res::Local(..) => "local variable",
             Res::Upvar(..) => "closure capture",
-            Res::Label(..) => "label",
             Res::SelfTy(..) => "self type",
             Res::ToolMod => "tool module",
             Res::NonMacroAttr(attr_kind) => attr_kind.descr(),
@@ -405,7 +402,6 @@ impl<Id> Res<Id> {
                 index,
                 closure
             ),
-            Res::Label(id) => Res::Label(id),
             Res::SelfTy(a, b) => Res::SelfTy(a, b),
             Res::ToolMod => Res::ToolMod,
             Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 9ae9995be43..fc3987a4b19 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -151,6 +151,9 @@ pub trait Resolver {
     /// Obtain per-namespace resolutions for `use` statement with the given `NoedId`.
     fn get_import_res(&mut self, id: NodeId) -> PerNS<Option<Res<NodeId>>>;
 
+    /// Obtain resolution for a label with the given `NodeId`.
+    fn get_label_res(&mut self, id: NodeId) -> Option<NodeId>;
+
     /// We must keep the set of definitions up to date as we add nodes that weren't in the AST.
     /// This should only return `None` during testing.
     fn definitions(&mut self) -> &mut Definitions;
@@ -1246,7 +1249,7 @@ impl<'a> LoweringContext<'a> {
     fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>) -> hir::Destination {
         let target_id = match destination {
             Some((id, _)) => {
-                if let Res::Label(loop_id) = self.expect_full_res(id) {
+                if let Some(loop_id) = self.resolver.get_label_res(id) {
                     Ok(self.lower_node_id(loop_id))
                 } else {
                     Err(hir::LoopIdError::UnresolvedLabel)
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 88465535c2c..0be26451ae4 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1071,13 +1071,13 @@ enum RibKind<'a> {
 /// 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)]
-struct Rib<'a> {
-    bindings: FxHashMap<Ident, Res>,
+struct Rib<'a, R = Res> {
+    bindings: FxHashMap<Ident, R>,
     kind: RibKind<'a>,
 }
 
-impl<'a> Rib<'a> {
-    fn new(kind: RibKind<'a>) -> Rib<'a> {
+impl<'a, R> Rib<'a, R> {
+    fn new(kind: RibKind<'a>) -> Rib<'a, R> {
         Rib {
             bindings: Default::default(),
             kind,
@@ -1638,7 +1638,7 @@ pub struct Resolver<'a> {
     ribs: PerNS<Vec<Rib<'a>>>,
 
     /// The current set of local scopes, for labels.
-    label_ribs: Vec<Rib<'a>>,
+    label_ribs: Vec<Rib<'a, NodeId>>,
 
     /// The trait that the current context can refer to.
     current_trait_ref: Option<(Module<'a>, TraitRef)>,
@@ -1663,6 +1663,8 @@ pub struct Resolver<'a> {
     partial_res_map: NodeMap<PartialRes>,
     /// Resolutions for import nodes, which have multiple resolutions in different namespaces.
     import_res_map: NodeMap<PerNS<Option<Res>>>,
+    /// Resolutions for labels (node IDs of their corresponding blocks or loops).
+    label_res_map: NodeMap<NodeId>,
 
     pub freevars: FreevarMap,
     freevars_seen: NodeMap<NodeMap<usize>>,
@@ -1841,6 +1843,10 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
         self.import_res_map.get(&id).cloned().unwrap_or_default()
     }
 
+    fn get_label_res(&mut self, id: NodeId) -> Option<NodeId> {
+        self.label_res_map.get(&id).cloned()
+    }
+
     fn definitions(&mut self) -> &mut Definitions {
         &mut self.definitions
     }
@@ -2024,6 +2030,7 @@ impl<'a> Resolver<'a> {
 
             partial_res_map: Default::default(),
             import_res_map: Default::default(),
+            label_res_map: Default::default(),
             freevars: Default::default(),
             freevars_seen: Default::default(),
             export_map: FxHashMap::default(),
@@ -2490,7 +2497,7 @@ impl<'a> Resolver<'a> {
     ///
     /// Stops after meeting a closure.
     fn search_label<P, R>(&self, mut ident: Ident, pred: P) -> Option<R>
-        where P: Fn(&Rib<'_>, Ident) -> Option<R>
+        where P: Fn(&Rib<'_, NodeId>, Ident) -> Option<R>
     {
         for rib in self.label_ribs.iter().rev() {
             match rib.kind {
@@ -4332,10 +4339,9 @@ impl<'a> Resolver<'a> {
     {
         if let Some(label) = label {
             self.unused_labels.insert(id, label.ident.span);
-            let res = Res::Label(id);
             self.with_label_rib(|this| {
                 let ident = label.ident.modern_and_legacy();
-                this.label_ribs.last_mut().unwrap().bindings.insert(ident, res);
+                this.label_ribs.last_mut().unwrap().bindings.insert(ident, id);
                 f(this);
             });
         } else {
@@ -4366,10 +4372,10 @@ impl<'a> Resolver<'a> {
             }
 
             ExprKind::Break(Some(label), _) | ExprKind::Continue(Some(label)) => {
-                let res = self.search_label(label.ident, |rib, ident| {
+                let node_id = self.search_label(label.ident, |rib, ident| {
                     rib.bindings.get(&ident.modern_and_legacy()).cloned()
                 });
-                match res {
+                match node_id {
                     None => {
                         // Search again for close matches...
                         // Picks the first label that is "close enough", which is not necessarily
@@ -4390,13 +4396,10 @@ impl<'a> Resolver<'a> {
                                       ResolutionError::UndeclaredLabel(&label.ident.as_str(),
                                                                        close_match));
                     }
-                    Some(Res::Label(id)) => {
+                    Some(node_id) => {
                         // Since this res is a label, it is never read.
-                        self.record_partial_res(expr.id, PartialRes::new(Res::Label(id)));
-                        self.unused_labels.remove(&id);
-                    }
-                    Some(_) => {
-                        span_bug!(expr.span, "label wasn't mapped to a label res!");
+                        self.label_res_map.insert(expr.id, node_id);
+                        self.unused_labels.remove(&node_id);
                     }
                 }
 
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index c242b4d6a41..f3e0fb32ec2 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -796,7 +796,6 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
             }
             Res::PrimTy(..) |
             Res::SelfTy(..) |
-            Res::Label(..) |
             Res::Def(HirDefKind::Macro(..), _) |
             Res::ToolMod |
             Res::NonMacroAttr(..) |
diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs
index 4f759b8a73f..fa12d9c49df 100644
--- a/src/librustc_save_analysis/sig.rs
+++ b/src/librustc_save_analysis/sig.rs
@@ -579,7 +579,7 @@ impl Sig for ast::Path {
         let res = scx.get_path_res(id.ok_or("Missing id for Path")?);
 
         let (name, start, end) = match res {
-            Res::Label(..) | Res::PrimTy(..) | Res::SelfTy(..) | Res::Err => {
+            Res::PrimTy(..) | Res::SelfTy(..) | Res::Err => {
                 return Ok(Signature {
                     text: pprust::path_to_string(self),
                     defs: vec![],