Skip to content

Commit

Permalink
Mark non-static generators as always Unpin
Browse files Browse the repository at this point in the history
  • Loading branch information
Nemo157 committed Jan 27, 2019
1 parent c4bf5f9 commit a21c95f
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 4 deletions.
18 changes: 15 additions & 3 deletions src/librustc/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())),
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/run-pass/generator/auxiliary/xcrate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
})
Expand Down
18 changes: 18 additions & 0 deletions src/test/run-pass/generator/non-static-is-unpin.rs
Original file line number Diff line number Diff line change
@@ -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);
});
}

0 comments on commit a21c95f

Please sign in to comment.