From 45257962d38d8b6871caf22063eb815bcf7c035d Mon Sep 17 00:00:00 2001
From: Takayuki Maeda <takoyaki0316@gmail.com>
Date: Wed, 5 Oct 2022 16:58:29 +0900
Subject: [PATCH] stop suggesting adding generic args for turbofish

---
 .../infer/error_reporting/need_type_info.rs   | 40 +++++++++++++++----
 .../need_type_info/concrete-impl.stderr       |  9 -----
 ...suggest-generic-arguments-for-turbofish.rs | 11 +++++
 ...est-generic-arguments-for-turbofish.stderr |  9 +++++
 src/test/ui/issues/issue-24013.stderr         |  5 ---
 src/test/ui/issues/issue-47486.stderr         |  5 ---
 6 files changed, 52 insertions(+), 27 deletions(-)
 create mode 100644 src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.rs
 create mode 100644 src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.stderr

diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index 03116d59bf491..2775d14a84780 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -435,6 +435,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 generics_def_id,
                 def_id: _,
                 generic_args,
+                have_turbofish,
             } => {
                 let generics = self.tcx.generics_of(generics_def_id);
                 let is_type = matches!(arg.unpack(), GenericArgKind::Type(_));
@@ -482,11 +483,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     .unwrap()
                     .into_buffer();
 
-                infer_subdiags.push(SourceKindSubdiag::GenericSuggestion {
-                    span: insert_span,
-                    arg_count: generic_args.len(),
-                    args,
-                });
+                if !have_turbofish {
+                    infer_subdiags.push(SourceKindSubdiag::GenericSuggestion {
+                        span: insert_span,
+                        arg_count: generic_args.len(),
+                        args,
+                    });
+                }
             }
             InferSourceKind::FullyQualifiedMethodCall { receiver, successor, substs, def_id } => {
                 let printer = fmt_printer(self, Namespace::ValueNS);
@@ -616,6 +619,7 @@ enum InferSourceKind<'tcx> {
         generics_def_id: DefId,
         def_id: DefId,
         generic_args: &'tcx [GenericArg<'tcx>],
+        have_turbofish: bool,
     },
     FullyQualifiedMethodCall {
         receiver: &'tcx Expr<'tcx>,
@@ -676,6 +680,7 @@ struct InsertableGenericArgs<'tcx> {
     substs: SubstsRef<'tcx>,
     generics_def_id: DefId,
     def_id: DefId,
+    have_turbofish: bool,
 }
 
 /// A visitor which searches for the "best" spot to use in the inference error.
@@ -916,6 +921,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
                             substs,
                             generics_def_id: def_id,
                             def_id,
+                            have_turbofish: false,
                         }
                     };
                     return Box::new(insertable.into_iter());
@@ -933,6 +939,9 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
         substs: SubstsRef<'tcx>,
     ) -> impl Iterator<Item = InsertableGenericArgs<'tcx>> + 'a {
         let tcx = self.infcx.tcx;
+        let have_turbofish = path.segments.iter().any(|segment| {
+            segment.args.map_or(false, |args| args.args.iter().any(|arg| arg.is_ty_or_const()))
+        });
         // The last segment of a path often has `Res::Err` and the
         // correct `Res` is the one of the whole path.
         //
@@ -942,7 +951,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
             let generics_def_id = tcx.res_generics_def_id(path.res)?;
             let generics = tcx.generics_of(generics_def_id);
             if generics.has_impl_trait() {
-                None?
+                None?;
             }
             let insert_span =
                 path.segments.last().unwrap().ident.span.shrink_to_hi().with_hi(path.span.hi());
@@ -951,6 +960,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
                 substs,
                 generics_def_id,
                 def_id: path.res.def_id(),
+                have_turbofish,
             }
         };
 
@@ -970,6 +980,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
                     substs,
                     generics_def_id,
                     def_id: res.def_id(),
+                    have_turbofish,
                 })
             })
             .chain(last_segment_using_path_data)
@@ -998,7 +1009,13 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
                     }
                     let span = tcx.hir().span(segment.hir_id);
                     let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
