Don't normalize higher-ranked assumptions if they're not used

This commit is contained in:
Michael Goulet 2025-10-03 10:32:11 -04:00
parent dd091003ac
commit e3f104608c
3 changed files with 107 additions and 13 deletions

View file

@ -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)

View file

@ -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() {}

View file

@ -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() {}