Skip to content

Commit

Permalink
Detect when method call on argument could be removed to fulfill faile…
Browse files Browse the repository at this point in the history
…d 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>` can be fulfilled
  |
8 -     qux(Bar.into());
8 +     qux(Bar);
  |
```

Fix #71252
  • Loading branch information
estebank committed Feb 14, 2024
1 parent eaff1af commit a71a218
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 1 deletion.
Expand Up @@ -3961,6 +3961,26 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if let Node::Expr(expr) = tcx.hir_node(arg_hir_id)
&& let Some(typeck_results) = &self.typeck_results
{
if let hir::Expr { kind: hir::ExprKind::MethodCall(_, rcvr, _, _), .. } = expr
&& let Some(ty) = typeck_results.node_type_opt(rcvr.hir_id)
&& let Some(failed_pred) = failed_pred.to_opt_poly_trait_pred()
&& let pred = failed_pred.skip_binder().with_self_ty(tcx, ty)
&& self
.evaluate_obligation_no_overflow(&Obligation::misc(
tcx, expr.span, body_id, param_env, pred,
))
.must_apply_modulo_regions()
{
err.span_suggestion_verbose(
expr.span.with_lo(rcvr.span.hi()),
format!(
"consider removing this method call, as the receiver has type `{ty}` and \
`{pred}` trivially holds",
),
"",
Applicability::MaybeIncorrect,
);
}
if let hir::Expr { kind: hir::ExprKind::Block(block, _), .. } = expr {
let inner_expr = expr.peel_blocks();
let ty = typeck_results
Expand Down Expand Up @@ -4096,7 +4116,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
}

if let Node::Expr(expr) = tcx.hir_node(call_hir_id) {
if let Node::Expr(expr) = call_node {
if let hir::ExprKind::Call(hir::Expr { span, .. }, _)
| hir::ExprKind::MethodCall(
hir::PathSegment { ident: Ident { span, .. }, .. },
Expand Down
5 changes: 5 additions & 0 deletions tests/ui/async-await/issue-72442.stderr
Expand Up @@ -8,6 +8,11 @@ LL | let mut f = File::open(path.to_str())?;
|
note: required by a bound in `File::open`
--> $SRC_DIR/std/src/fs.rs:LL:COL
help: consider removing this method call, as the receiver has type `&Path` and `&Path: AsRef<Path>` trivially holds
|
LL - let mut f = File::open(path.to_str())?;
LL + let mut f = File::open(path)?;
|

error: aborting due to 1 previous error

Expand Down
5 changes: 5 additions & 0 deletions tests/ui/error-should-say-copy-not-pod.stderr
Expand Up @@ -11,6 +11,11 @@ note: required by a bound in `check_bound`
|
LL | fn check_bound<T:Copy>(_: T) {}
| ^^^^ required by this bound in `check_bound`
help: consider removing this method call, as the receiver has type `&'static str` and `&'static str: Copy` trivially holds
|
LL - check_bound("nocopy".to_string());
LL + check_bound("nocopy");
|

error: aborting due to 1 previous error

Expand Down
5 changes: 5 additions & 0 deletions tests/ui/suggestions/issue-84973-blacklist.stderr
Expand Up @@ -11,6 +11,11 @@ note: required by a bound in `f_copy`
|
LL | fn f_copy<T: Copy>(t: T) {}
| ^^^^ required by this bound in `f_copy`
help: consider removing this method call, as the receiver has type `&'static str` and `&'static str: Copy` trivially holds
|
LL - f_copy("".to_string());
LL + f_copy("");
|

error[E0277]: the trait bound `S: Clone` is not satisfied
--> $DIR/issue-84973-blacklist.rs:16:13
Expand Down

0 comments on commit a71a218

Please sign in to comment.