Skip to content

Commit 7950f24

Browse files
committed
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 #147244 Fixes #147285
2 parents 595b9a4 + e3f1046 commit 7950f24

File tree

3 files changed

+107
-13
lines changed

3 files changed

+107
-13
lines changed

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -423,19 +423,24 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
423423
constituents.types,
424424
);
425425

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

441446
Ok(obligations)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//@ revisions: stock hr
2+
//@[hr] compile-flags: -Zhigher-ranked-assumptions
3+
//@ edition: 2024
4+
//@ check-pass
5+
6+
// Test that we don't normalize the higher-ranked assumptions of an auto trait goal
7+
// unless we have `-Zhigher-ranked-assumptions`, since obligations that result from
8+
// this normalization may lead to higher-ranked lifetime errors when the flag is not
9+
// enabled.
10+
11+
// Regression test for <https://github.com/rust-lang/rust/issues/147244>.
12+
13+
pub fn a() -> impl Future + Send {
14+
async {
15+
let queries = core::iter::empty().map(Thing::f);
16+
b(queries).await;
17+
}
18+
}
19+
20+
async fn b(queries: impl IntoIterator) {
21+
c(queries).await;
22+
}
23+
24+
fn c<'a, I>(_queries: I) -> impl Future
25+
where
26+
I: IntoIterator,
27+
I::IntoIter: 'a,
28+
{
29+
async {}
30+
}
31+
32+
pub struct Thing<'a>(pub &'a ());
33+
34+
impl Thing<'_> {
35+
fn f(_: &Self) {}
36+
}
37+
38+
fn main() {}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//@ revisions: stock hr
2+
//@[hr] compile-flags: -Zhigher-ranked-assumptions
3+
//@ edition: 2024
4+
//@ check-pass
5+
6+
// Test that we don't normalize the higher-ranked assumptions of an auto trait goal
7+
// unless we have `-Zhigher-ranked-assumptions`, since obligations that result from
8+
// this normalization may lead to higher-ranked lifetime errors when the flag is not
9+
// enabled.
10+
11+
// Regression test for <https://github.com/rust-lang/rust/issues/147285>.
12+
13+
pub trait Service {
14+
type Response;
15+
}
16+
17+
impl<T, R> Service for T
18+
where
19+
T: FnMut() -> R,
20+
R: 'static,
21+
{
22+
type Response = R;
23+
}
24+
25+
async fn serve<C>(_: C)
26+
where
27+
C: Service,
28+
C::Response: 'static,
29+
{
30+
connect::<C>().await;
31+
}
32+
33+
async fn connect<C>()
34+
where
35+
C: Service,
36+
C::Response: 'static,
37+
{
38+
}
39+
40+
fn repro() -> impl Send {
41+
async {
42+
let server = || do_something();
43+
serve(server).await;
44+
}
45+
}
46+
47+
fn do_something() -> Box<dyn std::error::Error> {
48+
unimplemented!()
49+
}
50+
51+
fn main() {}

0 commit comments

Comments
 (0)