mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Use parse_param_general when parsing (T, U)->R in parse_path_segment
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn> Co-authored-by: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
This commit is contained in:
@@ -702,6 +702,16 @@ parse_parenthesized_lifetime_suggestion = remove the parentheses
|
||||
parse_path_double_colon = path separator must be a double colon
|
||||
.suggestion = use a double colon instead
|
||||
|
||||
|
||||
parse_path_found_attribute_in_params = `Trait(...)` syntax does not support attributes in parameters
|
||||
.suggestion = remove the attributes
|
||||
|
||||
parse_path_found_c_variadic_params = `Trait(...)` syntax does not support c_variadic parameters
|
||||
.suggestion = remove the `...`
|
||||
|
||||
parse_path_found_named_params = `Trait(...)` syntax does not support named parameters
|
||||
.suggestion = remove the parameter name
|
||||
|
||||
parse_pattern_method_param_without_body = patterns aren't allowed in methods without bodies
|
||||
.suggestion = give this argument a name or use an underscore to ignore it
|
||||
|
||||
|
||||
@@ -1591,6 +1591,30 @@ pub(crate) struct ExpectedFnPathFoundFnKeyword {
|
||||
pub fn_token_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_path_found_named_params)]
|
||||
pub(crate) struct FnPathFoundNamedParams {
|
||||
#[primary_span]
|
||||
#[suggestion(applicability = "machine-applicable", code = "")]
|
||||
pub named_param_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_path_found_c_variadic_params)]
|
||||
pub(crate) struct PathFoundCVariadicParams {
|
||||
#[primary_span]
|
||||
#[suggestion(applicability = "machine-applicable", code = "")]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_path_found_attribute_in_params)]
|
||||
pub(crate) struct PathFoundAttributeInParams {
|
||||
#[primary_span]
|
||||
#[suggestion(applicability = "machine-applicable", code = "")]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_path_double_colon)]
|
||||
pub(crate) struct PathSingleColon {
|
||||
|
||||
@@ -2894,7 +2894,7 @@ pub(super) fn parse_fn_params(&mut self, req_name: ReqName) -> PResult<'a, ThinV
|
||||
let (mut params, _) = self.parse_paren_comma_seq(|p| {
|
||||
p.recover_vcs_conflict_marker();
|
||||
let snapshot = p.create_snapshot_for_diagnostic();
|
||||
let param = p.parse_param_general(req_name, first_param).or_else(|e| {
|
||||
let param = p.parse_param_general(req_name, first_param, true).or_else(|e| {
|
||||
let guar = e.emit();
|
||||
// When parsing a param failed, we should check to make the span of the param
|
||||
// not contain '(' before it.
|
||||
@@ -2922,7 +2922,13 @@ pub(super) fn parse_fn_params(&mut self, req_name: ReqName) -> PResult<'a, ThinV
|
||||
/// Parses a single function parameter.
|
||||
///
|
||||
/// - `self` is syntactically allowed when `first_param` holds.
|
||||
fn parse_param_general(&mut self, req_name: ReqName, first_param: bool) -> PResult<'a, Param> {
|
||||
/// - `recover_arg_parse` is used to recover from a failed argument parse.
|
||||
pub(super) fn parse_param_general(
|
||||
&mut self,
|
||||
req_name: ReqName,
|
||||
first_param: bool,
|
||||
recover_arg_parse: bool,
|
||||
) -> PResult<'a, Param> {
|
||||
let lo = self.token.span;
|
||||
let attrs = self.parse_outer_attributes()?;
|
||||
self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
|
||||
@@ -2990,12 +2996,13 @@ fn parse_param_general(&mut self, req_name: ReqName, first_param: bool) -> PResu
|
||||
// If this is a C-variadic argument and we hit an error, return the error.
|
||||
Err(err) if this.token == token::DotDotDot => return Err(err),
|
||||
Err(err) if this.unmatched_angle_bracket_count > 0 => return Err(err),
|
||||
// Recover from attempting to parse the argument as a type without pattern.
|
||||
Err(err) => {
|
||||
Err(err) if recover_arg_parse => {
|
||||
// Recover from attempting to parse the argument as a type without pattern.
|
||||
err.cancel();
|
||||
this.restore_snapshot(parser_snapshot_before_ty);
|
||||
this.recover_arg_parse()?
|
||||
}
|
||||
Err(err) => return Err(err),
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -15,7 +15,11 @@
|
||||
|
||||
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
|
||||
use super::{Parser, Restrictions, TokenType};
|
||||
use crate::errors::{self, PathSingleColon, PathTripleColon};
|
||||
use crate::ast::{PatKind, TyKind};
|
||||
use crate::errors::{
|
||||
self, FnPathFoundNamedParams, PathFoundAttributeInParams, PathFoundCVariadicParams,
|
||||
PathSingleColon, PathTripleColon,
|
||||
};
|
||||
use crate::exp;
|
||||
use crate::parser::{CommaRecoveryMode, RecoverColon, RecoverComma};
|
||||
|
||||
@@ -396,7 +400,28 @@ pub(super) fn parse_path_segment(
|
||||
snapshot = Some(self.create_snapshot_for_diagnostic());
|
||||
}
|
||||
|
||||
let (inputs, _) = match self.parse_paren_comma_seq(|p| p.parse_ty()) {
|
||||
let dcx = self.dcx();
|
||||
let parse_params_result = self.parse_paren_comma_seq(|p| {
|
||||
let param = p.parse_param_general(|_| false, false, false);
|
||||
param.map(move |param| {
|
||||
if !matches!(param.pat.kind, PatKind::Missing) {
|
||||
dcx.emit_err(FnPathFoundNamedParams {
|
||||
named_param_span: param.pat.span,
|
||||
});
|
||||
}
|
||||
if matches!(param.ty.kind, TyKind::CVarArgs) {
|
||||
dcx.emit_err(PathFoundCVariadicParams { span: param.pat.span });
|
||||
}
|
||||
if !param.attrs.is_empty() {
|
||||
dcx.emit_err(PathFoundAttributeInParams {
|
||||
span: param.attrs[0].span,
|
||||
});
|
||||
}
|
||||
param.ty
|
||||
})
|
||||
});
|
||||
|
||||
let (inputs, _) = match parse_params_result {
|
||||
Ok(output) => output,
|
||||
Err(mut error) if prev_token_before_parsing == token::PathSep => {
|
||||
error.span_label(
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
fn g(_: fn(a: u8)) {}
|
||||
fn x(_: impl Fn(u8, vvvv: u8)) {} //~ ERROR expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
|
||||
fn y(_: impl Fn(aaaa: u8, u8)) {} //~ ERROR expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
|
||||
fn z(_: impl Fn(aaaa: u8, vvvv: u8)) {} //~ ERROR expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
|
||||
fn f1(_: fn(a: u8)) {}
|
||||
fn f2(_: impl Fn(u8, vvvv: u8)) {} //~ ERROR `Trait(...)` syntax does not support named parameters
|
||||
fn f3(_: impl Fn(aaaa: u8, u8)) {} //~ ERROR `Trait(...)` syntax does not support named parameters
|
||||
fn f4(_: impl Fn(aaaa: u8, vvvv: u8)) {}
|
||||
//~^ ERROR `Trait(...)` syntax does not support named parameters
|
||||
//~| ERROR `Trait(...)` syntax does not support named parameters
|
||||
fn f5(_: impl Fn(u8, ...)) {}
|
||||
//~^ ERROR `Trait(...)` syntax does not support c_variadic parameters
|
||||
fn f6(_: impl Fn(u8, #[allow(unused_attributes)] u8)) {}
|
||||
//~^ ERROR `Trait(...)` syntax does not support attributes in parameters
|
||||
|
||||
fn main(){}
|
||||
|
||||
@@ -1,20 +1,38 @@
|
||||
error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
|
||||
--> $DIR/fn-trait-use-named-params-issue-140169.rs:2:25
|
||||
error: `Trait(...)` syntax does not support named parameters
|
||||
--> $DIR/fn-trait-use-named-params-issue-140169.rs:2:22
|
||||
|
|
||||
LL | fn x(_: impl Fn(u8, vvvv: u8)) {}
|
||||
| ^ expected one of 7 possible tokens
|
||||
LL | fn f2(_: impl Fn(u8, vvvv: u8)) {}
|
||||
| ^^^^ help: remove the parameter name
|
||||
|
||||
error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
|
||||
--> $DIR/fn-trait-use-named-params-issue-140169.rs:3:21
|
||||
error: `Trait(...)` syntax does not support named parameters
|
||||
--> $DIR/fn-trait-use-named-params-issue-140169.rs:3:18
|
||||
|
|
||||
LL | fn y(_: impl Fn(aaaa: u8, u8)) {}
|
||||
| ^ expected one of 7 possible tokens
|
||||
LL | fn f3(_: impl Fn(aaaa: u8, u8)) {}
|
||||
| ^^^^ help: remove the parameter name
|
||||
|
||||
error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
|
||||
--> $DIR/fn-trait-use-named-params-issue-140169.rs:4:21
|
||||
error: `Trait(...)` syntax does not support named parameters
|
||||
--> $DIR/fn-trait-use-named-params-issue-140169.rs:4:18
|
||||
|
|
||||
LL | fn z(_: impl Fn(aaaa: u8, vvvv: u8)) {}
|
||||
| ^ expected one of 7 possible tokens
|
||||
LL | fn f4(_: impl Fn(aaaa: u8, vvvv: u8)) {}
|
||||
| ^^^^ help: remove the parameter name
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: `Trait(...)` syntax does not support named parameters
|
||||
--> $DIR/fn-trait-use-named-params-issue-140169.rs:4:28
|
||||
|
|
||||
LL | fn f4(_: impl Fn(aaaa: u8, vvvv: u8)) {}
|
||||
| ^^^^ help: remove the parameter name
|
||||
|
||||
error: `Trait(...)` syntax does not support c_variadic parameters
|
||||
--> $DIR/fn-trait-use-named-params-issue-140169.rs:7:22
|
||||
|
|
||||
LL | fn f5(_: impl Fn(u8, ...)) {}
|
||||
| ^^^ help: remove the `...`
|
||||
|
||||
error: `Trait(...)` syntax does not support attributes in parameters
|
||||
--> $DIR/fn-trait-use-named-params-issue-140169.rs:9:22
|
||||
|
|
||||
LL | fn f6(_: impl Fn(u8, #[allow(unused_attributes)] u8)) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the attributes
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
dealloc(ptr2, Layout::(x: !)(1, 1)); //~ ERROR: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
|
||||
//~^ ERROR: expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
|
||||
//~| NOTE while parsing this parenthesized list of type arguments starting here
|
||||
dealloc(ptr2, Layout::(x: !)(1, 1)); //~ ERROR `Trait(...)` syntax does not support named parameters
|
||||
//~^ ERROR cannot find function `dealloc` in this scope [E0425]
|
||||
//~| ERROR cannot find value `ptr2` in this scope [E0425]
|
||||
//~| ERROR the `!` type is experimental [E0658]
|
||||
//~| ERROR cannot find function, tuple struct or tuple variant `Layout` in this scope [E0425]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,43 @@
|
||||
error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
|
||||
--> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:33
|
||||
error: `Trait(...)` syntax does not support named parameters
|
||||
--> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:32
|
||||
|
|
||||
LL | dealloc(ptr2, Layout::(x: !)(1, 1));
|
||||
| --- ^ expected one of 7 possible tokens
|
||||
| |
|
||||
| while parsing this parenthesized list of type arguments starting here
|
||||
| ^ help: remove the parameter name
|
||||
|
||||
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
|
||||
--> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:43
|
||||
error[E0425]: cannot find function `dealloc` in this scope
|
||||
--> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:9
|
||||
|
|
||||
LL | dealloc(ptr2, Layout::(x: !)(1, 1));
|
||||
| ^ expected one of `.`, `;`, `?`, `}`, or an operator
|
||||
| ^^^^^^^ not found in this scope
|
||||
|
|
||||
help: consider importing this function
|
||||
|
|
||||
LL + use std::alloc::dealloc;
|
||||
|
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0425]: cannot find value `ptr2` in this scope
|
||||
--> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:17
|
||||
|
|
||||
LL | dealloc(ptr2, Layout::(x: !)(1, 1));
|
||||
| ^^^^ not found in this scope
|
||||
|
||||
error[E0658]: the `!` type is experimental
|
||||
--> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:35
|
||||
|
|
||||
LL | dealloc(ptr2, Layout::(x: !)(1, 1));
|
||||
| ^
|
||||
|
|
||||
= note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
|
||||
= help: add `#![feature(never_type)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0425]: cannot find function, tuple struct or tuple variant `Layout` in this scope
|
||||
--> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:23
|
||||
|
|
||||
LL | dealloc(ptr2, Layout::(x: !)(1, 1));
|
||||
| ^^^^^^ not found in this scope
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0425, E0658.
|
||||
For more information about an error, try `rustc --explain E0425`.
|
||||
|
||||
@@ -2,7 +2,4 @@
|
||||
|
||||
struct Apple((Apple, Option(Banana ? Citron)));
|
||||
//~^ ERROR invalid `?` in type
|
||||
//~| ERROR expected one of `)` or `,`, found `Citron`
|
||||
//~| ERROR cannot find type `Citron` in this scope [E0412]
|
||||
//~| ERROR parenthesized type parameters may only be used with a `Fn` trait [E0214]
|
||||
//~| ERROR `Apple` has infinite size
|
||||
//~| ERROR unexpected token: `Citron`
|
||||
|
||||
@@ -10,44 +10,11 @@ LL - struct Apple((Apple, Option(Banana ? Citron)));
|
||||
LL + struct Apple((Apple, Option(Option<Banana > Citron)));
|
||||
|
|
||||
|
||||
error: expected one of `)` or `,`, found `Citron`
|
||||
error: unexpected token: `Citron`
|
||||
--> $DIR/issue-103748-ICE-wrong-braces.rs:3:38
|
||||
|
|
||||
LL | struct Apple((Apple, Option(Banana ? Citron)));
|
||||
| -^^^^^^ expected one of `)` or `,`
|
||||
| |
|
||||
| help: missing `,`
|
||||
| ^^^^^^ unexpected token after this
|
||||
|
||||
error[E0412]: cannot find type `Citron` in this scope
|
||||
--> $DIR/issue-103748-ICE-wrong-braces.rs:3:38
|
||||
|
|
||||
LL | struct Apple((Apple, Option(Banana ? Citron)));
|
||||
| ^^^^^^ not found in this scope
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
|
||||
--> $DIR/issue-103748-ICE-wrong-braces.rs:3:22
|
||||
|
|
||||
LL | struct Apple((Apple, Option(Banana ? Citron)));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses
|
||||
|
|
||||
help: use angle brackets instead
|
||||
|
|
||||
LL - struct Apple((Apple, Option(Banana ? Citron)));
|
||||
LL + struct Apple((Apple, Option<Banana ? Citron>));
|
||||
|
|
||||
|
||||
error[E0072]: recursive type `Apple` has infinite size
|
||||
--> $DIR/issue-103748-ICE-wrong-braces.rs:3:1
|
||||
|
|
||||
LL | struct Apple((Apple, Option(Banana ? Citron)));
|
||||
| ^^^^^^^^^^^^ ----- recursive without indirection
|
||||
|
|
||||
help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
|
||||
|
|
||||
LL | struct Apple((Box<Apple>, Option(Banana ? Citron)));
|
||||
| ++++ +
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0072, E0214, E0412.
|
||||
For more information about an error, try `rustc --explain E0072`.
|
||||
|
||||
Reference in New Issue
Block a user