feat(rustc_parse): recover from pre-RFC-2000 const generics syntax
Fixes #89013
This commit is contained in:
parent
2b5ddf36fd
commit
d8e9db0dcf
9 changed files with 197 additions and 1 deletions
|
@ -495,11 +495,16 @@ impl<'a> Parser<'a> {
|
||||||
None => {
|
None => {
|
||||||
let after_eq = eq.shrink_to_hi();
|
let after_eq = eq.shrink_to_hi();
|
||||||
let before_next = self.token.span.shrink_to_lo();
|
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 `=`")
|
self.struct_span_err(after_eq.to(before_next), "missing type to the right of `=`")
|
||||||
.span_suggestion(
|
.span_suggestion(
|
||||||
self.sess.source_map().next_point(eq).to(before_next),
|
self.sess.source_map().next_point(eq).to(before_next),
|
||||||
"to constrain the associated type, add a type after `=`",
|
"to constrain the associated type, add a type after `=`",
|
||||||
" TheType".to_string(),
|
the_type_placeholder.to_string(),
|
||||||
Applicability::HasPlaceholders,
|
Applicability::HasPlaceholders,
|
||||||
)
|
)
|
||||||
.span_suggestion(
|
.span_suggestion(
|
||||||
|
@ -572,6 +577,19 @@ impl<'a> Parser<'a> {
|
||||||
return self.recover_const_arg(start, err).map(Some);
|
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 {
|
} else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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() {}
|
|
@ -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
|
||||||
|
|
|
@ -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() {}
|
|
@ -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`.
|
|
@ -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() {}
|
|
@ -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
|
||||||
|
|
|
@ -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() {}
|
|
@ -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`.
|
Loading…
Add table
Add a link
Reference in a new issue