about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-04-11 21:15:39 +0000
committerMichael Goulet <michael@errs.io>2023-04-14 03:13:56 +0000
commitb335c2d49f1698ada99e3622d3cd482c27c9fc9b (patch)
tree86599bb811efc618bf26f829b8717d1ccb1609fb
parenta41fc00eaf352541008965fec0dee811e44373b3 (diff)
downloadrust-b335c2d49f1698ada99e3622d3cd482c27c9fc9b.tar.gz
rust-b335c2d49f1698ada99e3622d3cd482c27c9fc9b.zip
Assemble Unpin candidates specially for generators in new solver
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs19
-rw-r--r--tests/ui/generator/non-static-is-unpin.rs2
-rw-r--r--tests/ui/generator/static-not-unpin.current.stderr (renamed from tests/ui/generator/static-not-unpin.stderr)8
-rw-r--r--tests/ui/generator/static-not-unpin.next.stderr19
-rw-r--r--tests/ui/generator/static-not-unpin.rs3
5 files changed, 46 insertions, 5 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index 716d5acb324..73c599e1814 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -3,7 +3,7 @@
 use super::assembly::{self, structural_traits};
 use super::{EvalCtxt, SolverMode};
 use rustc_hir::def_id::DefId;
-use rustc_hir::LangItem;
+use rustc_hir::{LangItem, Movability};
 use rustc_infer::traits::query::NoSolution;
 use rustc_infer::traits::util::supertraits;
 use rustc_middle::traits::solve::{CanonicalResponse, Certainty, Goal, QueryResult};
@@ -168,6 +168,23 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
 
             ty::Infer(_) | ty::Bound(_, _) => bug!("unexpected type `{self_ty}`"),
 
+            // Generators have one special built-in candidate, `Unpin`, which
+            // takes precedence over the structural auto trait candidate being
+            // assembled.
+            ty::Generator(_, _, movability)
+                if Some(goal.predicate.def_id()) == ecx.tcx().lang_items().unpin_trait() =>
+            {
+                match movability {
+                    Movability::Static => {
+                        return Err(NoSolution);
+                    }
+                    Movability::Movable => {
+                        return ecx
+                            .evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
+                    }
+                }
+            }
+
             // For rigid types, we only register a builtin auto implementation
             // if there is no implementation that could ever apply to the self
             // type.
diff --git a/tests/ui/generator/non-static-is-unpin.rs b/tests/ui/generator/non-static-is-unpin.rs
index 96d0a8e2833..17e23f5bcd2 100644
--- a/tests/ui/generator/non-static-is-unpin.rs
+++ b/tests/ui/generator/non-static-is-unpin.rs
@@ -1,3 +1,5 @@
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
 // run-pass
 
 #![feature(generators, generator_trait)]
diff --git a/tests/ui/generator/static-not-unpin.stderr b/tests/ui/generator/static-not-unpin.current.stderr
index 7376116b338..ecd8ca60c6f 100644
--- a/tests/ui/generator/static-not-unpin.stderr
+++ b/tests/ui/generator/static-not-unpin.current.stderr
@@ -1,15 +1,15 @@
-error[E0277]: `[static generator@$DIR/static-not-unpin.rs:11:25: 11:34]` cannot be unpinned
-  --> $DIR/static-not-unpin.rs:14:18
+error[E0277]: `[static generator@$DIR/static-not-unpin.rs:14:25: 14:34]` cannot be unpinned
+  --> $DIR/static-not-unpin.rs:17:18
    |
 LL |     assert_unpin(generator);
-   |     ------------ ^^^^^^^^^ the trait `Unpin` is not implemented for `[static generator@$DIR/static-not-unpin.rs:11:25: 11:34]`
+   |     ------------ ^^^^^^^^^ the trait `Unpin` is not implemented for `[static generator@$DIR/static-not-unpin.rs:14:25: 14:34]`
    |     |
    |     required by a bound introduced by this call
    |
    = note: consider using the `pin!` macro
            consider using `Box::pin` if you need to access the pinned value outside of the current scope
 note: required by a bound in `assert_unpin`
-  --> $DIR/static-not-unpin.rs:7:20
+  --> $DIR/static-not-unpin.rs:10:20
    |
 LL | fn assert_unpin<T: Unpin>(_: T) {
    |                    ^^^^^ required by this bound in `assert_unpin`
diff --git a/tests/ui/generator/static-not-unpin.next.stderr b/tests/ui/generator/static-not-unpin.next.stderr
new file mode 100644
index 00000000000..ecd8ca60c6f
--- /dev/null
+++ b/tests/ui/generator/static-not-unpin.next.stderr
@@ -0,0 +1,19 @@
+error[E0277]: `[static generator@$DIR/static-not-unpin.rs:14:25: 14:34]` cannot be unpinned
+  --> $DIR/static-not-unpin.rs:17:18
+   |
+LL |     assert_unpin(generator);
+   |     ------------ ^^^^^^^^^ the trait `Unpin` is not implemented for `[static generator@$DIR/static-not-unpin.rs:14:25: 14:34]`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = note: consider using the `pin!` macro
+           consider using `Box::pin` if you need to access the pinned value outside of the current scope
+note: required by a bound in `assert_unpin`
+  --> $DIR/static-not-unpin.rs:10:20
+   |
+LL | fn assert_unpin<T: Unpin>(_: T) {
+   |                    ^^^^^ required by this bound in `assert_unpin`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generator/static-not-unpin.rs b/tests/ui/generator/static-not-unpin.rs
index cfcb94737be..30d3f291870 100644
--- a/tests/ui/generator/static-not-unpin.rs
+++ b/tests/ui/generator/static-not-unpin.rs
@@ -1,3 +1,6 @@
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
+
 #![feature(generators)]
 
 // normalize-stderr-test "std::pin::Unpin" -> "std::marker::Unpin"