Skip to content

Commit 4cae33a

Browse files
authored
Rollup merge of #63811 - estebank:impl-trait-arg, r=cramertj
Correctly suggest adding bounds to `impl Trait` argument Fix #63706.
2 parents 0414dfa + 055f7e2 commit 4cae33a

File tree

4 files changed

+71
-2
lines changed

4 files changed

+71
-2
lines changed

src/librustc_typeck/check/method/suggest.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -743,8 +743,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
743743
// We do this to avoid suggesting code that ends up as `T: FooBar`,
744744
// instead we suggest `T: Foo + Bar` in that case.
745745
let mut has_bounds = false;
746+
let mut impl_trait = false;
746747
if let Node::GenericParam(ref param) = hir.get(id) {
747-
has_bounds = !param.bounds.is_empty();
748+
match param.kind {
749+
hir::GenericParamKind::Type { synthetic: Some(_), .. } => {
750+
// We've found `fn foo(x: impl Trait)` instead of
751+
// `fn foo<T>(x: T)`. We want to suggest the correct
752+
// `fn foo(x: impl Trait + TraitBound)` instead of
753+
// `fn foo<T: TraitBound>(x: T)`. (#63706)
754+
impl_trait = true;
755+
has_bounds = param.bounds.len() > 1;
756+
}
757+
_ => {
758+
has_bounds = !param.bounds.is_empty();
759+
}
760+
}
748761
}
749762
let sp = hir.span(id);
750763
// `sp` only covers `T`, change it so that it covers
@@ -765,8 +778,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
765778
sp,
766779
&msg[..],
767780
candidates.iter().map(|t| format!(
768-
"{}: {}{}",
781+
"{}{} {}{}",
769782
param,
783+
if impl_trait { " +" } else { ":" },
770784
self.tcx.def_path_str(t.def_id),
771785
if has_bounds { " +"} else { "" },
772786
)),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// run-rustfix
2+
3+
trait Foo {}
4+
5+
trait Bar {
6+
fn hello(&self) {}
7+
}
8+
9+
struct S;
10+
11+
impl Foo for S {}
12+
impl Bar for S {}
13+
14+
fn test(foo: impl Foo + Bar) {
15+
foo.hello(); //~ ERROR E0599
16+
}
17+
18+
fn main() {
19+
test(S);
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// run-rustfix
2+
3+
trait Foo {}
4+
5+
trait Bar {
6+
fn hello(&self) {}
7+
}
8+
9+
struct S;
10+
11+
impl Foo for S {}
12+
impl Bar for S {}
13+
14+
fn test(foo: impl Foo) {
15+
foo.hello(); //~ ERROR E0599
16+
}
17+
18+
fn main() {
19+
test(S);
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0599]: no method named `hello` found for type `impl Foo` in the current scope
2+
--> $DIR/impl-trait-with-missing-trait-bounds-in-arg.rs:15:9
3+
|
4+
LL | foo.hello();
5+
| ^^^^^
6+
|
7+
= help: items from traits can only be used if the type parameter is bounded by the trait
8+
help: the following trait defines an item `hello`, perhaps you need to restrict type parameter `impl Foo` with it:
9+
|
10+
LL | fn test(foo: impl Foo + Bar) {
11+
| ^^^^^^^^^^^^^^
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0599`.

0 commit comments

Comments
 (0)