mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Rollup merge of #154431 - TaKO8Ki:fix-explicit-reference-cast-unrelated-leaf, r=JohnTitor
Avoid ICE in explicit reference cast suggestion for unrelated leaf pr… Fixes rust-lang/rust#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.
This commit is contained in:
@@ -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`.
|
||||
Reference in New Issue
Block a user