Mark non-static generators as always Unpin
This commit is contained in:
parent
c4bf5f9d63
commit
a21c95f08e
@ -2017,12 +2017,24 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
// the auto impl might apply, we don't know
|
// the auto impl might apply, we don't know
|
||||||
candidates.ambiguous = true;
|
candidates.ambiguous = true;
|
||||||
}
|
}
|
||||||
ty::Generator(_, _, hir::GeneratorMovability::Static)
|
ty::Generator(_, _, movability)
|
||||||
if self.tcx().lang_items().unpin_trait() == Some(def_id) =>
|
if self.tcx().lang_items().unpin_trait() == Some(def_id) =>
|
||||||
{
|
{
|
||||||
// Immovable generators are never `Unpin`, so suppress the
|
match movability {
|
||||||
// normal auto-impl candidate for it.
|
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())),
|
_ => candidates.vec.push(AutoImplCandidate(def_id.clone())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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(|| {
|
Box::new(|| {
|
||||||
yield t;
|
yield t;
|
||||||
})
|
})
|
||||||
|
18
src/test/run-pass/generator/non-static-is-unpin.rs
Normal file
18
src/test/run-pass/generator/non-static-is-unpin.rs
Normal 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);
|
||||||
|
});
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user