From ec5e685c4fa52e63ea13db63afa0e22d2805409f Mon Sep 17 00:00:00 2001 From: Orion Gonzalez Date: Wed, 11 Dec 2024 00:53:07 +0100 Subject: [PATCH] Don't emit "field expressions may not have generic arguments" if it's a method call without () --- compiler/rustc_errors/src/lib.rs | 1 + compiler/rustc_hir_typeck/src/expr.rs | 2 +- compiler/rustc_parse/src/parser/expr.rs | 6 ++++-- tests/ui/parser/bad-name.stderr | 12 ++++++------ ...680-method-call-with-generics-without-parens.rs | 4 ++++ ...method-call-with-generics-without-parens.stderr | 14 ++++++++++++++ 6 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 tests/ui/parser/issue-67680-method-call-with-generics-without-parens.rs create mode 100644 tests/ui/parser/issue-67680-method-call-with-generics-without-parens.stderr diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 6232c875ee81e..39b90c0b31c43 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -576,6 +576,7 @@ pub enum StashKey { UndeterminedMacroResolution, /// Used by `Parser::maybe_recover_trailing_expr` ExprInPat, + GenericInFieldExpr, } fn default_track_diagnostic(diag: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) -> R { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 0e079b037691e..6518a9312c367 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3055,7 +3055,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.help("methods are immutable and cannot be assigned to"); } - err.emit() + self.dcx().try_steal_replace_and_emit_err(expr.span, StashKey::GenericInFieldExpr, err) } fn point_at_param_definition(&self, err: &mut Diag<'_>, param: ty::ParamTy) { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index eeb83a85e59bb..07222482dcfb8 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1369,11 +1369,13 @@ impl<'a> Parser<'a> { )) } else { // Field access `expr.f` + let span = lo.to(self.prev_token.span); if let Some(args) = seg.args { - self.dcx().emit_err(errors::FieldExpressionWithGeneric(args.span())); + self.dcx() + .create_err(errors::FieldExpressionWithGeneric(args.span())) + .stash(span, StashKey::GenericInFieldExpr); } - let span = lo.to(self.prev_token.span); Ok(self.mk_expr(span, ExprKind::Field(self_arg, seg.ident))) } } diff --git a/tests/ui/parser/bad-name.stderr b/tests/ui/parser/bad-name.stderr index a336923f4fd89..112fdcad3369c 100644 --- a/tests/ui/parser/bad-name.stderr +++ b/tests/ui/parser/bad-name.stderr @@ -1,9 +1,3 @@ -error: field expressions cannot have generic arguments - --> $DIR/bad-name.rs:2:12 - | -LL | let x.y::.z foo; - | ^^^^^^^ - error: expected a pattern, found an expression --> $DIR/bad-name.rs:2:7 | @@ -18,5 +12,11 @@ error: expected one of `(`, `.`, `::`, `:`, `;`, `=`, `?`, `|`, or an operator, LL | let x.y::.z foo; | ^^^ expected one of 9 possible tokens +error: field expressions cannot have generic arguments + --> $DIR/bad-name.rs:2:12 + | +LL | let x.y::.z foo; + | ^^^^^^^ + error: aborting due to 3 previous errors diff --git a/tests/ui/parser/issue-67680-method-call-with-generics-without-parens.rs b/tests/ui/parser/issue-67680-method-call-with-generics-without-parens.rs new file mode 100644 index 0000000000000..9d90cdad0fa28 --- /dev/null +++ b/tests/ui/parser/issue-67680-method-call-with-generics-without-parens.rs @@ -0,0 +1,4 @@ +fn main() { + [1, 2].into_iter().collect::>; + //~^ ERROR attempted to take value of method +} diff --git a/tests/ui/parser/issue-67680-method-call-with-generics-without-parens.stderr b/tests/ui/parser/issue-67680-method-call-with-generics-without-parens.stderr new file mode 100644 index 0000000000000..bf9c71479d545 --- /dev/null +++ b/tests/ui/parser/issue-67680-method-call-with-generics-without-parens.stderr @@ -0,0 +1,14 @@ +error[E0615]: attempted to take value of method `collect` on type `std::slice::Iter<'_, {integer}>` + --> $DIR/issue-67680-method-call-with-generics-without-parens.rs:2:24 + | +LL | [1, 2].into_iter().collect::>; + | ^^^^^^^ method, not a field + | +help: use parentheses to call the method + | +LL | [1, 2].into_iter().collect::>(); + | ++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0615`.