Skip to content

Commit 43b227f

Browse files
committed
rustc: add some abstractions to ty::layout for a more concise API.
1 parent c977daf commit 43b227f

File tree

17 files changed

+188
-80
lines changed

17 files changed

+188
-80
lines changed

src/librustc/middle/intrinsicck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ impl<'a, 'gcx, 'tcx> ExprVisitor<'a, 'gcx, 'tcx> {
8989
let from = unpack_option_like(self.infcx.tcx.global_tcx(), from);
9090
match (&from.sty, sk_to) {
9191
(&ty::TyFnDef(..), SizeSkeleton::Known(size_to))
92-
if size_to == Pointer.size(&self.infcx.tcx.data_layout) => {
92+
if size_to == Pointer.size(self.infcx) => {
9393
struct_span_err!(self.infcx.tcx.sess, span, E0591,
9494
"`{}` is zero-sized and can't be transmuted to `{}`",
9595
from, to)

src/librustc/ty/layout.rs

+104-36
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,16 @@ impl TargetDataLayout {
202202
}
203203
}
204204

205+
pub trait HasDataLayout: Copy {
206+
fn data_layout(&self) -> &TargetDataLayout;
207+
}
208+
209+
impl<'a> HasDataLayout for &'a TargetDataLayout {
210+
fn data_layout(&self) -> &TargetDataLayout {
211+
self
212+
}
213+
}
214+
205215
/// Endianness of the target, which must match cfg(target-endian).
206216
#[derive(Copy, Clone)]
207217
pub enum Endian {
@@ -242,7 +252,9 @@ impl Size {
242252
Size::from_bytes((self.bytes() + mask) & !mask)
243253
}
244254

245-
pub fn checked_add(self, offset: Size, dl: &TargetDataLayout) -> Option<Size> {
255+
pub fn checked_add<C: HasDataLayout>(self, offset: Size, cx: C) -> Option<Size> {
256+
let dl = cx.data_layout();
257+
246258
// Each Size is less than dl.obj_size_bound(), so the sum is
247259
// also less than 1 << 62 (and therefore can't overflow).
248260
let bytes = self.bytes() + offset.bytes();
@@ -254,7 +266,9 @@ impl Size {
254266
}
255267
}
256268

257-
pub fn checked_mul(self, count: u64, dl: &TargetDataLayout) -> Option<Size> {
269+
pub fn checked_mul<C: HasDataLayout>(self, count: u64, cx: C) -> Option<Size> {
270+
let dl = cx.data_layout();
271+
258272
// Each Size is less than dl.obj_size_bound(), so the sum is
259273
// also less than 1 << 62 (and therefore can't overflow).
260274
match self.bytes().checked_mul(count) {
@@ -354,7 +368,9 @@ impl Integer {
354368
}
355369
}
356370

357-
pub fn align(&self, dl: &TargetDataLayout)-> Align {
371+
pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
372+
let dl = cx.data_layout();
373+
358374
match *self {
359375
I1 => dl.i1_align,
360376
I8 => dl.i8_align,
@@ -408,7 +424,9 @@ impl Integer {
408424
}
409425

410426
/// Find the smallest integer with the given alignment.
411-
pub fn for_abi_align(dl: &TargetDataLayout, align: Align) -> Option<Integer> {
427+
pub fn for_abi_align<C: HasDataLayout>(cx: C, align: Align) -> Option<Integer> {
428+
let dl = cx.data_layout();
429+
412430
let wanted = align.abi();
413431
for &candidate in &[I8, I16, I32, I64] {
414432
let ty = Int(candidate);
@@ -420,7 +438,9 @@ impl Integer {
420438
}
421439

422440
/// Get the Integer type from an attr::IntType.
423-
pub fn from_attr(dl: &TargetDataLayout, ity: attr::IntType) -> Integer {
441+
pub fn from_attr<C: HasDataLayout>(cx: C, ity: attr::IntType) -> Integer {
442+
let dl = cx.data_layout();
443+
424444
match ity {
425445
attr::SignedInt(IntTy::I8) | attr::UnsignedInt(UintTy::U8) => I8,
426446
attr::SignedInt(IntTy::I16) | attr::UnsignedInt(UintTy::U16) => I16,
@@ -450,7 +470,7 @@ impl Integer {
450470
let min_default = I8;
451471

452472
if let Some(ity) = repr.int {
453-
let discr = Integer::from_attr(&tcx.data_layout, ity);
473+
let discr = Integer::from_attr(tcx, ity);
454474
let fit = if ity.is_signed() { signed_fit } else { unsigned_fit };
455475
if discr < fit {
456476
bug!("Integer::repr_discr: `#[repr]` hint too small for \
@@ -491,7 +511,9 @@ pub enum Primitive {
491511
}
492512

493513
impl Primitive {
494-
pub fn size(self, dl: &TargetDataLayout) -> Size {
514+
pub fn size<C: HasDataLayout>(self, cx: C) -> Size {
515+
let dl = cx.data_layout();
516+
495517
match self {
496518
Int(I1) | Int(I8) => Size::from_bits(8),
497519
Int(I16) => Size::from_bits(16),
@@ -502,7 +524,9 @@ impl Primitive {
502524
}
503525
}
504526

505-
pub fn align(self, dl: &TargetDataLayout) -> Align {
527+
pub fn align<C: HasDataLayout>(self, cx: C) -> Align {
528+
let dl = cx.data_layout();
529+
506530
match self {
507531
Int(I1) => dl.i1_align,
508532
Int(I8) => dl.i8_align,
@@ -682,8 +706,8 @@ impl<'a, 'gcx, 'tcx> Struct {
682706
}
683707

684708
/// Determine whether a structure would be zero-sized, given its fields.
685-
pub fn would_be_zero_sized<I>(dl: &TargetDataLayout, fields: I)
686-
-> Result<bool, LayoutError<'gcx>>
709+
fn would_be_zero_sized<I>(dl: &TargetDataLayout, fields: I)
710+
-> Result<bool, LayoutError<'gcx>>
687711
where I: Iterator<Item=Result<&'a Layout, LayoutError<'gcx>>> {
688712
for field in fields {
689713
let field = field?;
@@ -831,7 +855,7 @@ pub struct Union {
831855
}
832856

833857
impl<'a, 'gcx, 'tcx> Union {
834-
pub fn new(dl: &TargetDataLayout, packed: bool) -> Union {
858+
fn new(dl: &TargetDataLayout, packed: bool) -> Union {
835859
Union {
836860
align: if packed { dl.i8_align } else { dl.aggregate_align },
837861
min_size: Size::from_bytes(0),
@@ -840,10 +864,10 @@ impl<'a, 'gcx, 'tcx> Union {
840864
}
841865

842866
/// Extend the Struct with more fields.
843-
pub fn extend<I>(&mut self, dl: &TargetDataLayout,
844-
fields: I,
845-
scapegoat: Ty<'gcx>)
846-
-> Result<(), LayoutError<'gcx>>
867+
fn extend<I>(&mut self, dl: &TargetDataLayout,
868+
fields: I,
869+
scapegoat: Ty<'gcx>)
870+
-> Result<(), LayoutError<'gcx>>
847871
where I: Iterator<Item=Result<&'a Layout, LayoutError<'gcx>>> {
848872
for (index, field) in fields.enumerate() {
849873
let field = field?;
@@ -1452,7 +1476,9 @@ impl<'a, 'gcx, 'tcx> Layout {
14521476
}
14531477
}
14541478

1455-
pub fn size(&self, dl: &TargetDataLayout) -> Size {
1479+
pub fn size<C: HasDataLayout>(&self, cx: C) -> Size {
1480+
let dl = cx.data_layout();
1481+
14561482
match *self {
14571483
Scalar { value, .. } | RawNullablePointer { value, .. } => {
14581484
value.size(dl)
@@ -1494,7 +1520,9 @@ impl<'a, 'gcx, 'tcx> Layout {
14941520
}
14951521
}
14961522

1497-
pub fn align(&self, dl: &TargetDataLayout) -> Align {
1523+
pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
1524+
let dl = cx.data_layout();
1525+
14981526
match *self {
14991527
Scalar { value, .. } | RawNullablePointer { value, .. } => {
15001528
value.align(dl)
@@ -1534,11 +1562,13 @@ impl<'a, 'gcx, 'tcx> Layout {
15341562
}
15351563
}
15361564

1537-
pub fn field_offset(&self,
1538-
dl: &TargetDataLayout,
1539-
i: usize,
1540-
variant_index: Option<usize>)
1541-
-> Size {
1565+
pub fn field_offset<C: HasDataLayout>(&self,
1566+
cx: C,
1567+
i: usize,
1568+
variant_index: Option<usize>)
1569+
-> Size {
1570+
let dl = cx.data_layout();
1571+
15421572
match *self {
15431573
Scalar { .. } |
15441574
CEnum { .. } |
@@ -1617,7 +1647,7 @@ impl<'a, 'gcx, 'tcx> SizeSkeleton<'gcx> {
16171647
// First try computing a static layout.
16181648
let err = match ty.layout(infcx) {
16191649
Ok(layout) => {
1620-
return Ok(SizeSkeleton::Known(layout.size(&tcx.data_layout)));
1650+
return Ok(SizeSkeleton::Known(layout.size(tcx)));
16211651
}
16221652
Err(err) => err
16231653
};
@@ -1748,27 +1778,64 @@ impl<'tcx> Deref for TyLayout<'tcx> {
17481778
}
17491779
}
17501780

1751-
impl<'a, 'gcx, 'tcx> TyLayout<'gcx> {
1752-
pub fn of(infcx: &InferCtxt<'a, 'gcx, 'tcx>, ty: Ty<'gcx>)
1753-
-> Result<Self, LayoutError<'gcx>> {
1754-
let ty = normalize_associated_type(infcx, ty);
1781+
pub trait HasTyCtxt<'tcx>: HasDataLayout {
1782+
fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx>;
1783+
}
1784+
1785+
impl<'a, 'gcx, 'tcx> HasDataLayout for TyCtxt<'a, 'gcx, 'tcx> {
1786+
fn data_layout(&self) -> &TargetDataLayout {
1787+
&self.data_layout
1788+
}
1789+
}
1790+
1791+
impl<'a, 'gcx, 'tcx> HasTyCtxt<'gcx> for TyCtxt<'a, 'gcx, 'tcx> {
1792+
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'gcx> {
1793+
self.global_tcx()
1794+
}
1795+
}
1796+
1797+
impl<'a, 'gcx, 'tcx> HasDataLayout for &'a InferCtxt<'a, 'gcx, 'tcx> {
1798+
fn data_layout(&self) -> &TargetDataLayout {
1799+
&self.tcx.data_layout
1800+
}
1801+
}
1802+
1803+
impl<'a, 'gcx, 'tcx> HasTyCtxt<'gcx> for &'a InferCtxt<'a, 'gcx, 'tcx> {
1804+
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'gcx> {
1805+
self.tcx.global_tcx()
1806+
}
1807+
}
1808+
1809+
pub trait LayoutTyper<'tcx>: HasTyCtxt<'tcx> {
1810+
type TyLayout;
1811+
1812+
fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout;
1813+
}
1814+
1815+
impl<'a, 'gcx, 'tcx> LayoutTyper<'gcx> for &'a InferCtxt<'a, 'gcx, 'tcx> {
1816+
type TyLayout = Result<TyLayout<'gcx>, LayoutError<'gcx>>;
1817+
1818+
fn layout_of(self, ty: Ty<'gcx>) -> Self::TyLayout {
1819+
let ty = normalize_associated_type(self, ty);
17551820

17561821
Ok(TyLayout {
17571822
ty: ty,
1758-
layout: ty.layout(infcx)?,
1823+
layout: ty.layout(self)?,
17591824
variant_index: None
17601825
})
17611826
}
1827+
}
17621828

1829+
impl<'a, 'tcx> TyLayout<'tcx> {
17631830
pub fn for_variant(&self, variant_index: usize) -> Self {
17641831
TyLayout {
17651832
variant_index: Some(variant_index),
17661833
..*self
17671834
}
17681835
}
17691836

1770-
pub fn field_offset(&self, dl: &TargetDataLayout, i: usize) -> Size {
1771-
self.layout.field_offset(dl, i, self.variant_index)
1837+
pub fn field_offset<C: HasDataLayout>(&self, cx: C, i: usize) -> Size {
1838+
self.layout.field_offset(cx, i, self.variant_index)
17721839
}
17731840

17741841
pub fn field_count(&self) -> usize {
@@ -1808,9 +1875,11 @@ impl<'a, 'gcx, 'tcx> TyLayout<'gcx> {
18081875
}
18091876
}
18101877

1811-
pub fn field_type(&self, tcx: TyCtxt<'a, 'gcx, 'gcx>, i: usize) -> Ty<'gcx> {
1812-
let ptr_field_type = |pointee: Ty<'gcx>| {
1813-
let slice = |element: Ty<'gcx>| {
1878+
pub fn field_type<C: HasTyCtxt<'tcx>>(&self, cx: C, i: usize) -> Ty<'tcx> {
1879+
let tcx = cx.tcx();
1880+
1881+
let ptr_field_type = |pointee: Ty<'tcx>| {
1882+
let slice = |element: Ty<'tcx>| {
18141883
assert!(i < 2);
18151884
if i == 0 {
18161885
tcx.mk_mut_ptr(element)
@@ -1877,8 +1946,7 @@ impl<'a, 'gcx, 'tcx> TyLayout<'gcx> {
18771946
}
18781947
}
18791948

1880-
pub fn field(&self, infcx: &InferCtxt<'a, 'gcx, 'tcx>, i: usize)
1881-
-> Result<Self, LayoutError<'gcx>> {
1882-
TyLayout::of(infcx, self.field_type(infcx.tcx.global_tcx(), i))
1949+
pub fn field<C: LayoutTyper<'tcx>>(&self, cx: C, i: usize) -> C::TyLayout {
1950+
cx.layout_of(self.field_type(cx, i))
18831951
}
18841952
}

src/librustc_lint/types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
733733
});
734734

735735
if let Layout::General { ref variants, ref size, discr, .. } = *layout {
736-
let discr_size = Primitive::Int(discr).size(&cx.tcx.data_layout).bytes();
736+
let discr_size = Primitive::Int(discr).size(cx.tcx).bytes();
737737

738738
debug!("enum `{}` is {} bytes large with layout:\n{:#?}",
739739
t, size.bytes(), layout);

src/librustc_trans/abi.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ use type_of;
3535

3636
use rustc::hir;
3737
use rustc::ty::{self, Ty};
38+
use rustc::ty::layout::{Layout, LayoutTyper};
3839

3940
use libc::c_uint;
4041
use std::cmp;
4142

4243
pub use syntax::abi::Abi;
4344
pub use rustc::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
44-
use rustc::ty::layout::Layout;
4545

4646
#[derive(Clone, Copy, PartialEq, Debug)]
4747
enum ArgKind {

src/librustc_trans/adt.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ use super::Disr;
4646
use std;
4747

4848
use llvm::{ValueRef, True, IntEQ, IntNE};
49-
use rustc::ty::layout;
5049
use rustc::ty::{self, Ty};
50+
use rustc::ty::layout::{self, LayoutTyper};
5151
use common::*;
5252
use builder::Builder;
5353
use base;
@@ -246,9 +246,8 @@ fn union_fill(cx: &CrateContext, size: u64, align: u64) -> Type {
246246
assert_eq!(size%align, 0);
247247
assert_eq!(align.count_ones(), 1, "Alignment must be a power fof 2. Got {}", align);
248248
let align_units = size/align;
249-
let dl = &cx.tcx().data_layout;
250249
let layout_align = layout::Align::from_bytes(align, align).unwrap();
251-
if let Some(ity) = layout::Integer::for_abi_align(dl, layout_align) {
250+
if let Some(ity) = layout::Integer::for_abi_align(cx, layout_align) {
252251
Type::array(&Type::from_integer(cx, ity), align_units)
253252
} else {
254253
Type::array(&Type::vector(&Type::i32(cx), align/4),

src/librustc_trans/base.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -1295,8 +1295,8 @@ fn gather_type_sizes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
12951295
// (delay format until we actually need it)
12961296
let record = |kind, opt_discr_size, variants| {
12971297
let type_desc = format!("{:?}", ty);
1298-
let overall_size = layout.size(&tcx.data_layout);
1299-
let align = layout.align(&tcx.data_layout);
1298+
let overall_size = layout.size(tcx);
1299+
let align = layout.align(tcx);
13001300
tcx.sess.code_stats.borrow_mut().record_type_size(kind,
13011301
type_desc,
13021302
align,
@@ -1332,8 +1332,8 @@ fn gather_type_sizes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
13321332
session::FieldInfo {
13331333
name: field_name.to_string(),
13341334
offset: offset.bytes(),
1335-
size: field_layout.size(&tcx.data_layout).bytes(),
1336-
align: field_layout.align(&tcx.data_layout).abi(),
1335+
size: field_layout.size(tcx).bytes(),
1336+
align: field_layout.align(tcx).abi(),
13371337
}
13381338
}
13391339
}
@@ -1343,8 +1343,8 @@ fn gather_type_sizes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
13431343
session::VariantInfo {
13441344
name: Some(name.to_string()),
13451345
kind: session::SizeKind::Exact,
1346-
align: value.align(&tcx.data_layout).abi(),
1347-
size: value.size(&tcx.data_layout).bytes(),
1346+
align: value.align(tcx).abi(),
1347+
size: value.size(tcx).bytes(),
13481348
fields: vec![],
13491349
}
13501350
};

src/librustc_trans/common.rs

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

@@ -63,7 +63,7 @@ pub fn type_is_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -
6363
Layout::UntaggedUnion { .. } |
6464
Layout::RawNullablePointer { .. } |
6565
Layout::StructWrappedNullablePointer { .. } => {
66-
!layout.is_unsized() && layout.size(&ccx.tcx().data_layout).bytes() == 0
66+
!layout.is_unsized() && layout.size(ccx).bytes() == 0
6767
}
6868
}
6969
}
@@ -126,7 +126,7 @@ pub fn type_is_imm_pair<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>)
126126
/// Identify types which have size zero at runtime.
127127
pub fn type_is_zero_size<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
128128
let layout = ccx.layout_of(ty);
129-
!layout.is_unsized() && layout.size(&ccx.tcx().data_layout).bytes() == 0
129+
!layout.is_unsized() && layout.size(ccx).bytes() == 0
130130
}
131131

132132
/*

0 commit comments

Comments
 (0)