diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index eeccf1eb0ecf..d6cfc993c8b8 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -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( diff --git a/tests/ui/traits/explicit-reference-cast-unrelated-leaf.rs b/tests/ui/traits/explicit-reference-cast-unrelated-leaf.rs new file mode 100644 index 000000000000..83687f37f054 --- /dev/null +++ b/tests/ui/traits/explicit-reference-cast-unrelated-leaf.rs @@ -0,0 +1,21 @@ +trait Output<'a> { + type Type; +} + +struct Wrapper; + +impl Wrapper { + fn do_something_wrapper(self, _: F) + where + for<'a> F: Output<'a>, + for<'a> O: From<>::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@ +} diff --git a/tests/ui/traits/explicit-reference-cast-unrelated-leaf.stderr b/tests/ui/traits/explicit-reference-cast-unrelated-leaf.stderr new file mode 100644 index 000000000000..1e4cb7f1cd18 --- /dev/null +++ b/tests/ui/traits/explicit-reference-cast-unrelated-leaf.stderr @@ -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(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(self, _: F) + | -------------------- required by a bound in this associated function +... +LL | for<'a> O: From<>::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`.