about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOrion Gonzalez <ardi@ardis.dev>2024-12-11 00:53:07 +0100
committerOrion Gonzalez <ardi@ardis.dev>2024-12-11 16:23:04 +0100
commit014363e89e4347332c50daede2efa66af3c2c243 (patch)
tree053869f875cb9a14aee13a2aa79340749834e5d8
parent33c245b9e98bc91e18ea1c5033824f4c6f92766f (diff)
downloadrust-014363e89e4347332c50daede2efa66af3c2c243.tar.gz
rust-014363e89e4347332c50daede2efa66af3c2c243.zip
Don't emit "field expressions may not have generic arguments" if it's a method call without ()
-rw-r--r--compiler/rustc_errors/src/lib.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs3
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs7
-rw-r--r--tests/ui/parser/bad-name.stderr12
-rw-r--r--tests/ui/suggestions/method-missing-parentheses.rs1
-rw-r--r--tests/ui/suggestions/method-missing-parentheses.stderr8
6 files changed, 18 insertions, 17 deletions
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 6232c875ee8..95b40b6a906 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<R>(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 0e079b03769..12257c449e7 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 eeb83a85e59..0904a42d8a4 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 a336923f4fd..112fdcad336 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::<isize>.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::<isize>.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::<isize>.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 f10bfb56d2e..bc576b71f0d 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::<usize>;
     //~^ 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 1bfff56a6a9..f0ff1f0334a 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::<usize>;
-   |                                         ^^^^^^^
-
 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::<usize>();
    |                                                ++
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0615`.