avoid ICE in explicit reference cast suggestion for unrelated leaf predicates

This commit is contained in:
Takayuki Maeda
2026-03-27 01:26:51 +09:00
parent 3a933e5bf5
commit 741a3a7fc4
3 changed files with 75 additions and 5 deletions
@@ -285,14 +285,16 @@ pub fn report_selection_error(
let mut err = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg);
let trait_def_id = main_trait_predicate.def_id();
if self.tcx.is_diagnostic_item(sym::From, trait_def_id)
|| self.tcx.is_diagnostic_item(sym::TryFrom, trait_def_id)
let leaf_trait_def_id = leaf_trait_predicate.def_id();
if (self.tcx.is_diagnostic_item(sym::From, trait_def_id)
|| self.tcx.is_diagnostic_item(sym::TryFrom, trait_def_id))
&& (self.tcx.is_diagnostic_item(sym::From, leaf_trait_def_id)
|| self.tcx.is_diagnostic_item(sym::TryFrom, leaf_trait_def_id))
{
let trait_ref = leaf_trait_predicate.skip_binder().trait_ref;
// Defensive: next-solver may produce fewer args than expected.
if trait_ref.args.len() > 1 {
let found_ty = trait_ref.args.type_at(1);
if let Some(found_ty) = trait_ref.args.get(1).and_then(|arg| arg.as_type())
{
let ty = main_trait_predicate.skip_binder().self_ty();
if let Some(cast_ty) = self.find_explicit_cast_type(
@@ -0,0 +1,21 @@
trait Output<'a> {
type Type;
}
struct Wrapper;
impl Wrapper {
fn do_something_wrapper<O, F>(self, _: F)
where
for<'a> F: Output<'a>,
for<'a> O: From<<F as Output<'a>>::Type>,
{
}
}
fn main() {
let wrapper = Wrapper;
wrapper.do_something_wrapper(|value| ());
//~^ ERROR the trait bound `for<'a> {closure@
//~| ERROR the trait bound `for<'a> _: From<<{closure@
}
@@ -0,0 +1,47 @@
error[E0277]: the trait bound `for<'a> {closure@$DIR/explicit-reference-cast-unrelated-leaf.rs:18:34: 18:41}: Output<'a>` is not satisfied
--> $DIR/explicit-reference-cast-unrelated-leaf.rs:18:34
|
LL | wrapper.do_something_wrapper(|value| ());
| -------------------- ^^^^^^^^^^ unsatisfied trait bound
| |
| required by a bound introduced by this call
|
= help: the trait `for<'a> Output<'a>` is not implemented for closure `{closure@$DIR/explicit-reference-cast-unrelated-leaf.rs:18:34: 18:41}`
help: this trait has no implementations, consider adding one
--> $DIR/explicit-reference-cast-unrelated-leaf.rs:1:1
|
LL | trait Output<'a> {
| ^^^^^^^^^^^^^^^^
note: required by a bound in `Wrapper::do_something_wrapper`
--> $DIR/explicit-reference-cast-unrelated-leaf.rs:10:20
|
LL | fn do_something_wrapper<O, F>(self, _: F)
| -------------------- required by a bound in this associated function
LL | where
LL | for<'a> F: Output<'a>,
| ^^^^^^^^^^ required by this bound in `Wrapper::do_something_wrapper`
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
--> $DIR/explicit-reference-cast-unrelated-leaf.rs:18:13
|
LL | wrapper.do_something_wrapper(|value| ());
| ^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
|
= help: the trait `for<'a> Output<'a>` is not implemented for closure `{closure@$DIR/explicit-reference-cast-unrelated-leaf.rs:18:34: 18:41}`
help: this trait has no implementations, consider adding one
--> $DIR/explicit-reference-cast-unrelated-leaf.rs:1:1
|
LL | trait Output<'a> {
| ^^^^^^^^^^^^^^^^
note: required by a bound in `Wrapper::do_something_wrapper`
--> $DIR/explicit-reference-cast-unrelated-leaf.rs:11:20
|
LL | fn do_something_wrapper<O, F>(self, _: F)
| -------------------- required by a bound in this associated function
...
LL | for<'a> O: From<<F as Output<'a>>::Type>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Wrapper::do_something_wrapper`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.