]> git.lizzy.rs Git - rust.git/commitdiff
Make immovable generators unsafe
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>
Fri, 22 Dec 2017 21:12:27 +0000 (22:12 +0100)
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>
Tue, 23 Jan 2018 04:10:38 +0000 (05:10 +0100)
src/librustc_mir/transform/check_unsafety.rs
src/test/run-pass/generator/static-generators.rs
src/test/ui/generator/unsafe-immovable.rs [new file with mode: 0644]
src/test/ui/generator/unsafe-immovable.stderr [new file with mode: 0644]

index e9ba5de3cc6941265982e30811eaf52813ae444f..ae27f54e618a1822c4edaaa5cb397152385db3fa 100644 (file)
@@ -124,13 +124,21 @@ fn visit_rvalue(&mut self,
                 &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);
index daf672942467c7762bf246d4f3d5b4ae8936df49..9504414d8b6f5768e79c3b29716e87e386b5bb80 100644 (file)
 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 (file)
index 0000000..45acbf5
--- /dev/null
@@ -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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 (file)
index 0000000..06e43bf
--- /dev/null
@@ -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
+