Skip to content

Commit 8864668

Browse files
committed
rustc: re-complicate the TyLayout API and use better names.
1 parent aa811d7 commit 8864668

File tree

18 files changed

+109
-120
lines changed

18 files changed

+109
-120
lines changed

src/librustc/ty/layout.rs

Lines changed: 52 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -227,12 +227,6 @@ impl<'a> HasDataLayout for &'a TargetDataLayout {
227227
}
228228
}
229229

230-
impl<'a, 'tcx> HasDataLayout for TyCtxt<'a, 'tcx, 'tcx> {
231-
fn data_layout(&self) -> &TargetDataLayout {
232-
&self.data_layout
233-
}
234-
}
235-
236230
/// Endianness of the target, which must match cfg(target-endian).
237231
#[derive(Copy, Clone)]
238232
pub enum Endian {
@@ -2089,80 +2083,85 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> {
20892083
}
20902084
}
20912085

2092-
/// A pair of a type and its layout. Implements various
2093-
/// type traversal APIs (e.g. recursing into fields).
2086+
/// The details of the layout of a type, alongside the type itself.
2087+
/// Provides various type traversal APIs (e.g. recursing into fields).
2088+
///
2089+
/// Note that the details are NOT guaranteed to always be identical
2090+
/// to those obtained from `layout_of(ty)`, as we need to produce
2091+
/// layouts for which Rust types do not exist, such as enum variants
2092+
/// or synthetic fields of enums (i.e. discriminants) and fat pointers.
20942093
#[derive(Copy, Clone, Debug)]
2095-
pub struct TyLayout<'tcx> {
2094+
pub struct FullLayout<'tcx> {
20962095
pub ty: Ty<'tcx>,
2097-
pub layout: &'tcx Layout,
20982096
pub variant_index: Option<usize>,
2097+
pub layout: &'tcx Layout,
20992098
}
21002099

