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
31 changes: 18 additions & 13 deletions compiler/rustc_trait_selection/src/traits/select/confirmation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,19 +423,24 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
constituents.types,
);

// FIXME(coroutine_clone): We could uplift this into `collect_predicates_for_types`
// and do this for `Copy`/`Clone` too, but that's feature-gated so it doesn't really
// matter yet.
for assumption in constituents.assumptions {
let assumption = normalize_with_depth_to(
self,
obligation.param_env,
cause.clone(),
obligation.recursion_depth + 1,
assumption,
&mut obligations,
);
self.infcx.register_region_assumption(assumption);
// Only normalize these goals if `-Zhigher-ranked-assumptions` is enabled, since
// we don't want to cause ourselves to do extra work if we're not even able to
// take advantage of these assumption clauses.
if self.tcx().sess.opts.unstable_opts.higher_ranked_assumptions {
// FIXME(coroutine_clone): We could uplift this into `collect_predicates_for_types`
// and do this for `Copy`/`Clone` too, but that's feature-gated so it doesn't really
// matter yet.
for assumption in constituents.assumptions {
let assumption = normalize_with_depth_to(
self,
obligation.param_env,
cause.clone(),
obligation.recursion_depth + 1,
assumption,
&mut obligations,
);
self.infcx.register_region_assumption(assumption);
}
}

Ok(obligations)
Expand Down
38 changes: 38 additions & 0 deletions tests/ui/async-await/higher-ranked-normalize-assumptions-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//@ revisions: stock hr
//@[hr] compile-flags: -Zhigher-ranked-assumptions
//@ edition: 2024
//@ check-pass

// Test that we don't normalize the higher-ranked assumptions of an auto trait goal
// unless we have `-Zhigher-ranked-assumptions`, since obligations that result from
// this normalization may lead to higher-ranked lifetime errors when the flag is not
// enabled.

// Regression test for <https://github.com/rust-lang/rust/issues/147244>.

pub fn a() -> impl Future + Send {
async {
let queries = core::iter::empty().map(Thing::f);
b(queries).await;
}
}

async fn b(queries: impl IntoIterator) {
c(queries).await;
}

fn c<'a, I>(_queries: I) -> impl Future
where
I: IntoIterator,
I::IntoIter: 'a,
{
async {}
}

pub struct Thing<'a>(pub &'a ());

impl Thing<'_> {
fn f(_: &Self) {}
}

fn main() {}
51 changes: 51 additions & 0 deletions tests/ui/async-await/higher-ranked-normalize-assumptions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//@ revisions: stock hr
//@[hr] compile-flags: -Zhigher-ranked-assumptions
//@ edition: 2024
//@ check-pass

// Test that we don't normalize the higher-ranked assumptions of an auto trait goal
// unless we have `-Zhigher-ranked-assumptions`, since obligations that result from
// this normalization may lead to higher-ranked lifetime errors when the flag is not
// enabled.

// Regression test for <https://github.com/rust-lang/rust/issues/147285>.

pub trait Service {
type Response;
}

impl<T, R> Service for T
where
T: FnMut() -> R,
R: 'static,
{
type Response = R;
}

async fn serve<C>(_: C)
where
C: Service,
C::Response: 'static,
{
connect::<C>().await;
}

async fn connect<C>()
where
C: Service,
C::Response: 'static,
{
}

fn repro() -> impl Send {
async {
let server = || do_something();
serve(server).await;
}
}

fn do_something() -> Box<dyn std::error::Error> {
unimplemented!()
}

fn main() {}
Loading