diff options
9 files changed, 197 insertions, 1 deletions
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 953c6915068..4e4130dfc23 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -495,11 +495,16 @@ impl<'a> Parser<'a> { None => { let after_eq = eq.shrink_to_hi(); let before_next = self.token.span.shrink_to_lo(); + let the_type_placeholder = if matches!(self.token.kind, token::Comma | token::Gt) { + " TheType" + } else { + " TheType " + }; self.struct_span_err(after_eq.to(before_next), "missing type to the right of `=`") .span_suggestion( self.sess.source_map().next_point(eq).to(before_next), "to constrain the associated type, add a type after `=`", - " TheType".to_string(), + the_type_placeholder.to_string(), Applicability::HasPlaceholders, ) .span_suggestion( @@ -572,6 +577,19 @@ impl<'a> Parser<'a> { return self.recover_const_arg(start, err).map(Some); } } + } else if self.eat_keyword_noexpect(kw::Const) { + // Detect and recover from the old, pre-RFC2000 syntax for const generics. + let mut err = self.struct_span_err( + start, + "expected lifetime, type, or constant, found keyword `const`", + ); + if self.check_const_arg() { + err.emit(); + GenericArg::Const(self.parse_const_arg()?) + } else { + let after_kw_const = self.token.span; + return self.recover_const_arg(after_kw_const, err).map(Some); + } } else { return Ok(None); }; diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.rs new file mode 100644 index 00000000000..99d8e9dea91 --- /dev/null +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.rs @@ -0,0 +1,16 @@ +trait Foo<const N: usize> { + fn do_x(&self) -> [u8; N]; +} + +struct Bar; + +const T: usize = 42; + +impl Foo<const 3> for Bar { +//~^ERROR expected lifetime, type, or constant, found keyword `const` + fn do_x(&self) -> [u8; 3] { + [0u8; 3] + } +} + +fn main() {} diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.stderr new file mode 100644 index 00000000000..533d381fa31 --- /dev/null +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.stderr @@ -0,0 +1,8 @@ +error: expected lifetime, type, or constant, found keyword `const` + --> $DIR/issue-89013-no-assoc.rs:9:10 + | +LL | impl Foo<const 3> for Bar { + | ^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs new file mode 100644 index 00000000000..b73b3e29104 --- /dev/null +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs @@ -0,0 +1,18 @@ +trait Foo<const N: usize> { + fn do_x(&self) -> [u8; N]; +} + +struct Bar; + +const T: usize = 42; + +impl Foo<N = 3> for Bar { +//~^ERROR cannot constrain an associated constant to a value +//~^^ERROR this trait takes 1 generic argument but 0 generic arguments +//~^^^ERROR associated type bindings are not allowed here + fn do_x(&self) -> [u8; 3] { + [0u8; 3] + } +} + +fn main() {} diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr new file mode 100644 index 00000000000..76828155576 --- /dev/null +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr @@ -0,0 +1,35 @@ +error: cannot constrain an associated constant to a value + --> $DIR/issue-89013-no-kw.rs:9:10 + | +LL | impl Foo<N = 3> for Bar { + | -^^^- + | | | + | | ...cannot be constrained to this value + | this associated constant... + +error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied + --> $DIR/issue-89013-no-kw.rs:9:6 + | +LL | impl Foo<N = 3> for Bar { + | ^^^ expected 1 generic argument + | +note: trait defined here, with 1 generic parameter: `N` + --> $DIR/issue-89013-no-kw.rs:1:7 + | +LL | trait Foo<const N: usize> { + | ^^^ - +help: add missing generic argument + | +LL | impl Foo<N, N = 3> for Bar { + | ++ + +error[E0229]: associated type bindings are not allowed here + --> $DIR/issue-89013-no-kw.rs:9:10 + | +LL | impl Foo<N = 3> for Bar { + | ^^^^^ associated type not allowed here + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0107, E0229. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.rs new file mode 100644 index 00000000000..c34936d1976 --- /dev/null +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.rs @@ -0,0 +1,17 @@ +trait Foo<const N: usize> { + fn do_x(&self) -> [u8; N]; +} + +struct Bar; + +const T: usize = 42; + +impl Foo<N = type 3> for Bar { +//~^ERROR missing type to the right of `=` +//~^^ERROR found keyword `type` + fn do_x(&self) -> [u8; 3] { + [0u8; 3] + } +} + +fn main() {} diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.stderr new file mode 100644 index 00000000000..0f33f4b0df6 --- /dev/null +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.stderr @@ -0,0 +1,24 @@ +error: missing type to the right of `=` + --> $DIR/issue-89013-type.rs:9:13 + | +LL | impl Foo<N = type 3> for Bar { + | ^ + | +help: to constrain the associated type, add a type after `=` + | +LL | impl Foo<N = TheType type 3> for Bar { + | +++++++ +help: remove the `=` if `N` is a type + | +LL - impl Foo<N = type 3> for Bar { +LL + impl Foo<N type 3> for Bar { + | + +error: expected one of `,`, `>`, a const expression, lifetime, or type, found keyword `type` + --> $DIR/issue-89013-type.rs:9:14 + | +LL | impl Foo<N = type 3> for Bar { + | ^^^^ expected one of `,`, `>`, a const expression, lifetime, or type + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs new file mode 100644 index 00000000000..d5ded44188a --- /dev/null +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs @@ -0,0 +1,19 @@ +trait Foo<const N: usize> { + fn do_x(&self) -> [u8; N]; +} + +struct Bar; + +const T: usize = 42; + +impl Foo<N = const 3> for Bar { +//~^ERROR expected lifetime, type, or constant, found keyword `const` +//~^^ERROR cannot constrain an associated constant to a value +//~^^^ERROR this trait takes 1 generic argument but 0 generic arguments +//~^^^^ERROR associated type bindings are not allowed here + fn do_x(&self) -> [u8; 3] { + [0u8; 3] + } +} + +fn main() {} diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr new file mode 100644 index 00000000000..3df459ce162 --- /dev/null +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr @@ -0,0 +1,41 @@ +error: expected lifetime, type, or constant, found keyword `const` + --> $DIR/issue-89013.rs:9:14 + | +LL | impl Foo<N = const 3> for Bar { + | ^^^^^ + +error: cannot constrain an associated constant to a value + --> $DIR/issue-89013.rs:9:10 + | +LL | impl Foo<N = const 3> for Bar { + | -^^^^^^^^^- + | | | + | | ...cannot be constrained to this value + | this associated constant... + +error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied + --> $DIR/issue-89013.rs:9:6 + | +LL | impl Foo<N = const 3> for Bar { + | ^^^ expected 1 generic argument + | +note: trait defined here, with 1 generic parameter: `N` + --> $DIR/issue-89013.rs:1:7 + | +LL | trait Foo<const N: usize> { + | ^^^ - +help: add missing generic argument + | +LL | impl Foo<N, N = const 3> for Bar { + | ++ + +error[E0229]: associated type bindings are not allowed here + --> $DIR/issue-89013.rs:9:10 + | +LL | impl Foo<N = const 3> for Bar { + | ^^^^^^^^^^^ associated type not allowed here + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0107, E0229. +For more information about an error, try `rustc --explain E0107`. |
