Rollup merge of #49194 - Zoxc:unsafe-generator, r=cramertj

Make resuming generators unsafe instead of the creation of immovable generators

cc @withoutboats

Fixes #47787
This commit is contained in:
kennytm 2018-03-25 01:26:34 +08:00 committed by GitHub
commit e2b89221f1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 96 additions and 124 deletions

View file

@ -15,7 +15,7 @@ use std::ops::Generator;
fn main() {
let _b = {
let a = 3;
(|| yield &a).resume()
unsafe { (|| yield &a).resume() }
//~^ ERROR: `a` does not live long enough
};

View file

@ -1,10 +1,10 @@
error[E0597]: `a` does not live long enough
--> $DIR/borrowing.rs:18:20
--> $DIR/borrowing.rs:18:29
|
LL | (|| yield &a).resume()
| -- ^ borrowed value does not live long enough
| |
| capture occurs here
LL | unsafe { (|| yield &a).resume() }
| -- ^ borrowed value does not live long enough
| |
| capture occurs here
LL | //~^ ERROR: `a` does not live long enough
LL | };
| - borrowed value only lives until here

View file

@ -23,6 +23,6 @@ fn main() {
let _d = ref_.take(); //~ ERROR `ref_` does not live long enough
yield;
};
gen.resume();
unsafe { gen.resume(); }
// drops the RefCell and then the Ref, leading to use-after-free
}

View file

@ -17,5 +17,5 @@ fn main() {
let mut gen = move || { //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
yield s[..];
};
gen.resume(); //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
unsafe { gen.resume(); } //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
}

View file

@ -11,10 +11,10 @@ LL | | };
= note: the yield type of a generator must have a statically known size
error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
--> $DIR/sized-yield.rs:20:8
--> $DIR/sized-yield.rs:20:17
|
LL | gen.resume(); //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
| ^^^^^^ `str` does not have a constant size known at compile-time
LL | unsafe { gen.resume(); } //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
| ^^^^^^ `str` does not have a constant size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `str`

View file

@ -1,17 +0,0 @@
// 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;
};
}

View file

@ -1,11 +0,0 @@
error[E0133]: construction of immovable generator requires unsafe function or block
--> $DIR/unsafe-immovable.rs:14:5
|
LL | / static || { //~ ERROR: construction of immovable generator requires unsafe
LL | | yield;
LL | | };
| |_____^ construction of immovable generator
error: aborting due to previous error
For more information about this error, try `rustc --explain E0133`.

View file

@ -43,7 +43,7 @@ fn yield_during_iter_borrowed_slice_2() {
println!("{:?}", x);
}
fn yield_during_iter_borrowed_slice_3() {
unsafe fn yield_during_iter_borrowed_slice_3() {
// OK to take a mutable ref to `x` and yield
// up pointers from it:
let mut x = vec![22_i32];
@ -55,7 +55,7 @@ fn yield_during_iter_borrowed_slice_3() {
b.resume();
}
fn yield_during_iter_borrowed_slice_4() {
unsafe fn yield_during_iter_borrowed_slice_4() {
// ...but not OK to do that while reading
// from `x` too
let mut x = vec![22_i32];
@ -68,7 +68,7 @@ fn yield_during_iter_borrowed_slice_4() {
b.resume();
}
fn yield_during_range_iter() {
unsafe fn yield_during_range_iter() {
// Should be OK.
let mut b = || {
let v = vec![1,2,3];

View file

@ -15,7 +15,7 @@
use std::ops::{GeneratorState, Generator};
use std::cell::Cell;
fn borrow_local_inline() {
unsafe fn borrow_local_inline() {
// Not OK to yield with a borrow of a temporary.
//
// (This error occurs because the region shows up in the type of
@ -30,7 +30,7 @@ fn borrow_local_inline() {
b.resume();
}
fn borrow_local_inline_done() {
unsafe fn borrow_local_inline_done() {
// No error here -- `a` is not in scope at the point of `yield`.
let mut b = move || {
{
@ -41,7 +41,7 @@ fn borrow_local_inline_done() {
b.resume();
}
fn borrow_local() {
unsafe fn borrow_local() {
// Not OK to yield with a borrow of a temporary.
//
// (This error occurs because the region shows up in the type of

View file

@ -13,7 +13,7 @@
use std::ops::{GeneratorState, Generator};
use std::cell::Cell;
fn reborrow_shared_ref(x: &i32) {
unsafe fn reborrow_shared_ref(x: &i32) {
// This is OK -- we have a borrow live over the yield, but it's of
// data that outlives the generator.
let mut b = move || {
@ -24,7 +24,7 @@ fn reborrow_shared_ref(x: &i32) {
b.resume();
}
fn reborrow_mutable_ref(x: &mut i32) {
unsafe fn reborrow_mutable_ref(x: &mut i32) {
// This is OK -- we have a borrow live over the yield, but it's of
// data that outlives the generator.
let mut b = move || {
@ -35,7 +35,7 @@ fn reborrow_mutable_ref(x: &mut i32) {
b.resume();
}
fn reborrow_mutable_ref_2(x: &mut i32) {
unsafe fn reborrow_mutable_ref_2(x: &mut i32) {
// ...but not OK to go on using `x`.
let mut b = || {
let a = &mut *x;