Don't normalize higher-ranked assumptions if they're not used
(cherry picked from commit e3f104608c)
This commit is contained in:
parent
21cd82aa63
commit
91163a9e1e
3 changed files with 107 additions and 13 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
tests/ui/async-await/higher-ranked-normalize-assumptions.rs
Normal file
51
tests/ui/async-await/higher-ranked-normalize-assumptions.rs
Normal 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() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue