diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index e9ba5de3cc69..ae27f54e618a 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -124,13 +124,21 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { &AggregateKind::Array(..) | &AggregateKind::Tuple | &AggregateKind::Adt(..) => {} - &AggregateKind::Closure(def_id, _) | - &AggregateKind::Generator(def_id, _, _) => { + &AggregateKind::Closure(def_id, _) => { let UnsafetyCheckResult { violations, unsafe_blocks } = self.tcx.unsafety_check_result(def_id); self.register_violations(&violations, &unsafe_blocks); } + &AggregateKind::Generator(def_id, _, interior) => { + let UnsafetyCheckResult { + violations, unsafe_blocks + } = self.tcx.unsafety_check_result(def_id); + self.register_violations(&violations, &unsafe_blocks); + if !interior.movable { + self.require_unsafe("construction of immovable generator") + } + } } } self.super_rvalue(rvalue, location); diff --git a/src/test/run-pass/generator/static-generators.rs b/src/test/run-pass/generator/static-generators.rs index daf672942467..9504414d8b6f 100644 --- a/src/test/run-pass/generator/static-generators.rs +++ b/src/test/run-pass/generator/static-generators.rs @@ -13,12 +13,14 @@ use std::ops::{Generator, GeneratorState}; fn main() { - let mut generator = static || { - let a = true; - let b = &a; - yield; - assert_eq!(b as *const _, &a as *const _); + let mut generator = unsafe { + static || { + let a = true; + let b = &a; + yield; + assert_eq!(b as *const _, &a as *const _); + } }; assert_eq!(generator.resume(), GeneratorState::Yielded(())); assert_eq!(generator.resume(), GeneratorState::Complete(())); -} \ No newline at end of file +} diff --git a/src/test/ui/generator/unsafe-immovable.rs b/src/test/ui/generator/unsafe-immovable.rs new file mode 100644 index 000000000000..45acbf50931b --- /dev/null +++ b/src/test/ui/generator/unsafe-immovable.rs @@ -0,0 +1,17 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators)] + +fn main() { + static || { //~ ERROR: construction of immovable generator requires unsafe + yield; + }; +} diff --git a/src/test/ui/generator/unsafe-immovable.stderr b/src/test/ui/generator/unsafe-immovable.stderr new file mode 100644 index 000000000000..06e43bf35e1f --- /dev/null +++ b/src/test/ui/generator/unsafe-immovable.stderr @@ -0,0 +1,10 @@ +error[E0133]: construction of immovable generator requires unsafe function or block + --> $DIR/unsafe-immovable.rs:14:5 + | +14 | / static || { //~ ERROR: construction of immovable generator requires unsafe +15 | | yield; +16 | | }; + | |_____^ construction of immovable generator + +error: aborting due to previous error +