-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Detect when method call on argument could be removed to fulfill failed trait bound #121100
Conversation
r? @wesleywiser rustbot has assigned @wesleywiser. Use r? to explicitly pick a reviewer |
expr.span.with_lo(rcvr.span.hi()), | ||
format!( | ||
"consider removing this method call, as the receiver has type `{ty}` and \ | ||
`{pred}` can be fulfilled", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
`{pred}` can be fulfilled", | |
`{pred}` is trivial", |
or "trivially holds"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@compiler-errors do we ever use that wording in user-facing messages? AFAICT we only use that wording for other compiler devs. (We can argue that "can be fulfilled" has the same problem.) Maybe "{pred}
is met"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could say the same about "fulfilled". 😆 don't believe the original wording gets across the fact that the method call is redundant, which is what I think this should be pointing out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point that I'm trying to make is that the wording should explain to the user why removing the method call is beneficial, which I don't believe it is doing right now; rn it's just stating facts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@compiler-errors yeah, that makes sense. Initially I was thinking "well, there could be cases where the predicate is actually more complex and the Self
is something like an assoc type or impl Trait", but thinking about it for just a minute was enough to realize that you're right and "yes, every case where this would work would be a trivial obligation".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like "is trivial" better than "can be fulfilled" 👍
I wonder if something even simpler would work ("is valid" or "is true" perhaps)?
9a1d514
to
a71a218
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
r=me after nits
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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use map_bound
here. otherwise, it's gonna ICE because you're skipping binders.
&& 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( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why did you use evaluate_obligation_no_overflow
here? please use predicate_may_hold_modulo_regions
.
a71a218
to
5a1c454
Compare
@bors r=compiler-errors |
Why did you use predicate_may_hold? That can hold even if there is inference that still needs to be made. Could you use predicate_may_hold_modulo_regions? False positives here feel like they would be really confusing. @bors r- |
Also, is there a reason why you left out the test from the PR description? None of the UI tests that were changed are trait ambiguity errors, just regular trait failures. Please add that test, too. |
This comment has been minimized.
This comment has been minimized.
…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 rust-lang#71252
5a1c454
to
9b3fcf9
Compare
Updated @bors r=compiler-errors |
I got confused between |
…rrors 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 rust-lang#71252
…rrors 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 rust-lang#71252
…llaumeGomez Rollup of 7 pull requests Successful merges: - rust-lang#118264 (Optimize `VecDeque::drain` for (half-)open ranges) - rust-lang#121079 (distribute tool documentations and avoid file conflicts on `x install`) - rust-lang#121100 (Detect when method call on argument could be removed to fulfill failed trait bound) - rust-lang#121160 (rustdoc: fix and refactor HTML rendering a bit) - rust-lang#121198 (Add more checks for `unnamed_fields` during HIR analysis) - rust-lang#121221 (AstConv: Refactor lowering of associated item bindings a bit) - rust-lang#121237 (Use better heuristic for printing Cargo specific diagnostics) r? `@ghost` `@rustbot` modify labels: rollup
Rollup of 7 pull requests Successful merges: - rust-lang#120526 (rustdoc: Correctly handle long crate names on mobile) - rust-lang#121100 (Detect when method call on argument could be removed to fulfill failed trait bound) - rust-lang#121160 (rustdoc: fix and refactor HTML rendering a bit) - rust-lang#121198 (Add more checks for `unnamed_fields` during HIR analysis) - rust-lang#121218 (Fix missing trait impls for type in rustc docs) - rust-lang#121221 (AstConv: Refactor lowering of associated item bindings a bit) - rust-lang#121237 (Use better heuristic for printing Cargo specific diagnostics) r? `@ghost` `@rustbot` modify labels: rollup
…rrors 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 rust-lang#71252
Rollup merge of rust-lang#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 rust-lang#71252
When encountering
Suggest removing
.into()
:Fix #71252