Recover upon encountering mistyped Const
in const param def
This commit is contained in:
parent
b9c5fdc888
commit
41f5a30690
@ -43,6 +43,15 @@ fn parse_lt_param_bounds(&mut self) -> GenericBounds {
|
|||||||
fn parse_ty_param(&mut self, preceding_attrs: AttrVec) -> PResult<'a, GenericParam> {
|
fn parse_ty_param(&mut self, preceding_attrs: AttrVec) -> PResult<'a, GenericParam> {
|
||||||
let ident = self.parse_ident()?;
|
let ident = self.parse_ident()?;
|
||||||
|
|
||||||
|
// We might have a typo'd `Const` that was parsed as a type parameter.
|
||||||
|
if self.may_recover()
|
||||||
|
&& ident.name.as_str().to_ascii_lowercase() == kw::Const.as_str()
|
||||||
|
&& self.check_ident()
|
||||||
|
// `Const` followed by IDENT
|
||||||
|
{
|
||||||
|
return Ok(self.recover_const_param_with_mistyped_const(preceding_attrs, ident)?);
|
||||||
|
}
|
||||||
|
|
||||||
// Parse optional colon and param bounds.
|
// Parse optional colon and param bounds.
|
||||||
let mut colon_span = None;
|
let mut colon_span = None;
|
||||||
let bounds = if self.eat(&token::Colon) {
|
let bounds = if self.eat(&token::Colon) {
|
||||||
@ -120,6 +129,41 @@ pub(crate) fn parse_const_param(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn recover_const_param_with_mistyped_const(
|
||||||
|
&mut self,
|
||||||
|
preceding_attrs: AttrVec,
|
||||||
|
mistyped_const_ident: Ident,
|
||||||
|
) -> PResult<'a, GenericParam> {
|
||||||
|
let ident = self.parse_ident()?;
|
||||||
|
self.expect(&token::Colon)?;
|
||||||
|
let ty = self.parse_ty()?;
|
||||||
|
|
||||||
|
// Parse optional const generics default value.
|
||||||
|
let default = if self.eat(&token::Eq) { Some(self.parse_const_arg()?) } else { None };
|
||||||
|
|
||||||
|
let mut err = self.struct_span_err(
|
||||||
|
mistyped_const_ident.span,
|
||||||
|
format!("`const` keyword was mistyped as `{}`", mistyped_const_ident.as_str()),
|
||||||
|
);
|
||||||
|
err.span_suggestion_verbose(
|
||||||
|
mistyped_const_ident.span,
|
||||||
|
"use the `const` keyword",
|
||||||
|
kw::Const.as_str(),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
err.emit();
|
||||||
|
|
||||||
|
Ok(GenericParam {
|
||||||
|
ident,
|
||||||
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
attrs: preceding_attrs,
|
||||||
|
bounds: Vec::new(),
|
||||||
|
kind: GenericParamKind::Const { ty, kw_span: mistyped_const_ident.span, default },
|
||||||
|
is_placeholder: false,
|
||||||
|
colon_span: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Parses a (possibly empty) list of lifetime and type parameters, possibly including
|
/// Parses a (possibly empty) list of lifetime and type parameters, possibly including
|
||||||
/// a trailing comma and erroneous trailing attributes.
|
/// a trailing comma and erroneous trailing attributes.
|
||||||
pub(super) fn parse_generic_params(&mut self) -> PResult<'a, ThinVec<ast::GenericParam>> {
|
pub(super) fn parse_generic_params(&mut self) -> PResult<'a, ThinVec<ast::GenericParam>> {
|
||||||
|
16
tests/ui/parser/typod-const-in-const-param-def.rs
Normal file
16
tests/ui/parser/typod-const-in-const-param-def.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
pub fn foo<Const N: u8>() {}
|
||||||
|
//~^ ERROR `const` keyword was mistyped as `Const`
|
||||||
|
|
||||||
|
pub fn bar<Const>() {}
|
||||||
|
// OK
|
||||||
|
|
||||||
|
pub fn baz<Const N: u8, T>() {}
|
||||||
|
//~^ ERROR `const` keyword was mistyped as `Const`
|
||||||
|
|
||||||
|
pub fn qux<T, Const N: u8>() {}
|
||||||
|
//~^ ERROR `const` keyword was mistyped as `Const`
|
||||||
|
|
||||||
|
pub fn quux<T, Const N: u8, U>() {}
|
||||||
|
//~^ ERROR `const` keyword was mistyped as `Const`
|
||||||
|
|
||||||
|
fn main() {}
|
46
tests/ui/parser/typod-const-in-const-param-def.stderr
Normal file
46
tests/ui/parser/typod-const-in-const-param-def.stderr
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
error: `const` keyword was mistyped as `Const`
|
||||||
|
--> $DIR/typod-const-in-const-param-def.rs:1:12
|
||||||
|
|
|
||||||
|
LL | pub fn foo<Const N: u8>() {}
|
||||||
|
| ^^^^^
|
||||||
|
|
|
||||||
|
help: use the `const` keyword
|
||||||
|
|
|
||||||
|
LL | pub fn foo<const N: u8>() {}
|
||||||
|
| ~~~~~
|
||||||
|
|
||||||
|
error: `const` keyword was mistyped as `Const`
|
||||||
|
--> $DIR/typod-const-in-const-param-def.rs:7:12
|
||||||
|
|
|
||||||
|
LL | pub fn baz<Const N: u8, T>() {}
|
||||||
|
| ^^^^^
|
||||||
|
|
|
||||||
|
help: use the `const` keyword
|
||||||
|
|
|
||||||
|
LL | pub fn baz<const N: u8, T>() {}
|
||||||
|
| ~~~~~
|
||||||
|
|
||||||
|
error: `const` keyword was mistyped as `Const`
|
||||||
|
--> $DIR/typod-const-in-const-param-def.rs:10:15
|
||||||
|
|
|
||||||
|
LL | pub fn qux<T, Const N: u8>() {}
|
||||||
|
| ^^^^^
|
||||||
|
|
|
||||||
|
help: use the `const` keyword
|
||||||
|
|
|
||||||
|
LL | pub fn qux<T, const N: u8>() {}
|
||||||
|
| ~~~~~
|
||||||
|
|
||||||
|
error: `const` keyword was mistyped as `Const`
|
||||||
|
--> $DIR/typod-const-in-const-param-def.rs:13:16
|
||||||
|
|
|
||||||
|
LL | pub fn quux<T, Const N: u8, U>() {}
|
||||||
|
| ^^^^^
|
||||||
|
|
|
||||||
|
help: use the `const` keyword
|
||||||
|
|
|
||||||
|
LL | pub fn quux<T, const N: u8, U>() {}
|
||||||
|
| ~~~~~
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
Loading…
Reference in New Issue
Block a user