Skip to content

Commit 32325e1

Browse files
Rollup merge of #140671 - xizheyin:issue-140169, r=petrochenkov
Parser: Recover error from named params while parse_path Fixes#140169 I added test to the first commit and the second added the code and changes to test. r? `@petrochenkov`
2 parents f7a9c67 + b922da3 commit 32325e1

10 files changed

Lines changed: 167 additions & 58 deletions

‎compiler/rustc_parse/messages.ftl‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,16 @@ parse_parenthesized_lifetime_suggestion = remove the parentheses
715715
parse_path_double_colon = path separator must be a double colon
716716
.suggestion = use a double colon instead
717717
718+
719+
parse_path_found_attribute_in_params = `Trait(...)` syntax does not support attributes in parameters
720+
.suggestion = remove the attributes
721+
722+
parse_path_found_c_variadic_params = `Trait(...)` syntax does not support c_variadic parameters
723+
.suggestion = remove the `...`
724+
725+
parse_path_found_named_params = `Trait(...)` syntax does not support named parameters
726+
.suggestion = remove the parameter name
727+
718728
parse_pattern_method_param_without_body = patterns aren't allowed in methods without bodies
719729
.suggestion = give this argument a name or use an underscore to ignore it
720730

‎compiler/rustc_parse/src/errors.rs‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1646,6 +1646,30 @@ pub(crate) struct ExpectedFnPathFoundFnKeyword {
16461646
pubfn_token_span:Span,
16471647
}
16481648

