From 014363e89e4347332c50daede2efa66af3c2c243 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 | 4 ++++ compiler/rustc_hir_typeck/src/expr.rs | 3 ++- compiler/rustc_parse/src/parser/expr.rs | 7 +++++-- tests/ui/parser/bad-name.stderr | 12 ++++++------ tests/ui/suggestions/method-missing-parentheses.rs | 1 - .../ui/suggestions/method-missing-parentheses.stderr | 8 +------- 6 files changed, 18 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 6232c875ee81e..95b40b6a906e5 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -576,6 +576,10 @@ pub enum StashKey { UndeterminedMacroResolution, /// Used by `Parser::maybe_recover_trailing_expr` ExprInPat, + /// If in the parser we detect a field expr with turbofish generic params it's possible that + /// it's a method call without parens. If later on in `hir_typeck` we find out that this is + /// the case we suppress this message and we give a better suggestion. + 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..12257c449e781 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3055,7 +3055,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.help("methods are immutable and cannot be assigned to"); } - err.emit() + // See `StashKey::GenericInFieldExpr` for more info + self.dcx().try_steal_replace_and_emit_err(field.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..0904a42d8a431 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1369,11 +1369,14 @@ 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())); + // See `StashKey::GenericInFieldExpr` for more info on why we stash this. + self.dcx() + .create_err(errors::FieldExpressionWithGeneric(args.span())) + .stash(seg.ident.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/suggestions/method-missing-parentheses.rs b/tests/ui/suggestions/method-missing-parentheses.rs index f10bfb56d2e12..bc576b71f0d0b 100644 --- a/tests/ui/suggestions/method-missing-parentheses.rs +++ b/tests/ui/suggestions/method-missing-parentheses.rs @@ -1,5 +1,4 @@ fn main() { let _ = vec![].into_iter().collect::; //~^ ERROR attempted to take value of method `collect` on type `std::vec::IntoIter<_>` - //~| ERROR field expressions cannot have generic arguments } diff --git a/tests/ui/suggestions/method-missing-parentheses.stderr b/tests/ui/suggestions/method-missing-parentheses.stderr index 1bfff56a6a906..f0ff1f0334a39 100644 --- a/tests/ui/suggestions/method-missing-parentheses.stderr +++ b/tests/ui/suggestions/method-missing-parentheses.stderr @@ -1,9 +1,3 @@ -error: field expressions cannot have generic arguments - --> $DIR/method-missing-parentheses.rs:2:41 - | -LL | let _ = vec![].into_iter().collect::; - | ^^^^^^^ - error[E0615]: attempted to take value of method `collect` on type `std::vec::IntoIter<_>` --> $DIR/method-missing-parentheses.rs:2:32 | @@ -15,6 +9,6 @@ help: use parentheses to call the method LL | let _ = vec![].into_iter().collect::(); | ++ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0615`.