Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
5b7f4e9e
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
5b7f4e9e
编写于
3月 29, 2019
作者:
E
Eduard-Mihai Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc_target: factor out common fields of non-Single Variants.
上级
70a497a4
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
193 addition
and
134 deletion
+193
-134
src/librustc/ty/layout.rs
src/librustc/ty/layout.rs
+34
-23
src/librustc_codegen_llvm/debuginfo/metadata.rs
src/librustc_codegen_llvm/debuginfo/metadata.rs
+48
-20
src/librustc_codegen_llvm/type_of.rs
src/librustc_codegen_llvm/type_of.rs
+7
-1
src/librustc_codegen_ssa/mir/place.rs
src/librustc_codegen_ssa/mir/place.rs
+20
-16
src/librustc_codegen_ssa/mir/rvalue.rs
src/librustc_codegen_ssa/mir/rvalue.rs
+1
-2
src/librustc_lint/types.rs
src/librustc_lint/types.rs
+46
-41
src/librustc_mir/interpret/cast.rs
src/librustc_mir/interpret/cast.rs
+1
-2
src/librustc_mir/interpret/operand.rs
src/librustc_mir/interpret/operand.rs
+7
-9
src/librustc_mir/interpret/place.rs
src/librustc_mir/interpret/place.rs
+12
-6
src/librustc_mir/interpret/visitor.rs
src/librustc_mir/interpret/visitor.rs
+1
-2
src/librustc_target/abi/call/x86_64.rs
src/librustc_target/abi/call/x86_64.rs
+1
-2
src/librustc_target/abi/mod.rs
src/librustc_target/abi/mod.rs
+15
-10
未找到文件。
src/librustc/ty/layout.rs
浏览文件 @
5b7f4e9e
...
...
@@ -913,11 +913,13 @@ enum StructKind {
}
return
Ok
(
tcx
.intern_layout
(
LayoutDetails
{
variants
:
Variants
::
NicheFilling
{
dataful_variant
:
i
,
niche_variants
,
niche
:
niche_scalar
,
niche_start
,
variants
:
Variants
::
Multiple
{
discr
:
niche_scalar
,
discr_kind
:
DiscriminantKind
::
Niche
{
dataful_variant
:
i
,
niche_variants
,
niche_start
,
},
variants
:
st
,
},
fields
:
FieldPlacement
::
Arbitrary
{
...
...
@@ -1137,8 +1139,9 @@ enum StructKind {
}
tcx
.intern_layout
(
LayoutDetails
{
variants
:
Variants
::
Tagged
{
tag
,
variants
:
Variants
::
Multiple
{
discr
:
tag
,
discr_kind
:
DiscriminantKind
::
Tag
,
variants
:
layout_variants
,
},
fields
:
FieldPlacement
::
Arbitrary
{
...
...
@@ -1293,8 +1296,7 @@ fn record_layout_for_printing_outlined(&self, layout: TyLayout<'tcx>) {
}
}
Variants
::
NicheFilling
{
..
}
|
Variants
::
Tagged
{
..
}
=>
{
Variants
::
Multiple
{
ref
discr
,
ref
discr_kind
,
..
}
=>
{
debug!
(
"print-type-size `{:#?}` adt general variants def {}"
,
layout
.ty
,
adt_def
.variants
.len
());
let
variant_infos
:
Vec
<
_
>
=
...
...
@@ -1306,8 +1308,8 @@ fn record_layout_for_printing_outlined(&self, layout: TyLayout<'tcx>) {
layout
.for_variant
(
self
,
i
))
})
.collect
();
record
(
adt_kind
.into
(),
adt_packed
,
match
layout
.variants
{
Variants
::
Tagged
{
ref
tag
,
..
}
=>
Some
(
tag
.value
.size
(
self
)),
record
(
adt_kind
.into
(),
adt_packed
,
match
discr_kind
{
DiscriminantKind
::
Tag
=>
Some
(
discr
.value
.size
(
self
)),
_
=>
None
},
variant_infos
);
}
...
...
@@ -1627,8 +1629,7 @@ fn for_variant(this: TyLayout<'tcx>, cx: &C, variant_index: VariantIdx) -> TyLay
})
}
Variants
::
NicheFilling
{
ref
variants
,
..
}
|
Variants
::
Tagged
{
ref
variants
,
..
}
=>
{
Variants
::
Multiple
{
ref
variants
,
..
}
=>
{
&
variants
[
variant_index
]
}
};
...
...
@@ -1735,8 +1736,7 @@ fn field(this: TyLayout<'tcx>, cx: &C, i: usize) -> C::TyLayout {
}
// Discriminant field for enums (where applicable).
Variants
::
Tagged
{
tag
:
ref
discr
,
..
}
|
Variants
::
NicheFilling
{
niche
:
ref
discr
,
..
}
=>
{
Variants
::
Multiple
{
ref
discr
,
..
}
=>
{
assert_eq!
(
i
,
0
);
let
layout
=
LayoutDetails
::
scalar
(
cx
,
discr
.clone
());
return
MaybeResult
::
from_ok
(
TyLayout
{
...
...
@@ -1881,26 +1881,37 @@ fn hash_stable<W: StableHasherResult>(&self,
Single
{
index
}
=>
{
index
.hash_stable
(
hcx
,
hasher
);
}
Tagged
{
ref
tag
,
Multiple
{
ref
discr
,
ref
discr_kind
,
ref
variants
,
}
=>
{
tag
.hash_stable
(
hcx
,
hasher
);
discr
.hash_stable
(
hcx
,
hasher
);
discr_kind
.hash_stable
(
hcx
,
hasher
);
variants
.hash_stable
(
hcx
,
hasher
);
}
NicheFilling
{
}
}
}
impl
<
'a
>
HashStable
<
StableHashingContext
<
'a
>>
for
DiscriminantKind
{
fn
hash_stable
<
W
:
StableHasherResult
>
(
&
self
,
hcx
:
&
mut
StableHashingContext
<
'a
>
,
hasher
:
&
mut
StableHasher
<
W
>
)
{
use
crate
::
ty
::
layout
::
DiscriminantKind
::
*
;
mem
::
discriminant
(
self
)
.hash_stable
(
hcx
,
hasher
);
match
*
self
{
Tag
=>
{}
Niche
{
dataful_variant
,
ref
niche_variants
,
ref
niche
,
niche_start
,
ref
variants
,
}
=>
{
dataful_variant
.hash_stable
(
hcx
,
hasher
);
niche_variants
.start
()
.hash_stable
(
hcx
,
hasher
);
niche_variants
.end
()
.hash_stable
(
hcx
,
hasher
);
niche
.hash_stable
(
hcx
,
hasher
);
niche_start
.hash_stable
(
hcx
,
hasher
);
variants
.hash_stable
(
hcx
,
hasher
);
}
}
}
...
...
src/librustc_codegen_llvm/debuginfo/metadata.rs
浏览文件 @
5b7f4e9e
...
...
@@ -1235,7 +1235,11 @@ fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
}
]
}
layout
::
Variants
::
Tagged
{
ref
variants
,
..
}
=>
{
layout
::
Variants
::
Multiple
{
discr_kind
:
layout
::
DiscriminantKind
::
Tag
,
ref
variants
,
..
}
=>
{
let
discriminant_info
=
if
fallback
{
RegularDiscriminant
(
self
.discriminant_type_metadata
.expect
(
""
))
...
...
@@ -1277,12 +1281,14 @@ fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
}
})
.collect
()
}
layout
::
Variants
::
NicheFilling
{
ref
niche_variants
,
niche_start
,
layout
::
Variants
::
Multiple
{
discr_kind
:
layout
::
DiscriminantKind
::
Niche
{
ref
niche_variants
,
niche_start
,
dataful_variant
,
},
ref
discr
,
ref
variants
,
dataful_variant
,
ref
niche
,
}
=>
{
if
fallback
{
let
variant
=
self
.layout
.for_variant
(
cx
,
dataful_variant
);
...
...
@@ -1369,7 +1375,11 @@ fn compute_field_path<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
let
value
=
(
i
.as_u32
()
as
u128
)
.wrapping_sub
(
niche_variants
.start
()
.as_u32
()
as
u128
)
.wrapping_add
(
niche_start
);
let
value
=
truncate
(
value
,
niche
.value
.size
(
cx
));
let
value
=
truncate
(
value
,
discr
.value
.size
(
cx
));
// NOTE(eddyb) do *NOT* remove this assert, until
// we pass the full 128-bit value to LLVM, otherwise
// truncation will be silent and remain undetected.
assert_eq!
(
value
as
u64
as
u128
,
value
);
Some
(
value
as
u64
)
};
...
...
@@ -1586,8 +1596,11 @@ fn prepare_enum_metadata(
let
layout
=
cx
.layout_of
(
enum_type
);
match
(
&
layout
.abi
,
&
layout
.variants
)
{
(
&
layout
::
Abi
::
Scalar
(
_
),
&
layout
::
Variants
::
Tagged
{
ref
tag
,
..
})
=>
return
FinalMetadata
(
discriminant_type_metadata
(
tag
.value
)),
(
&
layout
::
Abi
::
Scalar
(
_
),
&
layout
::
Variants
::
Multiple
{
discr_kind
:
layout
::
DiscriminantKind
::
Tag
,
ref
discr
,
..
})
=>
return
FinalMetadata
(
discriminant_type_metadata
(
discr
.value
)),
_
=>
{}
}
...
...
@@ -1599,9 +1612,16 @@ fn prepare_enum_metadata(
if
use_enum_fallback
(
cx
)
{
let
discriminant_type_metadata
=
match
layout
.variants
{
layout
::
Variants
::
Single
{
..
}
|
layout
::
Variants
::
NicheFilling
{
..
}
=>
None
,
layout
::
Variants
::
Tagged
{
ref
tag
,
..
}
=>
{
Some
(
discriminant_type_metadata
(
tag
.value
))
layout
::
Variants
::
Multiple
{
discr_kind
:
layout
::
DiscriminantKind
::
Niche
{
..
},
..
}
=>
None
,
layout
::
Variants
::
Multiple
{
discr_kind
:
layout
::
DiscriminantKind
::
Tag
,
ref
discr
,
..
}
=>
{
Some
(
discriminant_type_metadata
(
discr
.value
))
}
};
...
...
@@ -1636,16 +1656,20 @@ fn prepare_enum_metadata(
);
}
let
discriminator_metadata
=
match
&
layout
.variants
{
let
discriminator_metadata
=
match
layout
.variants
{
// A single-variant enum has no discriminant.
&
layout
::
Variants
::
Single
{
..
}
=>
None
,
layout
::
Variants
::
Single
{
..
}
=>
None
,
&
layout
::
Variants
::
NicheFilling
{
ref
niche
,
..
}
=>
{
layout
::
Variants
::
Multiple
{
discr_kind
:
layout
::
DiscriminantKind
::
Niche
{
..
},
ref
discr
,
..
}
=>
{
// Find the integer type of the correct size.
let
size
=
niche
.value
.size
(
cx
);
let
align
=
niche
.value
.align
(
cx
);
let
size
=
discr
.value
.size
(
cx
);
let
align
=
discr
.value
.align
(
cx
);
let
discr_type
=
match
niche
.value
{
let
discr_type
=
match
discr
.value
{
layout
::
Int
(
t
,
_
)
=>
t
,
layout
::
Float
(
layout
::
FloatTy
::
F32
)
=>
Integer
::
I32
,
layout
::
Float
(
layout
::
FloatTy
::
F64
)
=>
Integer
::
I64
,
...
...
@@ -1668,8 +1692,12 @@ fn prepare_enum_metadata(
}
},
&
layout
::
Variants
::
Tagged
{
ref
tag
,
..
}
=>
{
let
discr_type
=
tag
.value
.to_ty
(
cx
.tcx
);
layout
::
Variants
::
Multiple
{
discr_kind
:
layout
::
DiscriminantKind
::
Tag
,
ref
discr
,
..
}
=>
{
let
discr_type
=
discr
.value
.to_ty
(
cx
.tcx
);
let
(
size
,
align
)
=
cx
.size_and_align_of
(
discr_type
);
let
discr_metadata
=
basic_type_metadata
(
cx
,
discr_type
);
...
...
src/librustc_codegen_llvm/type_of.rs
浏览文件 @
5b7f4e9e
...
...
@@ -452,7 +452,13 @@ fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size)
_
=>
{
let
mut
data_variant
=
match
self
.variants
{
layout
::
Variants
::
NicheFilling
{
dataful_variant
,
..
}
=>
{
layout
::
Variants
::
Multiple
{
discr_kind
:
layout
::
DiscriminantKind
::
Niche
{
dataful_variant
,
..
},
..
}
=>
{
// Only the niche itself is always initialized,
// so only check for a pointer at its offset.
//
...
...
src/librustc_codegen_ssa/mir/place.rs
浏览文件 @
5b7f4e9e
...
...
@@ -216,37 +216,36 @@ pub fn codegen_get_discr<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
if
self
.layout.abi
.is_uninhabited
()
{
return
bx
.cx
()
.const_undef
(
cast_to
);
}
match
self
.layout.variants
{
let
(
discr_scalar
,
discr_kind
)
=
match
self
.layout.variants
{
layout
::
Variants
::
Single
{
index
}
=>
{
let
discr_val
=
self
.layout.ty
.ty_adt_def
()
.map_or
(
index
.as_u32
()
as
u128
,
|
def
|
def
.discriminant_for_variant
(
bx
.cx
()
.tcx
(),
index
)
.val
);
return
bx
.cx
()
.const_uint_big
(
cast_to
,
discr_val
);
}
layout
::
Variants
::
Tagged
{
..
}
|
layout
::
Variants
::
NicheFilling
{
..
}
=>
{},
}
layout
::
Variants
::
Multiple
{
ref
discr
,
ref
discr_kind
,
..
}
=>
{
(
discr
,
discr_kind
)
}
};
let
discr
=
self
.project_field
(
bx
,
0
);
let
lldiscr
=
bx
.load_operand
(
discr
)
.immediate
();
match
self
.layout.variants
{
layout
::
Variants
::
Single
{
..
}
=>
bug!
(),
layout
::
Variants
::
Tagged
{
ref
tag
,
..
}
=>
{
let
signed
=
match
tag
.value
{
match
*
discr_kind
{
layout
::
DiscriminantKind
::
Tag
=>
{
let
signed
=
match
discr_scalar
.value
{
// We use `i1` for bytes that are always `0` or `1`,
// e.g., `#[repr(i8)] enum E { A, B }`, but we can't
// let LLVM interpret the `i1` as signed, because
// then `i1 1` (i.e., E::B) is effectively `i8 -1`.
layout
::
Int
(
_
,
signed
)
=>
!
tag
.is_bool
()
&&
signed
,
layout
::
Int
(
_
,
signed
)
=>
!
discr_scalar
.is_bool
()
&&
signed
,
_
=>
false
};
bx
.intcast
(
lldiscr
,
cast_to
,
signed
)
}
layout
::
Variants
::
NicheFilling
{
layout
::
DiscriminantKind
::
Niche
{
dataful_variant
,
ref
niche_variants
,
niche_start
,
..
}
=>
{
let
niche_llty
=
bx
.cx
()
.immediate_backend_type
(
discr
.layout
);
if
niche_variants
.start
()
==
niche_variants
.end
()
{
...
...
@@ -291,7 +290,10 @@ pub fn codegen_set_discr<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
layout
::
Variants
::
Single
{
index
}
=>
{
assert_eq!
(
index
,
variant_index
);
}
layout
::
Variants
::
Tagged
{
..
}
=>
{
layout
::
Variants
::
Multiple
{
discr_kind
:
layout
::
DiscriminantKind
::
Tag
,
..
}
=>
{
let
ptr
=
self
.project_field
(
bx
,
0
);
let
to
=
self
.layout.ty
.ty_adt_def
()
.unwrap
()
.discriminant_for_variant
(
bx
.tcx
(),
variant_index
)
...
...
@@ -301,10 +303,12 @@ pub fn codegen_set_discr<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
ptr
.llval
,
ptr
.align
);
}
layout
::
Variants
::
NicheFilling
{
dataful_variant
,
ref
niche_variants
,
niche_start
,
layout
::
Variants
::
Multiple
{
discr_kind
:
layout
::
DiscriminantKind
::
Niche
{
dataful_variant
,
ref
niche_variants
,
niche_start
,
},
..
}
=>
{
if
variant_index
!=
dataful_variant
{
...
...
src/librustc_codegen_ssa/mir/rvalue.rs
浏览文件 @
5b7f4e9e
...
...
@@ -303,8 +303,7 @@ pub fn codegen_rvalue_operand(
});
}
}
layout
::
Variants
::
Tagged
{
..
}
|
layout
::
Variants
::
NicheFilling
{
..
}
=>
{},
layout
::
Variants
::
Multiple
{
..
}
=>
{},
}
let
llval
=
operand
.immediate
();
...
...
src/librustc_lint/types.rs
浏览文件 @
5b7f4e9e
...
...
@@ -842,51 +842,56 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
let
item_def_id
=
cx
.tcx
.hir
()
.local_def_id_from_hir_id
(
it
.hir_id
);
let
t
=
cx
.tcx
.type_of
(
item_def_id
);
let
ty
=
cx
.tcx
.erase_regions
(
&
t
);
match
cx
.layout_of
(
ty
)
{
Ok
(
layout
)
=>
{
let
variants
=
&
layout
.variants
;
if
let
layout
::
Variants
::
Tagged
{
ref
variants
,
ref
tag
,
..
}
=
variants
{
let
discr_size
=
tag
.value
.size
(
&
cx
.tcx
)
.bytes
();
debug!
(
"enum `{}` is {} bytes large with layout:
\n
{:#?}"
,
t
,
layout
.size
.bytes
(),
layout
);
let
(
largest
,
slargest
,
largest_index
)
=
enum_definition
.variants
.iter
()
.zip
(
variants
)
.map
(|(
variant
,
variant_layout
)|
{
// Subtract the size of the enum discriminant.
let
bytes
=
variant_layout
.size
.bytes
()
.saturating_sub
(
discr_size
);
debug!
(
"- variant `{}` is {} bytes large"
,
variant
.node.ident
,
bytes
);
bytes
})
.enumerate
()
.fold
((
0
,
0
,
0
),
|(
l
,
s
,
li
),
(
idx
,
size
)|
if
size
>
l
{
(
size
,
l
,
idx
)
}
else
if
size
>
s
{
(
l
,
size
,
li
)
}
else
{
(
l
,
s
,
li
)
});
// We only warn if the largest variant is at least thrice as large as
// the second-largest.
if
largest
>
slargest
*
3
&&
slargest
>
0
{
cx
.span_lint
(
VARIANT_SIZE_DIFFERENCES
,
enum_definition
.variants
[
largest_index
]
.span
,
&
format!
(
"enum variant is more than three times
\
larger ({} bytes) than the next largest"
,
largest
));
}
}
}
let
layout
=
match
cx
.layout_of
(
ty
)
{
Ok
(
layout
)
=>
layout
,
Err
(
ty
::
layout
::
LayoutError
::
Unknown
(
_
))
=>
return
,
Err
(
err
@
ty
::
layout
::
LayoutError
::
SizeOverflow
(
_
))
=>
{
bug!
(
"failed to get layout for `{}`: {}"
,
t
,
err
);
}
};
let
(
variants
,
tag
)
=
match
layout
.variants
{
layout
::
Variants
::
Multiple
{
discr_kind
:
layout
::
DiscriminantKind
::
Tag
,
ref
discr
,
ref
variants
,
}
=>
(
variants
,
discr
),
_
=>
return
,
};
let
discr_size
=
tag
.value
.size
(
&
cx
.tcx
)
.bytes
();
debug!
(
"enum `{}` is {} bytes large with layout:
\n
{:#?}"
,
t
,
layout
.size
.bytes
(),
layout
);
let
(
largest
,
slargest
,
largest_index
)
=
enum_definition
.variants
.iter
()
.zip
(
variants
)
.map
(|(
variant
,
variant_layout
)|
{
// Subtract the size of the enum discriminant.
let
bytes
=
variant_layout
.size
.bytes
()
.saturating_sub
(
discr_size
);
debug!
(
"- variant `{}` is {} bytes large"
,
variant
.node.ident
,
bytes
);
bytes
})
.enumerate
()
.fold
((
0
,
0
,
0
),
|(
l
,
s
,
li
),
(
idx
,
size
)|
if
size
>
l
{
(
size
,
l
,
idx
)
}
else
if
size
>
s
{
(
l
,
size
,
li
)
}
else
{
(
l
,
s
,
li
)
});
// We only warn if the largest variant is at least thrice as large as
// the second-largest.
if
largest
>
slargest
*
3
&&
slargest
>
0
{
cx
.span_lint
(
VARIANT_SIZE_DIFFERENCES
,
enum_definition
.variants
[
largest_index
]
.span
,
&
format!
(
"enum variant is more than three times
\
larger ({} bytes) than the next largest"
,
largest
));
}
}
}
...
...
src/librustc_mir/interpret/cast.rs
浏览文件 @
5b7f4e9e
...
...
@@ -64,8 +64,7 @@ pub fn cast(
dest
);
}
}
layout
::
Variants
::
Tagged
{
..
}
|
layout
::
Variants
::
NicheFilling
{
..
}
=>
{},
layout
::
Variants
::
Multiple
{
..
}
=>
{},
}
let
dest_val
=
self
.cast_scalar
(
src
.to_scalar
()
?
,
src
.layout
,
dest
.layout
)
?
;
...
...
src/librustc_mir/interpret/operand.rs
浏览文件 @
5b7f4e9e
...
...
@@ -610,25 +610,24 @@ pub fn read_discriminant(
)
->
EvalResult
<
'tcx
,
(
u128
,
VariantIdx
)
>
{
trace!
(
"read_discriminant_value {:#?}"
,
rval
.layout
);
match
rval
.layout.variants
{
let
discr_kind
=
match
rval
.layout.variants
{
layout
::
Variants
::
Single
{
index
}
=>
{
let
discr_val
=
rval
.layout.ty
.ty_adt_def
()
.map_or
(
index
.as_u32
()
as
u128
,
|
def
|
def
.discriminant_for_variant
(
*
self
.tcx
,
index
)
.val
);
return
Ok
((
discr_val
,
index
));
}
layout
::
Variants
::
Tagged
{
..
}
|
layout
::
Variants
::
NicheFilling
{
..
}
=>
{},
}
layout
::
Variants
::
Multiple
{
ref
discr_kind
,
..
}
=>
discr_kind
,
};
// read raw discriminant value
let
discr_op
=
self
.operand_field
(
rval
,
0
)
?
;
let
discr_val
=
self
.read_immediate
(
discr_op
)
?
;
let
raw_discr
=
discr_val
.to_scalar_or_undef
();
trace!
(
"discr value: {:?}"
,
raw_discr
);
// post-process
Ok
(
match
rval
.layout.variants
{
layout
::
Variants
::
Single
{
..
}
=>
bug!
(),
layout
::
Variants
::
Tagged
{
..
}
=>
{
Ok
(
match
*
discr_kind
{
layout
::
DiscriminantKind
::
Tag
=>
{
let
bits_discr
=
match
raw_discr
.to_bits
(
discr_val
.layout.size
)
{
Ok
(
raw_discr
)
=>
raw_discr
,
Err
(
_
)
=>
return
err!
(
InvalidDiscriminant
(
raw_discr
.erase_tag
())),
...
...
@@ -657,11 +656,10 @@ pub fn read_discriminant(
.ok_or_else
(||
EvalErrorKind
::
InvalidDiscriminant
(
raw_discr
.erase_tag
()))
?
;
(
real_discr
,
index
.0
)
},
layout
::
Variants
::
NicheFilling
{
layout
::
DiscriminantKind
::
Niche
{
dataful_variant
,
ref
niche_variants
,
niche_start
,
..
}
=>
{
let
variants_start
=
niche_variants
.start
()
.as_u32
()
as
u128
;
let
variants_end
=
niche_variants
.end
()
.as_u32
()
as
u128
;
...
...
src/librustc_mir/interpret/place.rs
浏览文件 @
5b7f4e9e
...
...
@@ -958,7 +958,11 @@ pub fn write_discriminant_index(
layout
::
Variants
::
Single
{
index
}
=>
{
assert_eq!
(
index
,
variant_index
);
}
layout
::
Variants
::
Tagged
{
ref
tag
,
..
}
=>
{
layout
::
Variants
::
Multiple
{
discr_kind
:
layout
::
DiscriminantKind
::
Tag
,
ref
discr
,
..
}
=>
{
let
adt_def
=
dest
.layout.ty
.ty_adt_def
()
.unwrap
();
assert
!
(
variant_index
.as_usize
()
<
adt_def
.variants
.len
());
let
discr_val
=
adt_def
...
...
@@ -968,16 +972,18 @@ pub fn write_discriminant_index(
// raw discriminants for enums are isize or bigger during
// their computation, but the in-memory tag is the smallest possible
// representation
let
size
=
tag
.value
.size
(
self
);
let
size
=
discr
.value
.size
(
self
);
let
discr_val
=
truncate
(
discr_val
,
size
);
let
discr_dest
=
self
.place_field
(
dest
,
0
)
?
;
self
.write_scalar
(
Scalar
::
from_uint
(
discr_val
,
size
),
discr_dest
)
?
;
}
layout
::
Variants
::
NicheFilling
{
dataful_variant
,
ref
niche_variants
,
niche_start
,
layout
::
Variants
::
Multiple
{
discr_kind
:
layout
::
DiscriminantKind
::
Niche
{
dataful_variant
,
ref
niche_variants
,
niche_start
,
},
..
}
=>
{
assert
!
(
...
...
src/librustc_mir/interpret/visitor.rs
浏览文件 @
5b7f4e9e
...
...
@@ -241,8 +241,7 @@ fn walk_value(&mut self, v: Self::V) -> EvalResult<'tcx>
// If this is a multi-variant layout, we have find the right one and proceed with
// that.
match
v
.layout
()
.variants
{
layout
::
Variants
::
NicheFilling
{
..
}
|
layout
::
Variants
::
Tagged
{
..
}
=>
{
layout
::
Variants
::
Multiple
{
..
}
=>
{
let
op
=
v
.to_op
(
self
.ecx
())
?
;
let
idx
=
self
.ecx
()
.read_discriminant
(
op
)
?
.1
;
let
inner
=
v
.project_downcast
(
self
.ecx
(),
idx
)
?
;
...
...
src/librustc_target/abi/call/x86_64.rs
浏览文件 @
5b7f4e9e
...
...
@@ -61,8 +61,7 @@ fn classify<'a, Ty, C>(cx: &C, layout: TyLayout<'a, Ty>,
}
return
Ok
(());
}
abi
::
Variants
::
Tagged
{
..
}
|
abi
::
Variants
::
NicheFilling
{
..
}
=>
return
Err
(
Memory
),
abi
::
Variants
::
Multiple
{
..
}
=>
return
Err
(
Memory
),
}
}
...
...
src/librustc_target/abi/mod.rs
浏览文件 @
5b7f4e9e
...
...
@@ -828,15 +828,22 @@ pub enum Variants {
index
:
VariantIdx
,
},
/// General-case enums: for each case there is a struct, and they all have
/// all space reserved for the tag, and their first field starts
/// at a non-0 offset, after where the tag would go.
Tagged
{
tag
:
Scalar
,
/// Enums with more than one inhabited variant: for each case there is
/// a struct, and they all have space reserved for the discriminant,
/// which is the sole field of the enum layout.
Multiple
{
discr
:
Scalar
,
discr_kind
:
DiscriminantKind
,
variants
:
IndexVec
<
VariantIdx
,
LayoutDetails
>
,
},
}
#[derive(PartialEq,
Eq,
Hash,
Debug)]
pub
enum
DiscriminantKind
{
/// Integer tag holding the discriminant value itself.
Tag
,
///
Multiple cases distinguished by a niche (values invalid for a type)
:
///
Niche (values invalid for a type) encoding the discriminant
:
/// the variant `dataful_variant` contains a niche at an arbitrary
/// offset (field 0 of the enum), which for a variant with discriminant
/// `d` is set to `(d - niche_variants.start).wrapping_add(niche_start)`.
...
...
@@ -844,13 +851,11 @@ pub enum Variants {
/// For example, `Option<(usize, &T)>` is represented such that
/// `None` has a null pointer for the second tuple field, and
/// `Some` is the identity function (with a non-null reference).
Niche
Filling
{
Niche
{
dataful_variant
:
VariantIdx
,
niche_variants
:
RangeInclusive
<
VariantIdx
>
,
niche
:
Scalar
,
niche_start
:
u128
,
variants
:
IndexVec
<
VariantIdx
,
LayoutDetails
>
,
}
},
}
#[derive(PartialEq,
Eq,
Hash,
Debug)]
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录