mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 00:03:43 +00:00
Remove Res::Label
Paths can never resolve to labels
This commit is contained in:
parent
85ddd1dc58
commit
7da9250fb5
@ -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),
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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(..) |
|
||||
|
@ -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![],
|
||||
|
Loading…
Reference in New Issue
Block a user