|
| 1 | +//@ edition: 2024 |
| 2 | +//@ revisions: current next |
| 3 | +//@ ignore-compare-mode-next-solver (explicit revisions) |
| 4 | +//@[next] compile-flags: -Znext-solver |
| 5 | +//@ check-pass |
| 6 | + |
| 7 | +// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/177>. |
| 8 | +// Coroutines erase all free lifetimes from their interior types, replacing them with higher- |
| 9 | +// ranked regions which act as universals, to properly represent the fact that we don't know what |
| 10 | +// the value of the region is within the coroutine. |
| 11 | +// |
| 12 | +// In the future in `from_request`, that means that the `'r` lifetime is being replaced in |
| 13 | +// `<T as FromRequest<'r>>::Assoc`, which is in present in the existential bounds of the |
| 14 | +// `dyn Future` that it's awaiting. Normalizing this associated type, with its free lifetimes |
| 15 | +// replaced, means proving `T: FromRequest<'!0>`, which doesn't hold without constraining the |
| 16 | +// `'!0` lifetime, which we don't do today. |
| 17 | + |
| 18 | +// Proving `T: Trait` holds when `<T as Trait>::Assoc` is rigid is not necessary for soundness, |
| 19 | +// at least not *yet*, and it's not even necessary for diagnostics since we have other special |
| 20 | +// casing for, e.g., AliasRelate goals failing in the BestObligation folder. |
| 21 | + |
| 22 | +// The old solver unintentioanlly avoids this by never checking that `T: Trait` holds when |
| 23 | +// `<T as Trait>::Assoc` is rigid. Introducing this additional requirement when projecting rigidly |
| 24 | +// in the old solver causes this (and tons of production crates) to fail. See the fallout from the |
| 25 | +// crater run at <https://github.com/rust-lang/rust/pull/139763>. |
| 26 | + |
| 27 | +use std::future::Future; |
| 28 | +use std::pin::Pin; |
| 29 | + |
| 30 | +pub trait FromRequest<'r> { |
| 31 | + type Assoc; |
| 32 | + fn from_request() -> Pin<Box<dyn Future<Output = Self::Assoc> + Send>>; |
| 33 | +} |
| 34 | + |
| 35 | +fn test<'r, T: FromRequest<'r>>() -> Pin<Box<dyn Future<Output = ()> + Send>> { |
| 36 | + Box::pin(async move { |
| 37 | + T::from_request().await; |
| 38 | + }) |
| 39 | +} |
| 40 | + |
| 41 | +fn main() {} |
0 commit comments