diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index f175c5b50b397..ec7e376656618 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -89,6 +89,19 @@ impl<'a> Parser<'a> { let attrs = self.parse_outer_attributes()?; let param = self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| { + if this.eat_keyword_noexpect(kw::SelfUpper) { + // `Self` as a generic param is invalid. Here we emit the diagnostic and continue parsing + // as if `Self` never existed. + this.struct_span_err( + this.prev_token.span, + "unexpected keyword `Self` in generic parameters", + ) + .note("you cannot use `Self` as a generic parameter because it is reserved for associated items") + .emit(); + + this.eat(&token::Comma); + } + let param = if this.check_lifetime() { let lifetime = this.expect_lifetime(); // Parse lifetime parameter. diff --git a/src/test/ui/keyword/keyword-self-as-type-param.rs b/src/test/ui/keyword/keyword-self-as-type-param.rs index 785d64ec8ea22..55c7ac128ffde 100644 --- a/src/test/ui/keyword/keyword-self-as-type-param.rs +++ b/src/test/ui/keyword/keyword-self-as-type-param.rs @@ -1,10 +1,10 @@ // Regression test of #36638. struct Foo(Self); -//~^ ERROR expected identifier, found keyword `Self` -//~^^ ERROR E0392 +//~^ ERROR unexpected keyword `Self` in generic parameters +//~| ERROR recursive type `Foo` has infinite size trait Bar {} -//~^ ERROR expected identifier, found keyword `Self` +//~^ ERROR unexpected keyword `Self` in generic parameters fn main() {} diff --git a/src/test/ui/keyword/keyword-self-as-type-param.stderr b/src/test/ui/keyword/keyword-self-as-type-param.stderr index cc3df2e36f7f5..fd101b32b4c9c 100644 --- a/src/test/ui/keyword/keyword-self-as-type-param.stderr +++ b/src/test/ui/keyword/keyword-self-as-type-param.stderr @@ -1,24 +1,33 @@ -error: expected identifier, found keyword `Self` +error: unexpected keyword `Self` in generic parameters --> $DIR/keyword-self-as-type-param.rs:3:12 | LL | struct Foo(Self); - | ^^^^ expected identifier, found keyword + | ^^^^ + | + = note: you cannot use `Self` as a generic parameter because it is reserved for associated items -error: expected identifier, found keyword `Self` +error: unexpected keyword `Self` in generic parameters --> $DIR/keyword-self-as-type-param.rs:7:11 | LL | trait Bar {} - | ^^^^ expected identifier, found keyword + | ^^^^ + | + = note: you cannot use `Self` as a generic parameter because it is reserved for associated items -error[E0392]: parameter `Self` is never used - --> $DIR/keyword-self-as-type-param.rs:3:12 +error[E0072]: recursive type `Foo` has infinite size + --> $DIR/keyword-self-as-type-param.rs:3:1 | LL | struct Foo(Self); - | ^^^^ unused parameter + | ^^^^^^^^^^^^^^^^^----^^ + | | | + | | recursive without indirection + | recursive type has infinite size + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Foo` representable | - = help: consider removing `Self`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `Self` to be a const parameter, use `const Self: usize` instead +LL | struct Foo(Box); + | ++++ + error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0392`. +For more information about this error, try `rustc --explain E0072`.