Skip to content

Commit 6499eb5

Browse files
authored
Rollup merge of #121100 - estebank:issue-71252, r=compiler-errors
Detect when method call on argument could be removed to fulfill failed trait bound When encountering ```rust struct Foo; struct Bar; impl From<Bar> for Foo { fn from(_: Bar) -> Self { Foo } } fn qux(_: impl From<Bar>) {} fn main() { qux(Bar.into()); } ``` Suggest removing `.into()`: ``` error[E0283]: type annotations needed --> f100.rs:8:13 | 8 | qux(Bar.into()); | --- ^^^^ | | | required by a bound introduced by this call | = note: cannot satisfy `_: From<Bar>` note: required by a bound in `qux` --> f100.rs:6:16 | 6 | fn qux(_: impl From<Bar>) {} | ^^^^^^^^^ required by this bound in `qux` help: try using a fully qualified path to specify the expected types | 8 | qux(<Bar as Into<T>>::into(Bar)); | +++++++++++++++++++++++ ~ help: consider removing this method call, as the receiver has type `Bar` and `Bar: From<Bar>` trivially holds | 8 - qux(Bar.into()); 8 + qux(Bar); | ``` Fix #71252
2 parents fb5982f + 9b3fcf9 commit 6499eb5

File tree

6 files changed

+72
-1
lines changed

6 files changed

+72
-1
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -3689,6 +3689,24 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
36893689
if let Node::Expr(expr) = tcx.hir_node(arg_hir_id)
36903690
&& let Some(typeck_results) = &self.typeck_results
36913691
{
3692+
if let hir::Expr { kind: hir::ExprKind::MethodCall(_, rcvr, _, _), .. } = expr
3693+
&& let Some(ty) = typeck_results.node_type_opt(rcvr.hir_id)
3694+
&& let Some(failed_pred) = failed_pred.to_opt_poly_trait_pred()
3695+
&& let pred = failed_pred.map_bound(|pred| pred.with_self_ty(tcx, ty))
3696+
&& self.predicate_must_hold_modulo_regions(&Obligation::misc(
3697+
tcx, expr.span, body_id, param_env, pred,
3698+
))
3699+
{
3700+
err.span_suggestion_verbose(
3701+
expr.span.with_lo(rcvr.span.hi()),
3702+
format!(
3703+
"consider removing this method call, as the receiver has type `{ty}` and \
3704+
`{pred}` trivially holds",
3705+
),
3706+
"",
3707+
Applicability::MaybeIncorrect,
3708+
);
3709+
}
36923710
if let hir::Expr { kind: hir::ExprKind::Block(block, _), .. } = expr {
36933711
let inner_expr = expr.peel_blocks();
36943712
let ty = typeck_results
@@ -3824,7 +3842,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
38243842
}
38253843
}
38263844

3827-
if let Node::Expr(expr) = tcx.hir_node(call_hir_id) {
3845+
if let Node::Expr(expr) = call_node {
38283846
if let hir::ExprKind::Call(hir::Expr { span, .. }, _)
38293847
| hir::ExprKind::MethodCall(
38303848
hir::PathSegment { ident: Ident { span, .. }, .. },

tests/ui/async-await/issue-72442.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ LL | let mut f = File::open(path.to_str())?;
88
|
99
note: required by a bound in `File::open`
1010
--> $SRC_DIR/std/src/fs.rs:LL:COL
11+
help: consider removing this method call, as the receiver has type `&Path` and `&Path: AsRef<Path>` trivially holds
12+
|
13+
LL - let mut f = File::open(path.to_str())?;
14+
LL + let mut f = File::open(path)?;
15+
|
1116

1217
error: aborting due to 1 previous error
1318

tests/ui/error-should-say-copy-not-pod.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ note: required by a bound in `check_bound`
1111
|
1212
LL | fn check_bound<T:Copy>(_: T) {}
1313
| ^^^^ required by this bound in `check_bound`
14+
help: consider removing this method call, as the receiver has type `&'static str` and `&'static str: Copy` trivially holds
15+
|
16+
LL - check_bound("nocopy".to_string());
17+
LL + check_bound("nocopy");
18+
|
1419

1520
error: aborting due to 1 previous error
1621

tests/ui/suggestions/issue-84973-blacklist.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ note: required by a bound in `f_copy`
1111
|
1212
LL | fn f_copy<T: Copy>(t: T) {}
1313
| ^^^^ required by this bound in `f_copy`
14+
help: consider removing this method call, as the receiver has type `&'static str` and `&'static str: Copy` trivially holds
15+
|
16+
LL - f_copy("".to_string());
17+
LL + f_copy("");
18+
|
1419

1520
error[E0277]: the trait bound `S: Clone` is not satisfied
1621
--> $DIR/issue-84973-blacklist.rs:16:13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
struct Foo;
2+
struct Bar;
3+
impl From<Bar> for Foo {
4+
fn from(_: Bar) -> Self { Foo }
5+
}
6+
fn qux(_: impl From<Bar>) {}
7+
fn main() {
8+
qux(Bar.into()); //~ ERROR type annotations needed
9+
//~| HELP try using a fully qualified path to specify the expected types
10+
//~| HELP consider removing this method call, as the receiver has type `Bar` and `Bar: From<Bar>` trivially holds
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error[E0283]: type annotations needed
2+
--> $DIR/argument-with-unnecessary-method-call.rs:8:13
3+
|
4+
LL | qux(Bar.into());
5+
| --- ^^^^
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
= note: cannot satisfy `_: From<Bar>`
10+
note: required by a bound in `qux`
11+
--> $DIR/argument-with-unnecessary-method-call.rs:6:16
12+
|
13+
LL | fn qux(_: impl From<Bar>) {}
14+
| ^^^^^^^^^ required by this bound in `qux`
15+
help: try using a fully qualified path to specify the expected types
16+
|
17+
LL | qux(<Bar as Into<T>>::into(Bar));
18+
| +++++++++++++++++++++++ ~
19+
help: consider removing this method call, as the receiver has type `Bar` and `Bar: From<Bar>` trivially holds
20+
|
21+
LL - qux(Bar.into());
22+
LL + qux(Bar);
23+
|
24+
25+
error: aborting due to 1 previous error
26+
27+
For more information about this error, try `rustc --explain E0283`.

0 commit comments

Comments
 (0)