Skip to content

Commit 257d8fc

Browse files
committed
Do not report mixed label/lifetime shadowing.
1 parent 85cbd0b commit 257d8fc

File tree

2 files changed

+45
-111
lines changed

2 files changed

+45
-111
lines changed

compiler/rustc_resolve/src/late.rs

Lines changed: 12 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ use crate::{path_names_to_string, BindingError, Finalize, LexicalScopeBinding};
1212
use crate::{Module, ModuleOrUniformRoot, NameBinding, ParentScope, PathResult};
1313
use crate::{ResolutionError, Resolver, Segment, UseError};
1414

15-
use diagnostics::{
16-
original_label, original_lifetime, original_lifetime_param, shadower_label, shadower_lifetime,
17-
};
18-
1915
use rustc_ast::ptr::P;
2016
use rustc_ast::visit::{self, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor};
2117
use rustc_ast::*;
@@ -1902,6 +1898,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
19021898
let mut function_value_rib = Rib::new(kind);
19031899
let mut function_lifetime_rib = LifetimeRib::new(lifetime_kind);
19041900
let mut seen_bindings = FxHashMap::default();
1901+
// Store all seen lifetimes names, and whether they were created in the currently processed
1902+
// parameter set.
19051903
let mut seen_lifetimes = FxHashMap::default();
19061904

19071905
// We also can't shadow bindings from the parent item
@@ -1920,20 +1918,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
19201918

19211919
// Forbid shadowing lifetime bindings
19221920
for rib in self.lifetime_ribs.iter().rev() {
1923-
seen_lifetimes.extend(
1924-
rib.bindings.iter().map(|(ident, _)| (*ident, original_lifetime(ident.span))),
1925-
);
1921+
seen_lifetimes.extend(rib.bindings.iter().map(|(ident, _)| (*ident, false)));
19261922
if let LifetimeRibKind::Item = rib.kind {
19271923
break;
19281924
}
19291925
}
1930-
for rib in self.label_ribs.iter().rev() {
1931-
if rib.kind.is_label_barrier() {
1932-
break;
1933-
}
1934-
seen_lifetimes
1935-
.extend(rib.bindings.iter().map(|(ident, _)| (*ident, original_label(ident.span))));
1936-
}
19371926

