From ecf2a9b75ec591db6e89f4bde391b87f35c2ea08 Mon Sep 17 00:00:00 2001 From: Ezra Shaw Date: Thu, 13 Apr 2023 20:29:41 +1200 Subject: [PATCH 1/3] fix: skip implied bounds if unconstrained lifetime exists --- .../src/traits/outlives_bounds.rs | 11 ++++++++- tests/ui/implied-bounds/issue-110161.rs | 24 +++++++++++++++++++ tests/ui/implied-bounds/issue-110161.stderr | 12 ++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 tests/ui/implied-bounds/issue-110161.rs create mode 100644 tests/ui/implied-bounds/issue-110161.stderr diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index cff3d277a78fb..64be4a55708ad 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -55,7 +55,16 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> { ) -> Vec> { let ty = self.resolve_vars_if_possible(ty); let ty = OpportunisticRegionResolver::new(self).fold_ty(ty); - assert!(!ty.needs_infer()); + + // We must avoid processing constrained lifetime variables in implied + // bounds. See #110161 for context. + if ty.needs_infer() { + self.tcx.sess.delay_span_bug( + self.tcx.source_span_untracked(body_id), + "skipped implied_outlives_bounds due to unconstrained lifetimes", + ); + return vec![]; + } let span = self.tcx.def_span(body_id); let result = param_env diff --git a/tests/ui/implied-bounds/issue-110161.rs b/tests/ui/implied-bounds/issue-110161.rs new file mode 100644 index 0000000000000..ca75026ffe842 --- /dev/null +++ b/tests/ui/implied-bounds/issue-110161.rs @@ -0,0 +1,24 @@ +// ICE regression relating to unconstrained lifetimes in implied +// bounds. See #110161. + +// compile-flags: --crate-type=lib + +trait Trait { + type Ty; +} + +// erroneous `Ty` impl +impl Trait for () { +//~^ ERROR not all trait items implemented, missing: `Ty` [E0046] +} + +// `'lt` is not constrained by the erroneous `Ty` +impl<'lt, T> Trait for Box +where + T: Trait, +{ + type Ty = &'lt (); +} + +// unconstrained lifetime appears in implied bounds +fn test(_: as Trait>::Ty) {} diff --git a/tests/ui/implied-bounds/issue-110161.stderr b/tests/ui/implied-bounds/issue-110161.stderr new file mode 100644 index 0000000000000..c76b47376264e --- /dev/null +++ b/tests/ui/implied-bounds/issue-110161.stderr @@ -0,0 +1,12 @@ +error[E0046]: not all trait items implemented, missing: `Ty` + --> $DIR/issue-110161.rs:11:1 + | +LL | type Ty; + | ------- `Ty` from trait +... +LL | impl Trait for () { + | ^^^^^^^^^^^^^^^^^ missing `Ty` in implementation + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0046`. From b506d966a3e413f0d8f3a2fc470f941d7d8c471d Mon Sep 17 00:00:00 2001 From: Ezra Shaw Date: Fri, 14 Apr 2023 20:18:28 +1200 Subject: [PATCH 2/3] implement review suggestions --- .../src/traits/outlives_bounds.rs | 5 +++-- tests/ui/implied-bounds/issue-110161.rs | 12 +++++++----- tests/ui/implied-bounds/issue-110161.stderr | 4 ++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index 64be4a55708ad..5b8d9e7f0f753 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -56,11 +56,12 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> { let ty = self.resolve_vars_if_possible(ty); let ty = OpportunisticRegionResolver::new(self).fold_ty(ty); - // We must avoid processing constrained lifetime variables in implied + // We must avoid processing unconstrained lifetime variables in implied // bounds. See #110161 for context. + assert!(!ty.has_non_region_infer()); if ty.needs_infer() { self.tcx.sess.delay_span_bug( - self.tcx.source_span_untracked(body_id), + self.tcx.def_span(body_id), "skipped implied_outlives_bounds due to unconstrained lifetimes", ); return vec![]; diff --git a/tests/ui/implied-bounds/issue-110161.rs b/tests/ui/implied-bounds/issue-110161.rs index ca75026ffe842..e52c8356b52b3 100644 --- a/tests/ui/implied-bounds/issue-110161.rs +++ b/tests/ui/implied-bounds/issue-110161.rs @@ -3,22 +3,24 @@ // compile-flags: --crate-type=lib -trait Trait { +trait LtTrait { type Ty; } // erroneous `Ty` impl -impl Trait for () { +impl LtTrait for () { //~^ ERROR not all trait items implemented, missing: `Ty` [E0046] } // `'lt` is not constrained by the erroneous `Ty` -impl<'lt, T> Trait for Box +impl<'lt, T> LtTrait for Box where - T: Trait, + T: LtTrait, { type Ty = &'lt (); } // unconstrained lifetime appears in implied bounds -fn test(_: as Trait>::Ty) {} +fn test(_: as LtTrait>::Ty) {} + +fn test2<'x>(_: &'x as LtTrait>::Ty) {} diff --git a/tests/ui/implied-bounds/issue-110161.stderr b/tests/ui/implied-bounds/issue-110161.stderr index c76b47376264e..9e0188694ed9c 100644 --- a/tests/ui/implied-bounds/issue-110161.stderr +++ b/tests/ui/implied-bounds/issue-110161.stderr @@ -4,8 +4,8 @@ error[E0046]: not all trait items implemented, missing: `Ty` LL | type Ty; | ------- `Ty` from trait ... -LL | impl Trait for () { - | ^^^^^^^^^^^^^^^^^ missing `Ty` in implementation +LL | impl LtTrait for () { + | ^^^^^^^^^^^^^^^^^^^ missing `Ty` in implementation error: aborting due to previous error From 4c80f58d4188165cc20f72223ec4d1ff46bfb4a8 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Sat, 15 Apr 2023 15:41:42 +0300 Subject: [PATCH 3/3] Update compiler/rustc_trait_selection/src/traits/outlives_bounds.rs --- compiler/rustc_trait_selection/src/traits/outlives_bounds.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index 5b8d9e7f0f753..e01a57ea4fee8 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -56,8 +56,9 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> { let ty = self.resolve_vars_if_possible(ty); let ty = OpportunisticRegionResolver::new(self).fold_ty(ty); - // We must avoid processing unconstrained lifetime variables in implied - // bounds. See #110161 for context. + // We do not expect existential variables in implied bounds. + // We may however encounter unconstrained lifetime variables in invalid + // code. See #110161 for context. assert!(!ty.has_non_region_infer()); if ty.needs_infer() { self.tcx.sess.delay_span_bug(