Skip to content

Commit 1c4b9ec

Browse files
committed
Add error for c_variadic and attribute in Trait(...) syntax
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
1 parent 804c6b4 commit 1c4b9ec

10 files changed

+109
-88
lines changed

compiler/rustc_parse/messages.ftl

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -702,8 +702,15 @@ 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+
706+
parse_path_found_attribute_in_params = `Trait(...)` syntax does not support attributes in parameters
707+
.suggestion = remove the attributes
708+
709+
parse_path_found_c_variadic_params = `Trait(...)` syntax does not support c_variadic parameters
710+
.suggestion = remove the `...`
711+
705712
parse_path_found_named_params = `Trait(...)` syntax does not support named parameters
706-
.suggestion = remove name of the parameter
713+
.suggestion = remove the parameter name
707714
708715
parse_pattern_method_param_without_body = patterns aren't allowed in methods without bodies
709716
.suggestion = give this argument a name or use an underscore to ignore it

compiler/rustc_parse/src/errors.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,6 +1599,22 @@ pub(crate) struct FnPathFoundNamedParams {
15991599
pub named_param_span: Span,
16001600
}
16011601

1602+
#[derive(Diagnostic)]
1603+
#[diag(parse_path_found_c_variadic_params)]
1604+
pub(crate) struct PathFoundCVariadicParams {
1605+
#[primary_span]
1606+
#[suggestion(applicability = "machine-applicable", code = "")]
1607+
pub span: Span,
1608+
}
1609+
1610+
#[derive(Diagnostic)]
1611+
#[diag(parse_path_found_attribute_in_params)]
1612+
pub(crate) struct PathFoundAttributeInParams {
1613+
#[primary_span]
1614+
#[suggestion(applicability = "machine-applicable", code = "")]
1615+
pub span: Span,
1616+
}
1617+
16021618
#[derive(Diagnostic)]
16031619
#[diag(parse_path_double_colon)]
16041620
pub(crate) struct PathSingleColon {

compiler/rustc_parse/src/parser/item.rs

Lines changed: 7 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,10 +2922,12 @@ impl<'a> Parser<'a> {
29222922
/// Parses a single function parameter.
29232923
///
29242924
/// - `self` is syntactically allowed when `first_param` holds.
2925+
/// - `recover_arg_parse` is used to recover from a failed argument parse.
29252926
pub(super) fn parse_param_general(
29262927
&mut self,
29272928
req_name: ReqName,
29282929
first_param: bool,
2930+
recover_arg_parse: bool,
29292931
) -> PResult<'a, Param> {
29302932
let lo = self.token.span;
29312933
let attrs = self.parse_outer_attributes()?;
@@ -2994,12 +2996,13 @@ impl<'a> Parser<'a> {
29942996
// If this is a C-variadic argument and we hit an error, return the error.
29952997
Err(err) if this.token == token::DotDotDot => return Err(err),
29962998
Err(err) if this.unmatched_angle_bracket_count > 0 => return Err(err),
2997-
// Recover from attempting to parse the argument as a type without pattern.
2998-
Err(err) => {
2999+
Err(err) if recover_arg_parse => {
3000+
// Recover from attempting to parse the argument as a type without pattern.
29993001
err.cancel();
30003002
this.restore_snapshot(parser_snapshot_before_ty);
30013003
this.recover_arg_parse()?
30023004
}
3005+
Err(err) => return Err(err),
30033006
}
30043007
};
30053008

@@ -3160,7 +3163,7 @@ impl<'a> Parser<'a> {
31603163
Ok(Some(Param::from_self(AttrVec::default(), eself, eself_ident)))
31613164
}
31623165

3163-
pub(super) fn is_named_param(&self) -> bool {
3166+
fn is_named_param(&self) -> bool {
31643167
let offset = match &self.token.kind {
31653168
token::OpenInvisible(origin) => match origin {
31663169
InvisibleOrigin::MetaVar(MetaVarKind::Pat(_)) => {

compiler/rustc_parse/src/parser/path.rs

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,18 @@ use rustc_ast::{
88
AssocItemConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs,
99
Path, PathSegment, QSelf,
1010
};
11-
use rustc_errors::{Applicability, Diag, PResult};
11+
use rustc_errors::{Applicability, Diag, DiagCtxtHandle, PResult};
1212
use rustc_span::{BytePos, Ident, Span, kw, sym};
1313
use thin_vec::ThinVec;
1414
use tracing::debug;
1515

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

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

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),
403+
let parse_type_params =
404+
|p: &mut Parser<'a>, dcx: &mut DiagCtxtHandle<'a>| -> PResult<'a, P<Ty>> {
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+
if matches!(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 mut dcx = self.dcx();
425+
let (inputs, _) = match self
426+
.parse_paren_comma_seq(|p| parse_type_params(p, &mut dcx))
427+
{
428+
Ok(output) => output,
414429
Err(mut error) if prev_token_before_parsing == token::PathSep => {
415430
error.span_label(
416431
prev_token_before_parsing.span.to(token_before_parsing.span),
Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
fn g(_: fn(a: u8)) {}
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
1+
fn f1(_: fn(a: u8)) {}
2+
fn f2(_: impl Fn(u8, vvvv: u8)) {} //~ ERROR `Trait(...)` syntax does not support named parameters
3+
fn f3(_: impl Fn(aaaa: u8, u8)) {} //~ ERROR `Trait(...)` syntax does not support named parameters
4+
fn f4(_: impl Fn(aaaa: u8, vvvv: u8)) {}
5+
//~^ ERROR `Trait(...)` syntax does not support named parameters
6+
//~| ERROR `Trait(...)` syntax does not support named parameters
7+
fn f5(_: impl Fn(u8, ...)) {}
8+
//~^ ERROR `Trait(...)` syntax does not support c_variadic parameters
9+
fn f6(_: impl Fn(u8, #[allow(unused_attributes)] u8)) {}
10+
//~^ ERROR `Trait(...)` syntax does not support attributes in parameters
711

812
fn main(){}
Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,38 @@
1-
error: syntax does not allow named arguments
2-
--> $DIR/fn-trait-use-named-params-issue-140169.rs:2:21
1+
error: `Trait(...)` syntax does not support named parameters
2+
--> $DIR/fn-trait-use-named-params-issue-140169.rs:2:22
33
|
4-
LL | fn x(_: impl Fn(u8, vvvv: u8)) {}
5-
| ^^^^ help: remove name of the param
4+
LL | fn f2(_: impl Fn(u8, vvvv: u8)) {}
5+
| ^^^^ help: remove the parameter name
66

7-
error: syntax does not allow named arguments
8-
--> $DIR/fn-trait-use-named-params-issue-140169.rs:3:17
7+
error: `Trait(...)` syntax does not support named parameters
8+
--> $DIR/fn-trait-use-named-params-issue-140169.rs:3:18
99
|
10-
LL | fn y(_: impl Fn(aaaa: u8, u8)) {}
11-
| ^^^^ help: remove name of the param
10+
LL | fn f3(_: impl Fn(aaaa: u8, u8)) {}
11+
| ^^^^ help: remove the parameter name
1212

13-
error: syntax does not allow named arguments
14-
--> $DIR/fn-trait-use-named-params-issue-140169.rs:4:17
13+
error: `Trait(...)` syntax does not support named parameters
14+
--> $DIR/fn-trait-use-named-params-issue-140169.rs:4:18
1515
|
16-
LL | fn z(_: impl Fn(aaaa: u8, vvvv: u8)) {}
17-
| ^^^^ help: remove name of the param
16+
LL | fn f4(_: impl Fn(aaaa: u8, vvvv: u8)) {}
17+
| ^^^^ help: remove the parameter name
1818

19-
error: syntax does not allow named arguments
20-
--> $DIR/fn-trait-use-named-params-issue-140169.rs:4:27
19+
error: `Trait(...)` syntax does not support named parameters
20+
--> $DIR/fn-trait-use-named-params-issue-140169.rs:4:28
2121
|
22-
LL | fn z(_: impl Fn(aaaa: u8, vvvv: u8)) {}
23-
| ^^^^ help: remove name of the param
22+
LL | fn f4(_: impl Fn(aaaa: u8, vvvv: u8)) {}
23+
| ^^^^ help: remove the parameter name
2424

25-
error: aborting due to 4 previous errors
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
2638

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

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

33
fn main() {
44
unsafe {
5-
dealloc(ptr2, Layout::(x: !)(1, 1)); //~ ERROR syntax does not allow named arguments
5+
dealloc(ptr2, Layout::(x: !)(1, 1)); //~ ERROR `Trait(...)` syntax does not support named parameters
66
//~^ ERROR cannot find function `dealloc` in this scope [E0425]
77
//~| ERROR cannot find value `ptr2` in this scope [E0425]
88
//~| ERROR the `!` type is experimental [E0658]

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: syntax does not allow named arguments
1+
error: `Trait(...)` syntax does not support named parameters
22
--> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:32
33
|
44
LL | dealloc(ptr2, Layout::(x: !)(1, 1));
5-
| ^ help: remove name of the param
5+
| ^ help: remove the parameter name
66

77
error[E0425]: cannot find function `dealloc` in this scope
88
--> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:9

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
struct Apple((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)