]> git.lizzy.rs Git - rust.git/commit
Auto merge of #32939 - eddyb:layout, r=nikomatsakis
authorbors <bors@rust-lang.org>
Wed, 20 Apr 2016 14:27:59 +0000 (07:27 -0700)
committerbors <bors@rust-lang.org>
Wed, 20 Apr 2016 14:27:59 +0000 (07:27 -0700)
commit6ece1447f02b2310e5f4c7ef1efd1312476cae80
treee2fc7e887c386f7524d50282c9ef575821aff120
parent133f60f82012ad92c40693bf1ae28419b60146a7
parentc7d564d8c96bf538cc64a3eeca1fcc3c99569625
Auto merge of #32939 - eddyb:layout, r=nikomatsakis

Compute LLVM-agnostic type layouts in rustc.

Layout for monomorphic types, and some polymorphic ones (e.g. `&T` where `T: Sized`),
can now be computed by rustc without involving LLVM in the actual process.

This gives rustc the ability to evaluate `size_of` or `align_of`, as well as obtain field offsets.
MIR-based CTFE will eventually make use of these layouts, as will MIR trans, shortly.

Layout computation also comes with a `[breaking-change]`, or two:
* `"data-layout"` is now mandatory in custom target specifications, reverting the decision from #27076.
This string is needed because it describes endianness, pointer size and alignments for various types.
We have the first two and we could allow tweaking alignments in target specifications.
Or we could also extract the data layout from LLVM and feed it back into rustc.
However, that can vary with the LLVM version, which is fragile and undermines stability.
For built-in targets, I've added a check that the hardcoded data-layout matches LLVM defaults.
* `transmute` calls are checked in a stricter fashion, which fixes #32377

To expand on `transmute`, there are only 2 allowed patterns: between types with statically known sizes and between pointers with the same potentially-unsized "tail" (which determines the type of unsized metadata they use, if any).
If you're affected, my suggestions are:
* try to use casts (and raw pointer deref) instead of transmutes
* *really* try to avoid `transmute` where possible
* if you have a structure, try working on individual fields and unpack/repack the structure instead of transmuting it whole, e.g. `transmute::<RefCell<Box<T>>, RefCell<*mut T>>(x)` doesn't work, but `RefCell::new(Box::into_raw(x.into_inner()))` does (and `Box::into_raw` is just a `transmute`)