about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_parse/messages.ftl10
-rw-r--r--compiler/rustc_parse/src/errors.rs24
-rw-r--r--compiler/rustc_parse/src/parser/item.rs15
-rw-r--r--compiler/rustc_parse/src/parser/path.rs29
-rw-r--r--tests/ui/fn/fn-trait-use-named-params-issue-140169.rs12
-rw-r--r--tests/ui/fn/fn-trait-use-named-params-issue-140169.stderr38
-rw-r--r--tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs8
-rw-r--r--tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr45
-rw-r--r--tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs5
-rw-r--r--tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr39
10 files changed, 167 insertions, 58 deletions
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index 3e953e6c855..3d7e0fcc308 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -715,6 +715,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
 
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 9e5c81d44a5..766baf6f80c 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -1647,6 +1647,30 @@ pub(crate) struct ExpectedFnPathFoundFnKeyword {
 }
 
 #[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 {
     #[primary_span]
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 4be8a90368d..babc55ccc0f 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2894,7 +2894,7 @@ impl<'a> Parser<'a> {
         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 @@ impl<'a> Parser<'a> {
     /// 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 @@ impl<'a> Parser<'a> {
                     // 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),
                 }
             };
 
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 1093e4f4af0..9bce2fa74ca 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -15,7 +15,11 @@ use tracing::debug;
 
 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 @@ impl<'a> Parser<'a> {
                         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(
diff --git a/tests/ui/fn/fn-trait-use-named-params-issue-140169.rs b/tests/ui/fn/fn-trait-use-named-params-issue-140169.rs
new file mode 100644
index 00000000000..218450abd49
--- /dev/null
+++ b/tests/ui/fn/fn-trait-use-named-params-issue-140169.rs
@@ -0,0 +1,12 @@
+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(){}
diff --git a/tests/ui/fn/fn-trait-use-named-params-issue-140169.stderr b/tests/ui/fn/fn-trait-use-named-params-issue-140169.stderr
new file mode 100644
index 00000000000..b72d5b7b3bc
--- /dev/null
+++ b/tests/ui/fn/fn-trait-use-named-params-issue-140169.stderr
@@ -0,0 +1,38 @@
+error: `Trait(...)` syntax does not support named parameters
+  --> $DIR/fn-trait-use-named-params-issue-140169.rs:2:22
+   |
+LL | fn f2(_: impl Fn(u8, vvvv: u8)) {}
+   |                      ^^^^ help: remove the parameter name
+
+error: `Trait(...)` syntax does not support named parameters
+  --> $DIR/fn-trait-use-named-params-issue-140169.rs:3:18
+   |
+LL | fn f3(_: impl Fn(aaaa: u8, u8)) {}
+   |                  ^^^^ help: remove the parameter name
+
+error: `Trait(...)` syntax does not support named parameters
+  --> $DIR/fn-trait-use-named-params-issue-140169.rs:4:18
+   |
+LL | fn f4(_: impl Fn(aaaa: u8, vvvv: u8)) {}
+   |                  ^^^^ help: remove the parameter name
+
+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
+
diff --git a/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs b/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs
index 6bfe16ae37d..db25ce44089 100644
--- a/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs
+++ b/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs
@@ -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]
     }
 }
diff --git a/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr b/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr
index c12bf7f9e3f..a083883af21 100644
--- a/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr
+++ b/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr
@@ -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[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 2 previous errors
+error: aborting due to 5 previous errors
 
+Some errors have detailed explanations: E0425, E0658.
+For more information about an error, try `rustc --explain E0425`.
diff --git a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs
index 1c28c0632fa..60dd88e6540 100644
--- a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs
+++ b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs
@@ -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`
diff --git a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr
index 97a73b4fd5e..c92535c3906 100644
--- a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr
+++ b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr
@@ -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[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
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0072, E0214, E0412.
-For more information about an error, try `rustc --explain E0072`.