Skip to content

Commit

Permalink
Rollup merge of rust-lang#63811 - estebank:impl-trait-arg, r=cramertj
Browse files Browse the repository at this point in the history
Correctly suggest adding bounds to `impl Trait` argument

Fix rust-lang#63706.
  • Loading branch information
Centril committed Aug 29, 2019
2 parents 0414dfa + 055f7e2 commit 4cae33a
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 2 deletions.
18 changes: 16 additions & 2 deletions src/librustc_typeck/check/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -743,8 +743,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// We do this to avoid suggesting code that ends up as `T: FooBar`,
// instead we suggest `T: Foo + Bar` in that case.
let mut has_bounds = false;
let mut impl_trait = false;
if let Node::GenericParam(ref param) = hir.get(id) {
has_bounds = !param.bounds.is_empty();
match param.kind {
hir::GenericParamKind::Type { synthetic: Some(_), .. } => {
// We've found `fn foo(x: impl Trait)` instead of
// `fn foo<T>(x: T)`. We want to suggest the correct
// `fn foo(x: impl Trait + TraitBound)` instead of
// `fn foo<T: TraitBound>(x: T)`. (#63706)
impl_trait = true;
has_bounds = param.bounds.len() > 1;
}
_ => {
has_bounds = !param.bounds.is_empty();
}
}
}
let sp = hir.span(id);
// `sp` only covers `T`, change it so that it covers
Expand All @@ -765,8 +778,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
sp,
&msg[..],
candidates.iter().map(|t| format!(
"{}: {}{}",
"{}{} {}{}",
param,
if impl_trait { " +" } else { ":" },
self.tcx.def_path_str(t.def_id),
if has_bounds { " +"} else { "" },
)),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// run-rustfix

trait Foo {}

trait Bar {
fn hello(&self) {}
}

struct S;

impl Foo for S {}
impl Bar for S {}

fn test(foo: impl Foo + Bar) {
foo.hello(); //~ ERROR E0599
}

fn main() {
test(S);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// run-rustfix

trait Foo {}

trait Bar {
fn hello(&self) {}
}

struct S;

impl Foo for S {}
impl Bar for S {}

fn test(foo: impl Foo) {
foo.hello(); //~ ERROR E0599
}

fn main() {
test(S);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0599]: no method named `hello` found for type `impl Foo` in the current scope
--> $DIR/impl-trait-with-missing-trait-bounds-in-arg.rs:15:9
|
LL | foo.hello();
| ^^^^^
|
= help: items from traits can only be used if the type parameter is bounded by the trait
help: the following trait defines an item `hello`, perhaps you need to restrict type parameter `impl Foo` with it:
|
LL | fn test(foo: impl Foo + Bar) {
| ^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.

0 comments on commit 4cae33a

Please sign in to comment.