diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-09-05 20:15:03 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-05 20:15:03 +0200 |
| commit | 8c0490782e8ba3da4aaf9250e886478b9d3a7f48 (patch) | |
| tree | 4a30fae8d92047ec9e58349de633c0dbadd7cb41 | |
| parent | c7d5c12cc87d9df08c1a04ea5c9045b53569b7ae (diff) | |
| parent | 98fa0c93ee031277e64eaee11fe9dbfe2147f532 (diff) | |
| download | rust-8c0490782e8ba3da4aaf9250e886478b9d3a7f48.tar.gz rust-8c0490782e8ba3da4aaf9250e886478b9d3a7f48.zip | |
Rollup merge of #115559 - lcnr:implied-bounds-unconstrained, r=aliemjay
implied bounds: do not ICE on unconstrained region vars fixes #112832 see tests/ui/implied-bounds/implied-bounds-unconstrained-2.rs for a minimal example showing why this is necessary. r? types cc ``@compiler-errors`` ``@aliemjay`` https://rust-lang.zulipchat.com/#narrow/stream/144729-t-types/topic/assoc.20type.20bound.20in.20super.20trait
3 files changed, 53 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 339baf611f3..32bbd626d4e 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -57,16 +57,12 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> { let ty = OpportunisticRegionResolver::new(self).fold_ty(ty); // We do not expect existential variables in implied bounds. - // We may however encounter unconstrained lifetime variables in invalid - // code. See #110161 for context. + // We may however encounter unconstrained lifetime variables + // in very rare cases. + // + // See `ui/implied-bounds/implied-bounds-unconstrained-2.rs` for + // an example. assert!(!ty.has_non_region_infer()); - if ty.has_infer() { - self.tcx.sess.delay_span_bug( - self.tcx.def_span(body_id), - "skipped implied_outlives_bounds due to unconstrained lifetimes", - ); - return vec![]; - } let mut canonical_var_values = OriginalQueryValues::default(); let canonical_ty = diff --git a/tests/ui/implied-bounds/implied-bounds-unconstrained-1.rs b/tests/ui/implied-bounds/implied-bounds-unconstrained-1.rs new file mode 100644 index 00000000000..025e5176ff7 --- /dev/null +++ b/tests/ui/implied-bounds/implied-bounds-unconstrained-1.rs @@ -0,0 +1,28 @@ +// check-pass + +// Regression test for #112832. +pub trait QueryDb { + type Db; +} + +pub struct QueryTable<Q, DB> { + db: DB, + storage: Q, +} + +// We normalize `<Q as QueryDb>::Db` to `<Q as AsyncQueryFunction<'d>>::SendDb` +// using the where-bound. 'd is an unconstrained region variable which previously +// triggered an assert. +impl<Q> QueryTable<Q, <Q as QueryDb>::Db> where Q: for<'d> AsyncQueryFunction<'d> {} + +pub trait AsyncQueryFunction<'d>: QueryDb<Db = <Self as AsyncQueryFunction<'d>>::SendDb> { + type SendDb: 'd; +} + +pub trait QueryStorageOpsAsync<Q> +where + Q: for<'d> AsyncQueryFunction<'d>, +{ +} + +fn main() {} diff --git a/tests/ui/implied-bounds/implied-bounds-unconstrained-2.rs b/tests/ui/implied-bounds/implied-bounds-unconstrained-2.rs new file mode 100644 index 00000000000..976054facee --- /dev/null +++ b/tests/ui/implied-bounds/implied-bounds-unconstrained-2.rs @@ -0,0 +1,20 @@ +// check-pass + +// Another minimized regression test for #112832. +trait Trait { + type Assoc; +} + +trait Sub<'a>: Trait<Assoc = <Self as Sub<'a>>::SubAssoc> { + type SubAssoc; +} + +// By using the where-clause we normalize `<T as Trait>::Assoc` to +// `<T as Sub<'a>>::SubAssoc` where `'a` is an unconstrained region +// variable. +fn foo<T>(x: <T as Trait>::Assoc) +where + for<'a> T: Sub<'a>, +{} + +fn main() {} |
