Skip to content

Commit b957df0

Browse files
committed
rustc: add some abstractions to ty::layout for a more concise API.
1 parent 03ce886 commit b957df0

File tree

17 files changed

+191
-81
lines changed

17 files changed

+191
-81
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

+107-37
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?;
@@ -1450,7 +1474,9 @@ impl<'a, 'gcx, 'tcx> Layout {
14501474
}
14511475
}
14521476

1453-
pub fn size(&self, dl: &TargetDataLayout) -> Size {
1477+
pub fn size<C: HasDataLayout>(&self, cx: C) -> Size {
1478+
let dl = cx.data_layout();
1479+
14541480
match *self {
14551481
Scalar { value, .. } | RawNullablePointer { value, .. } => {
14561482
value.size(dl)
@@ -1492,7 +1518,9 @@ impl<'a, 'gcx, 'tcx> Layout {
14921518
}
14931519
}
14941520

1495-
pub fn align(&self, dl: &TargetDataLayout) -> Align {
1521+
pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
1522+
let dl = cx.data_layout();
1523+
14961524
match *self {
14971525
Scalar { value, .. } | RawNullablePointer { value, .. } => {
14981526
value.align(dl)
@@ -1532,11 +1560,13 @@ impl<'a, 'gcx, 'tcx> Layout {
15321560
}
15331561
}
15341562

1535-
pub fn field_offset(&self,
1536-
dl: &TargetDataLayout,
1537-
i: usize,
1538-
variant_index: Option<usize>)
1539-
-> Size {
1563+
pub fn field_offset<C: HasDataLayout>(&self,
1564+
cx: C,
1565+
i: usize,
1566+
variant_index: Option<usize>)
1567+
-> Size {
1568+
let dl = cx.data_layout();
1569+
15401570
match *self {
15411571
Scalar { .. } |
15421572
CEnum { .. } |
@@ -1615,7 +1645,7 @@ impl<'a, 'gcx, 'tcx> SizeSkeleton<'gcx> {
16151645
// First try computing a static layout.
16161646
let err = match ty.layout(infcx) {
16171647
Ok(layout) => {
1618-
return Ok(SizeSkeleton::Known(layout.size(&tcx.data_layout)));
1648+
return Ok(SizeSkeleton::Known(layout.size(tcx)));
16191649
}
16201650
Err(err) => err
16211651
};
@@ -1746,30 +1776,69 @@ impl<'tcx> Deref for TyLayout<'tcx> {
17461776
}
17471777
}
17481778

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

17541819
Ok(TyLayout {
17551820
ty: ty,
1756-
layout: ty.layout(infcx)?,
1821+
layout: ty.layout(self)?,
17571822
variant_index: None
17581823
})
17591824
}
1825+
}
17601826

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

1768-
pub fn field_offset(&self, dl: &TargetDataLayout, i: usize) -> Size {
1769-
self.layout.field_offset(dl, i, self.variant_index)
1835+
pub fn field_offset<C: HasDataLayout>(&self, cx: C, i: usize) -> Size {
1836+
self.layout.field_offset(cx, i, self.variant_index)
17701837
}
17711838

1772-
pub fn field_count(&self, tcx: TyCtxt<'a, 'gcx, 'gcx>) -> usize {
1839+
pub fn field_count<C: HasTyCtxt<'tcx>>(&self, cx: C) -> usize {
1840+
let tcx = cx.tcx();
1841+
17731842
let ptr_field_count = || {
17741843
if let FatPointer { .. } = *self.layout {
17751844
2
@@ -1831,9 +1900,11 @@ impl<'a, 'gcx, 'tcx> TyLayout<'gcx> {
18311900
}
18321901
}
18331902

1834-
pub fn field_type(&self, tcx: TyCtxt<'a, 'gcx, 'gcx>, i: usize) -> Ty<'gcx> {
1835-
let ptr_field_type = |pointee: Ty<'gcx>| {
1836-
let slice = |element: Ty<'gcx>| {
1903+
pub fn field_type<C: HasTyCtxt<'tcx>>(&self, cx: C, i: usize) -> Ty<'tcx> {
1904+
let tcx = cx.tcx();
1905+
1906+
let ptr_field_type = |pointee: Ty<'tcx>| {
1907+
let slice = |element: Ty<'tcx>| {
18371908
assert!(i < 2);
18381909
if i == 0 {
18391910
tcx.mk_mut_ptr(element)
@@ -1907,8 +1978,7 @@ impl<'a, 'gcx, 'tcx> TyLayout<'gcx> {
19071978
}
19081979
}
19091980

1910-
pub fn field(&self, infcx: &InferCtxt<'a, 'gcx, 'tcx>, i: usize)
1911-
-> Result<Self, LayoutError<'gcx>> {
1912-
TyLayout::of(infcx, self.field_type(infcx.tcx.global_tcx(), i))
1981+
pub fn field<C: LayoutTyper<'tcx>>(&self, cx: C, i: usize) -> C::TyLayout {
1982+
cx.layout_of(self.field_type(cx, i))
19131983
}
19141984
}

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
@@ -1263,8 +1263,8 @@ fn gather_type_sizes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
12631263
// (delay format until we actually need it)
12641264
let record = |kind, opt_discr_size, variants| {
12651265
let type_desc = format!("{:?}", ty);
1266-
let overall_size = layout.size(&tcx.data_layout);
1267-
let align = layout.align(&tcx.data_layout);
1266+
let overall_size = layout.size(tcx);
1267+
let align = layout.align(tcx);
12681268
tcx.sess.code_stats.borrow_mut().record_type_size(kind,
12691269
type_desc,
12701270
align,
@@ -1300,8 +1300,8 @@ fn gather_type_sizes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
13001300
session::FieldInfo {
13011301
name: field_name.to_string(),
13021302
offset: offset.bytes(),
1303-
size: field_layout.size(&tcx.data_layout).bytes(),
1304-
align: field_layout.align(&tcx.data_layout).abi(),
1303+
size: field_layout.size(tcx).bytes(),
1304+
align: field_layout.align(tcx).abi(),
13051305
}
13061306
}
13071307
}
@@ -1311,8 +1311,8 @@ fn gather_type_sizes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
13111311
session::VariantInfo {
13121312
name: Some(name.to_string()),
13131313
kind: session::SizeKind::Exact,
1314-
align: value.align(&tcx.data_layout).abi(),
1315-
size: value.size(&tcx.data_layout).bytes(),
1314+
align: value.align(tcx).abi(),
1315+
size: value.size(tcx).bytes(),
13161316
fields: vec![],
13171317
}
13181318
};

0 commit comments

Comments
 (0)