about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2025-07-13 21:01:25 +0000
committerMichael Goulet <michael@errs.io>2025-07-15 16:02:26 +0000
commit512cf3ae88b26f50a92ebfcb69c24ca39acd72e6 (patch)
treef8195454815901d9922dc128e68c37abc30cb549
parente3f643c70670a3e1567b0816502ab247565305f8 (diff)
Gate things properly
-rw-r--r--compiler/rustc_borrowck/src/type_check/constraint_conversion.rs4
-rw-r--r--compiler/rustc_infer/src/infer/outlives/mod.rs14
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs7
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--tests/ui/async-await/drop-tracking-unresolved-typeck-results.no_assumptions.stderr25
-rw-r--r--tests/ui/async-await/drop-tracking-unresolved-typeck-results.rs5
-rw-r--r--tests/ui/async-await/return-type-notation/issue-110963-early.no_assumptions.stderr31
-rw-r--r--tests/ui/async-await/return-type-notation/issue-110963-early.rs5
-rw-r--r--tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives-2.no_assumptions.stderr24
-rw-r--r--tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives-2.rs5
-rw-r--r--tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives.no_assumptions.stderr8
-rw-r--r--tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives.rs5
12 files changed, 121 insertions, 14 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
index fec3e415f75..989d2cc70dd 100644
--- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
+++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
@@ -160,7 +160,9 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
             let mut next_outlives_predicates = vec![];
             for (pred, constraint_category) in outlives_predicates {
                 // Constraint is implied by a coroutine's well-formedness.
-                if higher_ranked_assumptions.contains(&pred) {
+                if self.infcx.tcx.sess.opts.unstable_opts.higher_ranked_assumptions
+                    && higher_ranked_assumptions.contains(&pred)
+                {
                     continue;
                 }
 
diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs
index db668032f1f..19911bfbd48 100644
--- a/compiler/rustc_infer/src/infer/outlives/mod.rs
+++ b/compiler/rustc_infer/src/infer/outlives/mod.rs
@@ -69,12 +69,14 @@ impl<'tcx> InferCtxt<'tcx> {
 
         // Filter out any region-region outlives assumptions that are implied by
         // coroutine well-formedness.
-        storage.data.constraints.retain(|(constraint, _)| match *constraint {
-            Constraint::RegSubReg(r1, r2) => !outlives_env
-                .higher_ranked_assumptions()
-                .contains(&ty::OutlivesPredicate(r2.into(), r1)),
-            _ => true,
-        });
+        if self.tcx.sess.opts.unstable_opts.higher_ranked_assumptions {
+            storage.data.constraints.retain(|(constraint, _)| match *constraint {
+                Constraint::RegSubReg(r1, r2) => !outlives_env
+                    .higher_ranked_assumptions()
+                    .contains(&ty::OutlivesPredicate(r2.into(), r1)),
+                _ => true,
+            });
+        }
 
         let region_rels = &RegionRelations::new(self.tcx, outlives_env.free_region_map());
 
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index 2066cdd717e..1ca59c8d130 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -235,9 +235,10 @@ impl<'tcx> InferCtxt<'tcx> {
                 let (sup_type, sub_region) =
                     (sup_type, sub_region).fold_with(&mut OpportunisticRegionResolver::new(self));
 
-                if outlives_env
-                    .higher_ranked_assumptions()
-                    .contains(&ty::OutlivesPredicate(sup_type.into(), sub_region))
+                if self.tcx.sess.opts.unstable_opts.higher_ranked_assumptions
+                    && outlives_env
+                        .higher_ranked_assumptions()
+                        .contains(&ty::OutlivesPredicate(sup_type.into(), sub_region))
                 {
                     continue;
                 }
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 626262c8442..2bdde2f887a 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -2256,6 +2256,8 @@ options! {
         environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)"),
     has_thread_local: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "explicitly enable the `cfg(target_thread_local)` directive"),
+    higher_ranked_assumptions: bool = (false, parse_bool, [TRACKED],
+        "allow deducing higher-ranked outlives assumptions from coroutines when proving auto traits"),
     hint_mostly_unused: bool = (false, parse_bool, [TRACKED],
         "hint that most of this crate will go unused, to minimize work for uncalled functions"),
     human_readable_cgu_names: bool = (false, parse_bool, [TRACKED],
diff --git a/tests/ui/async-await/drop-tracking-unresolved-typeck-results.no_assumptions.stderr b/tests/ui/async-await/drop-tracking-unresolved-typeck-results.no_assumptions.stderr
new file mode 100644
index 00000000000..d5560bf8920
--- /dev/null
+++ b/tests/ui/async-await/drop-tracking-unresolved-typeck-results.no_assumptions.stderr
@@ -0,0 +1,25 @@
+error: implementation of `FnOnce` is not general enough
+  --> $DIR/drop-tracking-unresolved-typeck-results.rs:102:5
+   |
+LL | /     send(async {
+LL | |         Next(&Buffered(Map(Empty(PhantomData), ready::<&()>), FuturesOrdered(PhantomData), 0)).await
+LL | |     });
+   | |______^ implementation of `FnOnce` is not general enough
+   |
+   = note: `fn(&'0 ()) -> std::future::Ready<&'0 ()> {std::future::ready::<&'0 ()>}` must implement `FnOnce<(&'1 (),)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `FnOnce<(&(),)>`
+
+error: implementation of `FnOnce` is not general enough
+  --> $DIR/drop-tracking-unresolved-typeck-results.rs:102:5
+   |
+LL | /     send(async {
+LL | |         Next(&Buffered(Map(Empty(PhantomData), ready::<&()>), FuturesOrdered(PhantomData), 0)).await
+LL | |     });
+   | |______^ implementation of `FnOnce` is not general enough
+   |
+   = note: `fn(&'0 ()) -> std::future::Ready<&'0 ()> {std::future::ready::<&'0 ()>}` must implement `FnOnce<(&'1 (),)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `FnOnce<(&(),)>`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/async-await/drop-tracking-unresolved-typeck-results.rs b/tests/ui/async-await/drop-tracking-unresolved-typeck-results.rs
index 51945e02352..16f929331cb 100644
--- a/tests/ui/async-await/drop-tracking-unresolved-typeck-results.rs
+++ b/tests/ui/async-await/drop-tracking-unresolved-typeck-results.rs
@@ -1,6 +1,9 @@
 //@ incremental
 //@ edition: 2021
-//@ check-pass
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] check-pass
+//@[no_assumptions] known-bug: #110338
 
 use std::future::*;
 use std::marker::PhantomData;
diff --git a/tests/ui/async-await/return-type-notation/issue-110963-early.no_assumptions.stderr b/tests/ui/async-await/return-type-notation/issue-110963-early.no_assumptions.stderr
new file mode 100644
index 00000000000..bb436364924
--- /dev/null
+++ b/tests/ui/async-await/return-type-notation/issue-110963-early.no_assumptions.stderr
@@ -0,0 +1,31 @@
+error: implementation of `Send` is not general enough
+  --> $DIR/issue-110963-early.rs:17:5
+   |
+LL | /     spawn(async move {
+LL | |         let mut hc = hc;
+LL | |         if !hc.check().await {
+LL | |             log_health_check_failure().await;
+LL | |         }
+LL | |     });
+   | |______^ implementation of `Send` is not general enough
+   |
+   = note: `Send` would have to be implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'0>(..) }`, for any two lifetimes `'0` and `'1`...
+   = note: ...but `Send` is actually implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'2>(..) }`, for some specific lifetime `'2`
+
+error: implementation of `Send` is not general enough
+  --> $DIR/issue-110963-early.rs:17:5
+   |
+LL | /     spawn(async move {
+LL | |         let mut hc = hc;
+LL | |         if !hc.check().await {
+LL | |             log_health_check_failure().await;
+LL | |         }
+LL | |     });
+   | |______^ implementation of `Send` is not general enough
+   |
+   = note: `Send` would have to be implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'0>(..) }`, for any two lifetimes `'0` and `'1`...
+   = note: ...but `Send` is actually implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'2>(..) }`, for some specific lifetime `'2`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/async-await/return-type-notation/issue-110963-early.rs b/tests/ui/async-await/return-type-notation/issue-110963-early.rs
index 7985f2e2de1..8c3180c0119 100644
--- a/tests/ui/async-await/return-type-notation/issue-110963-early.rs
+++ b/tests/ui/async-await/return-type-notation/issue-110963-early.rs
@@ -1,5 +1,8 @@
 //@ edition: 2021
-//@ check-pass
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] check-pass
+//@[no_assumptions] known-bug: #110338
 
 #![feature(return_type_notation)]
 
diff --git a/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives-2.no_assumptions.stderr b/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives-2.no_assumptions.stderr
new file mode 100644
index 00000000000..8b62fb6a254
--- /dev/null
+++ b/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives-2.no_assumptions.stderr
@@ -0,0 +1,24 @@
+error: lifetime bound not satisfied
+  --> $DIR/higher-ranked-coroutine-param-outlives-2.rs:14:5
+   |
+LL | /     async { // a coroutine checked for autotrait impl `Send`
+LL | |         let x = None::<I::Future<'_, '_>>; // a type referencing GAT
+LL | |         async {}.await; // a yield point
+LL | |     }
+   | |_____^
+   |
+   = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
+
+error: lifetime bound not satisfied
+  --> $DIR/higher-ranked-coroutine-param-outlives-2.rs:21:5
+   |
+LL | /     async { // a coroutine checked for autotrait impl `Send`
+LL | |         let x = None::<I::Future<'a, 'b>>; // a type referencing GAT
+LL | |         async {}.await; // a yield point
+LL | |     }
+   | |_____^
+   |
+   = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives-2.rs b/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives-2.rs
index f7762600165..a5ed162d62c 100644
--- a/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives-2.rs
+++ b/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives-2.rs
@@ -1,5 +1,8 @@
-//@ check-pass
 //@ edition: 2021
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] check-pass
+//@[no_assumptions] known-bug: #110338
 
 pub trait FutureIterator {
     type Future<'s, 'cx>: Send
diff --git a/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives.no_assumptions.stderr b/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives.no_assumptions.stderr
new file mode 100644
index 00000000000..f747ba9a733
--- /dev/null
+++ b/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives.no_assumptions.stderr
@@ -0,0 +1,8 @@
+error: `C` does not live long enough
+  --> $DIR/higher-ranked-coroutine-param-outlives.rs:21:5
+   |
+LL |     async move { c.connect().await }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives.rs b/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives.rs
index 33a085ad26b..5f683bd82fa 100644
--- a/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives.rs
+++ b/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives.rs
@@ -1,5 +1,8 @@
 //@ edition:2018
-//@ check-pass
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] check-pass
+//@[no_assumptions] known-bug: #110338
 
 use std::future::Future;