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 a15eecd2414..c2025f3fe4d 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 @@ -753,23 +753,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { if let (UnderspecifiedArgKind::Const { .. }, Some(parent_data)) = (&arg_data.kind, &arg_data.parent) { - let has_impl_trait = - self.tcx.generics_of(parent_data.def_id).params.iter().any(|param| { - matches!( - param.kind, - ty::GenericParamDefKind::Type { - synthetic: Some( - hir::SyntheticTyParamKind::ImplTrait - | hir::SyntheticTyParamKind::FromAttr, - ), - .. - } - ) - }); - // (#83606): Do not emit a suggestion if the parent has an `impl Trait` // as an argument otherwise it will cause the E0282 error. - if !has_impl_trait || self.tcx.features().explicit_generic_args_with_impl_trait { + if !self.tcx.generics_of(parent_data.def_id).has_impl_trait() + || self.tcx.features().explicit_generic_args_with_impl_trait + { err.span_suggestion_verbose( span, "consider specifying the const argument", @@ -814,7 +802,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let borrow = typeck_results.borrow(); if let Some((DefKind::AssocFn, did)) = borrow.type_dependent_def(e.hir_id) { let generics = self.tcx.generics_of(did); - if !generics.params.is_empty() { + if !generics.params.is_empty() && !generics.has_impl_trait() { err.span_suggestion_verbose( segment.ident.span.shrink_to_hi(), &format!( diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 4e3f475a915..0f89581ae66 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -198,6 +198,21 @@ impl<'tcx> Generics { _ => bug!("expected const parameter, but found another generic parameter"), } } + + /// Returns `true` if `params` has `impl Trait`. + pub fn has_impl_trait(&'tcx self) -> bool { + self.params.iter().any(|param| { + matches!( + param.kind, + ty::GenericParamDefKind::Type { + synthetic: Some( + hir::SyntheticTyParamKind::ImplTrait | hir::SyntheticTyParamKind::FromAttr, + ), + .. + } + ) + }) + } } /// Bounds on generics. diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index c134af44992..f46fae1326c 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1603,6 +1603,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { let generics = self.tcx.generics_of(*def_id); if generics.params.iter().any(|p| p.name != kw::SelfUpper) && !snippet.ends_with('>') + && !generics.has_impl_trait() { // FIXME: To avoid spurious suggestions in functions where type arguments // where already supplied, we check the snippet to make sure it doesn't diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index 9e700d9e8d8..0cfdde26c2b 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -647,17 +647,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { return false; } - let impl_trait = generics.params.iter().any(|param| { - matches!( - param.kind, - ty::GenericParamDefKind::Type { - synthetic: Some( - hir::SyntheticTyParamKind::ImplTrait | hir::SyntheticTyParamKind::FromAttr, - ), - .. - } - ) - }); + let impl_trait = generics.has_impl_trait(); if impl_trait { let spans = seg diff --git a/src/test/ui/inference/issue-86162-1.rs b/src/test/ui/inference/issue-86162-1.rs new file mode 100644 index 00000000000..5a547eb38d1 --- /dev/null +++ b/src/test/ui/inference/issue-86162-1.rs @@ -0,0 +1,9 @@ +// Regression test of #86162. + +fn foo(x: impl Clone) {} +fn gen() -> T { todo!() } + +fn main() { + foo(gen()); //<- Do not suggest `foo::()`! + //~^ ERROR: type annotations needed +} diff --git a/src/test/ui/inference/issue-86162-1.stderr b/src/test/ui/inference/issue-86162-1.stderr new file mode 100644 index 00000000000..f4e2161d7b8 --- /dev/null +++ b/src/test/ui/inference/issue-86162-1.stderr @@ -0,0 +1,14 @@ +error[E0283]: type annotations needed + --> $DIR/issue-86162-1.rs:7:5 + | +LL | fn foo(x: impl Clone) {} + | ----- required by this bound in `foo` +... +LL | foo(gen()); //<- Do not suggest `foo::()`! + | ^^^ cannot infer type for type parameter `impl Clone` declared on the function `foo` + | + = note: cannot satisfy `_: Clone` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/inference/issue-86162-2.rs b/src/test/ui/inference/issue-86162-2.rs new file mode 100644 index 00000000000..b8c75dd7728 --- /dev/null +++ b/src/test/ui/inference/issue-86162-2.rs @@ -0,0 +1,14 @@ +// Regression test of #86162. + +fn gen() -> T { todo!() } + +struct Foo; + +impl Foo { + fn bar(x: impl Clone) {} +} + +fn main() { + Foo::bar(gen()); //<- Do not suggest `Foo::bar::()`! + //~^ ERROR: type annotations needed +} diff --git a/src/test/ui/inference/issue-86162-2.stderr b/src/test/ui/inference/issue-86162-2.stderr new file mode 100644 index 00000000000..19f741e1cf6 --- /dev/null +++ b/src/test/ui/inference/issue-86162-2.stderr @@ -0,0 +1,14 @@ +error[E0283]: type annotations needed + --> $DIR/issue-86162-2.rs:12:5 + | +LL | fn bar(x: impl Clone) {} + | ----- required by this bound in `Foo::bar` +... +LL | Foo::bar(gen()); //<- Do not suggest `Foo::bar::()`! + | ^^^^^^^^ cannot infer type for type parameter `impl Clone` declared on the associated function `bar` + | + = note: cannot satisfy `_: Clone` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0283`.