about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJubilee <46493976+workingjubilee@users.noreply.github.com>2021-09-23 17:31:43 -0700
committerGitHub <noreply@github.com>2021-09-23 17:31:43 -0700
commit9e11d1cca4ea724468ec1589c8d424397d7de4bd (patch)
tree798a0b70fa291689ebf42ac6f31a6e318add07a3
parent5da2f460b36988d5e0226412080769bafd94eb3c (diff)
parentaffea730e9693623d7c0f6bad35b3fab36df02e4 (diff)
downloadrust-9e11d1cca4ea724468ec1589c8d424397d7de4bd.tar.gz
rust-9e11d1cca4ea724468ec1589c8d424397d7de4bd.zip
Rollup merge of #89148 - estebank:used-type-param, r=oli-obk
Suggest `_` in turbofish if param will be inferred from fn argument
-rw-r--r--compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs21
-rw-r--r--src/test/ui/suggestions/missing-type-param-used-in-param.fixed8
-rw-r--r--src/test/ui/suggestions/missing-type-param-used-in-param.rs8
-rw-r--r--src/test/ui/suggestions/missing-type-param-used-in-param.stderr21
4 files changed, 57 insertions, 1 deletions
diff --git a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
index 7e69ad21d03..2e3db4d6d65 100644
--- a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
@@ -1,6 +1,7 @@
 use crate::structured_errors::StructuredDiagnostic;
 use rustc_errors::{pluralize, Applicability, DiagnosticBuilder, DiagnosticId};
 use rustc_hir as hir;
+use rustc_middle::hir::map::fn_sig;
 use rustc_middle::middle::resolve_lifetime::LifetimeScopeForPath;
 use rustc_middle::ty::{self as ty, TyCtxt};
 use rustc_session::Session;
@@ -292,12 +293,30 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
         &self,
         num_params_to_take: usize,
     ) -> String {
+        let fn_sig = self.tcx.hir().get_if_local(self.def_id).and_then(|node| fn_sig(node));
+        let is_used_in_input = |def_id| {
+            fn_sig.map_or(false, |fn_sig| {
+                fn_sig.decl.inputs.iter().any(|ty| match ty.kind {
+                    hir::TyKind::Path(hir::QPath::Resolved(
+                        None,
+                        hir::Path { res: hir::def::Res::Def(_, id), .. },
+                    )) if *id == def_id => true,
+                    _ => false,
+                })
+            })
+        };
         self.gen_params
             .params
             .iter()
             .skip(self.params_offset + self.num_provided_type_or_const_args())
             .take(num_params_to_take)
-            .map(|param| param.name.to_string())
+            .map(|param| match param.kind {
+                // This is being infered from the item's inputs, no need to set it.
+                ty::GenericParamDefKind::Type { .. } if is_used_in_input(param.def_id) => {
+                    "_".to_string()
+                }
+                _ => param.name.to_string(),
+            })
             .collect::<Vec<_>>()
             .join(", ")
     }
diff --git a/src/test/ui/suggestions/missing-type-param-used-in-param.fixed b/src/test/ui/suggestions/missing-type-param-used-in-param.fixed
new file mode 100644
index 00000000000..cc4120041b9
--- /dev/null
+++ b/src/test/ui/suggestions/missing-type-param-used-in-param.fixed
@@ -0,0 +1,8 @@
+// run-rustfix
+
+fn two_type_params<A, B>(_: B) {}
+
+fn main() {
+    two_type_params::<String, _>(100); //~ ERROR this function takes 2 generic arguments
+    two_type_params::<String, _>(100);
+}
diff --git a/src/test/ui/suggestions/missing-type-param-used-in-param.rs b/src/test/ui/suggestions/missing-type-param-used-in-param.rs
new file mode 100644
index 00000000000..19286331b60
--- /dev/null
+++ b/src/test/ui/suggestions/missing-type-param-used-in-param.rs
@@ -0,0 +1,8 @@
+// run-rustfix
+
+fn two_type_params<A, B>(_: B) {}
+
+fn main() {
+    two_type_params::<String>(100); //~ ERROR this function takes 2 generic arguments
+    two_type_params::<String, _>(100);
+}
diff --git a/src/test/ui/suggestions/missing-type-param-used-in-param.stderr b/src/test/ui/suggestions/missing-type-param-used-in-param.stderr
new file mode 100644
index 00000000000..4f7058a6492
--- /dev/null
+++ b/src/test/ui/suggestions/missing-type-param-used-in-param.stderr
@@ -0,0 +1,21 @@
+error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied
+  --> $DIR/missing-type-param-used-in-param.rs:6:5
+   |
+LL |     two_type_params::<String>(100);
+   |     ^^^^^^^^^^^^^^^   ------ supplied 1 generic argument
+   |     |
+   |     expected 2 generic arguments
+   |
+note: function defined here, with 2 generic parameters: `A`, `B`
+  --> $DIR/missing-type-param-used-in-param.rs:3:4
+   |
+LL | fn two_type_params<A, B>(_: B) {}
+   |    ^^^^^^^^^^^^^^^ -  -
+help: add missing generic argument
+   |
+LL |     two_type_params::<String, _>(100);
+   |                             +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.