-                    InsertableGenericArgs { insert_span, substs, generics_def_id: def_id, def_id }
+                    InsertableGenericArgs {
+                        insert_span,
+                        substs,
+                        generics_def_id: def_id,
+                        def_id,
+                        have_turbofish: false,
+                    }
                 };
 
                 let parent_def_id = generics.parent.unwrap();
@@ -1121,7 +1138,13 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
 
         for args in self.expr_inferred_subst_iter(expr) {
             debug!(?args);
-            let InsertableGenericArgs { insert_span, substs, generics_def_id, def_id } = args;
+            let InsertableGenericArgs {
+                insert_span,
+                substs,
+                generics_def_id,
+                def_id,
+                have_turbofish,
+            } = args;
             let generics = tcx.generics_of(generics_def_id);
             if let Some(argument_index) = generics
                 .own_substs(substs)
@@ -1144,6 +1167,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
                         generics_def_id,
                         def_id,
                         generic_args,
+                        have_turbofish,
                     },
                 });
             }
diff --git a/src/test/ui/inference/need_type_info/concrete-impl.stderr b/src/test/ui/inference/need_type_info/concrete-impl.stderr
index b79d34affa249..aa32969950d6b 100644
--- a/src/test/ui/inference/need_type_info/concrete-impl.stderr
+++ b/src/test/ui/inference/need_type_info/concrete-impl.stderr
@@ -3,11 +3,6 @@ error[E0282]: type annotations needed
    |
 LL |     <Struct as Ambiguous<_>>::method();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Self` declared on the trait `Ambiguous`
-   |
-help: consider specifying the generic argument
-   |
-LL |     <Struct as Ambiguous::<_>>::method();
-   |                         ~~~~~
 
 error[E0283]: type annotations needed
   --> $DIR/concrete-impl.rs:13:5
@@ -22,10 +17,6 @@ LL | impl Ambiguous<One> for Struct {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL | impl Ambiguous<Two> for Struct {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: consider specifying the generic argument
-   |
-LL |     <Struct as Ambiguous::<_>>::method();
-   |                         ~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.rs b/src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.rs
new file mode 100644
index 0000000000000..3084f6eac67ab
--- /dev/null
+++ b/src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.rs
@@ -0,0 +1,11 @@
+enum OhNo<T, U> {
+    A(T),
+    B(U),
+    C,
+}
+
+fn uwu() {
+    OhNo::C::<u32, _>; //~ ERROR type annotations needed
+}
+
+fn main() {}
diff --git a/src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.stderr b/src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.stderr
new file mode 100644
index 0000000000000..2ad35ab039f4c
--- /dev/null
+++ b/src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+  --> $DIR/do-not-suggest-generic-arguments-for-turbofish.rs:8:5
+   |
+LL |     OhNo::C::<u32, _>;
+   |     ^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the enum `OhNo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/issues/issue-24013.stderr b/src/test/ui/issues/issue-24013.stderr
index 995dce552e37f..72102f460e0bd 100644
--- a/src/test/ui/issues/issue-24013.stderr
+++ b/src/test/ui/issues/issue-24013.stderr
@@ -3,11 +3,6 @@ error[E0282]: type annotations needed
    |
 LL |     unsafe {swap::<&mut _>(transmute(&a), transmute(&b))};
    |             ^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `swap`
-   |
-help: consider specifying the generic argument
-   |
-LL |     unsafe {swap::<&mut _>(transmute(&a), transmute(&b))};
-   |                 ~~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-47486.stderr b/src/test/ui/issues/issue-47486.stderr
index b45f57b7b846b..2bd24f08c1e51 100644
--- a/src/test/ui/issues/issue-47486.stderr
+++ b/src/test/ui/issues/issue-47486.stderr
@@ -9,11 +9,6 @@ error[E0282]: type annotations needed
    |
 LL |     [0u8; std::mem::size_of::<_>()];
    |           ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `size_of`
-   |
-help: consider specifying the generic argument
-   |
-LL |     [0u8; std::mem::size_of::<_>()];
-   |                            ~~~~~
 
 error: aborting due to 2 previous errors