Skip to content

Commit a21c95f

Browse files
committed
Mark non-static generators as always Unpin
1 parent c4bf5f9 commit a21c95f

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

src/librustc/traits/select.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -2017,12 +2017,24 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
20172017
// the auto impl might apply, we don't know
20182018
candidates.ambiguous = true;
20192019
}
2020-
ty::Generator(_, _, hir::GeneratorMovability::Static)
2020+
ty::Generator(_, _, movability)
20212021
if self.tcx().lang_items().unpin_trait() == Some(def_id) =>
20222022
{
2023-
// Immovable generators are never `Unpin`, so suppress the
2024-
// normal auto-impl candidate for it.
2023+
match movability {
2024+
hir::GeneratorMovability::Static => {
2025+
// Immovable generators are never `Unpin`, so
2026+
// suppress the normal auto-impl candidate for it.
2027+
}
2028+
hir::GeneratorMovability::Movable => {
2029+
// Movable generators are always `Unpin`, so add an
2030+
// unconditional builtin candidate.
2031+
candidates.vec.push(BuiltinCandidate {
2032+
has_nested: false,
2033+
});
2034+
}
2035+
}
20252036
}
2037+
20262038
_ => candidates.vec.push(AutoImplCandidate(def_id.clone())),
20272039
}
20282040
}

src/test/run-pass/generator/auxiliary/xcrate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub fn foo() -> impl Generator<Yield = (), Return = ()> {
1111
}
1212
}
1313

14-
pub fn bar<T: Unpin + 'static>(t: T) -> Box<Generator<Yield = T, Return = ()> + Unpin> {
14+
pub fn bar<T: 'static>(t: T) -> Box<Generator<Yield = T, Return = ()> + Unpin> {
1515
Box::new(|| {
1616
yield t;
1717
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// run-pass
2+
3+
#![feature(generators, generator_trait)]
4+
5+
use std::marker::{PhantomPinned, Unpin};
6+
7+
fn assert_unpin<G: Unpin>(_: G) {
8+
}
9+
10+
fn main() {
11+
// Even though this generator holds a `PhantomPinned` in its environment, it
12+
// remains `Unpin`.
13+
assert_unpin(|| {
14+
let pinned = PhantomPinned;
15+
yield;
16+
drop(pinned);
17+
});
18+
}

0 commit comments

Comments
 (0)