1649+
#[derive(Diagnostic)]
1650+
#[diag(parse_path_found_named_params)]
1651+
pub(crate)structFnPathFoundNamedParams{
1652+
#[primary_span]
1653+
#[suggestion(applicability = "machine-applicable", code = "")]
1654+
pubnamed_param_span:Span,
1655+
}
1656+
1657+
#[derive(Diagnostic)]
1658+
#[diag(parse_path_found_c_variadic_params)]
1659+
pub(crate)structPathFoundCVariadicParams{
1660+
#[primary_span]
1661+
#[suggestion(applicability = "machine-applicable", code = "")]
1662+
pubspan:Span,
1663+
}
1664+
1665+
#[derive(Diagnostic)]
1666+
#[diag(parse_path_found_attribute_in_params)]
1667+
pub(crate)structPathFoundAttributeInParams{
1668+
#[primary_span]
1669+
#[suggestion(applicability = "machine-applicable", code = "")]
1670+
pubspan:Span,
1671+
}
1672+
16491673
#[derive(Diagnostic)]
16501674
#[diag(parse_path_double_colon)]
16511675
pub(crate)structPathSingleColon{

‎compiler/rustc_parse/src/parser/item.rs‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2894,7 +2894,7 @@ impl<'a> Parser<'a> {
28942894
let(mut params, _) = self.parse_paren_comma_seq(|p| {
28952895
p.recover_vcs_conflict_marker();
28962896
let snapshot = p.create_snapshot_for_diagnostic();
2897-
let param = p.parse_param_general(req_name, first_param).or_else(|e| {
2897+
let param = p.parse_param_general(req_name, first_param,true).or_else(|e| {
28982898
let guar = e.emit();
28992899
// When parsing a param failed, we should check to make the span of the param
29002900
// not contain '(' before it.
@@ -2922,7 +2922,13 @@ impl<'a> Parser<'a> {
29222922
/// Parses a single function parameter.
29232923
///
29242924
/// - `self` is syntactically allowed when `first_param` holds.
2925-
fnparse_param_general(&mutself,req_name:ReqName,first_param:bool) -> PResult<'a,Param>{
2925+
/// - `recover_arg_parse` is used to recover from a failed argument parse.
2926+
pub(super)fnparse_param_general(
2927+
&mutself,
2928+
req_name:ReqName,
2929+
first_param:bool,
2930+
recover_arg_parse:bool,
2931+
) -> PResult<'a,Param>{
29262932
let lo = self.token.span;
29272933
let attrs = self.parse_outer_attributes()?;
29282934
self.collect_tokens(None, attrs,ForceCollect::No, |this, attrs| {
@@ -2990,12 +2996,13 @@ impl<'a> Parser<'a> {
29902996
// If this is a C-variadic argument and we hit an error, return the error.
29912997
Err(err)if this.token == token::DotDotDot => returnErr(err),
29922998
Err(err)if this.unmatched_angle_bracket_count > 0 => returnErr(err),
2993-
// Recover from attempting to parse the argument as a type without pattern.
2994-
Err(err) => {
2999+
Err(err)if recover_arg_parse => {
3000+
// Recover from attempting to parse the argument as a type without pattern.
29953001
err.cancel();
29963002
this.restore_snapshot(parser_snapshot_before_ty);
29973003
this.recover_arg_parse()?
29983004
}
3005+
Err(err) => returnErr(err),
29993006
}
30003007
};
30013008

‎compiler/rustc_parse/src/parser/path.rs‎

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ use tracing::debug;
1515

1616
usesuper::ty::{AllowPlus,RecoverQPath,RecoverReturnSign};
1717
usesuper::{Parser,Restrictions,TokenType};
18-
usecrate::errors::{self,PathSingleColon,PathTripleColon};
18+
usecrate::ast::{PatKind,TyKind};
19+
usecrate::errors::{
20+
self,FnPathFoundNamedParams,PathFoundAttributeInParams,PathFoundCVariadicParams,
21+
PathSingleColon,PathTripleColon,
22+
};
1923
usecrate::exp;
2024
usecrate::parser::{CommaRecoveryMode,RecoverColon,RecoverComma};
2125

@@ -396,7 +400,28 @@ impl<'a> Parser<'a> {
396400
snapshot = Some(self.create_snapshot_for_diagnostic());
397401
}
398402

399-
let(inputs, _) = matchself.parse_paren_comma_seq(|p| p.parse_ty()){
403+
let dcx = self.dcx();
404+
let parse_params_result = self.parse_paren_comma_seq(|p| {
405+
let param = p.parse_param_general(|_| false,false,false);
406+
param.map(move |param| {
407+
if !matches!(param.pat.kind,PatKind::Missing){
408+
dcx.emit_err(FnPathFoundNamedParams{
409+
named_param_span: param.pat.span,
410+
});
411+
}
412+
ifmatches!(param.ty.kind,TyKind::CVarArgs){
413+
dcx.emit_err(PathFoundCVariadicParams{span: param.pat.span});
414+
}
415+
if !param.attrs.is_empty(){
416+
dcx.emit_err(PathFoundAttributeInParams{
417+
span: param.attrs[0].span,
418+
});
419+
}
420+
param.ty
421+
})
422+
});
423+
424+
let(inputs, _) = match parse_params_result {
400425
Ok(output) => output,
401426
Err(mut error)if prev_token_before_parsing == token::PathSep => {
402427
error.span_label(
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
fnf1(_:fn(a:u8)){}
2+
fnf2(_:implFn(u8,vvvv:u8)){}//~ ERROR `Trait(...)` syntax does not support named parameters
3+
fnf3(_:implFn(aaaa:u8,u8)){}//~ ERROR `Trait(...)` syntax does not support named parameters
4+
fnf4(_:implFn(aaaa:u8,vvvv:u8)){}
5+
//~^ ERROR `Trait(...)` syntax does not support named parameters
6+
//~| ERROR `Trait(...)` syntax does not support named parameters
7+
fnf5(_:implFn(u8, ...)){}
8+
//~^ ERROR `Trait(...)` syntax does not support c_variadic parameters
9+
fnf6(_:implFn(u8,#[allow(unused_attributes)]u8)){}
10+
//~^ ERROR `Trait(...)` syntax does not support attributes in parameters
11+
12+
fnmain(){}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
error: `Trait(...)` syntax does not support named parameters
2+
--> $DIR/fn-trait-use-named-params-issue-140169.rs:2:22
3+
|
4+
LL | fn f2(_: impl Fn(u8, vvvv: u8)) {}
5+
| ^^^^ help: remove the parameter name
6+
7+
error: `Trait(...)` syntax does not support named parameters
8+
--> $DIR/fn-trait-use-named-params-issue-140169.rs:3:18
9+
|
10+
LL | fn f3(_: impl Fn(aaaa: u8, u8)) {}
11+
| ^^^^ help: remove the parameter name
12+
13+
error: `Trait(...)` syntax does not support named parameters
14+
--> $DIR/fn-trait-use-named-params-issue-140169.rs:4:18
15+
|
16+
LL | fn f4(_: impl Fn(aaaa: u8, vvvv: u8)) {}
17+
| ^^^^ help: remove the parameter name
18+
19+
error: `Trait(...)` syntax does not support named parameters
20+
--> $DIR/fn-trait-use-named-params-issue-140169.rs:4:28
21+
|
22+
LL | fn f4(_: impl Fn(aaaa: u8, vvvv: u8)) {}
23+
| ^^^^ help: remove the parameter name
24+
25+
error: `Trait(...)` syntax does not support c_variadic parameters
26+
--> $DIR/fn-trait-use-named-params-issue-140169.rs:7:22
27+
|
28+
LL | fn f5(_: impl Fn(u8, ...)) {}
29+
| ^^^ help: remove the `...`
30+
31+
error: `Trait(...)` syntax does not support attributes in parameters
32+
--> $DIR/fn-trait-use-named-params-issue-140169.rs:9:22
33+
|
34+
LL | fn f6(_: impl Fn(u8, #[allow(unused_attributes)] u8)) {}
35+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the attributes
36+
37+
error: aborting due to 6 previous errors
38+

‎tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
fnmain(){
44
unsafe{
5-
dealloc(ptr2,Layout::(x: !)(1,1));//~ ERROR: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
6-
//~^ ERROR: expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
7-
//~| NOTE while parsing this parenthesized list of type arguments starting here
5+
dealloc(ptr2,Layout::(x: !)(1,1));//~ ERROR `Trait(...)` syntax does not support named parameters
6+
//~^ ERROR cannot find function `dealloc` in this scope [E0425]
7+
//~| ERROR cannot find value `ptr2` in this scope [E0425]
8+
//~| ERROR the `!` type is experimental [E0658]
9+
//~| ERROR cannot find function, tuple struct or tuple variant `Layout` in this scope [E0425]
810
}
911
}
Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,43 @@
1-
error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
2-
--> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:33
1+
error: `Trait(...)` syntax does not support named parameters
2+
--> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:32
33
|
44
LL | dealloc(ptr2, Layout::(x: !)(1, 1));
5-
| --- ^ expected one of 7 possible tokens
6-
| |
7-
| while parsing this parenthesized list of type arguments starting here
5+
| ^ help: remove the parameter name
86

9-
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
10-
--> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:43
7+
error[E0425]: cannot find function `dealloc` in this scope
8+
--> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:9
119
|
1210
LL | dealloc(ptr2, Layout::(x: !)(1, 1));
13-
| ^ expected one of `.`, `;`, `?`, `}`, or an operator
11+
| ^^^^^^^ not found in this scope
12+
|
13+
help: consider importing this function
14+
|
15+
LL + use std::alloc::dealloc;
16+
|
17+
18+
error[E0425]: cannot find value `ptr2` in this scope
19+
--> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:17
20+
|
21+
LL | dealloc(ptr2, Layout::(x: !)(1, 1));
22+
| ^^^^ not found in this scope
23+
24+
error[E0658]: the `!` type is experimental
25+
--> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:35
26+
|
27+
LL | dealloc(ptr2, Layout::(x: !)(1, 1));
28+
| ^
29+
|
30+
= note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
31+
= help: add `#![feature(never_type)]` to the crate attributes to enable
32+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
33+
34+
error[E0425]: cannot find function, tuple struct or tuple variant `Layout` in this scope
35+
--> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:23
36+
|
37+
LL | dealloc(ptr2, Layout::(x: !)(1, 1));
38+
| ^^^^^^ not found in this scope
1439

15-
error: aborting due to 2 previous errors
40+
error: aborting due to 5 previous errors
1641

42+
Some errors have detailed explanations: E0425, E0658.
43+
For more information about an error, try `rustc --explain E0425`.

‎tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,4 @@
22

33
structApple((Apple,Option(Banana ? Citron)));
44
//~^ ERROR invalid `?` in type
5-
//~| ERROR expected one of `)` or `,`, found `Citron`
6-
//~| ERROR cannot find type `Citron` in this scope [E0412]
7-
//~| ERROR parenthesized type parameters may only be used with a `Fn` trait [E0214]
8-
//~| ERROR `Apple` has infinite size
5+
//~| ERROR unexpected token: `Citron`

‎tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr‎

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -10,44 +10,11 @@ LL - struct Apple((Apple, Option(Banana ? Citron)));
1010
LL + struct Apple((Apple, Option(Option<Banana > Citron)));
1111
|
1212

13-
error: expected one of `)` or `,`, found `Citron`
13+
error: unexpected token: `Citron`
1414
--> $DIR/issue-103748-ICE-wrong-braces.rs:3:38
1515
|
1616
LL | struct Apple((Apple, Option(Banana ? Citron)));
17-
| -^^^^^^ expected one of `)` or `,`
18-
| |
19-
| help: missing `,`
17+
| ^^^^^^ unexpected token after this
2018

21-
error[E0412]: cannot find type `Citron` in this scope
22-
--> $DIR/issue-103748-ICE-wrong-braces.rs:3:38
23-
|
24-
LL | struct Apple((Apple, Option(Banana ? Citron)));
25-
| ^^^^^^ not found in this scope
26-
27-
error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
28-
--> $DIR/issue-103748-ICE-wrong-braces.rs:3:22
29-
|
30-
LL | struct Apple((Apple, Option(Banana ? Citron)));
31-
| ^^^^^^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses
32-
|
33-
help: use angle brackets instead
34-
|
35-
LL - struct Apple((Apple, Option(Banana ? Citron)));
36-
LL + struct Apple((Apple, Option<Banana ? Citron>));
37-
|
38-
39-
error[E0072]: recursive type `Apple` has infinite size
40-
--> $DIR/issue-103748-ICE-wrong-braces.rs:3:1
41-
|
42-
LL | struct Apple((Apple, Option(Banana ? Citron)));
43-
| ^^^^^^^^^^^^ ----- recursive without indirection
44-
|
45-
help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
46-
|
47-
LL | struct Apple((Box<Apple>, Option(Banana ? Citron)));
48-
| ++++ +
49-
50-
error: aborting due to 5 previous errors
19+
error: aborting due to 2 previous errors
5120

52-
Some errors have detailed explanations: E0072, E0214, E0412.
53-
For more information about an error, try `rustc --explain E0072`.

0 commit comments

Comments
 (0)