Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ where
goal,
goal.predicate.alias,
);
this.add_goal(GoalSource::AliasWellFormed, goal.with(cx, trait_ref));
this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
})
Expand Down
41 changes: 41 additions & 0 deletions tests/ui/coroutine/higher-ranked-rigid.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//@ edition: 2024
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
//@ check-pass

// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/177>.
// Coroutines erase all free lifetimes from their interior types, replacing them with higher-
// ranked regions which act as universals, to properly represent the fact that we don't know what
// the value of the region is within the coroutine.
//
// In the future in `from_request`, that means that the `'r` lifetime is being replaced in
// `<T as FromRequest<'r>>::Assoc`, which is in present in the existential bounds of the
// `dyn Future` that it's awaiting. Normalizing this associated type, with its free lifetimes
// replaced, means proving `T: FromRequest<'!0>`, which doesn't hold without constraining the
// `'!0` lifetime, which we don't do today.

// Proving `T: Trait` holds when `<T as Trait>::Assoc` is rigid is not necessary for soundness,
// at least not *yet*, and it's not even necessary for diagnostics since we have other special
// casing for, e.g., AliasRelate goals failing in the BestObligation folder.

// The old solver unintentioanlly avoids this by never checking that `T: Trait` holds when
// `<T as Trait>::Assoc` is rigid. Introducing this additional requirement when projecting rigidly
// in the old solver causes this (and tons of production crates) to fail. See the fallout from the
// crater run at <https://github.com/rust-lang/rust/pull/139763>.

use std::future::Future;
use std::pin::Pin;

pub trait FromRequest<'r> {
type Assoc;
fn from_request() -> Pin<Box<dyn Future<Output = Self::Assoc> + Send>>;
}

fn test<'r, T: FromRequest<'r>>() -> Pin<Box<dyn Future<Output = ()> + Send>> {
Box::pin(async move {
T::from_request().await;
})
}

fn main() {}
Loading