2101-
impl<'tcx> Deref for TyLayout<'tcx> {
2100+
impl<'tcx> Deref for FullLayout<'tcx> {
21022101
type Target = Layout;
21032102
fn deref(&self) -> &Layout {
21042103
self.layout
21052104
}
21062105
}
21072106

2108-
pub trait LayoutTyper<'tcx>: HasDataLayout {
2109-
type TyLayout;
2110-
2107+
pub trait HasTyCtxt<'tcx>: HasDataLayout {
21112108
fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx>;
2112-
fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout;
2113-
fn normalize_projections(self, ty: Ty<'tcx>) -> Ty<'tcx>;
21142109
}
21152110

2116-
/// Combines a tcx with the parameter environment so that you can
2117-
/// compute layout operations.
2118-
#[derive(Copy, Clone)]
2119-
pub struct LayoutCx<'a, 'tcx: 'a> {
2120-
tcx: TyCtxt<'a, 'tcx, 'tcx>,
2121-
param_env: ty::ParamEnv<'tcx>,
2111+
impl<'a, 'gcx, 'tcx> HasDataLayout for TyCtxt<'a, 'gcx, 'tcx> {
2112+
fn data_layout(&self) -> &TargetDataLayout {
2113+
&self.data_layout
2114+
}
21222115
}
21232116

2124-
impl<'a, 'tcx> LayoutCx<'a, 'tcx> {
2125-
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self {
2126-
LayoutCx { tcx, param_env }
2117+
impl<'a, 'gcx, 'tcx> HasTyCtxt<'gcx> for TyCtxt<'a, 'gcx, 'tcx> {
2118+
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'gcx> {
2119+
self.global_tcx()
21272120
}
21282121
}
21292122

2130-
impl<'a, 'tcx> HasDataLayout for LayoutCx<'a, 'tcx> {
2123+
impl<'a, 'gcx, 'tcx, T: Copy> HasDataLayout for (TyCtxt<'a, 'gcx, 'tcx>, T) {
21312124
fn data_layout(&self) -> &TargetDataLayout {
2132-
&self.tcx.data_layout
2125+
self.0.data_layout()
21332126
}
21342127
}
21352128

2136-
impl<'a, 'tcx> LayoutTyper<'tcx> for LayoutCx<'a, 'tcx> {
2137-
type TyLayout = Result<TyLayout<'tcx>, LayoutError<'tcx>>;
2138-
2139-
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> {
2140-
self.tcx
2129+
impl<'a, 'gcx, 'tcx, T: Copy> HasTyCtxt<'gcx> for (TyCtxt<'a, 'gcx, 'tcx>, T) {
2130+
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'gcx> {
2131+
self.0.tcx()
21412132
}
2133+
}
2134+
2135+
pub trait LayoutOf<T> {
2136+
type FullLayout;
2137+
2138+
fn layout_of(self, ty: T) -> Self::FullLayout;
2139+
}
2140+
2141+
impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for (TyCtxt<'a, 'tcx, 'tcx>, ty::ParamEnv<'tcx>) {
2142+
type FullLayout = Result<FullLayout<'tcx>, LayoutError<'tcx>>;
21422143

2143-
fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
2144-
let ty = self.normalize_projections(ty);
2144+
fn layout_of(self, ty: Ty<'tcx>) -> Self::FullLayout {
2145+
let (tcx, param_env) = self;
21452146

2146-
Ok(TyLayout {
2147+
let ty = tcx.normalize_associated_type_in_env(&ty, param_env);
2148+
2149+
Ok(FullLayout {
21472150
ty,
2148-
layout: ty.layout(self.tcx, self.param_env)?,
2149-
variant_index: None
2151+
variant_index: None,
2152+
layout: ty.layout(tcx, param_env)?,
21502153
})
21512154
}
2152-
2153-
fn normalize_projections(self, ty: Ty<'tcx>) -> Ty<'tcx> {
2154-
self.tcx.normalize_associated_type_in_env(&ty, self.param_env)
2155-
}
21562155
}
21572156

2158-
impl<'a, 'tcx> TyLayout<'tcx> {
2157+
impl<'a, 'tcx> FullLayout<'tcx> {
21592158
pub fn for_variant(&self, variant_index: usize) -> Self {
21602159
let is_enum = match self.ty.sty {
21612160
ty::TyAdt(def, _) => def.is_enum(),
21622161
_ => false
21632162
};
21642163
assert!(is_enum);
2165-
TyLayout {
2164+
FullLayout {
21662165
variant_index: Some(variant_index),
21672166
..*self
21682167
}
@@ -2199,7 +2198,7 @@ impl<'a, 'tcx> TyLayout<'tcx> {
21992198

22002199
match *self.layout {
22012200
Scalar { .. } => {
2202-
bug!("TyLayout::field_count({:?}): not applicable", self)
2201+
bug!("FullLayout::field_count({:?}): not applicable", self)
22032202
}
22042203

22052204
// Handled above (the TyAdt case).
@@ -2222,9 +2221,7 @@ impl<'a, 'tcx> TyLayout<'tcx> {
22222221
}
22232222
}
22242223

2225-
fn field_type_unnormalized<C: LayoutTyper<'tcx>>(&self, cx: C, i: usize) -> Ty<'tcx> {
2226-
let tcx = cx.tcx();
2227-
2224+
fn field_type_unnormalized(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, i: usize) -> Ty<'tcx> {
22282225
let ptr_field_type = |pointee: Ty<'tcx>| {
22292226
assert!(i < 2);
22302227
let slice = |element: Ty<'tcx>| {
@@ -2238,7 +2235,7 @@ impl<'a, 'tcx> TyLayout<'tcx> {
22382235
ty::TySlice(element) => slice(element),
22392236
ty::TyStr => slice(tcx.types.u8),
22402237
ty::TyDynamic(..) => tcx.mk_mut_ptr(tcx.mk_nil()),
2241-
_ => bug!("TyLayout::field_type({:?}): not applicable", self)
2238+
_ => bug!("FullLayout::field_type({:?}): not applicable", self)
22422239
}
22432240
};
22442241

@@ -2253,7 +2250,7 @@ impl<'a, 'tcx> TyLayout<'tcx> {
22532250
ty::TyFnDef(..) |
22542251
ty::TyDynamic(..) |
22552252
ty::TyForeign(..) => {
2256-
bug!("TyLayout::field_type({:?}): not applicable", self)
2253+
bug!("FullLayout::field_type({:?}): not applicable", self)
22572254
}
22582255

22592256
// Potentially-fat pointers.
@@ -2311,20 +2308,16 @@ impl<'a, 'tcx> TyLayout<'tcx> {
23112308

23122309
ty::TyProjection(_) | ty::TyAnon(..) | ty::TyParam(_) |
23132310
ty::TyInfer(_) | ty::TyError => {
2314-
bug!("TyLayout::field_type: unexpected type `{}`", self.ty)
2311+
bug!("FullLayout::field_type: unexpected type `{}`", self.ty)
23152312
}
23162313
}
23172314
}
23182315

2319-
pub fn field_type<C: LayoutTyper<'tcx>>(&self, cx: C, i: usize) -> Ty<'tcx> {
2320-
cx.normalize_projections(self.field_type_unnormalized(cx, i))
2321-
}
2322-
2323-
pub fn field<C: LayoutTyper<'tcx>>(&self,
2324-
cx: C,
2325-
i: usize)
2326-
-> C::TyLayout {
2327-
cx.layout_of(self.field_type(cx, i))
2316+
pub fn field<C: LayoutOf<Ty<'tcx>> + HasTyCtxt<'tcx>>(&self,
2317+
cx: C,
2318+
i: usize)
2319+
-> C::FullLayout {
2320+
cx.layout_of(self.field_type_unnormalized(cx.tcx(), i))
23282321
}
23292322
}
23302323

src/librustc_trans/abi.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ use type_::Type;
3535

3636
use rustc::hir;
3737
use rustc::ty::{self, Ty};
38-
use rustc::ty::layout::{self, Align, Layout, Size, TyLayout};
39-
use rustc::ty::layout::{HasDataLayout, LayoutTyper};
38+
use rustc::ty::layout::{self, Align, Layout, Size, FullLayout};
39+
use rustc::ty::layout::{HasDataLayout, LayoutOf};
4040
use rustc_back::PanicStrategy;
4141

4242
use libc::c_uint;
@@ -274,7 +274,7 @@ pub trait LayoutExt<'tcx> {
274274
fn homogeneous_aggregate<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Option<Reg>;
275275
}
276276

