Remove Res::Label

Paths can never resolve to labels
This commit is contained in:
Vadim Petrochenkov 2019-05-04 17:22:00 +03:00
parent 85ddd1dc58
commit 7da9250fb5
5 changed files with 24 additions and 23 deletions

View File

@ -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),

View File

@ -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)

View File

@ -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);
}
}

View File

@ -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(..) |

View File

@ -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![],