Skip to content

Commit c643bb2

Browse files
committed
Recover from named params while parse_path
Signed-off-by: xizheyin <[email protected]>
1 parent 896cf80 commit c643bb2

8 files changed

+95
-30
lines changed

compiler/rustc_parse/messages.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,9 @@ parse_parenthesized_lifetime_suggestion = remove the parentheses
702702
parse_path_double_colon = path separator must be a double colon
703703
.suggestion = use a double colon instead
704704
705+
parse_path_found_named_params = syntax does not allow named arguments
706+
.suggestion = remove name of the param
707+
705708
parse_pattern_method_param_without_body = patterns aren't allowed in methods without bodies
706709
.suggestion = give this argument a name or use an underscore to ignore it
707710

compiler/rustc_parse/src/errors.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1591,6 +1591,14 @@ pub(crate) struct ExpectedFnPathFoundFnKeyword {
15911591
pub fn_token_span: Span,
15921592
}
15931593

1594+
#[derive(Diagnostic)]
1595+
#[diag(parse_path_found_named_params)]
1596+
pub(crate) struct FnPathFoundNamedParams {
1597+
#[primary_span]
1598+
#[suggestion(applicability = "machine-applicable", code = "")]
1599+
pub named_param_span: Span,
1600+
}
1601+
15941602
#[derive(Diagnostic)]
15951603
#[diag(parse_path_double_colon)]
15961604
pub(crate) struct PathSingleColon {

compiler/rustc_parse/src/parser/item.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -2922,7 +2922,11 @@ impl<'a> Parser<'a> {
29222922
/// Parses a single function parameter.
29232923
///
29242924
/// - `self` is syntactically allowed when `first_param` holds.
2925-
fn parse_param_general(&mut self, req_name: ReqName, first_param: bool) -> PResult<'a, Param> {
2925+
pub(super) fn parse_param_general(
2926+
&mut self,
2927+
req_name: ReqName,
2928+
first_param: bool,
2929+
) -> PResult<'a, Param> {
29262930
let lo = self.token.span;
29272931
let attrs = self.parse_outer_attributes()?;
29282932
self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
@@ -3156,7 +3160,7 @@ impl<'a> Parser<'a> {
31563160
Ok(Some(Param::from_self(AttrVec::default(), eself, eself_ident)))
31573161
}
31583162

3159-
fn is_named_param(&self) -> bool {
3163+
pub(super) fn is_named_param(&self) -> bool {
31603164
let offset = match &self.token.kind {
31613165
token::OpenInvisible(origin) => match origin {
31623166
InvisibleOrigin::MetaVar(MetaVarKind::Pat(_)) => {

compiler/rustc_parse/src/parser/path.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use tracing::debug;
1515

1616
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
1717
use super::{Parser, Restrictions, TokenType};
18-
use crate::errors::{self, PathSingleColon, PathTripleColon};
18+
use crate::errors::{self, FnPathFoundNamedParams, PathSingleColon, PathTripleColon};
1919
use crate::exp;
2020
use crate::parser::{CommaRecoveryMode, RecoverColon, RecoverComma};
2121

@@ -396,8 +396,21 @@ impl<'a> Parser<'a> {
396396
snapshot = Some(self.create_snapshot_for_diagnostic());
397397
}
398398

399-
let (inputs, _) = match self.parse_paren_comma_seq(|p| p.parse_ty()) {
400-
Ok(output) => output,
399+
let dcx = self.dcx();
400+
let (inputs, _) = match self.parse_paren_comma_seq(|p| {
401+
if p.is_named_param() {
402+
let param = p.parse_param_general(|_| false, false);
403+
if let Ok(ref param) = param {
404+
dcx.emit_err(FnPathFoundNamedParams {
405+
named_param_span: param.pat.span,
406+
});
407+
}
408+
param.map(|param| param.ty)
409+
} else {
410+
p.parse_ty()
411+
}
412+
}) {
413+
Ok((output, trailing)) => (output, trailing),
401414
Err(mut error) if prev_token_before_parsing == token::PathSep => {
402415
error.span_label(
403416
prev_token_before_parsing.span.to(token_before_parsing.span),
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
fn g(_: fn(a: u8)) {}
2-
fn x(_: impl Fn(u8, vvvv: u8)) {} //~ ERROR expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
3-
fn y(_: impl Fn(aaaa: u8, u8)) {} //~ ERROR expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
4-
fn z(_: impl Fn(aaaa: u8, vvvv: u8)) {} //~ ERROR expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
2+
fn x(_: impl Fn(u8, vvvv: u8)) {} //~ ERROR syntax does not allow named arguments
3+
fn y(_: impl Fn(aaaa: u8, u8)) {} //~ ERROR syntax does not allow named arguments
4+
fn z(_: impl Fn(aaaa: u8, vvvv: u8)) {}
5+
//~^ ERROR syntax does not allow named arguments
6+
//~| ERROR syntax does not allow named arguments
57

68
fn main(){}
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
1-
error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
2-
--> $DIR/fn-trait-use-named-params-issue-140169.rs:2:25
1+
error: syntax does not allow named arguments
2+
--> $DIR/fn-trait-use-named-params-issue-140169.rs:2:21
33
|
44
LL | fn x(_: impl Fn(u8, vvvv: u8)) {}
5-
| ^ expected one of 7 possible tokens
5+
| ^^^^ help: remove name of the param
66

7-
error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
8-
--> $DIR/fn-trait-use-named-params-issue-140169.rs:3:21
7+
error: syntax does not allow named arguments
8+
--> $DIR/fn-trait-use-named-params-issue-140169.rs:3:17
99
|
1010
LL | fn y(_: impl Fn(aaaa: u8, u8)) {}
11-
| ^ expected one of 7 possible tokens
11+
| ^^^^ help: remove name of the param
1212

13-
error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
14-
--> $DIR/fn-trait-use-named-params-issue-140169.rs:4:21
13+
error: syntax does not allow named arguments
14+
--> $DIR/fn-trait-use-named-params-issue-140169.rs:4:17
1515
|
1616
LL | fn z(_: impl Fn(aaaa: u8, vvvv: u8)) {}
17-
| ^ expected one of 7 possible tokens
17+
| ^^^^ help: remove name of the param
1818

19-
error: aborting due to 3 previous errors
19+
error: syntax does not allow named arguments
20+
--> $DIR/fn-trait-use-named-params-issue-140169.rs:4:27
21+
|
22+
LL | fn z(_: impl Fn(aaaa: u8, vvvv: u8)) {}
23+
| ^^^^ help: remove name of the param
24+
25+
error: aborting due to 4 previous errors
2026

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

+5-3
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
fn main() {
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 syntax does not allow named arguments
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
}
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: syntax does not allow named arguments
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 name of the param
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`.

0 commit comments

Comments
 (0)