Skip to content

Commit 45ca2f7

Browse files
authored
Rollup merge of rust-lang#112029 - jieyouxu:typo-const-in-const-param-def, r=cjgillot
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 rust-lang#111941.
2 parents 089677e + 41f5a30 commit 45ca2f7

File tree

3 files changed

+106
-0
lines changed

3 files changed

+106
-0
lines changed

compiler/rustc_parse/src/parser/generics.rs

+44
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@ impl<'a> Parser<'a> {
4343
fn parse_ty_param(&mut self, preceding_attrs: AttrVec) -> PResult<'a, GenericParam> {
4444
let ident = self.parse_ident()?;
4545

46+
// We might have a typo'd `Const` that was parsed as a type parameter.
47+
if self.may_recover()
48+
&& ident.name.as_str().to_ascii_lowercase() == kw::Const.as_str()
49+
&& self.check_ident()
50+
// `Const` followed by IDENT
51+
{
52+
return Ok(self.recover_const_param_with_mistyped_const(preceding_attrs, ident)?);
53+
}
54+
4655
// Parse optional colon and param bounds.
4756
let mut colon_span = None;
4857
let bounds = if self.eat(&token::Colon) {
@@ -120,6 +129,41 @@ impl<'a> Parser<'a> {
120129
})
121130
}
122131

132+
pub(crate) fn recover_const_param_with_mistyped_const(
133+
&mut self,
134+
preceding_attrs: AttrVec,
135+
mistyped_const_ident: Ident,
136+
) -> PResult<'a, GenericParam> {
137+
let ident = self.parse_ident()?;
138+
self.expect(&token::Colon)?;
139+
let ty = self.parse_ty()?;
140+
141+
// Parse optional const generics default value.
142+
let default = if self.eat(&token::Eq) { Some(self.parse_const_arg()?) } else { None };
143+
144+
let mut err = self.struct_span_err(
145+
mistyped_const_ident.span,
146+
format!("`const` keyword was mistyped as `{}`", mistyped_const_ident.as_str()),
147+
);
148+
err.span_suggestion_verbose(
149+
mistyped_const_ident.span,
150+
"use the `const` keyword",
151+
kw::Const.as_str(),
152+
Applicability::MachineApplicable,
153+
);
154+
err.emit();
155+
156+
Ok(GenericParam {
157+
ident,
158+
id: ast::DUMMY_NODE_ID,
159+
attrs: preceding_attrs,
160+
bounds: Vec::new(),
161+
kind: GenericParamKind::Const { ty, kw_span: mistyped_const_ident.span, default },
162+
is_placeholder: false,
163+
colon_span: None,
164+
})
165+
}
166+
123167
/// Parses a (possibly empty) list of lifetime and type parameters, possibly including
124168
/// a trailing comma and erroneous trailing attributes.
125169
pub(super) fn parse_generic_params(&mut self) -> PResult<'a, ThinVec<ast::GenericParam>> {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
pub fn foo<Const N: u8>() {}
2+
//~^ ERROR `const` keyword was mistyped as `Const`
3+
4+
pub fn bar<Const>() {}
5+
// OK
6+
7+
pub fn baz<Const N: u8, T>() {}
8+
//~^ ERROR `const` keyword was mistyped as `Const`
9+
10+
pub fn qux<T, Const N: u8>() {}
11+
//~^ ERROR `const` keyword was mistyped as `Const`
12+
13+
pub fn quux<T, Const N: u8, U>() {}
14+
//~^ ERROR `const` keyword was mistyped as `Const`
15+
16+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
error: `const` keyword was mistyped as `Const`
2+
--> $DIR/typod-const-in-const-param-def.rs:1:12
3+
|
4+
LL | pub fn foo<Const N: u8>() {}
5+
| ^^^^^
6+
|
7+
help: use the `const` keyword
8+
|
9+
LL | pub fn foo<const N: u8>() {}
10+
| ~~~~~
11+
12+
error: `const` keyword was mistyped as `Const`
13+
--> $DIR/typod-const-in-const-param-def.rs:7:12
14+
|
15+
LL | pub fn baz<Const N: u8, T>() {}
16+
| ^^^^^
17+
|
18+
help: use the `const` keyword
19+
|
20+
LL | pub fn baz<const N: u8, T>() {}
21+
| ~~~~~
22+
23+
error: `const` keyword was mistyped as `Const`
24+
--> $DIR/typod-const-in-const-param-def.rs:10:15
25+
|
26+
LL | pub fn qux<T, Const N: u8>() {}
27+
| ^^^^^
28+
|
29+
help: use the `const` keyword
30+
|
31+
LL | pub fn qux<T, const N: u8>() {}
32+
| ~~~~~
33+
34+
error: `const` keyword was mistyped as `Const`
35+
--> $DIR/typod-const-in-const-param-def.rs:13:16
36+
|
37+
LL | pub fn quux<T, Const N: u8, U>() {}
38+
| ^^^^^
39+
|
40+
help: use the `const` keyword
41+
|
42+
LL | pub fn quux<T, const N: u8, U>() {}
43+
| ~~~~~
44+
45+
error: aborting due to 4 previous errors
46+

0 commit comments

Comments
 (0)