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
Encode a custom "producers" section in wasm files
This commit implements WebAssembly/tool-conventions#65 for wasm files
produced by the Rust compiler. This adds a bit of metadata to wasm
modules to indicate that the file's language includes Rust and the
file's "processed-by" tools includes rustc.
The thinking with this section is to eventually have telemetry in
browsers tracking all this.
Check arg/ret sizedness at ExprKind::Path
This PR solves three problems:
- #50940: ICE on casting unsized tuple struct constructors
- Unsized tuple struct constructors were callable in presence of `unsized_locals`.
- https://github.com/rust-lang/rust/issues/48055#issuecomment-437178966: we cannot relax `Sized` bounds on stable functions because of fn ptr casting
These are caused by lack of `Sized`ness checks for arguments/retvals at **reference sites of `FnDef` items** (not call sites of the functions). Therefore we can basically add more `Sized` obligations on typeck. However, adding `Sized` obligations arbitrarily breaks type inference; to prevent that I added a new method `require_type_is_sized_deferred` which doesn't interfere usual type inference.
Clean up and streamline snapshot data structures
These commits clean up the snapshot structures a bit, so they are more consistent with each other and with the `ena` crate.
They also remove the `OpenSnapshot` and `CommittedSnapshot` entries in the undo log, just like I did for the `ena` crate in https://github.com/rust-lang-nursery/ena/pull/14. This PR in combination with that `ena` PR reduces instruction counts by up to 6% on benchmarks.
r? @nikomatsakis. Note that this isn't quite ready for landing, because the `ena` dependency in the first commit needs to be updated once https://github.com/rust-lang-nursery/ena/pull/14 lands. But otherwise it should be good.
They're not strictly necessary, and they result in the `Vec` being
allocated even for the trivial (and common) case where a
`start_snapshot` is immediately followed by a `commit` or `rollback_to`.
The commit also removes a now-unnecessary argument of
`pop_placeholders()`.
They're not strictly necessary, and they result in the `Vec` being
allocated even for the trivial (and common) case where a
`start_snapshot` is immediately followed by a `commit` or `rollback_to`.
Because it's as useless as its name suggests.
This commit also renames `UndoLog::Noop` as `UndoLog::Purged`, because
(a) that's a more descriptive name and (b) it matches the name used in
similar code in `librustc/infer/region_constraints/mod.rs`.
Cleanup from lexical MIR borrowck removal
Lexical MIR borrowck was removed months ago now, and `EndRegion`s are no longer used for MIRI verification.
* Remove `rustc::mir::StatementKind::EndRegion` and the `-Zemit_end_regions` flag
* Use `RegionVid` instead of `Region` in BorrowSet
* Rewrite drop generation to create fewer goto terminators.
r? @nikomatsakis