Skip to content

Commit 4f6837e

Browse files
authored
Rollup merge of rust-lang#154431 - TaKO8Ki:fix-explicit-reference-cast-unrelated-leaf, r=JohnTitor
Avoid ICE in explicit reference cast suggestion for unrelated leaf pr… Fixes rust-lang#154403 The explicit reference cast suggestion in was enabled based on `main_trait_predicate` being `From`/`TryFrom`, but it then extracted the source type from `leaf_trait_predicate`. That is only valid when the leaf obligation is also part of the `From`/`TryFrom` conversion family.
2 parents da5a1d7 + 741a3a7 commit 4f6837e

3 files changed

Lines changed: 75 additions & 5 deletions

File tree

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -285,14 +285,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
285285
let mut err = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg);
286286

287287
let trait_def_id = main_trait_predicate.def_id();
288-
if self.tcx.is_diagnostic_item(sym::From, trait_def_id)
289-
|| self.tcx.is_diagnostic_item(sym::TryFrom, trait_def_id)
288+
let leaf_trait_def_id = leaf_trait_predicate.def_id();
289+
if (self.tcx.is_diagnostic_item(sym::From, trait_def_id)
290+
|| self.tcx.is_diagnostic_item(sym::TryFrom, trait_def_id))
291+
&& (self.tcx.is_diagnostic_item(sym::From, leaf_trait_def_id)
292+
|| self.tcx.is_diagnostic_item(sym::TryFrom, leaf_trait_def_id))
290293
{
291294
let trait_ref = leaf_trait_predicate.skip_binder().trait_ref;
292295

293-
// Defensive: next-solver may produce fewer args than expected.
294-
if trait_ref.args.len() > 1 {
295-
let found_ty = trait_ref.args.type_at(1);
296+
if let Some(found_ty) = trait_ref.args.get(1).and_then(|arg| arg.as_type())
297+
{
296298
let ty = main_trait_predicate.skip_binder().self_ty();
297299

298300
if let Some(cast_ty) = self.find_explicit_cast_type(
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
trait Output<'a> {
2+
type Type;
3+
}
4+
5+
struct Wrapper;
6+
7+
impl Wrapper {
8+
fn do_something_wrapper<O, F>(self, _: F)
9+
where
10+
for<'a> F: Output<'a>,
11+
for<'a> O: From<<F as Output<'a>>::Type>,
12+
{
13+
}
14+
}
15+
16+
fn main() {
17+
let wrapper = Wrapper;
18+
wrapper.do_something_wrapper(|value| ());
19+
//~^ ERROR the trait bound `for<'a> {closure@
20+
//~| ERROR the trait bound `for<'a> _: From<<{closure@
21+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
error[E0277]: the trait bound `for<'a> {closure@$DIR/explicit-reference-cast-unrelated-leaf.rs:18:34: 18:41}: Output<'a>` is not satisfied
2+
--> $DIR/explicit-reference-cast-unrelated-leaf.rs:18:34
3+
|
4+
LL | wrapper.do_something_wrapper(|value| ());
5+
| -------------------- ^^^^^^^^^^ unsatisfied trait bound
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
= help: the trait `for<'a> Output<'a>` is not implemented for closure `{closure@$DIR/explicit-reference-cast-unrelated-leaf.rs:18:34: 18:41}`
10+
help: this trait has no implementations, consider adding one
11+
--> $DIR/explicit-reference-cast-unrelated-leaf.rs:1:1
12+
|
13+
LL | trait Output<'a> {
14+
| ^^^^^^^^^^^^^^^^
15+
note: required by a bound in `Wrapper::do_something_wrapper`
16+
--> $DIR/explicit-reference-cast-unrelated-leaf.rs:10:20
17+
|
18+
LL | fn do_something_wrapper<O, F>(self, _: F)
19+
| -------------------- required by a bound in this associated function
20+
LL | where
21+
LL | for<'a> F: Output<'a>,
22+
| ^^^^^^^^^^ required by this bound in `Wrapper::do_something_wrapper`
23+
24+
error[E0277]: the trait bound `for<'a> _: From<<{closure@$DIR/explicit-reference-cast-unrelated-leaf.rs:18:34: 18:41} as Output<'a>>::Type>` is not satisfied
25+
--> $DIR/explicit-reference-cast-unrelated-leaf.rs:18:13
26+
|
27+
LL | wrapper.do_something_wrapper(|value| ());
28+
| ^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
29+
|
30+
= help: the trait `for<'a> Output<'a>` is not implemented for closure `{closure@$DIR/explicit-reference-cast-unrelated-leaf.rs:18:34: 18:41}`
31+
help: this trait has no implementations, consider adding one
32+
--> $DIR/explicit-reference-cast-unrelated-leaf.rs:1:1
33+
|
34+
LL | trait Output<'a> {
35+
| ^^^^^^^^^^^^^^^^
36+
note: required by a bound in `Wrapper::do_something_wrapper`
37+
--> $DIR/explicit-reference-cast-unrelated-leaf.rs:11:20
38+
|
39+
LL | fn do_something_wrapper<O, F>(self, _: F)
40+
| -------------------- required by a bound in this associated function
41+
...
42+
LL | for<'a> O: From<<F as Output<'a>>::Type>,
43+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Wrapper::do_something_wrapper`
44+
45+
error: aborting due to 2 previous errors
46+
47+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)