diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2021-12-05 00:37:56 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-12-05 00:37:56 +0100 |
| commit | 29fe57def2693a3f9b4fcfbb1072b4b655700260 (patch) | |
| tree | 75d7c86abe168f2f7773e72c1023c671c2534439 | |
| parent | b97f375ea2c40926d941138a0b3e858ed3799071 (diff) | |
| parent | a72dd4a5b973a3d94876ebea66e428fabaff00b0 (diff) | |
| download | rust-29fe57def2693a3f9b4fcfbb1072b4b655700260.tar.gz rust-29fe57def2693a3f9b4fcfbb1072b4b655700260.zip | |
Rollup merge of #90022 - hkmatsumoto:self-upper-as-generic-parameter, r=jackh726
Explain why `Self` is invalid in generic parameters Close #89985. r? `@estebank`
| -rw-r--r-- | compiler/rustc_parse/src/parser/generics.rs | 13 | ||||
| -rw-r--r-- | src/test/ui/keyword/keyword-self-as-type-param.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/keyword/keyword-self-as-type-param.stderr | 29 |
3 files changed, 35 insertions, 13 deletions
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index a9ab2cd3f68..07887a7a59c 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -92,6 +92,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 785d64ec8ea..55c7ac128ff 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>(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<Self> {} -//~^ 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 cc3df2e36f7..fd101b32b4c 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>(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<Self> {} - | ^^^^ 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>(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<Self>(Box<Self>); + | ++++ + 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`. |
