From 7da9250fb51e71ecd3dbb4c760c24e836ed3530f Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 4 May 2019 17:22:00 +0300 Subject: [PATCH] Remove `Res::Label` Paths can never resolve to labels --- src/librustc/hir/def.rs | 4 ---- src/librustc/hir/lowering.rs | 5 ++++- src/librustc_resolve/lib.rs | 35 +++++++++++++++++-------------- src/librustc_save_analysis/lib.rs | 1 - src/librustc_save_analysis/sig.rs | 2 +- 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 { 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 Res { Res::Local(..) | Res::Upvar(..) | - Res::Label(..) | Res::PrimTy(..) | Res::SelfTy(..) | Res::SelfCtor(..) | @@ -377,7 +375,6 @@ impl Res { 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 Res { 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>>; + /// Obtain resolution for a label with the given `NodeId`. + fn get_label_res(&mut self, id: NodeId) -> Option; + /// 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, +struct Rib<'a, R = Res> { + bindings: FxHashMap, 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>>, /// The current set of local scopes, for labels. - label_ribs: Vec>, + label_ribs: Vec>, /// 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, /// Resolutions for import nodes, which have multiple resolutions in different namespaces. import_res_map: NodeMap>>, + /// Resolutions for labels (node IDs of their corresponding blocks or loops). + label_res_map: NodeMap, pub freevars: FreevarMap, freevars_seen: NodeMap>, @@ -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 { + 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(&self, mut ident: Ident, pred: P) -> Option - where P: Fn(&Rib<'_>, Ident) -> Option + where P: Fn(&Rib<'_, NodeId>, Ident) -> Option { 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![],