Skip to content

Commit 86bd990

Browse files
committed
Reuse resolve_label to check lifetime shadowing.
1 parent c75409d commit 86bd990

File tree

2 files changed

+29
-40
lines changed

2 files changed

+29
-40
lines changed

Diff for: compiler/rustc_resolve/src/late.rs

+20-33
Original file line numberDiff line numberDiff line change
@@ -1548,13 +1548,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
15481548

15491549
/// Searches the current set of local scopes for labels. Returns the `NodeId` of the resolved
15501550
/// label and reports an error if the label is not found or is unreachable.
1551-
fn resolve_label(&mut self, mut label: Ident) -> Option<NodeId> {
1551+
fn resolve_label(&mut self, mut label: Ident) -> Result<(NodeId, Span), ResolutionError<'a>> {
15521552
let mut suggestion = None;
15531553

1554-
// Preserve the original span so that errors contain "in this macro invocation"
1555-
// information.
1556-
let original_span = label.span;
1557-
15581554
for i in (0..self.label_ribs.len()).rev() {
15591555
let rib = &self.label_ribs[i];
15601556

@@ -1570,18 +1566,13 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
15701566
if let Some((ident, id)) = rib.bindings.get_key_value(&ident) {
15711567
let definition_span = ident.span;
15721568
return if self.is_label_valid_from_rib(i) {
1573-
Some(*id)
1569+
Ok((*id, definition_span))
15741570
} else {
1575-
self.report_error(
1576-
original_span,
1577-
ResolutionError::UnreachableLabel {
1578-
name: label.name,
1579-
definition_span,
1580-
suggestion,
1581-
},
1582-
);
1583-
1584-
None
1571+
Err(ResolutionError::UnreachableLabel {
1572+
name: label.name,
1573+
definition_span,
1574+
suggestion,
1575+
})
15851576
};
15861577
}
15871578

@@ -1590,11 +1581,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
15901581
suggestion = suggestion.or_else(|| self.suggestion_for_label_in_rib(i, label));
15911582
}
15921583

1593-
self.report_error(
1594-
original_span,
1595-
ResolutionError::UndeclaredLabel { name: label.name, suggestion },
1596-
);
1597-
None
1584+
Err(ResolutionError::UndeclaredLabel { name: label.name, suggestion })
15981585
}
15991586

16001587
/// Determine whether or not a label from the `rib_index`th label rib is reachable.
@@ -3152,17 +3139,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
31523139
self.diagnostic_metadata.unused_labels.insert(id, label.ident.span);
31533140
}
31543141

3155-
let ident = label.ident.normalize_to_macro_rules();
3156-
for rib in self.label_ribs.iter_mut().rev() {
3157-
if let Some((&orig_ident, _)) = rib.bindings.get_key_value(&ident) {
3158-
diagnostics::signal_label_shadowing(self.r.session, orig_ident, label.ident)
3159-
}
3160-
if rib.kind.is_label_barrier() {
3161-
break;
3162-
}
3142+
if let Ok((_, orig_span)) = self.resolve_label(label.ident) {
3143+
diagnostics::signal_label_shadowing(self.r.session, orig_span, label.ident)
31633144
}
31643145

31653146
self.with_label_rib(NormalRibKind, |this| {
3147+
let ident = label.ident.normalize_to_macro_rules();
31663148
this.label_ribs.last_mut().unwrap().bindings.insert(ident, id);
31673149
f(this);
31683150
});
@@ -3266,10 +3248,15 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
32663248
}
32673249

32683250
ExprKind::Break(Some(label), _) | ExprKind::Continue(Some(label)) => {
3269-
if let Some(node_id) = self.resolve_label(label.ident) {
3270-
// Since this res is a label, it is never read.
3271-
self.r.label_res_map.insert(expr.id, node_id);
3272-
self.diagnostic_metadata.unused_labels.remove(&node_id);
3251+
match self.resolve_label(label.ident) {
3252+
Ok((node_id, _)) => {
3253+
// Since this res is a label, it is never read.
3254+
self.r.label_res_map.insert(expr.id, node_id);
3255+
self.diagnostic_metadata.unused_labels.remove(&node_id);
3256+
}
3257+
Err(error) => {
3258+
self.report_error(label.ident.span, error);
3259+
}
32733260
}
32743261

32753262
// visit `break` argument if any

Diff for: compiler/rustc_resolve/src/late/diagnostics.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -2066,15 +2066,17 @@ pub fn signal_lifetime_shadowing(
20662066
err.emit();
20672067
}
20682068

2069-
/// Shadowing involving a label is only a warning, due to issues with
2070-
/// labels and lifetimes not being macro-hygienic.
2071-
pub fn signal_label_shadowing(sess: &Session, orig: Ident, shadower: Ident) {
2069+
/// Shadowing involving a label is only a warning for historical reasons.
2070+
//FIXME: make this a proper lint.
2071+
pub fn signal_label_shadowing(sess: &Session, orig: Span, shadower: Ident) {
2072+
let name = shadower.name;
2073+
let shadower = shadower.span;
20722074
let mut err = sess.struct_span_warn(
2073-
shadower.span,
2074-
&format!("label name `{}` shadows a label name that is already in scope", orig.name),
2075+
shadower,
2076+
&format!("label name `{}` shadows a label name that is already in scope", name),
20752077
);
2076-
err.span_label(orig.span, "first declared here");
2077-
err.span_label(shadower.span, format!("label `{}` already in scope", orig.name));
2078+
err.span_label(orig, "first declared here");
2079+
err.span_label(shadower, format!("label `{}` already in scope", name));
20782080
err.emit();
20792081
}
20802082

0 commit comments

Comments
 (0)