From bfcd191905ce48c5b746af12c2995ef535d61b83 Mon Sep 17 00:00:00 2001 From: ricked-twice <39213807+ricked-twice@users.noreply.github.com> Date: Tue, 3 May 2022 21:16:03 +0200 Subject: [PATCH 1/2] Quick fix for #96223. --- .../src/traits/error_reporting/suggestions.rs | 8 ++- src/test/ui/suggestions/issue-96223.rs | 53 +++++++++++++++++++ src/test/ui/suggestions/issue-96223.stderr | 28 ++++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/suggestions/issue-96223.rs create mode 100644 src/test/ui/suggestions/issue-96223.stderr 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 a3d3c7c0cf3aa..fcf188228dcc0 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 ([issue#96223](https://github.com/rust-lang/rust/issues/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` 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 0000000000000..501373d96abec --- /dev/null +++ b/src/test/ui/suggestions/issue-96223.rs @@ -0,0 +1,53 @@ +// Test case for #96223. +// An ICE was triggered because of a failed assertion. +// Thanks to @Manishearth for the minimal test case. + +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(pub T); + +impl<'de, T> Foo<'de> for Baz where T: Foo<'de> {} + +struct Empty; + +impl Dummy for Empty +where + M: Fubar, + for<'de> Baz<>::Inner>: Foo<'de>, +{ +} + +pub trait Dummy +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>(p: &D) {} + +fn trigger_ice() { + let p = Empty; + icey_bounds(&p); //~ERROR +} + +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 0000000000000..2737ebe517bef --- /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:50: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` +note: required because of the requirements on the impl of `for<'de> Foo<'de>` for `Baz>` + --> $DIR/issue-96223.rs:17:14 + | +LL | impl<'de, T> Foo<'de> for Baz where T: Foo<'de> {} + | ^^^^^^^^ ^^^^^^ +note: required because of the requirements on the impl of `Dummy` for `Empty` + --> $DIR/issue-96223.rs:21:9 + | +LL | impl Dummy for Empty + | ^^^^^^^^ ^^^^^ +note: required by a bound in `icey_bounds` + --> $DIR/issue-96223.rs:46:19 + | +LL | fn icey_bounds>(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`. From 574bee35fb2ea0a94e5045bc714ab3884500648e Mon Sep 17 00:00:00 2001 From: ricked-twice <39213807+ricked-twice@users.noreply.github.com> Date: Tue, 3 May 2022 22:23:30 +0200 Subject: [PATCH 2/2] Taking review hints into account. --- .../src/traits/error_reporting/suggestions.rs | 2 +- src/test/ui/suggestions/issue-96223.rs | 7 +++---- src/test/ui/suggestions/issue-96223.stderr | 8 ++++---- 3 files changed, 8 insertions(+), 9 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 fcf188228dcc0..bfb8ce6f1051c 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,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { return false; } - // This is a quick fix to resolve an ICE ([issue#96223](https://github.com/rust-lang/rust/issues/96223)). + // 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` leading to some changes to its call places. diff --git a/src/test/ui/suggestions/issue-96223.rs b/src/test/ui/suggestions/issue-96223.rs index 501373d96abec..85667bb849bd4 100644 --- a/src/test/ui/suggestions/issue-96223.rs +++ b/src/test/ui/suggestions/issue-96223.rs @@ -1,6 +1,5 @@ -// Test case for #96223. -// An ICE was triggered because of a failed assertion. -// Thanks to @Manishearth for the minimal test case. +// Previously ICEd because we didn't properly track binders in suggestions +// check-fail pub trait Foo<'de>: Sized {} @@ -47,7 +46,7 @@ fn icey_bounds>(p: &D) {} fn trigger_ice() { let p = Empty; - icey_bounds(&p); //~ERROR + 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 index 2737ebe517bef..513725d99628c 100644 --- a/src/test/ui/suggestions/issue-96223.stderr +++ b/src/test/ui/suggestions/issue-96223.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `for<'de> EmptyBis<'de>: Foo<'_>` is not satisfied - --> $DIR/issue-96223.rs:50:17 + --> $DIR/issue-96223.rs:49:17 | LL | icey_bounds(&p); | ----------- ^^ the trait `for<'de> Foo<'_>` is not implemented for `EmptyBis<'de>` @@ -8,17 +8,17 @@ LL | icey_bounds(&p); | = help: the trait `Foo<'de>` is implemented for `Baz` note: required because of the requirements on the impl of `for<'de> Foo<'de>` for `Baz>` - --> $DIR/issue-96223.rs:17:14 + --> $DIR/issue-96223.rs:16:14 | LL | impl<'de, T> Foo<'de> for Baz where T: Foo<'de> {} | ^^^^^^^^ ^^^^^^ note: required because of the requirements on the impl of `Dummy` for `Empty` - --> $DIR/issue-96223.rs:21:9 + --> $DIR/issue-96223.rs:20:9 | LL | impl Dummy for Empty | ^^^^^^^^ ^^^^^ note: required by a bound in `icey_bounds` - --> $DIR/issue-96223.rs:46:19 + --> $DIR/issue-96223.rs:45:19 | LL | fn icey_bounds>(p: &D) {} | ^^^^^^^^^^^^^^^^^^ required by this bound in `icey_bounds`