Skip to content

Commit

Permalink
Explain why Self is invalid in generic parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
hkmatsumoto committed Oct 19, 2021
1 parent d45ed75 commit a72dd4a
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 13 deletions.
13 changes: 13 additions & 0 deletions compiler/rustc_parse/src/parser/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/keyword/keyword-self-as-type-param.rs
Original file line number Diff line number Diff line change
@@ -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() {}
29 changes: 19 additions & 10 deletions src/test/ui/keyword/keyword-self-as-type-param.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit a72dd4a

Please sign in to comment.