diff options
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs | 8 | ||||
| -rw-r--r-- | src/test/ui/suggestions/issue-96223.rs | 52 | ||||
| -rw-r--r-- | src/test/ui/suggestions/issue-96223.stderr | 28 |
3 files changed, 87 insertions, 1 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index a3d3c7c0cf3..bfb8ce6f105 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -866,7 +866,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { return false; } - let orig_ty = old_pred.self_ty().skip_binder(); + // This is a quick fix to resolve an ICE (#96223). + // This change should probably be deeper. + // As suggested by @jackh726, `mk_trait_obligation_with_new_self_ty` could take a `Binder<(TraitRef, Ty)> + // instead of `Binder<Ty>` leading to some changes to its call places. + let Some(orig_ty) = old_pred.self_ty().no_bound_vars() else { + return false; + }; let mk_result = |new_ty| { let obligation = self.mk_trait_obligation_with_new_self_ty(param_env, old_pred, new_ty); diff --git a/src/test/ui/suggestions/issue-96223.rs b/src/test/ui/suggestions/issue-96223.rs new file mode 100644 index 00000000000..85667bb849b --- /dev/null +++ b/src/test/ui/suggestions/issue-96223.rs @@ -0,0 +1,52 @@ +// Previously ICEd because we didn't properly track binders in suggestions +// check-fail + +pub trait Foo<'de>: Sized {} + +pub trait Bar<'a>: 'static { + type Inner: 'a; +} + +pub trait Fubar { + type Bar: for<'a> Bar<'a>; +} + +pub struct Baz<T>(pub T); + +impl<'de, T> Foo<'de> for Baz<T> where T: Foo<'de> {} + +struct Empty; + +impl<M> Dummy<M> for Empty +where + M: Fubar, + for<'de> Baz<<M::Bar as Bar<'de>>::Inner>: Foo<'de>, +{ +} + +pub trait Dummy<M> +where + M: Fubar, +{ +} + +pub struct EmptyBis<'a>(&'a [u8]); + +impl<'a> Bar<'a> for EmptyBis<'static> { + type Inner = EmptyBis<'a>; +} + +pub struct EmptyMarker; + +impl Fubar for EmptyMarker { + type Bar = EmptyBis<'static>; +} + +fn icey_bounds<D: Dummy<EmptyMarker>>(p: &D) {} + +fn trigger_ice() { + let p = Empty; + icey_bounds(&p); //~ERROR the trait bound +} + +fn main() {} diff --git a/src/test/ui/suggestions/issue-96223.stderr b/src/test/ui/suggestions/issue-96223.stderr new file mode 100644 index 00000000000..513725d9962 --- /dev/null +++ b/src/test/ui/suggestions/issue-96223.stderr @@ -0,0 +1,28 @@ +error[E0277]: the trait bound `for<'de> EmptyBis<'de>: Foo<'_>` is not satisfied + --> $DIR/issue-96223.rs:49:17 + | +LL | icey_bounds(&p); + | ----------- ^^ the trait `for<'de> Foo<'_>` is not implemented for `EmptyBis<'de>` + | | + | required by a bound introduced by this call + | + = help: the trait `Foo<'de>` is implemented for `Baz<T>` +note: required because of the requirements on the impl of `for<'de> Foo<'de>` for `Baz<EmptyBis<'de>>` + --> $DIR/issue-96223.rs:16:14 + | +LL | impl<'de, T> Foo<'de> for Baz<T> where T: Foo<'de> {} + | ^^^^^^^^ ^^^^^^ +note: required because of the requirements on the impl of `Dummy<EmptyMarker>` for `Empty` + --> $DIR/issue-96223.rs:20:9 + | +LL | impl<M> Dummy<M> for Empty + | ^^^^^^^^ ^^^^^ +note: required by a bound in `icey_bounds` + --> $DIR/issue-96223.rs:45:19 + | +LL | fn icey_bounds<D: Dummy<EmptyMarker>>(p: &D) {} + | ^^^^^^^^^^^^^^^^^^ required by this bound in `icey_bounds` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. |
