Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
04eadedb
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
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,发现更多精彩内容 >>
未验证
提交
04eadedb
编写于
12月 19, 2016
作者:
O
Oliver Schneider
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
allow using tuple variant names as function handles
上级
684f7571
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
75 addition
and
25 deletion
+75
-25
src/eval_context.rs
src/eval_context.rs
+55
-15
src/terminator/mod.rs
src/terminator/mod.rs
+17
-10
tests/run-pass/tuple_like_enum_variant_constructor.rs
tests/run-pass/tuple_like_enum_variant_constructor.rs
+3
-0
未找到文件。
src/eval_context.rs
浏览文件 @
04eadedb
...
...
@@ -355,18 +355,44 @@ pub(super) fn pop_stack_frame(&mut self) -> EvalResult<'tcx, ()> {
Ok
(())
}
fn
assign_fields
<
I
:
IntoIterator
<
Item
=
u64
>>
(
pub
fn
assign_discr_and_fields
<
I
:
IntoIterator
<
Item
=
u64
>
,
V
:
IntoValTyPair
<
'tcx
>
,
J
:
IntoIterator
<
Item
=
V
>
,
>
(
&
mut
self
,
dest
:
Lvalue
<
'tcx
>
,
offsets
:
I
,
operands
:
&
[
mir
::
Operand
<
'tcx
>
],
operands
:
J
,
discr_val
:
u128
,
discr_size
:
u64
,
)
->
EvalResult
<
'tcx
,
()
>
{
// FIXME(solson)
let
dest_ptr
=
self
.force_allocation
(
dest
)
?
.to_ptr
();
let
mut
offsets
=
offsets
.into_iter
();
let
discr_offset
=
offsets
.next
()
.unwrap
();
let
discr_dest
=
dest_ptr
.offset
(
discr_offset
);
self
.memory
.write_uint
(
discr_dest
,
discr_val
,
discr_size
)
?
;
self
.assign_fields
(
dest
,
offsets
,
operands
)
}
pub
fn
assign_fields
<
I
:
IntoIterator
<
Item
=
u64
>
,
V
:
IntoValTyPair
<
'tcx
>
,
J
:
IntoIterator
<
Item
=
V
>
,
>
(
&
mut
self
,
dest
:
Lvalue
<
'tcx
>
,
offsets
:
I
,
operands
:
J
,
)
->
EvalResult
<
'tcx
,
()
>
{
// FIXME(solson)
let
dest
=
self
.force_allocation
(
dest
)
?
.to_ptr
();
for
(
offset
,
operand
)
in
offsets
.into_iter
()
.zip
(
operands
)
{
let
value
=
self
.eval_operand
(
operand
)
?
;
let
value_ty
=
self
.operand_ty
(
operand
);
let
(
value
,
value_ty
)
=
operand
.into_val_ty_pair
(
self
)
?
;
let
field_dest
=
dest
.offset
(
offset
);
self
.write_value_to_ptr
(
value
,
field_dest
,
value_ty
)
?
;
}
...
...
@@ -431,18 +457,14 @@ pub(super) fn eval_rvalue_into_lvalue(
if
let
mir
::
AggregateKind
::
Adt
(
adt_def
,
variant
,
_
,
_
)
=
*
kind
{
let
discr_val
=
adt_def
.variants
[
variant
]
.disr_val
.to_u128_unchecked
();
let
discr_size
=
discr
.size
()
.bytes
();
let
discr_offset
=
variants
[
variant
]
.offsets
[
0
]
.bytes
();
// FIXME(solson)
let
dest
=
self
.force_allocation
(
dest
)
?
;
let
discr_dest
=
(
dest
.to_ptr
())
.offset
(
discr_offset
);
self
.memory
.write_uint
(
discr_dest
,
discr_val
,
discr_size
)
?
;
// Don't include the first offset; it's for the discriminant.
let
field_offsets
=
variants
[
variant
]
.offsets
.iter
()
.skip
(
1
)
.map
(|
s
|
s
.bytes
());
self
.assign_fields
(
dest
,
field_offsets
,
operands
)
?
;
self
.assign_discr_and_fields
(
dest
,
variants
[
variant
]
.offsets
.iter
()
.cloned
()
.map
(
Size
::
bytes
),
operands
,
discr_val
,
discr_size
,
)
?
;
}
else
{
bug!
(
"tried to assign {:?} to Layout::General"
,
kind
);
}
...
...
@@ -1464,3 +1486,21 @@ pub fn monomorphize_field_ty<'a, 'tcx:'a >(tcx: TyCtxt<'a, 'tcx, 'tcx>, f: &ty::
pub
fn
is_inhabited
<
'a
,
'tcx
:
'a
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
ty
:
Ty
<
'tcx
>
)
->
bool
{
ty
.uninhabited_from
(
&
mut
FxHashSet
::
default
(),
tcx
)
.is_empty
()
}
pub
trait
IntoValTyPair
<
'tcx
>
{
fn
into_val_ty_pair
<
'a
>
(
self
,
ecx
:
&
mut
EvalContext
<
'a
,
'tcx
>
)
->
EvalResult
<
'tcx
,
(
Value
,
Ty
<
'tcx
>
)
>
where
'tcx
:
'a
;
}
impl
<
'tcx
>
IntoValTyPair
<
'tcx
>
for
(
Value
,
Ty
<
'tcx
>
)
{
fn
into_val_ty_pair
<
'a
>
(
self
,
_
:
&
mut
EvalContext
<
'a
,
'tcx
>
)
->
EvalResult
<
'tcx
,
(
Value
,
Ty
<
'tcx
>
)
>
where
'tcx
:
'a
{
Ok
(
self
)
}
}
impl
<
'b
,
'tcx
:
'b
>
IntoValTyPair
<
'tcx
>
for
&
'b
mir
::
Operand
<
'tcx
>
{
fn
into_val_ty_pair
<
'a
>
(
self
,
ecx
:
&
mut
EvalContext
<
'a
,
'tcx
>
)
->
EvalResult
<
'tcx
,
(
Value
,
Ty
<
'tcx
>
)
>
where
'tcx
:
'a
{
let
value
=
ecx
.eval_operand
(
self
)
?
;
let
value_ty
=
ecx
.operand_ty
(
self
);
Ok
((
value
,
value_ty
))
}
}
src/terminator/mod.rs
浏览文件 @
04eadedb
...
...
@@ -2,7 +2,7 @@
use
rustc
::
mir
;
use
rustc
::
traits
::{
self
,
Reveal
};
use
rustc
::
ty
::
fold
::
TypeFoldable
;
use
rustc
::
ty
::
layout
::
Layout
;
use
rustc
::
ty
::
layout
::
{
Layout
,
Size
}
;
use
rustc
::
ty
::
subst
::{
Substs
,
Kind
};
use
rustc
::
ty
::{
self
,
Ty
,
TyCtxt
,
BareFnTy
};
use
syntax
::
codemap
::{
DUMMY_SP
,
Span
};
...
...
@@ -238,20 +238,27 @@ fn eval_fn_call(
let
(
lvalue
,
target
)
=
destination
.expect
(
"tuple struct constructors can't diverge"
);
let
dest_ty
=
self
.tcx
.item_type
(
adt_def
.did
);
let
dest_layout
=
self
.type_layout
(
dest_ty
)
?
;
let
disr
=
v
.disr_val
.to_u128_unchecked
();
match
*
dest_layout
{
Layout
::
Univariant
{
ref
variant
,
..
}
=>
{
assert_eq!
(
v
.disr_val
.to_u128_unchecked
()
,
0
);
assert_eq!
(
disr
,
0
);
let
offsets
=
variant
.offsets
.iter
()
.map
(|
s
|
s
.bytes
());
// FIXME: don't allocate for single or dual field structs
let
dest
=
self
.force_allocation
(
lvalue
)
?
.to_ptr
();
for
(
offset
,
(
value
,
value_ty
))
in
offsets
.into_iter
()
.zip
(
args
)
{
let
field_dest
=
dest
.offset
(
offset
);
self
.write_value_to_ptr
(
value
,
field_dest
,
value_ty
)
?
;
}
self
.assign_fields
(
lvalue
,
offsets
,
args
)
?
;
},
Layout
::
General
{
discr
,
ref
variants
,
..
}
=>
{
// FIXME: report a proper error for invalid discriminants
// right now we simply go into index out of bounds
let
discr_size
=
discr
.size
()
.bytes
();
self
.assign_discr_and_fields
(
lvalue
,
variants
[
disr
as
usize
]
.offsets
.iter
()
.cloned
()
.map
(
Size
::
bytes
),
args
,
disr
,
discr_size
,
)
?
;
},
// FIXME:
enum variant
constructors
// FIXME:
raw nullable pointer
constructors
_
=>
bug!
(
"bad layout for tuple struct constructor: {:?}"
,
dest_layout
),
}
self
.goto_block
(
target
);
...
...
tests/run-pass/tuple_like_enum_variant_constructor.rs
0 → 100644
浏览文件 @
04eadedb
fn
main
()
{
assert_eq!
(
Some
(
42
)
.map
(
Some
),
Some
(
Some
(
42
)));
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录