Skip to content

Commit

Permalink
Use the same message as type & const generics.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjgillot committed Jun 3, 2022
1 parent 86bd990 commit 2aa9c70
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 71 deletions.
4 changes: 3 additions & 1 deletion compiler/rustc_error_codes/src/error_codes/E0263.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#### Note: this error code is no longer emitted by the compiler.

A lifetime was declared more than once in the same scope.

Erroneous code example:

```compile_fail,E0263
```compile_fail,E0403
fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str, z: &'a str) { // error!
}
```
Expand Down
48 changes: 20 additions & 28 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1885,9 +1885,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
let mut function_value_rib = Rib::new(kind);
let mut function_lifetime_rib = LifetimeRib::new(lifetime_kind);
let mut seen_bindings = FxHashMap::default();
// Store all seen lifetimes names, and whether they were created in the currently processed
// parameter set.
let mut seen_lifetimes = FxHashMap::default();
// Store all seen lifetimes names from outer scopes.
let mut seen_lifetimes = FxHashSet::default();

// We also can't shadow bindings from the parent item
if let AssocItemRibKind = kind {
Expand All @@ -1905,7 +1904,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {

// Forbid shadowing lifetime bindings
for rib in self.lifetime_ribs.iter().rev() {
seen_lifetimes.extend(rib.bindings.iter().map(|(ident, _)| (*ident, false)));
seen_lifetimes.extend(rib.bindings.iter().map(|(ident, _)| *ident));
if let LifetimeRibKind::Item = rib.kind {
break;
}
Expand All @@ -1915,35 +1914,28 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
let ident = param.ident.normalize_to_macros_2_0();
debug!("with_generic_param_rib: {}", param.id);

if let GenericParamKind::Lifetime = param.kind {
match seen_lifetimes.entry(ident) {
Entry::Occupied(entry) => {
let original = *entry.key();
let orig_is_param = *entry.get();
diagnostics::signal_lifetime_shadowing(
self.r.session,
original,
param.ident,
orig_is_param,
);
if let GenericParamKind::Lifetime = param.kind
&& let Some(&original) = seen_lifetimes.get(&ident)
{
diagnostics::signal_lifetime_shadowing(self.r.session, original, param.ident);
// Record lifetime res, so lowering knows there is something fishy.
self.record_lifetime_res(param.id, LifetimeRes::Error);
continue;
}

match seen_bindings.entry(ident) {
Entry::Occupied(entry) => {
let span = *entry.get();
let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, span);
self.report_error(param.ident.span, err);
if let GenericParamKind::Lifetime = param.kind {
// Record lifetime res, so lowering knows there is something fishy.
self.record_lifetime_res(param.id, LifetimeRes::Error);
continue;
}
Entry::Vacant(entry) => {
entry.insert(true);
}
}
} else {
match seen_bindings.entry(ident) {
Entry::Occupied(entry) => {
let span = *entry.get();
let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, span);
self.report_error(param.ident.span, err);
}
Entry::Vacant(entry) => {
entry.insert(param.ident.span);
}
Entry::Vacant(entry) => {
entry.insert(param.ident.span);
}
}

Expand Down
31 changes: 8 additions & 23 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2038,29 +2038,14 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
}

/// Report lifetime/lifetime shadowing as an error.
pub fn signal_lifetime_shadowing(
sess: &Session,
orig: Ident,
shadower: Ident,
orig_is_param: bool,
) {
let mut err = if orig_is_param {
struct_span_err!(
sess,
shadower.span,
E0263,
"lifetime name `{}` declared twice in the same scope",
orig.name,
)
} else {
struct_span_err!(
sess,
shadower.span,
E0496,
"lifetime name `{}` shadows a lifetime name that is already in scope",
orig.name,
)
};
pub fn signal_lifetime_shadowing(sess: &Session, orig: Ident, shadower: Ident) {
let mut err = struct_span_err!(
sess,
shadower.span,
E0496,
"lifetime name `{}` shadows a lifetime name that is already in scope",
orig.name,
);
err.span_label(orig.span, "first declared here");
err.span_label(shadower.span, format!("lifetime `{}` already in scope", orig.name));
err.emit();
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/error-codes/E0263.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) {
//~^ ERROR E0263
//~^ ERROR E0403
}

fn main() {}
8 changes: 4 additions & 4 deletions src/test/ui/error-codes/E0263.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0263]: lifetime name `'a` declared twice in the same scope
error[E0403]: the name `'a` is already used for a generic parameter in this item's generic parameters
--> $DIR/E0263.rs:1:16
|
LL | fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) {
| -- ^^ lifetime `'a` already in scope
| -- ^^ already used
| |
| first declared here
| first use of `'a`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0263`.
For more information about this error, try `rustc --explain E0403`.
4 changes: 2 additions & 2 deletions src/test/ui/hygiene/duplicate_lifetimes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

#[rustc_macro_transparency = "semitransparent"]
macro m($a:lifetime) {
fn g<$a, 'a>() {} //~ ERROR lifetime name `'a` declared twice
fn g<$a, 'a>() {} //~ ERROR the name `'a` is already used for a generic parameter
}

#[rustc_macro_transparency = "transparent"]
macro n($a:lifetime) {
fn h<$a, 'a>() {} //~ ERROR lifetime name `'a` declared twice
fn h<$a, 'a>() {} //~ ERROR the name `'a` is already used for a generic parameter
}

m!('a);
Expand Down
14 changes: 7 additions & 7 deletions src/test/ui/hygiene/duplicate_lifetimes.stderr
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
error[E0263]: lifetime name `'a` declared twice in the same scope
error[E0403]: the name `'a` is already used for a generic parameter in this item's generic parameters
--> $DIR/duplicate_lifetimes.rs:8:14
|
LL | fn g<$a, 'a>() {}
| ^^ lifetime `'a` already in scope
| ^^ already used
...
LL | m!('a);
| ------
| | |
| | first declared here
| | first use of `'a`
| in this macro invocation
|
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0263]: lifetime name `'a` declared twice in the same scope
error[E0403]: the name `'a` is already used for a generic parameter in this item's generic parameters
--> $DIR/duplicate_lifetimes.rs:13:14
|
LL | fn h<$a, 'a>() {}
| ^^ lifetime `'a` already in scope
| ^^ already used
...
LL | n!('a);
| ------
| | |
| | first declared here
| | first use of `'a`
| in this macro invocation
|
= note: this error originates in the macro `n` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0263`.
For more information about this error, try `rustc --explain E0403`.
2 changes: 1 addition & 1 deletion src/test/ui/regions/regions-name-duplicated.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
struct Foo<'a, 'a> {
//~^ ERROR lifetime name `'a` declared twice
//~^ ERROR the name `'a` is already used for a generic parameter
x: &'a isize,
}

Expand Down
8 changes: 4 additions & 4 deletions src/test/ui/regions/regions-name-duplicated.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0263]: lifetime name `'a` declared twice in the same scope
error[E0403]: the name `'a` is already used for a generic parameter in this item's generic parameters
--> $DIR/regions-name-duplicated.rs:1:16
|
LL | struct Foo<'a, 'a> {
| -- ^^ lifetime `'a` already in scope
| -- ^^ already used
| |
| first declared here
| first use of `'a`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0263`.
For more information about this error, try `rustc --explain E0403`.

0 comments on commit 2aa9c70

Please sign in to comment.