Skip to content

Commit

Permalink
Rollup merge of #112029 - jieyouxu:typo-const-in-const-param-def, r=c…
Browse files Browse the repository at this point in the history
…jgillot

Recover upon mistyped error on typo'd `const` in const param def

And add machine-applicable fix for the typo'd `const` keyword.

### Before

```
error: expected one of `,`, `:`, `=`, or `>`, found `N`
 --> src/lib.rs:1:18
  |
1 | pub fn bar<Const N: u8>() {}
  |                  ^ expected one of `,`, `:`, `=`, or `>`
```

### After This PR

```
error: `const` keyword was mistyped as `Const`
 --> test.rs:1:8
  |
1 | fn bar<Const N: u8>() {}
  |        ^^^^^
  |
help: use the `const` keyword
  |
1 | fn bar<const N: u8>() {}
  |        ~~~~~

```

Fixes #111941.
  • Loading branch information
matthiaskrgr authored May 29, 2023
2 parents 089677e + 41f5a30 commit 45ca2f7
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 0 deletions.
44 changes: 44 additions & 0 deletions compiler/rustc_parse/src/parser/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ impl<'a> Parser<'a> {
fn parse_ty_param(&mut self, preceding_attrs: AttrVec) -> PResult<'a, GenericParam> {
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.
let mut colon_span = None;
let bounds = if self.eat(&token::Colon) {
Expand Down Expand Up @@ -120,6 +129,41 @@ impl<'a> Parser<'a> {
})
}

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
/// a trailing comma and erroneous trailing attributes.
pub(super) fn parse_generic_params(&mut self) -> PResult<'a, ThinVec<ast::GenericParam>> {
Expand Down
16 changes: 16 additions & 0 deletions tests/ui/parser/typod-const-in-const-param-def.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 46 additions & 0 deletions tests/ui/parser/typod-const-in-const-param-def.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 45ca2f7

Please sign in to comment.