Skip to content

Commit ab29555

Browse files
authored
Unrolled build for rust-lang#139828
Rollup merge of rust-lang#139828 - compiler-errors:rigid-trait, r=lcnr Don't require rigid alias's trait to hold See test for write-up. TL;DR is that we don't need the trait bound to hold, since we enforce it during WF. I think this is preferable to introducing (if we even could do so) a more specific hack around coroutine interiors, higher ranked types, etc, since this is just a manifestation of more pervasive issues w/ lifetime erasure in coroutines. This just doesn't manifest in the old solver b/c it doesn't try to prove `T: Trait` holds when rigidly projecting `<T as Trait>::Assoc`. It's pretty clear that this affects quite a few traits (rust-lang#139763), so I think this needs fixing. r? lcnr Fixes rust-lang/trait-system-refactor-initiative#177
2 parents 79a272c + bb3c981 commit ab29555

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

Diff for: compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ where
4545
goal,
4646
goal.predicate.alias,
4747
);
48-
this.add_goal(GoalSource::AliasWellFormed, goal.with(cx, trait_ref));
4948
this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
5049
})
5150
})

Diff for: tests/ui/coroutine/higher-ranked-rigid.rs

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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

Comments
 (0)