Mark non-static generators as always Unpin

This commit is contained in:
Wim Looman 2018-11-21 15:32:51 +01:00
parent c4bf5f9d63
commit a21c95f08e
3 changed files with 34 additions and 4 deletions

View File

@ -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())),
}
}

View File

@ -11,7 +11,7 @@ pub fn foo() -> impl Generator<Yield = (), Return = ()> {
}
}
pub fn bar<T: Unpin + 'static>(t: T) -> Box<Generator<Yield = T, Return = ()> + Unpin> {
pub fn bar<T: 'static>(t: T) -> Box<Generator<Yield = T, Return = ()> + Unpin> {
Box::new(|| {
yield t;
})

View File

@ -0,0 +1,18 @@
// run-pass
#![feature(generators, generator_trait)]
use std::marker::{PhantomPinned, Unpin};
fn assert_unpin<G: 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);
});
}