Skip to content

Fix misleading cannot infer type for type parameter error #97109

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))),
Expand Down Expand Up @@ -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()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't have to happen in.this PR, but we could extend this to Node::ImplItem, too, so that we'd show it for associated functions

&& 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,
Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/const-generics/issues/issue-83249.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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<T: Foo>(_: [u8; T::N]) -> T {
| ^

error: aborting due to previous error

Expand Down
12 changes: 12 additions & 0 deletions src/test/ui/consts/issue-64662.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>() -> 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<T>() -> isize {
| ^

error: aborting due to 2 previous errors

Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/error-codes/E0401.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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<U, V: Baz<U>, W: Fn()>(y: T) {
| ^

error: aborting due to 4 previous errors

Expand Down
17 changes: 17 additions & 0 deletions src/test/ui/inference/ambiguous_type_parameter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use std::collections::HashMap;

trait Store<K, V> {
fn get_raw(&self, key: &K) -> Option<()>;
}

struct InMemoryStore;

impl<K> Store<String, HashMap<K, String>> for InMemoryStore {
fn get_raw(&self, key: &String) -> Option<()> {
None
}
}

fn main() {
InMemoryStore.get_raw(&String::default()); //~ ERROR type annotations needed
}
15 changes: 15 additions & 0 deletions src/test/ui/inference/ambiguous_type_parameter.stderr
Original file line number Diff line number Diff line change
@@ -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<K> Store<String, HashMap<K, String>> for InMemoryStore {
| ^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0282`.
10 changes: 10 additions & 0 deletions src/test/ui/inference/erase-type-params-in-label.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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, K, W: Default, Z: Default>(t: T, k: K) -> Foo<T, K, W, Z> {
| ^
= note: cannot satisfy `_: Default`
note: required by a bound in `foo`
--> $DIR/erase-type-params-in-label.rs:25:17
Expand All @@ -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, K, Z: Default>(t: T, k: K) -> Bar<T, K, Z> {
| ^
= note: cannot satisfy `_: Default`
note: required by a bound in `bar`
--> $DIR/erase-type-params-in-label.rs:14:17
Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/inference/issue-86162-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ error[E0283]: type annotations needed
LL | foo(gen()); //<- Do not suggest `foo::<impl Clone>()`!
| ^^^ 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
Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/inference/issue-86162-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ error[E0283]: type annotations needed
LL | Foo::bar(gen()); //<- Do not suggest `Foo::bar::<impl Clone>()`!
| ^^^^^^^^ 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
Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/issues/issue-6458.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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<State>(_: TypeWithState<State>) {}
| ^^^^^

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<X>() { }
| ^

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>() -> A { unimplemented!() }
| ^

error: aborting due to previous error

Expand Down
11 changes: 11 additions & 0 deletions src/test/ui/traits/multidispatch-convert-ambig-dest.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,24 @@ 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>(_: T, _: U)
| ^

error[E0283]: type annotations needed
--> $DIR/multidispatch-convert-ambig-dest.rs:26:5
|
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>(_: T, _: U)
| ^
note: multiple `impl`s satisfying `i32: Convert<_>` found
--> $DIR/multidispatch-convert-ambig-dest.rs:8:1
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<T, U> V<U> for A<T>
| ^
note: multiple `impl`s satisfying `B: I<_>` found
--> $DIR/not-suggest-non-existing-fully-qualified-path.rs:5:1
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 = u64>() -> (T, U) {
| ^

error: aborting due to previous error

Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/type-inference/unbounded-type-param-in-fn.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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>() -> T {
| ^

error: aborting due to previous error

Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/type/type-annotation-needed.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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<T: Into<String>>(x: i32) {}
| ^
= note: cannot satisfy `_: Into<String>`
note: required by a bound in `foo`
--> $DIR/type-annotation-needed.rs:1:11
Expand Down