Skip to content

Commit

Permalink
Auto merge of #3132 - rust-lang:rustup-2023-10-21, r=RalfJung
Browse files Browse the repository at this point in the history
Automatic Rustup
  • Loading branch information
bors committed Oct 21, 2023
2 parents a2533ed + b3b6023 commit 87ce1b1
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 100 deletions.
2 changes: 1 addition & 1 deletion rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
029d00c4a3176a705e0092de3e1739f8b7c32010
249624b5043013d18c00f0401ca431c1a6baa8cd
2 changes: 1 addition & 1 deletion src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
// `Variants::Multiple`.
match v.layout.variants {
Variants::Multiple { .. } => {
// A multi-variant enum, or generator, or so.
// A multi-variant enum, or coroutine, or so.
// Treat this like a union: without reading from memory,
// we cannot determine the variant we are in. Reading from
// memory would be subject to Stacked Borrows rules, leading
Expand Down
46 changes: 46 additions & 0 deletions tests/fail/coroutine-pinned-moved.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows
#![feature(coroutines, coroutine_trait)]

use std::{
ops::{Coroutine, CoroutineState},
pin::Pin,
};

fn firstn() -> impl Coroutine<Yield = u64, Return = ()> {
static move || {
let mut num = 0;
let num = &mut num;
*num += 0;

yield *num;
*num += 1; //~ERROR: has been freed
}
}

struct CoroutineIteratorAdapter<G>(G);

impl<G> Iterator for CoroutineIteratorAdapter<G>
where
G: Coroutine<Return = ()>,
{
type Item = G::Yield;

fn next(&mut self) -> Option<Self::Item> {
let me = unsafe { Pin::new_unchecked(&mut self.0) };
match me.resume(()) {
CoroutineState::Yielded(x) => Some(x),
CoroutineState::Complete(_) => None,
}
}
}

fn main() {
let mut coroutine_iterator_2 = {
let mut coroutine_iterator = Box::new(CoroutineIteratorAdapter(firstn()));
coroutine_iterator.next(); // pin it

Box::new(*coroutine_iterator) // move it
}; // *deallocate* coroutine_iterator

coroutine_iterator_2.next(); // and use moved value
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling
--> $DIR/generator-pinned-moved.rs:LL:CC
--> $DIR/coroutine-pinned-moved.rs:LL:CC
|
LL | *num += 1;
| ^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
help: ALLOC was allocated here:
--> $DIR/generator-pinned-moved.rs:LL:CC
--> $DIR/coroutine-pinned-moved.rs:LL:CC
|
LL | let mut generator_iterator = Box::new(GeneratorIteratorAdapter(firstn()));
LL | let mut coroutine_iterator = Box::new(CoroutineIteratorAdapter(firstn()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: ALLOC was deallocated here:
--> $DIR/generator-pinned-moved.rs:LL:CC
--> $DIR/coroutine-pinned-moved.rs:LL:CC
|
LL | }; // *deallocate* generator_iterator
LL | }; // *deallocate* coroutine_iterator
| ^
= note: BACKTRACE (of the first span):
= note: inside closure at $DIR/generator-pinned-moved.rs:LL:CC
note: inside `<GeneratorIteratorAdapter<{static generator@$DIR/generator-pinned-moved.rs:LL:CC}> as std::iter::Iterator>::next`
--> $DIR/generator-pinned-moved.rs:LL:CC
= note: inside closure at $DIR/coroutine-pinned-moved.rs:LL:CC
note: inside `<CoroutineIteratorAdapter<{static coroutine@$DIR/coroutine-pinned-moved.rs:LL:CC}> as std::iter::Iterator>::next`
--> $DIR/coroutine-pinned-moved.rs:LL:CC
|
LL | match me.resume(()) {
| ^^^^^^^^^^^^^
= note: inside `<std::boxed::Box<GeneratorIteratorAdapter<{static generator@$DIR/generator-pinned-moved.rs:LL:CC}>> as std::iter::Iterator>::next` at RUSTLIB/alloc/src/boxed.rs:LL:CC
= note: inside `<std::boxed::Box<CoroutineIteratorAdapter<{static coroutine@$DIR/coroutine-pinned-moved.rs:LL:CC}>> as std::iter::Iterator>::next` at RUSTLIB/alloc/src/boxed.rs:LL:CC
note: inside `main`
--> $DIR/generator-pinned-moved.rs:LL:CC
--> $DIR/coroutine-pinned-moved.rs:LL:CC
|
LL | generator_iterator_2.next(); // and use moved value
LL | coroutine_iterator_2.next(); // and use moved value
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
Expand Down
46 changes: 0 additions & 46 deletions tests/fail/generator-pinned-moved.rs

This file was deleted.

24 changes: 12 additions & 12 deletions tests/pass/generator.rs → tests/pass/coroutine.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
//@revisions: stack tree
//@[tree]compile-flags: -Zmiri-tree-borrows
#![feature(generators, generator_trait, never_type)]
#![feature(coroutines, coroutine_trait, never_type)]

use std::fmt::Debug;
use std::mem::ManuallyDrop;
use std::ops::{
Generator,
GeneratorState::{self, *},
Coroutine,
CoroutineState::{self, *},
};
use std::pin::Pin;
use std::ptr;
Expand All @@ -15,22 +15,22 @@ use std::sync::atomic::{AtomicUsize, Ordering};
fn basic() {
fn finish<T>(mut amt: usize, self_referential: bool, mut t: T) -> T::Return
where
T: Generator<Yield = usize>,
T: Coroutine<Yield = usize>,
{
// We are not moving the `t` around until it gets dropped, so this is okay.
let mut t = unsafe { Pin::new_unchecked(&mut t) };
loop {
let state = t.as_mut().resume(());
// Test if the generator is valid (according to type invariants).
// For self-referential generators however this is UB!
// Test if the coroutine is valid (according to type invariants).
// For self-referential coroutines however this is UB!
if !self_referential {
let _ = unsafe { ManuallyDrop::new(ptr::read(t.as_mut().get_unchecked_mut())) };
}
match state {
GeneratorState::Yielded(y) => {
CoroutineState::Yielded(y) => {
amt -= y;
}
GeneratorState::Complete(ret) => {
CoroutineState::Complete(ret) => {
assert_eq!(amt, 0);
return ret;
}
Expand Down Expand Up @@ -86,7 +86,7 @@ fn basic() {
yield 1;
});

// also test self-referential generators
// also test self-referential coroutines
assert_eq!(
finish(5, true, static || {
let mut x = 5;
Expand Down Expand Up @@ -134,9 +134,9 @@ fn basic() {
}

fn smoke_resume_arg() {
fn drain<G: Generator<R, Yield = Y> + Unpin, R, Y>(
fn drain<G: Coroutine<R, Yield = Y> + Unpin, R, Y>(
gen: &mut G,
inout: Vec<(R, GeneratorState<Y, G::Return>)>,
inout: Vec<(R, CoroutineState<Y, G::Return>)>,
) where
Y: Debug + PartialEq,
G::Return: Debug + PartialEq,
Expand All @@ -145,7 +145,7 @@ fn smoke_resume_arg() {

for (input, out) in inout {
assert_eq!(gen.as_mut().resume(input), out);
// Test if the generator is valid (according to type invariants).
// Test if the coroutine is valid (according to type invariants).
let _ = unsafe { ManuallyDrop::new(ptr::read(gen.as_mut().get_unchecked_mut())) };
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/pass/move-data-across-await-point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ async fn data_moved_async() {
// `raw_pointer` points to the original location where the Vec was stored in the caller.
// `data` is where that Vec (to be precise, its ptr+capacity+len on-stack data)
// got moved to. Those will usually not be the same since the Vec got moved twice
// (into the function call, and then into the generator upvar).
// (into the function call, and then into the coroutine upvar).
assert_ne!(raw_pointer, raw_pointer2);
unsafe {
// This writes into the `x` in `data_moved_async`, re-initializing it.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// See https://github.com/rust-lang/unsafe-code-guidelines/issues/148:
// this fails when Stacked Borrows is strictly applied even to `!Unpin` types.
#![feature(generators, generator_trait)]
#![feature(coroutines, coroutine_trait)]

use std::{
ops::{Generator, GeneratorState},
ops::{Coroutine, CoroutineState},
pin::Pin,
};

fn firstn() -> impl Generator<Yield = u64, Return = ()> {
fn firstn() -> impl Coroutine<Yield = u64, Return = ()> {
static move || {
let mut num = 0;
let num = &mut num;
Expand All @@ -24,10 +24,10 @@ fn firstn() -> impl Generator<Yield = u64, Return = ()> {
}

fn main() {
let mut generator_iterator = firstn();
let mut pin = unsafe { Pin::new_unchecked(&mut generator_iterator) };
let mut coroutine_iterator = firstn();
let mut pin = unsafe { Pin::new_unchecked(&mut coroutine_iterator) };
let mut sum = 0;
while let GeneratorState::Yielded(x) = pin.as_mut().resume(()) {
while let CoroutineState::Yielded(x) = pin.as_mut().resume(()) {
sum += x;
}
assert_eq!(sum, 3);
Expand Down
2 changes: 1 addition & 1 deletion tests/pass/stacked-borrows/stacked-borrows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ fn wide_raw_ptr_in_tuple() {
fn not_unpin_not_protected() {
// `&mut !Unpin`, at least for now, does not get `noalias` nor `dereferenceable`, so we also
// don't add protectors. (We could, but until we have a better idea for where we want to go with
// the self-referential-generator situation, it does not seem worth the potential trouble.)
// the self-referential-coroutine situation, it does not seem worth the potential trouble.)
use std::marker::PhantomPinned;

pub struct NotUnpin(i32, PhantomPinned);
Expand Down
40 changes: 20 additions & 20 deletions tests/pass/track-caller-attribute.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#![feature(core_intrinsics)]
#![feature(stmt_expr_attributes)]
#![feature(closure_track_caller)]
#![feature(generator_trait)]
#![feature(generators)]
#![feature(coroutine_trait)]
#![feature(coroutines)]

use std::ops::{Generator, GeneratorState};
use std::ops::{Coroutine, CoroutineState};
use std::panic::Location;
use std::pin::Pin;

Expand Down Expand Up @@ -210,55 +210,55 @@ fn test_closure() {
assert_eq!(non_tracked_loc.column(), 33);
}

fn test_generator() {
fn test_coroutine() {
#[track_caller]
fn mono_generator<F: Generator<String, Yield = (&'static str, String, Loc), Return = ()>>(
fn mono_coroutine<F: Coroutine<String, Yield = (&'static str, String, Loc), Return = ()>>(
val: Pin<&mut F>,
) -> (&'static str, String, Loc) {
match val.resume("Mono".to_string()) {
GeneratorState::Yielded(val) => val,
CoroutineState::Yielded(val) => val,
_ => unreachable!(),
}
}

#[track_caller]
fn dyn_generator(
val: Pin<&mut dyn Generator<String, Yield = (&'static str, String, Loc), Return = ()>>,
fn dyn_coroutine(
val: Pin<&mut dyn Coroutine<String, Yield = (&'static str, String, Loc), Return = ()>>,
) -> (&'static str, String, Loc) {
match val.resume("Dyn".to_string()) {
GeneratorState::Yielded(val) => val,
CoroutineState::Yielded(val) => val,
_ => unreachable!(),
}
}

#[rustfmt::skip]
let generator = #[track_caller] |arg: String| {
let coroutine = #[track_caller] |arg: String| {
yield ("first", arg.clone(), Location::caller());
yield ("second", arg.clone(), Location::caller());
};

let mut pinned = Box::pin(generator);
let (dyn_ret, dyn_arg, dyn_loc) = dyn_generator(pinned.as_mut());
let mut pinned = Box::pin(coroutine);
let (dyn_ret, dyn_arg, dyn_loc) = dyn_coroutine(pinned.as_mut());
assert_eq!(dyn_ret, "first");
assert_eq!(dyn_arg, "Dyn".to_string());
// The `Generator` trait does not have `#[track_caller]` on `resume`, so
// The `Coroutine` trait does not have `#[track_caller]` on `resume`, so
// this will not match.
assert_ne!(dyn_loc.file(), file!());

let (mono_ret, mono_arg, mono_loc) = mono_generator(pinned.as_mut());
let (mono_ret, mono_arg, mono_loc) = mono_coroutine(pinned.as_mut());
let mono_line = line!() - 1;
assert_eq!(mono_ret, "second");
// The generator ignores the argument to the second `resume` call
// The coroutine ignores the argument to the second `resume` call
assert_eq!(mono_arg, "Dyn".to_string());
assert_eq!(mono_loc.file(), file!());
assert_eq!(mono_loc.line(), mono_line);
assert_eq!(mono_loc.column(), 42);

#[rustfmt::skip]
let non_tracked_generator = || { yield Location::caller(); };
let non_tracked_line = line!() - 1; // This is the line of the generator, not its caller
let non_tracked_loc = match Box::pin(non_tracked_generator).as_mut().resume(()) {
GeneratorState::Yielded(val) => val,
let non_tracked_coroutine = || { yield Location::caller(); };
let non_tracked_line = line!() - 1; // This is the line of the coroutine, not its caller
let non_tracked_loc = match Box::pin(non_tracked_coroutine).as_mut().resume(()) {
CoroutineState::Yielded(val) => val,
_ => unreachable!(),
};
assert_eq!(non_tracked_loc.file(), file!());
Expand All @@ -272,5 +272,5 @@ fn main() {
test_trait_obj();
test_trait_obj2();
test_closure();
test_generator();
test_coroutine();
}
2 changes: 1 addition & 1 deletion tests/pass/tree_borrows/tree-borrows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ fn wide_raw_ptr_in_tuple() {
fn not_unpin_not_protected() {
// `&mut !Unpin`, at least for now, does not get `noalias` nor `dereferenceable`, so we also
// don't add protectors. (We could, but until we have a better idea for where we want to go with
// the self-referential-generator situation, it does not seem worth the potential trouble.)
// the self-referential-coroutine situation, it does not seem worth the potential trouble.)
use std::marker::PhantomPinned;

pub struct NotUnpin(i32, PhantomPinned);
Expand Down

0 comments on commit 87ce1b1

Please sign in to comment.