From a21c95f08e37a2e609a0cb523eb9c132d8c341f3 Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Wed, 21 Nov 2018 15:32:51 +0100 Subject: [PATCH] Mark non-static generators as always Unpin --- src/librustc/traits/select.rs | 18 +++++++++++++++--- .../run-pass/generator/auxiliary/xcrate.rs | 2 +- .../run-pass/generator/non-static-is-unpin.rs | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 src/test/run-pass/generator/non-static-is-unpin.rs diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 7a244b7e80e6a..6fe4a7a52be86 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2017,12 +2017,24 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // the auto impl might apply, we don't know candidates.ambiguous = true; } - ty::Generator(_, _, hir::GeneratorMovability::Static) + ty::Generator(_, _, movability) if self.tcx().lang_items().unpin_trait() == Some(def_id) => { - // Immovable generators are never `Unpin`, so suppress the - // normal auto-impl candidate for it. + match movability { + hir::GeneratorMovability::Static => { + // Immovable generators are never `Unpin`, so + // suppress the normal auto-impl candidate for it. + } + hir::GeneratorMovability::Movable => { + // Movable generators are always `Unpin`, so add an + // unconditional builtin candidate. + candidates.vec.push(BuiltinCandidate { + has_nested: false, + }); + } + } } + _ => candidates.vec.push(AutoImplCandidate(def_id.clone())), } } diff --git a/src/test/run-pass/generator/auxiliary/xcrate.rs b/src/test/run-pass/generator/auxiliary/xcrate.rs index 831c248bf909c..613c495832f00 100644 --- a/src/test/run-pass/generator/auxiliary/xcrate.rs +++ b/src/test/run-pass/generator/auxiliary/xcrate.rs @@ -11,7 +11,7 @@ pub fn foo() -> impl Generator { } } -pub fn bar(t: T) -> Box + Unpin> { +pub fn bar(t: T) -> Box + Unpin> { Box::new(|| { yield t; }) diff --git a/src/test/run-pass/generator/non-static-is-unpin.rs b/src/test/run-pass/generator/non-static-is-unpin.rs new file mode 100644 index 0000000000000..96d0a8e283372 --- /dev/null +++ b/src/test/run-pass/generator/non-static-is-unpin.rs @@ -0,0 +1,18 @@ +// run-pass + +#![feature(generators, generator_trait)] + +use std::marker::{PhantomPinned, Unpin}; + +fn assert_unpin(_: G) { +} + +fn main() { + // Even though this generator holds a `PhantomPinned` in its environment, it + // remains `Unpin`. + assert_unpin(|| { + let pinned = PhantomPinned; + yield; + drop(pinned); + }); +}