Skip to content
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

Do not suggest impl traits as type arguments #86338

Merged
merged 2 commits into from
Aug 3, 2021
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
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| {
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess we could also add an fn is_impl_trait to param, but that's not necessary in this PR.

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`.