Skip to content

Commit

Permalink
Auto merge of #86338 - JohnTitor:issue-86162, r=estebank
Browse files Browse the repository at this point in the history
Do not suggest impl traits as type arguments

Fixes #86162
  • Loading branch information
bors committed Aug 3, 2021
2 parents 2939249 + b84d08d commit d5fd37f
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 27 deletions.
20 changes: 4 additions & 16 deletions compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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!(
Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_middle/src/ty/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 1 addition & 11 deletions compiler/rustc_typeck/src/astconv/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions src/test/ui/inference/issue-86162-1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Regression test of #86162.

fn foo(x: impl Clone) {}
fn gen<T>() -> T { todo!() }

fn main() {
foo(gen()); //<- Do not suggest `foo::<impl Clone>()`!
//~^ ERROR: type annotations needed
}
14 changes: 14 additions & 0 deletions src/test/ui/inference/issue-86162-1.stderr
Original file line number Diff line number Diff line change
@@ -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::<impl Clone>()`!
| ^^^ 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`.
14 changes: 14 additions & 0 deletions src/test/ui/inference/issue-86162-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Regression test of #86162.

fn gen<T>() -> T { todo!() }

struct Foo;

impl Foo {
fn bar(x: impl Clone) {}
}

fn main() {
Foo::bar(gen()); //<- Do not suggest `Foo::bar::<impl Clone>()`!
//~^ ERROR: type annotations needed
}
14 changes: 14 additions & 0 deletions src/test/ui/inference/issue-86162-2.stderr
Original file line number Diff line number Diff line change
@@ -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::<impl Clone>()`!
| ^^^^^^^^ 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`.

0 comments on commit d5fd37f

Please sign in to comment.