about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs4
-rw-r--r--tests/ui/traits/unsend-future.rs21
-rw-r--r--tests/ui/traits/unsend-future.stderr24
3 files changed, 47 insertions, 2 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index cd3f3c114ba..48c3b3601b4 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1083,7 +1083,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     let mut nested_result = EvaluationResult::EvaluatedToOk;
                     for obligation in nested_obligations {
                         nested_result = cmp::max(
-                            this.evaluate_predicate_recursively(stack.list(), obligation)?,
+                            this.evaluate_predicate_recursively(previous_stack, obligation)?,
                             nested_result,
                         );
                     }
@@ -1092,7 +1092,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                         let obligation = obligation.with(this.tcx(), predicate);
                         result = cmp::max(
                             nested_result,
-                            this.evaluate_trait_predicate_recursively(stack.list(), obligation)?,
+                            this.evaluate_trait_predicate_recursively(previous_stack, obligation)?,
                         );
                     }
                 }
diff --git a/tests/ui/traits/unsend-future.rs b/tests/ui/traits/unsend-future.rs
new file mode 100644
index 00000000000..fbbc07b11e7
--- /dev/null
+++ b/tests/ui/traits/unsend-future.rs
@@ -0,0 +1,21 @@
+// edition:2021
+
+// issue 108897
+trait Handler {}
+impl<F, Fut> Handler for F
+where
+    Fut: Send,
+    F: FnOnce() -> Fut,
+{}
+
+fn require_handler<H: Handler>(h: H) {}
+
+async fn handler() {
+    let a = &1 as *const i32;
+    async {}.await;
+}
+
+fn main() {
+    require_handler(handler)
+     //~^ ERROR future cannot be sent between threads safely
+}
diff --git a/tests/ui/traits/unsend-future.stderr b/tests/ui/traits/unsend-future.stderr
new file mode 100644
index 00000000000..4aaa7c4a924
--- /dev/null
+++ b/tests/ui/traits/unsend-future.stderr
@@ -0,0 +1,24 @@
+error: future cannot be sent between threads safely
+  --> $DIR/unsend-future.rs:19:21
+   |
+LL |     require_handler(handler)
+   |                     ^^^^^^^ future returned by `handler` is not `Send`
+   |
+   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `*const i32`
+note: future is not `Send` as this value is used across an await
+  --> $DIR/unsend-future.rs:15:13
+   |
+LL |     let a = &1 as *const i32;
+   |         - has type `*const i32` which is not `Send`
+LL |     async {}.await;
+   |             ^^^^^^ await occurs here, with `a` maybe used later
+LL | }
+   | - `a` is later dropped here
+note: required by a bound in `require_handler`
+  --> $DIR/unsend-future.rs:11:23
+   |
+LL | fn require_handler<H: Handler>(h: H) {}
+   |                       ^^^^^^^ required by this bound in `require_handler`
+
+error: aborting due to previous error
+