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 62edfc6495cf6..e1a2a237c2324 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 @@ -866,6 +866,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } + self.report_ambiguous_type_parameter(&mut err, arg); err.span_label( span, arg_data.cannot_infer_msg(use_diag.filter(|d| d.applies_to(span))), @@ -933,6 +934,28 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } + fn report_ambiguous_type_parameter(&self, err: &mut Diagnostic, arg: GenericArg<'tcx>) { + if let GenericArgKind::Type(ty) = arg.unpack() + && let ty::Infer(ty::TyVar(ty_vid)) = *ty.kind() + { + let mut inner = self.inner.borrow_mut(); + let ty_vars = &inner.type_variables(); + let var_origin = ty_vars.var_origin(ty_vid); + if let TypeVariableOriginKind::TypeParameterDefinition(_, Some(def_id)) = + var_origin.kind + && let Some(parent_def_id) = self.tcx.parent(def_id).as_local() + && let Some(node) = self.tcx.hir().find_by_def_id(parent_def_id) + { + match node { + hir::Node::Item(item) if matches!(item.kind, hir::ItemKind::Impl(_) | hir::ItemKind::Fn(..)) => (), + hir::Node::ImplItem(impl_item) if matches!(impl_item.kind, hir::ImplItemKind::Fn(..)) => (), + _ => return, + } + err.span_help(self.tcx.def_span(def_id), "type parameter declared here"); + } + } + } + pub fn need_type_info_err_in_generator( &self, kind: hir::GeneratorKind, diff --git a/src/test/ui/const-generics/issues/issue-83249.stderr b/src/test/ui/const-generics/issues/issue-83249.stderr index 402b3aa2d61dc..3f44a54e80adc 100644 --- a/src/test/ui/const-generics/issues/issue-83249.stderr +++ b/src/test/ui/const-generics/issues/issue-83249.stderr @@ -5,6 +5,12 @@ LL | let _ = foo([0; 1]); | - ^^^ cannot infer type for type parameter `T` declared on the function `foo` | | | consider giving this pattern a type + | +help: type parameter declared here + --> $DIR/issue-83249.rs:12:8 + | +LL | fn foo(_: [u8; T::N]) -> T { + | ^ error: aborting due to previous error diff --git a/src/test/ui/consts/issue-64662.stderr b/src/test/ui/consts/issue-64662.stderr index dd281e911da96..caa582d87f527 100644 --- a/src/test/ui/consts/issue-64662.stderr +++ b/src/test/ui/consts/issue-64662.stderr @@ -3,12 +3,24 @@ error[E0282]: type annotations needed | LL | A = foo(), | ^^^ cannot infer type for type parameter `T` declared on the function `foo` + | +help: type parameter declared here + --> $DIR/issue-64662.rs:6:14 + | +LL | const fn foo() -> isize { + | ^ error[E0282]: type annotations needed --> $DIR/issue-64662.rs:3:9 | LL | B = foo(), | ^^^ cannot infer type for type parameter `T` declared on the function `foo` + | +help: type parameter declared here + --> $DIR/issue-64662.rs:6:14 + | +LL | const fn foo() -> isize { + | ^ error: aborting due to 2 previous errors diff --git a/src/test/ui/error-codes/E0401.stderr b/src/test/ui/error-codes/E0401.stderr index 8b1d4e6c07ceb..e58c9d3116a1c 100644 --- a/src/test/ui/error-codes/E0401.stderr +++ b/src/test/ui/error-codes/E0401.stderr @@ -37,6 +37,12 @@ error[E0282]: type annotations needed | LL | bfnr(x); | ^^^^ cannot infer type for type parameter `U` declared on the function `bfnr` + | +help: type parameter declared here + --> $DIR/E0401.rs:4:13 + | +LL | fn bfnr, W: Fn()>(y: T) { + | ^ error: aborting due to 4 previous errors diff --git a/src/test/ui/inference/ambiguous_type_parameter.rs b/src/test/ui/inference/ambiguous_type_parameter.rs new file mode 100644 index 0000000000000..dc70ed661d223 --- /dev/null +++ b/src/test/ui/inference/ambiguous_type_parameter.rs @@ -0,0 +1,17 @@ +use std::collections::HashMap; + +trait Store { + fn get_raw(&self, key: &K) -> Option<()>; +} + +struct InMemoryStore; + +impl Store> for InMemoryStore { + fn get_raw(&self, key: &String) -> Option<()> { + None + } +} + +fn main() { + InMemoryStore.get_raw(&String::default()); //~ ERROR type annotations needed +} diff --git a/src/test/ui/inference/ambiguous_type_parameter.stderr b/src/test/ui/inference/ambiguous_type_parameter.stderr new file mode 100644 index 0000000000000..47ef1948aee9f --- /dev/null +++ b/src/test/ui/inference/ambiguous_type_parameter.stderr @@ -0,0 +1,15 @@ +error[E0282]: type annotations needed + --> $DIR/ambiguous_type_parameter.rs:16:19 + | +LL | InMemoryStore.get_raw(&String::default()); + | ^^^^^^^ cannot infer type for type parameter `K` + | +help: type parameter declared here + --> $DIR/ambiguous_type_parameter.rs:9:6 + | +LL | impl Store> for InMemoryStore { + | ^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/inference/erase-type-params-in-label.stderr b/src/test/ui/inference/erase-type-params-in-label.stderr index d0b06cde9d63a..51fac5f79df47 100644 --- a/src/test/ui/inference/erase-type-params-in-label.stderr +++ b/src/test/ui/inference/erase-type-params-in-label.stderr @@ -6,6 +6,11 @@ LL | let foo = foo(1, ""); | | | consider giving `foo` the explicit type `Foo<_, _, W, Z>`, where the type parameter `W` is specified | +help: type parameter declared here + --> $DIR/erase-type-params-in-label.rs:25:14 + | +LL | fn foo(t: T, k: K) -> Foo { + | ^ = note: cannot satisfy `_: Default` note: required by a bound in `foo` --> $DIR/erase-type-params-in-label.rs:25:17 @@ -25,6 +30,11 @@ LL | let bar = bar(1, ""); | | | consider giving `bar` the explicit type `Bar<_, _, Z>`, where the type parameter `Z` is specified | +help: type parameter declared here + --> $DIR/erase-type-params-in-label.rs:14:14 + | +LL | fn bar(t: T, k: K) -> Bar { + | ^ = note: cannot satisfy `_: Default` note: required by a bound in `bar` --> $DIR/erase-type-params-in-label.rs:14:17 diff --git a/src/test/ui/inference/issue-86162-1.stderr b/src/test/ui/inference/issue-86162-1.stderr index 8d6f50748cbeb..edf97c0aed47e 100644 --- a/src/test/ui/inference/issue-86162-1.stderr +++ b/src/test/ui/inference/issue-86162-1.stderr @@ -4,6 +4,11 @@ error[E0283]: type annotations needed LL | foo(gen()); //<- Do not suggest `foo::()`! | ^^^ cannot infer type for type parameter `impl Clone` declared on the function `foo` | +help: type parameter declared here + --> $DIR/issue-86162-1.rs:3:11 + | +LL | fn foo(x: impl Clone) {} + | ^^^^^^^^^^ = note: cannot satisfy `_: Clone` note: required by a bound in `foo` --> $DIR/issue-86162-1.rs:3:16 diff --git a/src/test/ui/inference/issue-86162-2.stderr b/src/test/ui/inference/issue-86162-2.stderr index 5f80c595628e4..c642ebb057603 100644 --- a/src/test/ui/inference/issue-86162-2.stderr +++ b/src/test/ui/inference/issue-86162-2.stderr @@ -4,6 +4,11 @@ error[E0283]: type annotations needed LL | Foo::bar(gen()); //<- Do not suggest `Foo::bar::()`! | ^^^^^^^^ cannot infer type for type parameter `impl Clone` declared on the associated function `bar` | +help: type parameter declared here + --> $DIR/issue-86162-2.rs:8:15 + | +LL | fn bar(x: impl Clone) {} + | ^^^^^^^^^^ = note: cannot satisfy `_: Clone` note: required by a bound in `Foo::bar` --> $DIR/issue-86162-2.rs:8:20 diff --git a/src/test/ui/issues/issue-6458.stderr b/src/test/ui/issues/issue-6458.stderr index f1a982616a4a1..f548692d78583 100644 --- a/src/test/ui/issues/issue-6458.stderr +++ b/src/test/ui/issues/issue-6458.stderr @@ -3,6 +3,12 @@ error[E0282]: type annotations needed | LL | foo(TypeWithState(marker::PhantomData)); | ^^^ cannot infer type for type parameter `State` declared on the function `foo` + | +help: type parameter declared here + --> $DIR/issue-6458.rs:6:12 + | +LL | pub fn foo(_: TypeWithState) {} + | ^^^^^ error: aborting due to previous error diff --git a/src/test/ui/missing/missing-items/missing-type-parameter.stderr b/src/test/ui/missing/missing-items/missing-type-parameter.stderr index 1219badc5b3fc..2aa2b0e6a3c2c 100644 --- a/src/test/ui/missing/missing-items/missing-type-parameter.stderr +++ b/src/test/ui/missing/missing-items/missing-type-parameter.stderr @@ -3,6 +3,12 @@ error[E0282]: type annotations needed | LL | foo(); | ^^^ cannot infer type for type parameter `X` declared on the function `foo` + | +help: type parameter declared here + --> $DIR/missing-type-parameter.rs:1:8 + | +LL | fn foo() { } + | ^ error: aborting due to previous error diff --git a/src/test/ui/suggestions/fn-needing-specified-return-type-param.stderr b/src/test/ui/suggestions/fn-needing-specified-return-type-param.stderr index b59a3818e7042..a4cfee5563373 100644 --- a/src/test/ui/suggestions/fn-needing-specified-return-type-param.stderr +++ b/src/test/ui/suggestions/fn-needing-specified-return-type-param.stderr @@ -5,6 +5,12 @@ LL | let _ = f; | - ^ cannot infer type for type parameter `A` declared on the function `f` | | | consider giving this pattern the explicit type `fn() -> A`, where the type parameter `A` is specified + | +help: type parameter declared here + --> $DIR/fn-needing-specified-return-type-param.rs:1:6 + | +LL | fn f() -> A { unimplemented!() } + | ^ error: aborting due to previous error diff --git a/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr b/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr index 9fd81b56bf153..da7461347106f 100644 --- a/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr +++ b/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr @@ -3,6 +3,12 @@ error[E0282]: type annotations needed | LL | test(22, std::default::Default::default()); | ^^^^ cannot infer type for type parameter `U` declared on the function `test` + | +help: type parameter declared here + --> $DIR/multidispatch-convert-ambig-dest.rs:20:11 + | +LL | fn test(_: T, _: U) + | ^ error[E0283]: type annotations needed --> $DIR/multidispatch-convert-ambig-dest.rs:26:5 @@ -10,6 +16,11 @@ error[E0283]: type annotations needed LL | test(22, std::default::Default::default()); | ^^^^ cannot infer type for type parameter `U` declared on the function `test` | +help: type parameter declared here + --> $DIR/multidispatch-convert-ambig-dest.rs:20:11 + | +LL | fn test(_: T, _: U) + | ^ note: multiple `impl`s satisfying `i32: Convert<_>` found --> $DIR/multidispatch-convert-ambig-dest.rs:8:1 | diff --git a/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr b/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr index 65f2d99417f2f..3c8d7450f96fa 100644 --- a/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr +++ b/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr @@ -16,6 +16,11 @@ LL | a.method(); | | cannot infer type for type parameter `U` | this method call resolves to `U` | +help: type parameter declared here + --> $DIR/not-suggest-non-existing-fully-qualified-path.rs:12:9 + | +LL | impl V for A + | ^ note: multiple `impl`s satisfying `B: I<_>` found --> $DIR/not-suggest-non-existing-fully-qualified-path.rs:5:1 | diff --git a/src/test/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.stderr b/src/test/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.stderr index d60ca4a49325c..501fa7c8c67c1 100644 --- a/src/test/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.stderr +++ b/src/test/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.stderr @@ -3,6 +3,12 @@ error[E0282]: type annotations needed | LL | foo(); | ^^^ cannot infer type for type parameter `T` declared on the function `foo` + | +help: type parameter declared here + --> $DIR/unbounded-type-param-in-fn-with-assoc-type.rs:3:8 + | +LL | fn foo() -> (T, U) { + | ^ error: aborting due to previous error diff --git a/src/test/ui/type-inference/unbounded-type-param-in-fn.stderr b/src/test/ui/type-inference/unbounded-type-param-in-fn.stderr index 45d879d8d5670..d01c3a7d4e220 100644 --- a/src/test/ui/type-inference/unbounded-type-param-in-fn.stderr +++ b/src/test/ui/type-inference/unbounded-type-param-in-fn.stderr @@ -3,6 +3,12 @@ error[E0282]: type annotations needed | LL | foo(); | ^^^ cannot infer type for type parameter `T` declared on the function `foo` + | +help: type parameter declared here + --> $DIR/unbounded-type-param-in-fn.rs:1:8 + | +LL | fn foo() -> T { + | ^ error: aborting due to previous error diff --git a/src/test/ui/type/type-annotation-needed.stderr b/src/test/ui/type/type-annotation-needed.stderr index f7dfb84523802..64fdbfe7db4c8 100644 --- a/src/test/ui/type/type-annotation-needed.stderr +++ b/src/test/ui/type/type-annotation-needed.stderr @@ -4,6 +4,11 @@ error[E0283]: type annotations needed LL | foo(42); | ^^^ cannot infer type for type parameter `T` declared on the function `foo` | +help: type parameter declared here + --> $DIR/type-annotation-needed.rs:1:8 + | +LL | fn foo>(x: i32) {} + | ^ = note: cannot satisfy `_: Into` note: required by a bound in `foo` --> $DIR/type-annotation-needed.rs:1:11