Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
018323ff
R
Rust
项目概览
int
/
Rust
12 个月 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
018323ff
编写于
9月 23, 2017
作者:
E
Eduard-Mihai Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc: collapse the remains of Layout into Variants (enums vs everything else).
上级
b28f668e
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
188 addition
and
236 deletion
+188
-236
src/librustc/ty/layout.rs
src/librustc/ty/layout.rs
+64
-122
src/librustc_lint/types.rs
src/librustc_lint/types.rs
+2
-2
src/librustc_trans/cabi_x86_64.rs
src/librustc_trans/cabi_x86_64.rs
+10
-12
src/librustc_trans/debuginfo/metadata.rs
src/librustc_trans/debuginfo/metadata.rs
+48
-50
src/librustc_trans/intrinsic.rs
src/librustc_trans/intrinsic.rs
+1
-6
src/librustc_trans/mir/constant.rs
src/librustc_trans/mir/constant.rs
+21
-20
src/librustc_trans/mir/lvalue.rs
src/librustc_trans/mir/lvalue.rs
+22
-16
src/librustc_trans/mir/rvalue.rs
src/librustc_trans/mir/rvalue.rs
+6
-3
src/librustc_trans/type_of.rs
src/librustc_trans/type_of.rs
+14
-5
未找到文件。
src/librustc/ty/layout.rs
浏览文件 @
018323ff
...
...
@@ -769,33 +769,17 @@ pub fn is_packed(&self) -> bool {
}
}
/// Type layout, from which size and alignment can be cheaply computed.
/// For ADTs, it also includes field placement and enum optimizations.
/// NOTE: Because Layout is interned, redundant information should be
/// kept to a minimum, e.g. it includes no sub-component Ty or Layout.
#[derive(PartialEq,
Eq,
Hash,
Debug)]
pub
enum
Layout
{
/// TyBool, TyChar, TyInt, TyUint, TyFloat, TyRawPtr, TyRef or TyFnPtr.
Scalar
,
/// SIMD vectors, from structs marked with #[repr(simd)].
Vector
,
/// TyArray, TySlice or TyStr.
Array
,
// Remaining variants are all ADTs such as structs, enums or tuples.
/// Single-case enums, and structs/tuples.
Univariant
,
/// Untagged unions.
UntaggedUnion
,
pub
enum
Variants
{
/// Single enum variants, structs/tuples, unions, and all non-ADTs.
Single
{
index
:
usize
},
/// General-case enums: for each case there is a struct, and they all have
/// all space reserved for the discriminant, and their first field starts
/// at a non-0 offset, after where the discriminant would go.
General
{
Tagged
{
discr
:
Primitive
,
/// Inclusive wrap-around range of discriminant values, that is,
/// if min > max, it represents min..=u64::MAX followed by 0..=max.
...
...
@@ -806,7 +790,7 @@ pub enum Layout {
variants
:
Vec
<
CachedLayout
>
,
},
/// Two cases distinguished by a n
ullable pointer
: the case with discriminant
/// Two cases distinguished by a n
iche
: the case with discriminant
/// `nndiscr` is represented by the struct `nonnull`, where field `0`
/// is known to be nonnull due to its type; if that field is null, then
/// it represents the other case, which is known to be zero sized.
...
...
@@ -814,7 +798,7 @@ pub enum Layout {
/// For example, `std::option::Option` instantiated at a safe pointer type
/// is represented such that `None` is a null pointer and `Some` is the
/// identity function.
N
ullablePointer
{
N
icheFilling
{
nndiscr
:
u64
,
discr
:
Primitive
,
variants
:
Vec
<
CachedLayout
>
,
...
...
@@ -842,8 +826,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
#[derive(PartialEq,
Eq,
Hash,
Debug)]
pub
struct
CachedLayout
{
pub
variant_index
:
Option
<
usize
>
,
pub
layout
:
Layout
,
pub
variants
:
Variants
,
pub
fields
:
FieldPlacement
,
pub
abi
:
Abi
,
pub
align
:
Align
,
...
...
@@ -865,7 +848,7 @@ fn layout_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
tcx
.layout_depth
.set
(
depth
+
1
);
let
layout
=
Layout
::
compute_uncached
(
tcx
,
param_env
,
ty
);
let
layout
=
Cached
Layout
::
compute_uncached
(
tcx
,
param_env
,
ty
);
tcx
.layout_depth
.set
(
depth
);
layout
...
...
@@ -878,18 +861,17 @@ pub fn provide(providers: &mut ty::maps::Providers) {
};
}
impl
<
'a
,
'tcx
>
Layout
{
impl
<
'a
,
'tcx
>
Cached
Layout
{
fn
compute_uncached
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
param_env
:
ty
::
ParamEnv
<
'tcx
>
,
ty
:
Ty
<
'tcx
>
)
->
Result
<&
'tcx
CachedLayout
,
LayoutError
<
'tcx
>>
{
->
Result
<&
'tcx
Self
,
LayoutError
<
'tcx
>>
{
let
cx
=
(
tcx
,
param_env
);
let
dl
=
cx
.data_layout
();
let
scalar
=
|
value
:
Primitive
|
{
let
align
=
value
.align
(
dl
);
tcx
.intern_layout
(
CachedLayout
{
variant_index
:
None
,
layout
:
Layout
::
Scalar
,
variants
:
Variants
::
Single
{
index
:
0
},
fields
:
FieldPlacement
::
Union
(
0
),
abi
:
Abi
::
Scalar
(
value
),
size
:
value
.size
(
dl
),
...
...
@@ -1028,8 +1010,7 @@ enum StructKind {
}
Ok
(
CachedLayout
{
variant_index
:
None
,
layout
:
Layout
::
Univariant
,
variants
:
Variants
::
Single
{
index
:
0
},
fields
:
FieldPlacement
::
Arbitrary
{
offsets
,
memory_index
...
...
@@ -1073,8 +1054,7 @@ enum StructKind {
memory_index
:
vec!
[
0
,
1
]
};
Ok
(
tcx
.intern_layout
(
CachedLayout
{
variant_index
:
None
,
layout
:
Layout
::
Univariant
,
variants
:
Variants
::
Single
{
index
:
0
},
fields
,
abi
:
Abi
::
Aggregate
{
sized
:
true
,
...
...
@@ -1129,8 +1109,7 @@ enum StructKind {
.ok_or
(
LayoutError
::
SizeOverflow
(
ty
))
?
;
tcx
.intern_layout
(
CachedLayout
{
variant_index
:
None
,
layout
:
Layout
::
Array
,
variants
:
Variants
::
Single
{
index
:
0
},
fields
:
FieldPlacement
::
Array
{
stride
:
element
.size
,
count
...
...
@@ -1147,8 +1126,7 @@ enum StructKind {
ty
::
TySlice
(
element
)
=>
{
let
element
=
cx
.layout_of
(
element
)
?
;
tcx
.intern_layout
(
CachedLayout
{
variant_index
:
None
,
layout
:
Layout
::
Array
,
variants
:
Variants
::
Single
{
index
:
0
},
fields
:
FieldPlacement
::
Array
{
stride
:
element
.size
,
count
:
0
...
...
@@ -1164,8 +1142,7 @@ enum StructKind {
}
ty
::
TyStr
=>
{
tcx
.intern_layout
(
CachedLayout
{
variant_index
:
None
,
layout
:
Layout
::
Array
,
variants
:
Variants
::
Single
{
index
:
0
},
fields
:
FieldPlacement
::
Array
{
stride
:
Size
::
from_bytes
(
1
),
count
:
0
...
...
@@ -1238,8 +1215,7 @@ enum StructKind {
let
size
=
size
.abi_align
(
align
);
tcx
.intern_layout
(
CachedLayout
{
variant_index
:
None
,
layout
:
Layout
::
Vector
,
variants
:
Variants
::
Single
{
index
:
0
},
fields
:
FieldPlacement
::
Array
{
stride
:
element
.size
,
count
...
...
@@ -1302,8 +1278,7 @@ enum StructKind {
}
return
Ok
(
tcx
.intern_layout
(
CachedLayout
{
variant_index
:
None
,
layout
:
Layout
::
UntaggedUnion
,
variants
:
Variants
::
Single
{
index
:
0
},
fields
:
FieldPlacement
::
Union
(
variants
[
0
]
.len
()),
abi
:
Abi
::
Aggregate
{
sized
:
true
,
...
...
@@ -1332,11 +1307,7 @@ enum StructKind {
else
{
StructKind
::
AlwaysSized
}
};
let
mut
cached
=
univariant_uninterned
(
&
variants
[
0
],
&
def
.repr
,
kind
)
?
;
if
def
.is_enum
()
{
cached
.variant_index
=
Some
(
0
);
}
return
Ok
(
tcx
.intern_layout
(
cached
));
return
univariant
(
&
variants
[
0
],
&
def
.repr
,
kind
);
}
let
no_explicit_discriminants
=
def
.variants
.iter
()
.enumerate
()
...
...
@@ -1359,8 +1330,9 @@ enum StructKind {
univariant_uninterned
(
&
variants
[
1
],
&
def
.repr
,
StructKind
::
AlwaysSized
)
?
];
st
[
0
]
.variant_index
=
Some
(
0
);
st
[
1
]
.variant_index
=
Some
(
1
);
for
(
i
,
v
)
in
st
.iter_mut
()
.enumerate
()
{
v
.variants
=
Variants
::
Single
{
index
:
i
};
}
let
offset
=
st
[
i
]
.fields
.offset
(
field_index
)
+
offset
;
let
CachedLayout
{
mut
abi
,
...
...
@@ -1383,8 +1355,7 @@ enum StructKind {
primitive_align
=
primitive_align
.max
(
discr_align
);
return
Ok
(
tcx
.intern_layout
(
CachedLayout
{
variant_index
:
None
,
layout
:
Layout
::
NullablePointer
{
variants
:
Variants
::
NicheFilling
{
nndiscr
:
i
as
u64
,
discr
,
...
...
@@ -1426,7 +1397,7 @@ enum StructKind {
let
mut
variants
=
variants
.into_iter
()
.enumerate
()
.map
(|(
i
,
field_layouts
)|
{
let
mut
st
=
univariant_uninterned
(
&
field_layouts
,
&
def
.repr
,
StructKind
::
EnumVariant
(
min_ity
))
?
;
st
.variant
_index
=
Some
(
i
)
;
st
.variant
s
=
Variants
::
Single
{
index
:
i
}
;
// Find the first field we can't move later
// to make room for a larger discriminant.
for
field
in
st
.fields
.index_by_increasing_offset
()
.map
(|
j
|
field_layouts
[
j
])
{
...
...
@@ -1506,8 +1477,7 @@ enum StructKind {
let
discr
=
Int
(
ity
,
signed
);
tcx
.intern_layout
(
CachedLayout
{
variant_index
:
None
,
layout
:
Layout
::
General
{
variants
:
Variants
::
Tagged
{
discr
,
// FIXME: should be u128?
...
...
@@ -1544,7 +1514,7 @@ enum StructKind {
return
Err
(
LayoutError
::
Unknown
(
ty
));
}
ty
::
TyInfer
(
_
)
|
ty
::
TyError
=>
{
bug!
(
"Layout::compute: unexpected type `{}`"
,
ty
)
bug!
(
"
Cached
Layout::compute: unexpected type `{}`"
,
ty
)
}
})
}
...
...
@@ -1650,8 +1620,8 @@ fn record_layout_for_printing_outlined(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
};
match
layout
.
layout
{
Layout
::
Univariant
=>
{
match
layout
.
variants
{
Variants
::
Single
{
..
}
=>
{
let
variant_names
=
||
{
adt_def
.variants
.iter
()
.map
(|
v
|
format!
(
"{}"
,
v
.name
))
.collect
::
<
Vec
<
_
>>
()
};
...
...
@@ -1675,8 +1645,8 @@ fn record_layout_for_printing_outlined(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
}
Layout
::
NullablePointer
{
..
}
|
Layout
::
General
{
..
}
=>
{
Variants
::
NicheFilling
{
..
}
|
Variants
::
Tagged
{
..
}
=>
{
debug!
(
"print-type-size `{:#?}` adt general variants def {}"
,
ty
,
adt_def
.variants
.len
());
let
variant_infos
:
Vec
<
_
>
=
...
...
@@ -1688,27 +1658,11 @@ fn record_layout_for_printing_outlined(tcx: TyCtxt<'a, 'tcx, 'tcx>,
layout
.for_variant
(
i
))
})
.collect
();
record
(
adt_kind
.into
(),
match
layout
.
layout
{
Layout
::
General
{
discr
,
..
}
=>
Some
(
discr
.size
(
tcx
)),
record
(
adt_kind
.into
(),
match
layout
.
variants
{
Variants
::
Tagged
{
discr
,
..
}
=>
Some
(
discr
.size
(
tcx
)),
_
=>
None
},
variant_infos
);
}
Layout
::
UntaggedUnion
=>
{
debug!
(
"print-type-size t: `{:?}` adt union"
,
ty
);
// layout does not currently store info about each
// variant...
record
(
adt_kind
.into
(),
None
,
Vec
::
new
());
}
// other cases provide little interesting (i.e. adjustable
// via representation tweaks) size info beyond total size.
Layout
::
Scalar
|
Layout
::
Vector
|
Layout
::
Array
=>
{
debug!
(
"print-type-size t: `{:?}` adt other"
,
ty
);
record
(
adt_kind
.into
(),
None
,
Vec
::
new
())
}
}
}
}
...
...
@@ -1950,7 +1904,7 @@ fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
// completed, to avoid problems around recursive structures
// and the like. (Admitedly, I wasn't able to reproduce a problem
// here, but it seems like the right thing to do. -nmatsakis)
Layout
::
record_layout_for_printing
(
tcx
,
ty
,
param_env
,
layout
);
Cached
Layout
::
record_layout_for_printing
(
tcx
,
ty
,
param_env
,
layout
);
Ok
(
layout
)
}
...
...
@@ -1979,7 +1933,7 @@ fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
// completed, to avoid problems around recursive structures
// and the like. (Admitedly, I wasn't able to reproduce a problem
// here, but it seems like the right thing to do. -nmatsakis)
Layout
::
record_layout_for_printing
(
tcx_at
.tcx
,
ty
,
param_env
,
layout
);
Cached
Layout
::
record_layout_for_printing
(
tcx_at
.tcx
,
ty
,
param_env
,
layout
);
Ok
(
layout
)
}
...
...
@@ -1987,15 +1941,15 @@ fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
impl
<
'a
,
'tcx
>
TyLayout
<
'tcx
>
{
pub
fn
for_variant
(
&
self
,
variant_index
:
usize
)
->
Self
{
let
cached
=
match
self
.layout
{
Layout
::
NullablePointer
{
ref
variants
,
..
}
|
Layout
::
General
{
ref
variants
,
..
}
=>
{
let
cached
=
match
self
.variants
{
Variants
::
Single
{
..
}
=>
self
.cached
,
Variants
::
NicheFilling
{
ref
variants
,
..
}
|
Variants
::
Tagged
{
ref
variants
,
..
}
=>
{
&
variants
[
variant_index
]
}
_
=>
self
.cached
};
assert_eq!
(
cached
.variant
_index
,
Some
(
variant_index
)
);
assert_eq!
(
cached
.variant
s
,
Variants
::
Single
{
index
:
variant_index
}
);
TyLayout
{
ty
:
self
.ty
,
...
...
@@ -2081,26 +2035,17 @@ pub fn field<C>(&self, cx: C, i: usize) -> C::TyLayout
// ADTs.
ty
::
TyAdt
(
def
,
substs
)
=>
{
let
v
=
if
def
.is_enum
()
{
match
self
.variant_index
{
None
=>
match
self
.layout
{
// Discriminant field for enums (where applicable).
Layout
::
General
{
discr
,
..
}
|
Layout
::
NullablePointer
{
discr
,
..
}
=>
{
return
cx
.layout_of
([
discr
.to_ty
(
tcx
)][
i
]);
}
_
=>
{
bug!
(
"TyLayout::field_type: enum `{}` has no discriminant"
,
self
.ty
)
}
},
Some
(
v
)
=>
v
match
self
.variants
{
Variants
::
Single
{
index
}
=>
{
def
.variants
[
index
]
.fields
[
i
]
.ty
(
tcx
,
substs
)
}
}
else
{
0
};
def
.variants
[
v
]
.fields
[
i
]
.ty
(
tcx
,
substs
)
// Discriminant field for enums (where applicable).
Variants
::
Tagged
{
discr
,
..
}
|
Variants
::
NicheFilling
{
discr
,
..
}
=>
{
return
cx
.layout_of
([
discr
.to_ty
(
tcx
)][
i
]);
}
}
}
ty
::
TyProjection
(
_
)
|
ty
::
TyAnon
(
..
)
|
ty
::
TyParam
(
_
)
|
...
...
@@ -2143,18 +2088,18 @@ fn non_zero_field<C>(&self, cx: C)
HasTyCtxt
<
'tcx
>
{
let
tcx
=
cx
.tcx
();
match
(
&
self
.
layout
,
self
.abi
,
&
self
.ty.sty
)
{
match
(
&
self
.
variants
,
self
.abi
,
&
self
.ty.sty
)
{
// FIXME(eddyb) check this via value ranges on scalars.
(
&
Layout
::
Scalar
,
Abi
::
Scalar
(
Pointer
),
&
ty
::
TyRef
(
..
))
|
(
&
Layout
::
Scalar
,
Abi
::
Scalar
(
Pointer
),
&
ty
::
TyFnPtr
(
..
))
=>
{
(
_
,
Abi
::
Scalar
(
Pointer
),
&
ty
::
TyRef
(
..
))
|
(
_
,
Abi
::
Scalar
(
Pointer
),
&
ty
::
TyFnPtr
(
..
))
=>
{
Ok
(
Some
((
Size
::
from_bytes
(
0
),
Pointer
)))
}
(
&
Layout
::
Scalar
,
Abi
::
Scalar
(
Pointer
),
&
ty
::
TyAdt
(
def
,
_
))
if
def
.is_box
()
=>
{
(
_
,
Abi
::
Scalar
(
Pointer
),
&
ty
::
TyAdt
(
def
,
_
))
if
def
.is_box
()
=>
{
Ok
(
Some
((
Size
::
from_bytes
(
0
),
Pointer
)))
}
// FIXME(eddyb) check this via value ranges on scalars.
(
&
Layout
::
General
{
discr
,
..
},
_
,
&
ty
::
TyAdt
(
def
,
_
))
=>
{
(
&
Variants
::
Tagged
{
discr
,
..
},
_
,
&
ty
::
TyAdt
(
def
,
_
))
=>
{
if
def
.discriminants
(
tcx
)
.all
(|
d
|
d
.to_u128_unchecked
()
!=
0
)
{
Ok
(
Some
((
self
.fields
.offset
(
0
),
discr
)))
}
else
{
...
...
@@ -2196,20 +2141,18 @@ fn non_zero_field<C>(&self, cx: C)
}
}
impl
<
'gcx
>
HashStable
<
StableHashingContext
<
'gcx
>>
for
Layout
{
impl
<
'gcx
>
HashStable
<
StableHashingContext
<
'gcx
>>
for
Variants
{
fn
hash_stable
<
W
:
StableHasherResult
>
(
&
self
,
hcx
:
&
mut
StableHashingContext
<
'gcx
>
,
hasher
:
&
mut
StableHasher
<
W
>
)
{
use
ty
::
layout
::
Layout
::
*
;
use
ty
::
layout
::
Variants
::
*
;
mem
::
discriminant
(
self
)
.hash_stable
(
hcx
,
hasher
);
match
*
self
{
Scalar
=>
{}
Vector
=>
{}
Array
=>
{}
Univariant
=>
{}
UntaggedUnion
=>
{}
General
{
Single
{
index
}
=>
{
index
.hash_stable
(
hcx
,
hasher
);
}
Tagged
{
discr
,
discr_range
:
RangeInclusive
{
start
,
end
},
ref
variants
,
...
...
@@ -2219,7 +2162,7 @@ fn hash_stable<W: StableHasherResult>(&self,
end
.hash_stable
(
hcx
,
hasher
);
variants
.hash_stable
(
hcx
,
hasher
);
}
N
ullablePointer
{
N
icheFilling
{
nndiscr
,
ref
variants
,
ref
discr
,
...
...
@@ -2279,8 +2222,7 @@ fn hash_stable<W: StableHasherResult>(&self,
}
impl_stable_hash_for!
(
struct
::
ty
::
layout
::
CachedLayout
{
variant_index
,
layout
,
variants
,
fields
,
abi
,
size
,
...
...
src/librustc_lint/types.rs
浏览文件 @
018323ff
...
...
@@ -13,7 +13,7 @@
use
rustc
::
hir
::
def_id
::
DefId
;
use
rustc
::
ty
::
subst
::
Substs
;
use
rustc
::
ty
::{
self
,
AdtKind
,
Ty
,
TyCtxt
};
use
rustc
::
ty
::
layout
::{
Layout
,
LayoutOf
};
use
rustc
::
ty
::
layout
::{
self
,
LayoutOf
};
use
middle
::
const_val
::
ConstVal
;
use
rustc_const_eval
::
ConstContext
;
use
util
::
nodemap
::
FxHashSet
;
...
...
@@ -753,7 +753,7 @@ fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
bug!
(
"failed to get layout for `{}`: {}"
,
t
,
e
)
});
if
let
Layout
::
General
{
ref
variants
,
discr
,
..
}
=
layout
.layout
{
if
let
layout
::
Variants
::
Tagged
{
ref
variants
,
discr
,
..
}
=
layout
.variants
{
let
discr_size
=
discr
.size
(
cx
.tcx
)
.bytes
();
debug!
(
"enum `{}` is {} bytes large with layout:
\n
{:#?}"
,
...
...
src/librustc_trans/cabi_x86_64.rs
浏览文件 @
018323ff
...
...
@@ -14,7 +14,7 @@
use
abi
::{
ArgType
,
ArgAttribute
,
CastTarget
,
FnType
,
LayoutExt
,
Reg
,
RegKind
};
use
context
::
CrateContext
;
use
rustc
::
ty
::
layout
::{
self
,
Layout
,
TyLayout
,
Size
};
use
rustc
::
ty
::
layout
::{
self
,
TyLayout
,
Size
};
#[derive(Clone,
Copy,
PartialEq,
Debug)]
enum
Class
{
...
...
@@ -87,17 +87,15 @@ fn classify<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
}
layout
::
Abi
::
Aggregate
{
..
}
=>
{
// FIXME(eddyb) have to work around Rust enums for now.
// Fix is either guarantee no data where there is no field,
// by putting variants in fields, or be more clever.
match
layout
.layout
{
Layout
::
General
{
..
}
|
Layout
::
NullablePointer
{
..
}
=>
return
Err
(
Memory
),
_
=>
{}
}
for
i
in
0
..
layout
.fields
.count
()
{
let
field_off
=
off
+
layout
.fields
.offset
(
i
);
classify
(
ccx
,
layout
.field
(
ccx
,
i
),
cls
,
field_off
)
?
;
match
layout
.variants
{
layout
::
Variants
::
Single
{
..
}
=>
{
for
i
in
0
..
layout
.fields
.count
()
{
let
field_off
=
off
+
layout
.fields
.offset
(
i
);
classify
(
ccx
,
layout
.field
(
ccx
,
i
),
cls
,
field_off
)
?
;
}
}
layout
::
Variants
::
Tagged
{
..
}
|
layout
::
Variants
::
NicheFilling
{
..
}
=>
return
Err
(
Memory
),
}
}
...
...
src/librustc_trans/debuginfo/metadata.rs
浏览文件 @
018323ff
...
...
@@ -1119,7 +1119,7 @@ fn prepare_union_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
// offset of zero bytes).
struct
EnumMemberDescriptionFactory
<
'tcx
>
{
enum_type
:
Ty
<
'tcx
>
,
type_rep
:
TyLayout
<
'tcx
>
,
layout
:
TyLayout
<
'tcx
>
,
discriminant_type_metadata
:
Option
<
DIType
>
,
containing_scope
:
DIScope
,
span
:
Span
,
...
...
@@ -1129,37 +1129,8 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
fn
create_member_descriptions
<
'a
>
(
&
self
,
cx
:
&
CrateContext
<
'a
,
'tcx
>
)
->
Vec
<
MemberDescription
>
{
let
adt
=
&
self
.enum_type
.ty_adt_def
()
.unwrap
();
match
self
.type_rep.layout
{
layout
::
Layout
::
General
{
ref
variants
,
..
}
=>
{
let
discriminant_info
=
RegularDiscriminant
(
self
.discriminant_type_metadata
.expect
(
""
));
(
0
..
variants
.len
())
.map
(|
i
|
{
let
variant
=
self
.type_rep
.for_variant
(
i
);
let
(
variant_type_metadata
,
member_desc_factory
)
=
describe_enum_variant
(
cx
,
variant
,
&
adt
.variants
[
i
],
discriminant_info
,
self
.containing_scope
,
self
.span
);
let
member_descriptions
=
member_desc_factory
.create_member_descriptions
(
cx
);
set_members_of_composite_type
(
cx
,
variant_type_metadata
,
&
member_descriptions
);
MemberDescription
{
name
:
""
.to_string
(),
type_metadata
:
variant_type_metadata
,
offset
:
Size
::
from_bytes
(
0
),
size
:
variant
.size
,
align
:
variant
.align
,
flags
:
DIFlags
::
FlagZero
}
})
.collect
()
},
layout
::
Layout
::
Univariant
=>
{
match
self
.layout.variants
{
layout
::
Variants
::
Single
{
..
}
=>
{
assert
!
(
adt
.variants
.len
()
<=
1
);
if
adt
.variants
.is_empty
()
{
...
...
@@ -1167,7 +1138,7 @@ fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
}
else
{
let
(
variant_type_metadata
,
member_description_factory
)
=
describe_enum_variant
(
cx
,
self
.
type_rep
,
self
.
layout
,
&
adt
.variants
[
0
],
NoDiscriminant
,
self
.containing_scope
,
...
...
@@ -1184,19 +1155,48 @@ fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
name
:
""
.to_string
(),
type_metadata
:
variant_type_metadata
,
offset
:
Size
::
from_bytes
(
0
),
size
:
self
.
type_rep
.size
,
align
:
self
.
type_rep
.align
,
size
:
self
.
layout
.size
,
align
:
self
.
layout
.align
,
flags
:
DIFlags
::
FlagZero
}
]
}
}
layout
::
Layout
::
NullablePointer
{
layout
::
Variants
::
Tagged
{
ref
variants
,
..
}
=>
{
let
discriminant_info
=
RegularDiscriminant
(
self
.discriminant_type_metadata
.expect
(
""
));
(
0
..
variants
.len
())
.map
(|
i
|
{
let
variant
=
self
.layout
.for_variant
(
i
);
let
(
variant_type_metadata
,
member_desc_factory
)
=
describe_enum_variant
(
cx
,
variant
,
&
adt
.variants
[
i
],
discriminant_info
,
self
.containing_scope
,
self
.span
);
let
member_descriptions
=
member_desc_factory
.create_member_descriptions
(
cx
);
set_members_of_composite_type
(
cx
,
variant_type_metadata
,
&
member_descriptions
);
MemberDescription
{
name
:
""
.to_string
(),
type_metadata
:
variant_type_metadata
,
offset
:
Size
::
from_bytes
(
0
),
size
:
variant
.size
,
align
:
variant
.align
,
flags
:
DIFlags
::
FlagZero
}
})
.collect
()
}
layout
::
Variants
::
NicheFilling
{
nndiscr
,
discr
,
..
}
=>
{
let
variant
=
self
.
type_rep
.for_variant
(
nndiscr
as
usize
);
let
variant
=
self
.
layout
.for_variant
(
nndiscr
as
usize
);
// Create a description of the non-null variant
let
(
variant_type_metadata
,
member_description_factory
)
=
describe_enum_variant
(
cx
,
...
...
@@ -1237,8 +1237,8 @@ fn compute_field_path<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
}
}
compute_field_path
(
cx
,
&
mut
name
,
self
.
type_rep
,
self
.
type_rep
.fields
.offset
(
0
),
self
.
layout
,
self
.
layout
.fields
.offset
(
0
),
discr
.size
(
cx
));
name
.push_str
(
&
adt
.variants
[(
1
-
nndiscr
)
as
usize
]
.name
.as_str
());
...
...
@@ -1253,8 +1253,7 @@ fn compute_field_path<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
flags
:
DIFlags
::
FlagZero
}
]
},
ref
l
@
_
=>
bug!
(
"Not an enum layout: {:#?}"
,
l
)
}
}
}
}
...
...
@@ -1429,21 +1428,20 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
}
};
let
type_rep
=
cx
.layout_of
(
enum_type
);
let
layout
=
cx
.layout_of
(
enum_type
);
let
discriminant_type_metadata
=
match
type_rep
.layout
{
layout
::
Layout
::
NullablePointer
{
..
}
|
layout
::
Layout
::
Univariant
{
..
}
=>
None
,
layout
::
Layout
::
General
{
discr
,
..
}
=>
Some
(
discriminant_type_metadata
(
discr
)),
ref
l
@
_
=>
bug!
(
"Not an enum layout: {:#?}"
,
l
)
let
discriminant_type_metadata
=
match
layout
.variants
{
layout
::
Variants
::
Single
{
..
}
|
layout
::
Variants
::
NicheFilling
{
..
}
=>
None
,
layout
::
Variants
::
Tagged
{
discr
,
..
}
=>
Some
(
discriminant_type_metadata
(
discr
)),
};
match
(
type_rep
.abi
,
discriminant_type_metadata
)
{
match
(
layout
.abi
,
discriminant_type_metadata
)
{
(
layout
::
Abi
::
Scalar
(
_
),
Some
(
discr
))
=>
return
FinalMetadata
(
discr
),
_
=>
{}
}
let
(
enum_type_size
,
enum_type_align
)
=
type_rep
.size_and_align
();
let
(
enum_type_size
,
enum_type_align
)
=
layout
.size_and_align
();
let
enum_name
=
CString
::
new
(
enum_name
)
.unwrap
();
let
unique_type_id_str
=
CString
::
new
(
...
...
@@ -1471,7 +1469,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
enum_metadata
,
EnumMDF
(
EnumMemberDescriptionFactory
{
enum_type
,
type_rep
,
layout
,
discriminant_type_metadata
,
containing_scope
,
span
,
...
...
src/librustc_trans/intrinsic.rs
浏览文件 @
018323ff
...
...
@@ -394,12 +394,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
},
"discriminant_value"
=>
{
match
substs
.type_at
(
0
)
.sty
{
ty
::
TyAdt
(
adt
,
..
)
if
adt
.is_enum
()
=>
{
args
[
0
]
.deref
(
bcx
.ccx
)
.trans_get_discr
(
bcx
,
ret_ty
)
}
_
=>
C_null
(
llret_ty
)
}
args
[
0
]
.deref
(
bcx
.ccx
)
.trans_get_discr
(
bcx
,
ret_ty
)
}
"align_offset"
=>
{
...
...
src/librustc_trans/mir/constant.rs
浏览文件 @
018323ff
...
...
@@ -1094,8 +1094,26 @@ fn trans_const_adt<'a, 'tcx>(
mir
::
AggregateKind
::
Adt
(
_
,
index
,
_
,
_
)
=>
index
,
_
=>
0
,
};
match
l
.layout
{
layout
::
Layout
::
General
{
..
}
=>
{
match
l
.variants
{
layout
::
Variants
::
Single
{
index
}
=>
{
assert_eq!
(
variant_index
,
index
);
if
let
layout
::
Abi
::
Vector
{
..
}
=
l
.abi
{
Const
::
new
(
C_vector
(
&
vals
.iter
()
.map
(|
x
|
x
.llval
)
.collect
::
<
Vec
<
_
>>
()),
t
)
}
else
if
let
layout
::
FieldPlacement
::
Union
(
_
)
=
l
.fields
{
assert_eq!
(
variant_index
,
0
);
assert_eq!
(
vals
.len
(),
1
);
let
contents
=
[
vals
[
0
]
.llval
,
padding
(
ccx
,
l
.size
-
ccx
.size_of
(
vals
[
0
]
.ty
))
];
Const
::
new
(
C_struct
(
ccx
,
&
contents
,
l
.is_packed
()),
t
)
}
else
{
assert_eq!
(
variant_index
,
0
);
build_const_struct
(
ccx
,
l
,
vals
,
None
)
}
}
layout
::
Variants
::
Tagged
{
..
}
=>
{
let
discr
=
match
*
kind
{
mir
::
AggregateKind
::
Adt
(
adt_def
,
_
,
_
,
_
)
=>
{
adt_def
.discriminant_for_variant
(
ccx
.tcx
(),
variant_index
)
...
...
@@ -1112,23 +1130,7 @@ fn trans_const_adt<'a, 'tcx>(
build_const_struct
(
ccx
,
l
.for_variant
(
variant_index
),
vals
,
Some
(
discr
))
}
}
layout
::
Layout
::
UntaggedUnion
=>
{
assert_eq!
(
variant_index
,
0
);
let
contents
=
[
vals
[
0
]
.llval
,
padding
(
ccx
,
l
.size
-
ccx
.size_of
(
vals
[
0
]
.ty
))
];
Const
::
new
(
C_struct
(
ccx
,
&
contents
,
l
.is_packed
()),
t
)
}
layout
::
Layout
::
Univariant
=>
{
assert_eq!
(
variant_index
,
0
);
build_const_struct
(
ccx
,
l
,
vals
,
None
)
}
layout
::
Layout
::
Vector
=>
{
Const
::
new
(
C_vector
(
&
vals
.iter
()
.map
(|
x
|
x
.llval
)
.collect
::
<
Vec
<
_
>>
()),
t
)
}
layout
::
Layout
::
NullablePointer
{
nndiscr
,
..
}
=>
{
layout
::
Variants
::
NicheFilling
{
nndiscr
,
..
}
=>
{
if
variant_index
as
u64
==
nndiscr
{
build_const_struct
(
ccx
,
l
.for_variant
(
variant_index
),
vals
,
None
)
}
else
{
...
...
@@ -1137,7 +1139,6 @@ fn trans_const_adt<'a, 'tcx>(
Const
::
new
(
C_null
(
ccx
.layout_of
(
t
)
.llvm_type
(
ccx
)),
t
)
}
}
_
=>
bug!
(
"trans_const_adt: cannot handle type {} repreented as {:#?}"
,
t
,
l
)
}
}
...
...
src/librustc_trans/mir/lvalue.rs
浏览文件 @
018323ff
...
...
@@ -296,10 +296,13 @@ pub fn project_field(self, bcx: &Builder<'a, 'tcx>, ix: usize) -> LvalueRef<'tcx
/// Obtain the actual discriminant of a value.
pub
fn
trans_get_discr
(
self
,
bcx
:
&
Builder
<
'a
,
'tcx
>
,
cast_to
:
Ty
<
'tcx
>
)
->
ValueRef
{
let
cast_to
=
bcx
.ccx
.layout_of
(
cast_to
)
.immediate_llvm_type
(
bcx
.ccx
);
match
self
.layout.layout
{
layout
::
Layout
::
Univariant
{
..
}
|
layout
::
Layout
::
UntaggedUnion
{
..
}
=>
return
C_uint
(
cast_to
,
0
),
_
=>
{}
match
self
.layout.variants
{
layout
::
Variants
::
Single
{
index
}
=>
{
assert_eq!
(
index
,
0
);
return
C_uint
(
cast_to
,
0
);
}
layout
::
Variants
::
Tagged
{
..
}
|
layout
::
Variants
::
NicheFilling
{
..
}
=>
{},
}
let
discr
=
self
.project_field
(
bcx
,
0
);
...
...
@@ -307,8 +310,10 @@ pub fn trans_get_discr(self, bcx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> Valu
layout
::
Abi
::
Scalar
(
discr
)
=>
discr
,
_
=>
bug!
(
"discriminant not scalar: {:#?}"
,
discr
.layout
)
};
let
(
min
,
max
)
=
match
self
.layout.layout
{
layout
::
Layout
::
General
{
ref
discr_range
,
..
}
=>
(
discr_range
.start
,
discr_range
.end
),
let
(
min
,
max
)
=
match
self
.layout.variants
{
layout
::
Variants
::
Tagged
{
ref
discr_range
,
..
}
=>
{
(
discr_range
.start
,
discr_range
.end
)
}
_
=>
(
0
,
u64
::
max_value
()),
};
let
max_next
=
max
.wrapping_add
(
1
);
...
...
@@ -333,20 +338,20 @@ pub fn trans_get_discr(self, bcx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> Valu
bcx
.load
(
discr
.llval
,
discr
.alignment
.non_abi
())
}
};
match
self
.layout.layout
{
layout
::
Layout
::
General
{
..
}
=>
{
match
self
.layout.variants
{
layout
::
Variants
::
Single
{
..
}
=>
bug!
(),
layout
::
Variants
::
Tagged
{
..
}
=>
{
let
signed
=
match
discr_scalar
{
layout
::
Int
(
_
,
signed
)
=>
signed
,
_
=>
false
};
bcx
.intcast
(
lldiscr
,
cast_to
,
signed
)
}
layout
::
Layout
::
NullablePointer
{
nndiscr
,
..
}
=>
{
layout
::
Variants
::
NicheFilling
{
nndiscr
,
..
}
=>
{
let
cmp
=
if
nndiscr
==
0
{
llvm
::
IntEQ
}
else
{
llvm
::
IntNE
};
let
zero
=
C_null
(
discr
.layout
.llvm_type
(
bcx
.ccx
));
bcx
.intcast
(
bcx
.icmp
(
cmp
,
lldiscr
,
zero
),
cast_to
,
false
)
}
_
=>
bug!
(
"{} is not an enum"
,
self
.layout.ty
)
}
}
...
...
@@ -356,13 +361,17 @@ pub fn trans_set_discr(&self, bcx: &Builder<'a, 'tcx>, variant_index: usize) {
let
to
=
self
.layout.ty
.ty_adt_def
()
.unwrap
()
.discriminant_for_variant
(
bcx
.tcx
(),
variant_index
)
.to_u128_unchecked
()
as
u64
;
match
self
.layout.layout
{
layout
::
Layout
::
General
{
..
}
=>
{
match
self
.layout.variants
{
layout
::
Variants
::
Single
{
index
}
=>
{
assert_eq!
(
to
,
0
);
assert_eq!
(
variant_index
,
index
);
}
layout
::
Variants
::
Tagged
{
..
}
=>
{
let
ptr
=
self
.project_field
(
bcx
,
0
);
bcx
.store
(
C_int
(
ptr
.layout
.llvm_type
(
bcx
.ccx
),
to
as
i64
),
ptr
.llval
,
ptr
.alignment
.non_abi
());
}
layout
::
Layout
::
NullablePointer
{
nndiscr
,
..
}
=>
{
layout
::
Variants
::
NicheFilling
{
nndiscr
,
..
}
=>
{
if
to
!=
nndiscr
{
let
use_memset
=
match
self
.layout.abi
{
layout
::
Abi
::
Scalar
(
_
)
=>
false
,
...
...
@@ -385,9 +394,6 @@ pub fn trans_set_discr(&self, bcx: &Builder<'a, 'tcx>, variant_index: usize) {
}
}
}
_
=>
{
assert_eq!
(
to
,
0
);
}
}
}
...
...
src/librustc_trans/mir/rvalue.rs
浏览文件 @
018323ff
...
...
@@ -11,7 +11,7 @@
use
llvm
::{
self
,
ValueRef
};
use
rustc
::
ty
::{
self
,
Ty
};
use
rustc
::
ty
::
cast
::{
CastTy
,
IntTy
};
use
rustc
::
ty
::
layout
::{
self
,
Layout
,
Layout
Of
};
use
rustc
::
ty
::
layout
::{
self
,
LayoutOf
};
use
rustc
::
mir
;
use
rustc
::
middle
::
lang_items
::
ExchangeMallocFnLangItem
;
use
rustc_apfloat
::{
ieee
,
Float
,
Status
,
Round
};
...
...
@@ -278,8 +278,10 @@ pub fn trans_rvalue_operand(&mut self,
let
ll_t_out
=
cast
.immediate_llvm_type
(
bcx
.ccx
);
let
llval
=
operand
.immediate
();
if
let
Layout
::
General
{
ref
discr_range
,
..
}
=
operand
.layout.layout
{
if
discr_range
.end
>
discr_range
.start
{
match
operand
.layout.variants
{
layout
::
Variants
::
Tagged
{
ref
discr_range
,
..
}
if
discr_range
.end
>
discr_range
.start
=>
{
// We want `table[e as usize]` to not
// have bound checks, and this is the most
// convenient place to put the `assume`.
...
...
@@ -290,6 +292,7 @@ pub fn trans_rvalue_operand(&mut self,
C_uint
(
ll_t_in
,
discr_range
.end
)
));
}
_
=>
{}
}
let
signed
=
match
operand
.layout.abi
{
...
...
src/librustc_trans/type_of.rs
浏览文件 @
018323ff
...
...
@@ -40,8 +40,13 @@ fn uncached_llvm_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
let
mut
name
=
String
::
with_capacity
(
32
);
let
printer
=
DefPathBasedNames
::
new
(
ccx
.tcx
(),
true
,
true
);
printer
.push_type_name
(
layout
.ty
,
&
mut
name
);
if
let
(
&
ty
::
TyAdt
(
def
,
_
),
Some
(
v
))
=
(
&
layout
.ty.sty
,
layout
.variant_index
)
{
write!
(
&
mut
name
,
"::{}"
,
def
.variants
[
v
]
.name
)
.unwrap
();
match
(
&
layout
.ty.sty
,
&
layout
.variants
)
{
(
&
ty
::
TyAdt
(
def
,
_
),
&
layout
::
Variants
::
Single
{
index
})
=>
{
if
def
.is_enum
()
&&
!
def
.variants
.is_empty
()
{
write!
(
&
mut
name
,
"::{}"
,
def
.variants
[
index
]
.name
)
.unwrap
();
}
}
_
=>
{}
}
Some
(
name
)
}
...
...
@@ -206,7 +211,11 @@ fn llvm_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Type {
// Check the cache.
if
let
Some
(
&
llty
)
=
ccx
.lltypes
()
.borrow
()
.get
(
&
(
self
.ty
,
self
.variant_index
))
{
let
variant_index
=
match
self
.variants
{
layout
::
Variants
::
Single
{
index
}
=>
Some
(
index
),
_
=>
None
};
if
let
Some
(
&
llty
)
=
ccx
.lltypes
()
.borrow
()
.get
(
&
(
self
.ty
,
variant_index
))
{
return
llty
;
}
...
...
@@ -221,7 +230,7 @@ fn llvm_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Type {
let
mut
defer
=
None
;
let
llty
=
if
self
.ty
!=
normal_ty
{
let
mut
layout
=
ccx
.layout_of
(
normal_ty
);
if
let
Some
(
v
)
=
self
.
variant_index
{
if
let
Some
(
v
)
=
variant_index
{
layout
=
layout
.for_variant
(
v
);
}
layout
.llvm_type
(
ccx
)
...
...
@@ -230,7 +239,7 @@ fn llvm_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Type {
};
debug!
(
"--> mapped {:#?} to llty={:?}"
,
self
,
llty
);
ccx
.lltypes
()
.borrow_mut
()
.insert
((
self
.ty
,
self
.
variant_index
),
llty
);
ccx
.lltypes
()
.borrow_mut
()
.insert
((
self
.ty
,
variant_index
),
llty
);
if
let
Some
((
mut
llty
,
layout
))
=
defer
{
llty
.set_struct_body
(
&
struct_llfields
(
ccx
,
layout
),
layout
.is_packed
())
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录