diff options
author | bors <bors@rust-lang.org> | 2025-10-04 00:02:26 +0000 |
---|---|---|
committer | bors <bors@rust-lang.org> | 2025-10-04 00:02:26 +0000 |
commit | 7950f244e7ef55b61a83d12f4662be643cd182d6 (patch) | |
tree | 6f741b4059ce1061d04ffa47c43658535c62b6f3 | |
parent | 595b9a498bc55fcd30111e430d8e4290ed833b4c (diff) | |
parent | e3f104608c0ad26e80b1ebedef2ab8a748189e52 (diff) | |
download | rust-7950f244e7ef55b61a83d12f4662be643cd182d6.tar.gz rust-7950f244e7ef55b61a83d12f4662be643cd182d6.zip |
Auto merge of #147299 - compiler-errors:hr-norm, r=jackh726
Don't normalize higher-ranked assumptions if they're not used See the comment in the code. Normalizing these assumptions may cause us to register things like new placeholder outlives obligations that cause higher-ranked lifetime errors, and this is problematic if we're not even using these assumptions in borrowck. Fixes rust-lang/rust#147244 Fixes rust-lang/rust#147285
3 files changed, 107 insertions, 13 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 7ad65a1df8e..708a53f6c65 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -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) diff --git a/tests/ui/async-await/higher-ranked-normalize-assumptions-2.rs b/tests/ui/async-await/higher-ranked-normalize-assumptions-2.rs new file mode 100644 index 00000000000..410d4e503b7 --- /dev/null +++ b/tests/ui/async-await/higher-ranked-normalize-assumptions-2.rs @@ -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() {} diff --git a/tests/ui/async-await/higher-ranked-normalize-assumptions.rs b/tests/ui/async-await/higher-ranked-normalize-assumptions.rs new file mode 100644 index 00000000000..ec9cf3a1522 --- /dev/null +++ b/tests/ui/async-await/higher-ranked-normalize-assumptions.rs @@ -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() {} |