Detect non-lifetime binder params shadowing item params

This commit is contained in:
Michael Goulet 2024-07-29 14:26:16 -04:00
parent 4db3d12e6f
commit 454c600004
6 changed files with 89 additions and 17 deletions

View File

@ -2671,17 +2671,17 @@ fn with_generic_param_rib<'c, F>(
// 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 RibKind::AssocItem = kind {
let mut add_bindings_for_ns = |ns| {
let parent_rib = self.ribs[ns]
.iter()
.rfind(|r| matches!(r.kind, RibKind::Item(..)))
.expect("associated item outside of an item");
// We also can't shadow bindings from associated parent items.
for ns in [ValueNS, TypeNS] {
for parent_rib in self.ribs[ns].iter().rev() {
seen_bindings.extend(parent_rib.bindings.keys().map(|ident| (*ident, ident.span)));
};
add_bindings_for_ns(ValueNS);
add_bindings_for_ns(TypeNS);
// Break at mod level, to account for nested items which are
// allowed to shadow generic param names.
if matches!(parent_rib.kind, RibKind::Module(..)) {
break;
}
}
}
// Forbid shadowing lifetime bindings

View File

@ -1,4 +1,4 @@
//@ known-bug: #119716
#![feature(non_lifetime_binders)]
trait Trait<T> {}
fn f<T>() -> impl for<T> Trait<impl Trait<T>> {}
fn f() -> impl for<T> Trait<impl Trait<T>> {}

View File

@ -9,9 +9,10 @@ fn bug<const N: Nat>(&self)
where
for<const N: usize = 3, T = u32> [(); COT::BYTES]:,
//~^ ERROR only lifetime parameters can be used in this context
//~^^ ERROR defaults for generic parameters are not allowed in `for<...>` binders
//~^^^ ERROR defaults for generic parameters are not allowed in `for<...>` binders
//~^^^^ ERROR failed to resolve: use of undeclared type `COT`
//~| ERROR defaults for generic parameters are not allowed in `for<...>` binders
//~| ERROR defaults for generic parameters are not allowed in `for<...>` binders
//~| ERROR failed to resolve: use of undeclared type `COT`
//~| ERROR the name `N` is already used for a generic parameter in this item's generic parameters
{
}

View File

@ -6,6 +6,15 @@ LL | fn bug<const N: Nat>(&self)
|
= note: associated functions are those in `impl` or `trait` definitions
error[E0403]: the name `N` is already used for a generic parameter in this item's generic parameters
--> $DIR/ice-predicates-of-no-entry-found-for-key-119275.rs:10:15
|
LL | fn bug<const N: Nat>(&self)
| - first use of `N`
...
LL | for<const N: usize = 3, T = u32> [(); COT::BYTES]:,
| ^ already used
error[E0412]: cannot find type `Nat` in this scope
--> $DIR/ice-predicates-of-no-entry-found-for-key-119275.rs:6:17
|
@ -40,7 +49,7 @@ error[E0433]: failed to resolve: use of undeclared type `COT`
LL | for<const N: usize = 3, T = u32> [(); COT::BYTES]:,
| ^^^ use of undeclared type `COT`
error: aborting due to 6 previous errors
error: aborting due to 7 previous errors
Some errors have detailed explanations: E0412, E0433, E0658.
For more information about an error, try `rustc --explain E0412`.
Some errors have detailed explanations: E0403, E0412, E0433, E0658.
For more information about an error, try `rustc --explain E0403`.

View File

@ -0,0 +1,18 @@
#![feature(non_lifetime_binders)]
//~^ WARN the feature `non_lifetime_binders` is incomplete
fn function<T>() where for<T> (): Sized {}
//~^ ERROR the name `T` is already used for a generic parameter
struct Struct<T>(T) where for<T> (): Sized;
//~^ ERROR the name `T` is already used for a generic parameter
impl<T> Struct<T> {
fn method() where for<T> (): Sized {}
//~^ ERROR the name `T` is already used for a generic parameter
}
fn repeated() where for<T, T> (): Sized {}
//~^ ERROR the name `T` is already used for a generic parameter
fn main() {}

View File

@ -0,0 +1,44 @@
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
--> $DIR/shadowed.rs:4:28
|
LL | fn function<T>() where for<T> (): Sized {}
| - ^ already used
| |
| first use of `T`
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
--> $DIR/shadowed.rs:7:31
|
LL | struct Struct<T>(T) where for<T> (): Sized;
| - ^ already used
| |
| first use of `T`
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
--> $DIR/shadowed.rs:11:27
|
LL | impl<T> Struct<T> {
| - first use of `T`
LL | fn method() where for<T> (): Sized {}
| ^ already used
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
--> $DIR/shadowed.rs:15:28
|
LL | fn repeated() where for<T, T> (): Sized {}
| - ^ already used
| |
| first use of `T`
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/shadowed.rs:1:12
|
LL | #![feature(non_lifetime_binders)]
| ^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
= note: `#[warn(incomplete_features)]` on by default
error: aborting due to 4 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0403`.