diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index c14ad62e9a60b..b7a9765d09273 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -255,7 +255,7 @@ impl PathSegment { pub enum GenericArgs { /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`. AngleBracketed(AngleBracketedArgs), - /// The `(A, B)` and `C` in `Foo(A, B) -> C`. + /// The `(A, B)` and `C` in `Foo(A, B) -> C`, used for the `Fn` trait among others. Parenthesized(ParenthesizedArgs), /// `(..)` in return type notation. ParenthesizedElided(Span), diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index fe5c604544448..010afc6be5534 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -291,8 +291,11 @@ impl<'a> AstValidator<'a> { }); } - fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option, bool)) { - for Param { pat, .. } in &decl.inputs { + fn check_decl_no_pat( + fn_inputs: &[Param], + mut report_err: impl FnMut(Span, Option, bool), + ) { + for Param { pat, .. } in fn_inputs { match pat.kind { PatKind::Missing | PatKind::Ident(BindingMode::NONE, _, None) | PatKind::Wild => {} PatKind::Ident(BindingMode::MUT, ident, None) => { @@ -397,7 +400,7 @@ impl<'a> AstValidator<'a> { let c_variadic_span = self.check_decl_cvariadic_pos(fn_decl); self.check_decl_splatting(fn_decl, c_variadic_span, splat_semantic); self.check_decl_attrs(fn_decl); - self.check_decl_self_param(fn_decl, self_semantic); + self.check_decl_self_param(&fn_decl.inputs, self_semantic); } /// Emits fatal error if function declaration has more than `u16::MAX` arguments @@ -544,8 +547,8 @@ impl<'a> AstValidator<'a> { }); } - fn check_decl_self_param(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) { - if let (SelfSemantic::No, [param, ..]) = (self_semantic, &*fn_decl.inputs) { + fn check_decl_self_param(&self, fn_inputs: &[Param], self_semantic: SelfSemantic) { + if let (SelfSemantic::No, [param, ..]) = (self_semantic, fn_inputs) { if param.is_self() { self.dcx().emit_err(diagnostics::FnParamForbiddenSelf { span: param.span }); } @@ -1200,7 +1203,7 @@ impl<'a> AstValidator<'a> { SelfSemantic::No, SplatSemantic::from_extern(bfty.ext), ); - Self::check_decl_no_pat(&bfty.decl, |span, _, _| { + Self::check_decl_no_pat(&bfty.decl.inputs, |span, _, _| { self.dcx().emit_err(diagnostics::PatternFnPointer { span }); }); if let Extern::Implicit(extern_span) = bfty.ext { @@ -2009,7 +2012,7 @@ impl Visitor<'_> for AstValidator<'_> { // Functions without bodies cannot have patterns. if let FnKind::Fn(ctxt, _, Fn { body: None, sig, .. }) = fk { - Self::check_decl_no_pat(&sig.decl, |span, ident, mut_ident| { + Self::check_decl_no_pat(&sig.decl.inputs, |span, ident, mut_ident| { if mut_ident && matches!(ctxt, FnCtxt::Assoc(_)) { if let Some(ident) = ident { let is_foreign = matches!(ctxt, FnCtxt::Foreign); @@ -2208,6 +2211,16 @@ impl Visitor<'_> for AstValidator<'_> { |this| visit::walk_anon_const(this, anon_const), ) } + + fn visit_path_segment(&mut self, seg: &PathSegment) -> Self::Result { + if let Some(Parenthesized(args)) = &seg.args { + self.check_decl_self_param(&args.inputs, SelfSemantic::No); + Self::check_decl_no_pat(&args.inputs, |span, _, _| { + self.dcx().emit_err(diagnostics::PatternParenthesizedArgList { span }); + }); + } + visit::walk_path_segment(self, seg); + } } pub fn check_crate( diff --git a/compiler/rustc_ast_passes/src/diagnostics.rs b/compiler/rustc_ast_passes/src/diagnostics.rs index 5ab905b5df52b..19516272ce166 100644 --- a/compiler/rustc_ast_passes/src/diagnostics.rs +++ b/compiler/rustc_ast_passes/src/diagnostics.rs @@ -675,6 +675,13 @@ pub(crate) struct PatternFnPointer { pub span: Span, } +#[derive(Diagnostic)] +#[diag("patterns aren't allowed in parenthesized argument lists", code = E0561)] +pub(crate) struct PatternParenthesizedArgList { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag("only a single explicit lifetime bound is permitted", code = E0226)] pub(crate) struct TraitObjectBound { diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 7efa784bd8622..5bad528963987 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -642,7 +642,7 @@ declare_features! ( /// Allows using `#[target_feature(enable = "...")]` on `#[naked]` on functions. (unstable, naked_functions_target_feature, "1.86.0", Some(138568)), /// Allows providing names to parameters of `impl Fn` etc - (incomplete, named_fn_trait_parameters, "1.99.0", Some(158499)), + (unstable, named_fn_trait_parameters, "1.99.0", Some(158499)), /// Allows specifying the as-needed link modifier (unstable, native_link_modifiers_as_needed, "1.53.0", Some(81490)), /// Allow negative trait implementations. diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 6d4a0215eb7b3..a8bc293d96751 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2379,6 +2379,7 @@ impl<'a> Parser<'a> { target: match context { FnContext::Trait => "methods without bodies", FnContext::FunctionPtrType => "function pointer types", + FnContext::ParenthesizedArgumentList => "parenthesized argument list", FnContext::Free => unreachable!("This method is not called in free functions, as patterns are always allowed there"), FnContext::Impl => unreachable!("This method is not called in impls, as patterns are always allowed there"), }, diff --git a/compiler/rustc_parse/src/parser/function.rs b/compiler/rustc_parse/src/parser/function.rs index 57fe19226066c..220cc5a3bc069 100644 --- a/compiler/rustc_parse/src/parser/function.rs +++ b/compiler/rustc_parse/src/parser/function.rs @@ -103,6 +103,8 @@ pub(crate) enum FnContext { Free, /// A Function Pointer Type `fn(..)`. FunctionPtrType, + /// A Parenthesized Argument List `impl Fn(...)` + ParenthesizedArgumentList, /// A Trait context. Trait, /// An Impl block. @@ -691,7 +693,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(fn_parse_mode, first_param, true).or_else(|e| { + let param = p.parse_param_general(fn_parse_mode, first_param).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. @@ -724,7 +726,6 @@ impl<'a> Parser<'a> { &mut self, fn_parse_mode: &FnParseMode, first_param: bool, - recover_arg_parse: bool, ) -> PResult<'a, Param> { let lo = self.token.span; let attrs = self.parse_outer_attributes()?; @@ -812,13 +813,22 @@ 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), - Err(err) if recover_arg_parse => { + Err(err) => { // 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(fn_parse_mode.context)? + match this.recover_arg_parse(fn_parse_mode.context) { + Ok(res) => { + // We managed to parse the argument as a pattern, cancel the original error and emit a better one + err.cancel(); + res + } + Err(new_err) => { + // We did not manage to parse the argument as a pattern, avoid suggesting a pattern and emit the original error + new_err.cancel(); + return Err(err); + } + } } - Err(err) => return Err(err), } }; diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index cbd0891c7fe9a..6bc7195b8371c 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -397,14 +397,16 @@ impl<'a> Parser<'a> { } let dcx = self.dcx(); + let mut first_param = true; let parse_params_result = self.parse_paren_comma_seq(|p| { // Inside parenthesized type arguments, we want types only, not names. let mode = FnParseMode { - context: FnContext::Free, + context: FnContext::ParenthesizedArgumentList, req_name: |_, _| false, req_body: false, }; - let param = p.parse_param_general(&mode, false, false)?; + let param = p.parse_param_general(&mode, first_param)?; + first_param = false; if !matches!(param.pat.kind, PatKind::Missing) { self.psess .gated_spans diff --git a/tests/ui/fn/fn-ptr-pattern.rs b/tests/ui/fn/fn-ptr-pattern.rs index 9bf759af19af7..4260a5095048e 100644 --- a/tests/ui/fn/fn-ptr-pattern.rs +++ b/tests/ui/fn/fn-ptr-pattern.rs @@ -42,6 +42,8 @@ fn semantics( //~^ ERROR patterns aren't allowed in function pointer types restricted_pat6: fn(&true: ()), //~^ ERROR patterns aren't allowed in function pointer types + + duplicate_names: fn(x: usize, x: usize), ) { } // Patterns are also syntactically rejected, but restricted patterns are not diff --git a/tests/ui/fn/fn-ptr-pattern.stderr b/tests/ui/fn/fn-ptr-pattern.stderr index 4425caee39e3f..27982d26dbc54 100644 --- a/tests/ui/fn/fn-ptr-pattern.stderr +++ b/tests/ui/fn/fn-ptr-pattern.stderr @@ -71,7 +71,7 @@ LL | self3: fn(bool, self), | ^^^^ must be the first parameter of an associated function error[E0642]: patterns aren't allowed in function pointer types - --> $DIR/fn-ptr-pattern.rs:50:14 + --> $DIR/fn-ptr-pattern.rs:52:14 | LL | pat1: fn(1..3: bool), | ^^^^ @@ -83,7 +83,7 @@ LL + pat1: fn(_: bool), | error[E0642]: patterns aren't allowed in function pointer types - --> $DIR/fn-ptr-pattern.rs:52:14 + --> $DIR/fn-ptr-pattern.rs:54:14 | LL | pat2: fn((x, y): (bool, bool)), | ^^^^^^ @@ -95,7 +95,7 @@ LL + pat2: fn(_: (bool, bool)), | error[E0642]: patterns aren't allowed in function pointer types - --> $DIR/fn-ptr-pattern.rs:54:14 + --> $DIR/fn-ptr-pattern.rs:56:14 | LL | pat3: fn(Thing { a, b }: Thing), | ^^^^^^^^^^^^^^ @@ -107,7 +107,7 @@ LL + pat3: fn(_: Thing), | error[E0642]: patterns aren't allowed in function pointer types - --> $DIR/fn-ptr-pattern.rs:56:14 + --> $DIR/fn-ptr-pattern.rs:58:14 | LL | pat4: fn(NoThing { a, b }: NoThing), | ^^^^^^^^^^^^^^^^ @@ -119,7 +119,7 @@ LL + pat4: fn(_: NoThing), | error[E0642]: patterns aren't allowed in function pointer types - --> $DIR/fn-ptr-pattern.rs:58:14 + --> $DIR/fn-ptr-pattern.rs:60:14 | LL | pat5: fn((((((x))))): bool), | ^^^^^^^^^^^ @@ -131,13 +131,13 @@ LL + pat5: fn(_: bool), | error: unexpected `self` parameter in function - --> $DIR/fn-ptr-pattern.rs:62:21 + --> $DIR/fn-ptr-pattern.rs:64:21 | LL | self2: fn(self, self), | ^^^^ must be the first parameter of an associated function error: unexpected `self` parameter in function - --> $DIR/fn-ptr-pattern.rs:64:21 + --> $DIR/fn-ptr-pattern.rs:66:21 | LL | self3: fn(bool, self), | ^^^^ must be the first parameter of an associated function @@ -201,7 +201,7 @@ LL | pat4: fn(NoThing { a, b }: NoThing), | ^^^^^^^ not found in this scope | note: similarly named struct `Thing` defined here - --> $DIR/fn-ptr-pattern.rs:75:1 + --> $DIR/fn-ptr-pattern.rs:77:1 | LL | struct Thing { a: bool, b: bool } | ^^^^^^^^^^^^ diff --git a/tests/ui/fn/named-fn-trait-parameters.rs b/tests/ui/fn/named-fn-trait-parameters.rs index 00b00b53a94d6..103ce5902048e 100644 --- a/tests/ui/fn/named-fn-trait-parameters.rs +++ b/tests/ui/fn/named-fn-trait-parameters.rs @@ -15,52 +15,58 @@ fn allowed( // Patterns are semantically rejected fn semantics( pat1: impl Fn(1..3: bool), - //~^ ERROR expected type, found `1` + //~^ ERROR patterns aren't allowed in parenthesized argument list pat2: impl Fn((x, y): (bool, bool)), - //~^ ERROR unexpected token: `:` + //~^ ERROR patterns aren't allowed in parenthesized argument list pat3: impl Fn(Thing { a, b }: Thing), - //~^ ERROR expected one of `!`, `(`, `+`, `::`, or `<`, found `{` + //~^ ERROR patterns aren't allowed in parenthesized argument list pat4: impl Fn(NoThing { a, b }: NoThing), - //~^ ERROR expected one of `!`, `(`, `+`, `::`, or `<`, found `{` + //~^ ERROR patterns aren't allowed in parenthesized argument list + //~| ERROR cannot find type `NoThing` in this scope pat5: impl Fn((((((x))))): bool), - //~^ ERROR unexpected token: `:` + //~^ ERROR patterns aren't allowed in parenthesized argument list self1: impl Fn(self), - //~^ ERROR unexpected `self` parameter in function + //~^ ERROR `self` parameter is only allowed in associated functions self2: impl Fn(self, self), - //~^ ERROR unexpected `self` parameter in function + //~^ ERROR `self` parameter is only allowed in associated functions //~| ERROR unexpected `self` parameter in function self3: impl Fn(bool, self), //~^ ERROR unexpected `self` parameter in function - // FIXME should be rejected restricted_pat1: impl Fn(mut x: ()), + //~^ ERROR patterns aren't allowed in parenthesized argument lists restricted_pat2: impl Fn(&x: ()), + //~^ ERROR patterns aren't allowed in parenthesized argument lists restricted_pat3: impl Fn(&&x: ()), + //~^ ERROR patterns aren't allowed in parenthesized argument lists restricted_pat4: impl Fn(false: ()), + //~^ ERROR patterns aren't allowed in parenthesized argument lists restricted_pat5: impl Fn(&_: ()), + //~^ ERROR patterns aren't allowed in parenthesized argument lists restricted_pat6: impl Fn(&true: ()), + //~^ ERROR patterns aren't allowed in parenthesized argument lists + + duplicate_names: impl Fn(x: usize, x: usize), ) { } // Patterns are also syntactically rejected, but restricted patterns are not #[cfg(false)] fn syntax( pat1: impl Fn(1..3: bool), - //~^ ERROR expected type, found `1` + //~^ ERROR patterns aren't allowed in parenthesized argument list pat2: impl Fn((x, y): (bool, bool)), - //~^ ERROR unexpected token: `:` + //~^ ERROR patterns aren't allowed in parenthesized argument list pat3: impl Fn(Thing { a, b }: Thing), - //~^ ERROR expected one of `!`, `(`, `+`, `::`, or `<`, found `{` + //~^ ERROR patterns aren't allowed in parenthesized argument list pat4: impl Fn(NoThing { a, b }: NoThing), - //~^ ERROR expected one of `!`, `(`, `+`, `::`, or `<`, found `{` + //~^ ERROR patterns aren't allowed in parenthesized argument list pat5: impl Fn((((((x))))): bool), - //~^ ERROR unexpected token: `:` + //~^ ERROR patterns aren't allowed in parenthesized argument list - self1: impl Fn(self), // FIXME should be accepted - //~^ ERROR unexpected `self` parameter in function + self1: impl Fn(self), self2: impl Fn(self, self), //~^ ERROR unexpected `self` parameter in function - //~| ERROR unexpected `self` parameter in function self3: impl Fn(bool, self), //~^ ERROR unexpected `self` parameter in function diff --git a/tests/ui/fn/named-fn-trait-parameters.stderr b/tests/ui/fn/named-fn-trait-parameters.stderr index fa583ec52c543..d675826ff8559 100644 --- a/tests/ui/fn/named-fn-trait-parameters.stderr +++ b/tests/ui/fn/named-fn-trait-parameters.stderr @@ -1,110 +1,217 @@ -error: expected type, found `1` +error[E0642]: patterns aren't allowed in parenthesized argument list --> $DIR/named-fn-trait-parameters.rs:17:19 | LL | pat1: impl Fn(1..3: bool), - | ^ expected type + | ^^^^ + | +help: give this argument a name or use an underscore to ignore it + | +LL - pat1: impl Fn(1..3: bool), +LL + pat1: impl Fn(_: bool), + | -error: unexpected token: `:` - --> $DIR/named-fn-trait-parameters.rs:19:25 +error[E0642]: patterns aren't allowed in parenthesized argument list + --> $DIR/named-fn-trait-parameters.rs:19:19 | LL | pat2: impl Fn((x, y): (bool, bool)), - | ^ unexpected token after this + | ^^^^^^ + | +help: give this argument a name or use an underscore to ignore it + | +LL - pat2: impl Fn((x, y): (bool, bool)), +LL + pat2: impl Fn(_: (bool, bool)), + | -error: expected one of `!`, `(`, `+`, `::`, or `<`, found `{` - --> $DIR/named-fn-trait-parameters.rs:21:25 +error[E0642]: patterns aren't allowed in parenthesized argument list + --> $DIR/named-fn-trait-parameters.rs:21:19 | LL | pat3: impl Fn(Thing { a, b }: Thing), - | ^ expected one of `!`, `(`, `+`, `::`, or `<` + | ^^^^^^^^^^^^^^ + | +help: give this argument a name or use an underscore to ignore it + | +LL - pat3: impl Fn(Thing { a, b }: Thing), +LL + pat3: impl Fn(_: Thing), + | -error: expected one of `!`, `(`, `+`, `::`, or `<`, found `{` - --> $DIR/named-fn-trait-parameters.rs:23:27 +error[E0642]: patterns aren't allowed in parenthesized argument list + --> $DIR/named-fn-trait-parameters.rs:23:19 | LL | pat4: impl Fn(NoThing { a, b }: NoThing), - | ^ expected one of `!`, `(`, `+`, `::`, or `<` + | ^^^^^^^^^^^^^^^^ + | +help: give this argument a name or use an underscore to ignore it + | +LL - pat4: impl Fn(NoThing { a, b }: NoThing), +LL + pat4: impl Fn(_: NoThing), + | -error: unexpected token: `:` - --> $DIR/named-fn-trait-parameters.rs:25:30 +error[E0642]: patterns aren't allowed in parenthesized argument list + --> $DIR/named-fn-trait-parameters.rs:26:19 | LL | pat5: impl Fn((((((x))))): bool), - | ^ unexpected token after this - -error: unexpected `self` parameter in function - --> $DIR/named-fn-trait-parameters.rs:28:20 + | ^^^^^^^^^^^ | -LL | self1: impl Fn(self), - | ^^^^ must be the first parameter of an associated function - -error: unexpected `self` parameter in function - --> $DIR/named-fn-trait-parameters.rs:30:20 +help: give this argument a name or use an underscore to ignore it + | +LL - pat5: impl Fn((((((x))))): bool), +LL + pat5: impl Fn(_: bool), | -LL | self2: impl Fn(self, self), - | ^^^^ must be the first parameter of an associated function error: unexpected `self` parameter in function - --> $DIR/named-fn-trait-parameters.rs:30:26 + --> $DIR/named-fn-trait-parameters.rs:31:26 | LL | self2: impl Fn(self, self), | ^^^^ must be the first parameter of an associated function error: unexpected `self` parameter in function - --> $DIR/named-fn-trait-parameters.rs:33:26 + --> $DIR/named-fn-trait-parameters.rs:34:26 | LL | self3: impl Fn(bool, self), | ^^^^ must be the first parameter of an associated function -error: expected type, found `1` - --> $DIR/named-fn-trait-parameters.rs:48:19 +error[E0642]: patterns aren't allowed in parenthesized argument list + --> $DIR/named-fn-trait-parameters.rs:56:19 | LL | pat1: impl Fn(1..3: bool), - | ^ expected type + | ^^^^ + | +help: give this argument a name or use an underscore to ignore it + | +LL - pat1: impl Fn(1..3: bool), +LL + pat1: impl Fn(_: bool), + | -error: unexpected token: `:` - --> $DIR/named-fn-trait-parameters.rs:50:25 +error[E0642]: patterns aren't allowed in parenthesized argument list + --> $DIR/named-fn-trait-parameters.rs:58:19 | LL | pat2: impl Fn((x, y): (bool, bool)), - | ^ unexpected token after this + | ^^^^^^ + | +help: give this argument a name or use an underscore to ignore it + | +LL - pat2: impl Fn((x, y): (bool, bool)), +LL + pat2: impl Fn(_: (bool, bool)), + | -error: expected one of `!`, `(`, `+`, `::`, or `<`, found `{` - --> $DIR/named-fn-trait-parameters.rs:52:25 +error[E0642]: patterns aren't allowed in parenthesized argument list + --> $DIR/named-fn-trait-parameters.rs:60:19 | LL | pat3: impl Fn(Thing { a, b }: Thing), - | ^ expected one of `!`, `(`, `+`, `::`, or `<` + | ^^^^^^^^^^^^^^ + | +help: give this argument a name or use an underscore to ignore it + | +LL - pat3: impl Fn(Thing { a, b }: Thing), +LL + pat3: impl Fn(_: Thing), + | -error: expected one of `!`, `(`, `+`, `::`, or `<`, found `{` - --> $DIR/named-fn-trait-parameters.rs:54:27 +error[E0642]: patterns aren't allowed in parenthesized argument list + --> $DIR/named-fn-trait-parameters.rs:62:19 | LL | pat4: impl Fn(NoThing { a, b }: NoThing), - | ^ expected one of `!`, `(`, `+`, `::`, or `<` + | ^^^^^^^^^^^^^^^^ + | +help: give this argument a name or use an underscore to ignore it + | +LL - pat4: impl Fn(NoThing { a, b }: NoThing), +LL + pat4: impl Fn(_: NoThing), + | -error: unexpected token: `:` - --> $DIR/named-fn-trait-parameters.rs:56:30 +error[E0642]: patterns aren't allowed in parenthesized argument list + --> $DIR/named-fn-trait-parameters.rs:64:19 | LL | pat5: impl Fn((((((x))))): bool), - | ^ unexpected token after this - -error: unexpected `self` parameter in function - --> $DIR/named-fn-trait-parameters.rs:59:20 + | ^^^^^^^^^^^ | -LL | self1: impl Fn(self), // FIXME should be accepted - | ^^^^ must be the first parameter of an associated function - -error: unexpected `self` parameter in function - --> $DIR/named-fn-trait-parameters.rs:61:20 +help: give this argument a name or use an underscore to ignore it + | +LL - pat5: impl Fn((((((x))))): bool), +LL + pat5: impl Fn(_: bool), | -LL | self2: impl Fn(self, self), - | ^^^^ must be the first parameter of an associated function error: unexpected `self` parameter in function - --> $DIR/named-fn-trait-parameters.rs:61:26 + --> $DIR/named-fn-trait-parameters.rs:68:26 | LL | self2: impl Fn(self, self), | ^^^^ must be the first parameter of an associated function error: unexpected `self` parameter in function - --> $DIR/named-fn-trait-parameters.rs:64:26 + --> $DIR/named-fn-trait-parameters.rs:70:26 | LL | self3: impl Fn(bool, self), | ^^^^ must be the first parameter of an associated function -error: aborting due to 18 previous errors +error: `self` parameter is only allowed in associated functions + --> $DIR/named-fn-trait-parameters.rs:29:20 + | +LL | self1: impl Fn(self), + | ^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/named-fn-trait-parameters.rs:31:20 + | +LL | self2: impl Fn(self, self), + | ^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error[E0561]: patterns aren't allowed in parenthesized argument lists + --> $DIR/named-fn-trait-parameters.rs:37:30 + | +LL | restricted_pat1: impl Fn(mut x: ()), + | ^^^^^ + +error[E0561]: patterns aren't allowed in parenthesized argument lists + --> $DIR/named-fn-trait-parameters.rs:39:30 + | +LL | restricted_pat2: impl Fn(&x: ()), + | ^^ + +error[E0561]: patterns aren't allowed in parenthesized argument lists + --> $DIR/named-fn-trait-parameters.rs:41:30 + | +LL | restricted_pat3: impl Fn(&&x: ()), + | ^^^ + +error[E0561]: patterns aren't allowed in parenthesized argument lists + --> $DIR/named-fn-trait-parameters.rs:43:30 + | +LL | restricted_pat4: impl Fn(false: ()), + | ^^^^^ + +error[E0561]: patterns aren't allowed in parenthesized argument lists + --> $DIR/named-fn-trait-parameters.rs:45:30 + | +LL | restricted_pat5: impl Fn(&_: ()), + | ^^ + +error[E0561]: patterns aren't allowed in parenthesized argument lists + --> $DIR/named-fn-trait-parameters.rs:47:30 + | +LL | restricted_pat6: impl Fn(&true: ()), + | ^^^^^ + +error[E0425]: cannot find type `NoThing` in this scope + --> $DIR/named-fn-trait-parameters.rs:23:37 + | +LL | pat4: impl Fn(NoThing { a, b }: NoThing), + | ^^^^^^^ not found in this scope + | +note: similarly named struct `Thing` defined here + --> $DIR/named-fn-trait-parameters.rs:82:1 + | +LL | struct Thing { a: bool, b: bool } + | ^^^^^^^^^^^^ +help: a struct with a similar name exists + | +LL - pat4: impl Fn(NoThing { a, b }: NoThing), +LL + pat4: impl Fn(NoThing { a, b }: Thing), + | + +error: aborting due to 23 previous errors +Some errors have detailed explanations: E0425, E0561, E0642. +For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/parser/dotdotdot-rest-pattern-suggestion-span.rs b/tests/ui/parser/dotdotdot-rest-pattern-suggestion-span.rs index 0db10726c5dc4..36091b480d3c3 100644 --- a/tests/ui/parser/dotdotdot-rest-pattern-suggestion-span.rs +++ b/tests/ui/parser/dotdotdot-rest-pattern-suggestion-span.rs @@ -10,7 +10,7 @@ impl S { fn f(···>) } //~| ERROR unknown start of token //~| ERROR unknown start of token //~| ERROR unexpected `...` -//~| ERROR expected `:`, found `>` +//~| ERROR unexpected token: `>` //~| ERROR expected one of //~| ERROR associated function in `impl` without body //~| ERROR cannot find type `S` in this scope diff --git a/tests/ui/parser/dotdotdot-rest-pattern-suggestion-span.stderr b/tests/ui/parser/dotdotdot-rest-pattern-suggestion-span.stderr index d483c40ca5e0b..0889ca8a495af 100644 --- a/tests/ui/parser/dotdotdot-rest-pattern-suggestion-span.stderr +++ b/tests/ui/parser/dotdotdot-rest-pattern-suggestion-span.stderr @@ -48,11 +48,11 @@ LL - impl S { fn f(···>) } LL + impl S { fn f(..>) } | -error: expected `:`, found `>` +error: unexpected token: `>` --> $DIR/dotdotdot-rest-pattern-suggestion-span.rs:8:18 | LL | impl S { fn f(···>) } - | ^ expected `:` + | ^ unexpected token after this error: expected one of `->`, `where`, or `{`, found `}` --> $DIR/dotdotdot-rest-pattern-suggestion-span.rs:8:21 diff --git a/tests/ui/parser/issue-116781.rs b/tests/ui/parser/issue-116781.rs index 176350fe2eec6..5ff0989b3df00 100644 --- a/tests/ui/parser/issue-116781.rs +++ b/tests/ui/parser/issue-116781.rs @@ -1,8 +1,8 @@ #[derive(Debug)] struct Foo { #[cfg(true)] - field: fn(($),), //~ ERROR expected pattern, found `$` - //~^ ERROR expected pattern, found `$` + field: fn(($),), //~ ERROR expected type, found `$` + //~^ ERROR expected type, found `$` } fn main() {} diff --git a/tests/ui/parser/issue-116781.stderr b/tests/ui/parser/issue-116781.stderr index 1a77b60a50dc8..fdfadf4a9e313 100644 --- a/tests/ui/parser/issue-116781.stderr +++ b/tests/ui/parser/issue-116781.stderr @@ -1,14 +1,14 @@ -error: expected pattern, found `$` +error: expected type, found `$` --> $DIR/issue-116781.rs:4:16 | LL | field: fn(($),), - | ^ expected pattern + | ^ expected type -error: expected pattern, found `$` +error: expected type, found `$` --> $DIR/issue-116781.rs:4:16 | LL | field: fn(($),), - | ^ expected pattern + | ^ expected type | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` 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 60dd88e65400a..08997f8a6afd0 100644 --- a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs +++ b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs @@ -3,3 +3,4 @@ struct Apple((Apple, Option(Banana ? Citron))); //~^ ERROR invalid `?` in type //~| ERROR unexpected token: `Citron` +//~| ERROR expected a pattern, found an expression 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 c92535c3906bc..fff09d19772f5 100644 --- a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr +++ b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr @@ -16,5 +16,13 @@ error: unexpected token: `Citron` LL | struct Apple((Apple, Option(Banana ? Citron))); | ^^^^^^ unexpected token after this -error: aborting due to 2 previous errors +error: expected a pattern, found an expression + --> $DIR/issue-103748-ICE-wrong-braces.rs:3:29 + | +LL | struct Apple((Apple, Option(Banana ? Citron))); + | ^^^^^^^^ not a pattern + | + = note: arbitrary expressions are not allowed in patterns: + +error: aborting due to 3 previous errors diff --git a/tests/ui/rfcs/rfc-2565-param-attrs/attr-without-param.rs b/tests/ui/rfcs/rfc-2565-param-attrs/attr-without-param.rs index 14402eaeecac1..d775545dd571c 100644 --- a/tests/ui/rfcs/rfc-2565-param-attrs/attr-without-param.rs +++ b/tests/ui/rfcs/rfc-2565-param-attrs/attr-without-param.rs @@ -11,7 +11,7 @@ impl T for S { #[cfg(false)] trait T { - fn f(#[attr]); //~ ERROR expected argument name, found `)` + fn f(#[attr]); //~ ERROR expected type, found `)` } fn main() {} diff --git a/tests/ui/rfcs/rfc-2565-param-attrs/attr-without-param.stderr b/tests/ui/rfcs/rfc-2565-param-attrs/attr-without-param.stderr index 2fa03f3cb0bba..65b265fb6289a 100644 --- a/tests/ui/rfcs/rfc-2565-param-attrs/attr-without-param.stderr +++ b/tests/ui/rfcs/rfc-2565-param-attrs/attr-without-param.stderr @@ -10,11 +10,11 @@ error: expected parameter name, found `)` LL | fn f(#[attr]) {} | ^ expected parameter name -error: expected argument name, found `)` +error: expected type, found `)` --> $DIR/attr-without-param.rs:14:17 | LL | fn f(#[attr]); - | ^ expected argument name + | ^ expected type error: aborting due to 3 previous errors