Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of rust-lang#56100 - RalfJung:visiting-generators, r=oli…
…-obk generator fields are not necessarily initialized Looking at the MIR we generate for generators, I think we deliberately leave fields of the generator uninitialized in ways that would be illegal if this was a normal struct (or rather, one would have to use `MaybeUninit`). Consider [this example](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=417b4a2950421b726dd7b307e9ee3bec): ```rust #![feature(generators, generator_trait)] fn main() { let generator = || { let mut x = Box::new(5); { let y = &mut *x; *y = 5; yield *y; *y = 10; } *x }; let _gen = generator; } ``` It generates the MIR ``` fn main() -> (){ let mut _0: (); // return place scope 1 { scope 3 { } scope 4 { let _2: [generator@src/main.rs:4:21: 13:6 for<'r> {std::boxed::Box<i32>, i32, &'r mut i32, ()}]; // "_gen" in scope 4 at src/main.rs:14:9: 14:13 } } scope 2 { let _1: [generator@src/main.rs:4:21: 13:6 for<'r> {std::boxed::Box<i32>, i32, &'r mut i32, ()}]; // "generator" in scope 2 at src/main.rs:4:9: 4:18 } bb0: { StorageLive(_1); // bb0[0]: scope 0 at src/main.rs:4:9: 4:18 (_1.0: u32) = const 0u32; // bb0[1]: scope 0 at src/main.rs:4:21: 13:6 // ty::Const // + ty: u32 // + val: Scalar(Bits { size: 4, bits: 0 }) // mir::Constant // + span: src/main.rs:4:21: 13:6 // + ty: u32 // + literal: Const { ty: u32, val: Scalar(Bits { size: 4, bits: 0 }) } StorageLive(_2); // bb0[2]: scope 1 at src/main.rs:14:9: 14:13 _2 = move _1; // bb0[3]: scope 1 at src/main.rs:14:16: 14:25 drop(_2) -> bb1; // bb0[4]: scope 1 at src/main.rs:15:1: 15:2 } bb1: { StorageDead(_2); // bb1[0]: scope 1 at src/main.rs:15:1: 15:2 StorageDead(_1); // bb1[1]: scope 0 at src/main.rs:15:1: 15:2 return; // bb1[2]: scope 0 at src/main.rs:15:2: 15:2 } } ``` Notice how we only initialize the first field of `_1` (even though it contains a `Box`!), and then assign it to `_2`. This violates the rule "on assignment, all data must satisfy the validity invariant", and hence miri complains about this code. What this PR effectively does is to change the validity invariant for generators such that it says nothing about the fields of the generator. We behave as if every field of the generator was wrapped in a `MaybeUninit`. r? @oli-obk Cc @nikomatsakis @eddyb @cramertj @withoutboats @Zoxc
- Loading branch information