19381927
for param in params {
19391928
let ident = param.ident.normalize_to_macros_2_0();
@@ -1942,16 +1931,17 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
19421931
if let GenericParamKind::Lifetime = param.kind {
19431932
match seen_lifetimes.entry(ident) {
19441933
Entry::Occupied(entry) => {
1945-
let original = *entry.get();
1946-
diagnostics::signal_shadowing_problem(
1934+
let original = *entry.key();
1935+
let orig_is_param = *entry.get();
1936+
diagnostics::signal_lifetime_shadowing(
19471937
self.r.session,
1948-
ident.name,
19491938
original,
1950-
shadower_lifetime(param.ident.span),
1951-
)
1939+
param.ident,
1940+
orig_is_param,
1941+
);
19521942
}
19531943
Entry::Vacant(entry) => {
1954-
entry.insert(original_lifetime_param(param.ident.span));
1944+
entry.insert(true);
19551945
}
19561946
}
19571947
} else {
@@ -3155,26 +3145,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
31553145
self.diagnostic_metadata.unused_labels.insert(id, label.ident.span);
31563146
}
31573147

3158-
// Forbid shadowing lifetime bindings
31593148
let ident = label.ident.normalize_to_macro_rules();
3160-
for rib in self.lifetime_ribs.iter().rev() {
3161-
if let Some((orig_ident, _)) = rib.bindings.get_key_value(&ident) {
3162-
diagnostics::signal_shadowing_problem(
3163-
self.r.session,
3164-
label.ident.name,
3165-
original_lifetime(orig_ident.span),
3166-
shadower_label(label.ident.span),
3167-
)
3168-
}
3169-
}
31703149
for rib in self.label_ribs.iter_mut().rev() {
3171-
if let Some((orig_ident, _)) = rib.bindings.get_key_value(&ident) {
3172-
diagnostics::signal_shadowing_problem(
3173-
self.r.session,
3174-
label.ident.name,
3175-
original_label(orig_ident.span),
3176-
shadower_label(label.ident.span),
3177-
)
3150+
if let Some((&orig_ident, _)) = rib.bindings.get_key_value(&ident) {
3151+
diagnostics::signal_label_shadowing(self.r.session, orig_ident, label.ident)
31783152
}
31793153
if rib.kind.is_label_barrier() {
31803154
rib.bindings.insert(ident, id);

compiler/rustc_resolve/src/late/diagnostics.rs

Lines changed: 33 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -2037,84 +2037,44 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
20372037
}
20382038
}
20392039

2040-
#[derive(Copy, Clone, PartialEq)]
2041-
enum ShadowKind {
2042-
Label,
2043-
Lifetime,
2044-
}
2045-
#[derive(Copy, Clone)]
2046-
pub struct Original {
2047-
kind: ShadowKind,
2048-
span: Span,
2049-
param: bool,
2050-
}
2051-
#[derive(Copy, Clone)]
2052-
pub struct Shadower {
2053-
kind: ShadowKind,
2054-
span: Span,
2055-
}
2056-
2057-
pub fn original_label(span: Span) -> Original {
2058-
Original { kind: ShadowKind::Label, span, param: false }
2059-
}
2060-
pub fn shadower_label(span: Span) -> Shadower {
2061-
Shadower { kind: ShadowKind::Label, span }
2062-
}
2063-
pub fn original_lifetime(span: Span) -> Original {
2064-
Original { kind: ShadowKind::Lifetime, span, param: false }
2065-
}
2066-
pub fn original_lifetime_param(span: Span) -> Original {
2067-
Original { kind: ShadowKind::Lifetime, span, param: true }
2068-
}
2069-
pub fn shadower_lifetime(span: Span) -> Shadower {
2070-
Shadower { kind: ShadowKind::Lifetime, span }
2071-
}
2072-
2073-
impl ShadowKind {
2074-
fn desc(&self) -> &'static str {
2075-
match *self {
2076-
ShadowKind::Label => "label",
2077-
ShadowKind::Lifetime => "lifetime",
2078-
}
2079-
}
2080-
}
2081-
2082-
pub fn signal_shadowing_problem(sess: &Session, name: Symbol, orig: Original, shadower: Shadower) {
2083-
let mut err = if let (ShadowKind::Lifetime, ShadowKind::Lifetime) = (orig.kind, shadower.kind) {
2084-
// lifetime/lifetime shadowing is an error
2085-
if orig.param {
2086-
struct_span_err!(
2087-
sess,
2088-
shadower.span,
2089-
E0263,
2090-
"lifetime name `{}` declared twice in the same scope",
2091-
name,
2092-
)
2093-
} else {
2094-
struct_span_err!(
2095-
sess,
2096-
shadower.span,
2097-
E0496,
2098-
"lifetime name `{}` shadows a lifetime name that is already in scope",
2099-
name,
2100-
)
2101-
}
2102-
.forget_guarantee()
2040+
/// Report lifetime/lifetime shadowing as an error.
2041+
pub fn signal_lifetime_shadowing(
2042+
sess: &Session,
2043+
orig: Ident,
2044+
shadower: Ident,
2045+
orig_is_param: bool,
2046+
) {
2047+
let mut err = if orig_is_param {
2048+
struct_span_err!(
2049+
sess,
2050+
shadower.span,
2051+
E0263,
2052+
"lifetime name `{}` declared twice in the same scope",
2053+
orig.name,
2054+
)
21032055
} else {
2104-
// shadowing involving a label is only a warning, due to issues with
2105-
// labels and lifetimes not being macro-hygienic.
2106-
sess.struct_span_warn(
2056+
struct_span_err!(
2057+
sess,
21072058
shadower.span,
2108-
&format!(
2109-
"{} name `{}` shadows a {} name that is already in scope",
2110-
shadower.kind.desc(),
2111-
name,
2112-
orig.kind.desc()
2113-
),
2059+
E0496,
2060+
"lifetime name `{}` shadows a lifetime name that is already in scope",
2061+
orig.name,
21142062
)
21152063
};
21162064
err.span_label(orig.span, "first declared here");
2117-
err.span_label(shadower.span, format!("{} `{}` already in scope", orig.kind.desc(), name));
2065+
err.span_label(shadower.span, format!("lifetime `{}` already in scope", orig.name));
2066+
err.emit();
2067+
}
2068+
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) {
2072+
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+
);
2076+
err.span_label(orig.span, "first declared here");
2077+
err.span_label(shadower.span, format!("label `{}` already in scope", orig.name));
21182078
err.emit();
21192079
}
21202080

0 commit comments

Comments
 (0)