277-
impl<'tcx> LayoutExt<'tcx> for TyLayout<'tcx> {
277+
impl<'tcx> LayoutExt<'tcx> for FullLayout<'tcx> {
278278
fn is_aggregate(&self) -> bool {
279279
match *self.layout {
280280
Layout::Scalar { .. } |
@@ -471,7 +471,7 @@ impl CastTarget {
471471
#[derive(Clone, Copy, Debug)]
472472
pub struct ArgType<'tcx> {
473473
kind: ArgKind,
474-
pub layout: TyLayout<'tcx>,
474+
pub layout: FullLayout<'tcx>,
475475
/// Cast target, either a single uniform or a pair of registers.
476476
pub cast: Option<CastTarget>,
477477
/// Dummy argument, which is emitted before the real argument.
@@ -481,7 +481,7 @@ pub struct ArgType<'tcx> {
481481
}
482482

483483
impl<'a, 'tcx> ArgType<'tcx> {
484-
fn new(layout: TyLayout<'tcx>) -> ArgType<'tcx> {
484+
fn new(layout: FullLayout<'tcx>) -> ArgType<'tcx> {
485485
ArgType {
486486
kind: ArgKind::Direct,
487487
layout,

src/librustc_trans/adt.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
//! taken to it, implementing them for Rust seems difficult.
4343
4444
use rustc::ty::{self, Ty};
45-
use rustc::ty::layout::{self, Align, HasDataLayout, LayoutTyper, Size, TyLayout};
45+
use rustc::ty::layout::{self, Align, HasDataLayout, LayoutOf, Size, FullLayout};
4646

4747
use context::CrateContext;
4848
use type_::Type;
@@ -207,7 +207,7 @@ pub fn memory_index_to_gep(index: u64) -> u64 {
207207
}
208208

209209
pub fn struct_llfields<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
210-
layout: TyLayout<'tcx>,
210+
layout: FullLayout<'tcx>,
211211
variant: &layout::Struct) -> Vec<Type> {
212212
let field_count = layout.field_count();
213213
debug!("struct_llfields: variant: {:?}", variant);

src/librustc_trans/cabi_s390x.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use abi::{FnType, ArgType, LayoutExt, Reg};
1515
use context::CrateContext;
1616

17-
use rustc::ty::layout::{self, Layout, TyLayout};
17+
use rustc::ty::layout::{self, Layout, FullLayout};
1818

1919
fn classify_ret_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ret: &mut ArgType<'tcx>) {
2020
if !ret.layout.is_aggregate() && ret.layout.size(ccx).bits() <= 64 {
@@ -25,7 +25,7 @@ fn classify_ret_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ret: &mut ArgType<'tc
2525
}
2626

2727
fn is_single_fp_element<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
28-
layout: TyLayout<'tcx>) -> bool {
28+
layout: FullLayout<'tcx>) -> bool {
2929
match *layout {
3030
Layout::Scalar { value: layout::F32, .. } |
3131
Layout::Scalar { value: layout::F64, .. } => true,

src/librustc_trans/cabi_x86.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use abi::{ArgAttribute, FnType, LayoutExt, Reg, RegKind};
1212
use common::CrateContext;
1313

14-
use rustc::ty::layout::{self, Layout, TyLayout};
14+
use rustc::ty::layout::{self, Layout, FullLayout};
1515

1616
#[derive(PartialEq)]
1717
pub enum Flavor {
@@ -20,7 +20,7 @@ pub enum Flavor {
2020
}
2121

2222
fn is_single_fp_element<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
23-
layout: TyLayout<'tcx>) -> bool {
23+
layout: FullLayout<'tcx>) -> bool {
2424
match *layout {
2525
Layout::Scalar { value: layout::F32, .. } |
2626
Layout::Scalar { value: layout::F64, .. } => true,

src/librustc_trans/cabi_x86_64.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use abi::{ArgType, ArgAttribute, CastTarget, FnType, LayoutExt, Reg, RegKind};
1515
use context::CrateContext;
1616

17-
use rustc::ty::layout::{self, Layout, TyLayout, Size};
17+
use rustc::ty::layout::{self, Layout, FullLayout, Size};
1818

1919
#[derive(Clone, Copy, PartialEq, Debug)]
2020
enum Class {
@@ -53,7 +53,7 @@ fn classify_arg<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &ArgType<'tcx>)
5353
}
5454

5555
fn classify<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
56-
layout: TyLayout<'tcx>,
56+
layout: FullLayout<'tcx>,
5757
cls: &mut [Class],
5858
off: Size)
5959
-> Result<(), Memory> {

src/librustc_trans/common.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use type_::Type;
2727
use value::Value;
2828
use rustc::traits;
2929
use rustc::ty::{self, Ty, TyCtxt};
30-
use rustc::ty::layout::{HasDataLayout, Layout, LayoutTyper};
30+
use rustc::ty::layout::{HasDataLayout, Layout, LayoutOf};
3131
use rustc::ty::subst::{Kind, Subst, Substs};
3232
use rustc::hir;
3333

@@ -81,8 +81,8 @@ pub fn type_is_imm_pair<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>)
8181
}
8282

8383
// The two fields must be both immediates.
84-
type_is_immediate(ccx, layout.field_type(ccx, 0)) &&
85-
type_is_immediate(ccx, layout.field_type(ccx, 1))
84+
type_is_immediate(ccx, layout.field(ccx, 0).ty) &&
85+
type_is_immediate(ccx, layout.field(ccx, 1).ty)
8686
}
8787
_ => false
8888
}

0 commit comments

Comments
 (0)