Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
bb8b83a6
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,发现更多精彩内容 >>
提交
bb8b83a6
编写于
7月 17, 2013
作者:
P
Patrick Walton
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
librustc: Remove a bunch of `@` boxes from `Match`.
This will be needed to add `'static` bounds to `@`.
上级
559d2ef9
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
91 addition
and
63 deletion
+91
-63
src/librustc/middle/trans/_match.rs
src/librustc/middle/trans/_match.rs
+91
-63
未找到文件。
src/librustc/middle/trans/_match.rs
浏览文件 @
bb8b83a6
...
...
@@ -17,8 +17,8 @@
*
* ## Matching
*
* The basic state of the code is maintained in an array `m` of `
@
Match`
* objects. Each `
@
Match` describes some list of patterns, all of which must
* The basic state of the code is maintained in an array `m` of `Match`
* objects. Each `Match` describes some list of patterns, all of which must
* match against the current list of values. If those patterns match, then
* the arm listed in the match is the correct arm. A given arm may have
* multiple corresponding match entries, one for each alternative that
...
...
@@ -316,6 +316,7 @@ pub fn variant_opt(bcx: block, pat_id: ast::node_id)
}
}
#[deriving(Clone)]
pub
enum
TransBindingMode
{
TrByValue
(
/*llbinding:*/
ValueRef
),
TrByRef
,
...
...
@@ -329,6 +330,7 @@ pub enum TransBindingMode {
* - `trmode` is the trans binding mode
* - `id` is the node id of the binding
* - `ty` is the Rust type of the binding */
#[deriving(Clone)]
pub
struct
BindingInfo
{
llmatch
:
ValueRef
,
trmode
:
TransBindingMode
,
...
...
@@ -338,15 +340,17 @@ pub struct BindingInfo {
pub
type
BindingsMap
=
HashMap
<
ident
,
BindingInfo
>
;
#[deriving(Clone)]
pub
struct
ArmData
<
'self
>
{
bodycx
:
block
,
arm
:
&
'self
ast
::
arm
,
bindings_map
:
BindingsMap
bindings_map
:
@
BindingsMap
}
#[deriving(Clone)]
pub
struct
Match
<
'self
>
{
pats
:
~
[
@
ast
::
pat
],
data
:
@
ArmData
<
'self
>
data
:
ArmData
<
'self
>
}
pub
fn
match_to_str
(
bcx
:
block
,
m
:
&
Match
)
->
~
str
{
...
...
@@ -358,11 +362,11 @@ pub fn match_to_str(bcx: block, m: &Match) -> ~str {
}
}
pub
fn
matches_to_str
(
bcx
:
block
,
m
:
&
[
@
Match
])
->
~
str
{
fmt!
(
"%?"
,
m
.map
(|
n
|
match_to_str
(
bcx
,
*
n
)))
pub
fn
matches_to_str
(
bcx
:
block
,
m
:
&
[
Match
])
->
~
str
{
fmt!
(
"%?"
,
m
.map
(|
n
|
match_to_str
(
bcx
,
n
)))
}
pub
fn
has_nested_bindings
(
m
:
&
[
@
Match
],
col
:
uint
)
->
bool
{
pub
fn
has_nested_bindings
(
m
:
&
[
Match
],
col
:
uint
)
->
bool
{
for
m
.iter
()
.advance
|
br
|
{
match
br
.pats
[
col
]
.node
{
ast
::
pat_ident
(
_
,
_
,
Some
(
_
))
=>
return
true
,
...
...
@@ -373,10 +377,10 @@ pub fn has_nested_bindings(m: &[@Match], col: uint) -> bool {
}
pub
fn
expand_nested_bindings
<
'r
>
(
bcx
:
block
,
m
:
&
[
@
Match
<
'r
>
],
m
:
&
[
Match
<
'r
>
],
col
:
uint
,
val
:
ValueRef
)
->
~
[
@
Match
<
'r
>
]
{
->
~
[
Match
<
'r
>
]
{
debug!
(
"expand_nested_bindings(bcx=%s, m=%s, col=%u, val=%?)"
,
bcx
.to_str
(),
matches_to_str
(
bcx
,
m
),
...
...
@@ -397,11 +401,12 @@ pub fn expand_nested_bindings<'r>(bcx: block,
br
.data.bindings_map
.get
(
&
path_to_ident
(
path
));
Store
(
bcx
,
val
,
binding_info
.llmatch
);
@
Match
{
pats
:
pats
,
data
:
br
.data
}
}
_
=>
{
*
br
Match
{
pats
:
pats
,
data
:
br
.data
.clone
()
}
}
_
=>
(
*
br
)
.clone
(),
}
}
}
...
...
@@ -419,11 +424,11 @@ pub fn assert_is_binding_or_wild(bcx: block, p: @ast::pat) {
pub
fn
enter_match
<
'r
>
(
bcx
:
block
,
dm
:
DefMap
,
m
:
&
[
@
Match
<
'r
>
],
m
:
&
[
Match
<
'r
>
],
col
:
uint
,
val
:
ValueRef
,
e
:
enter_pat
)
->
~
[
@
Match
<
'r
>
]
{
->
~
[
Match
<
'r
>
]
{
debug!
(
"enter_match(bcx=%s, m=%s, col=%u, val=%?)"
,
bcx
.to_str
(),
matches_to_str
(
bcx
,
m
),
...
...
@@ -453,7 +458,10 @@ pub fn enter_match<'r>(bcx: block,
_
=>
{}
}
result
.push
(
@
Match
{
pats
:
pats
,
data
:
br
.data
});
result
.push
(
Match
{
pats
:
pats
,
data
:
br
.data
.clone
()
});
}
None
=>
()
}
...
...
@@ -466,10 +474,10 @@ pub fn enter_match<'r>(bcx: block,
pub
fn
enter_default
<
'r
>
(
bcx
:
block
,
dm
:
DefMap
,
m
:
&
[
@
Match
<
'r
>
],
m
:
&
[
Match
<
'r
>
],
col
:
uint
,
val
:
ValueRef
)
->
~
[
@
Match
<
'r
>
]
{
->
~
[
Match
<
'r
>
]
{
debug!
(
"enter_default(bcx=%s, m=%s, col=%u, val=%?)"
,
bcx
.to_str
(),
matches_to_str
(
bcx
,
m
),
...
...
@@ -511,12 +519,12 @@ pub fn enter_default<'r>(bcx: block,
// wildcards
pub
fn
enter_opt
<
'r
>
(
bcx
:
block
,
m
:
&
[
@
Match
<
'r
>
],
m
:
&
[
Match
<
'r
>
],
opt
:
&
Opt
,
col
:
uint
,
variant_size
:
uint
,
val
:
ValueRef
)
->
~
[
@
Match
<
'r
>
]
{
->
~
[
Match
<
'r
>
]
{
debug!
(
"enter_opt(bcx=%s, m=%s, col=%u, val=%?)"
,
bcx
.to_str
(),
matches_to_str
(
bcx
,
m
),
...
...
@@ -624,11 +632,11 @@ pub fn enter_opt<'r>(bcx: block,
pub
fn
enter_rec_or_struct
<
'r
>
(
bcx
:
block
,
dm
:
DefMap
,
m
:
&
[
@
Match
<
'r
>
],
m
:
&
[
Match
<
'r
>
],
col
:
uint
,
fields
:
&
[
ast
::
ident
],
val
:
ValueRef
)
->
~
[
@
Match
<
'r
>
]
{
->
~
[
Match
<
'r
>
]
{
debug!
(
"enter_rec_or_struct(bcx=%s, m=%s, col=%u, val=%?)"
,
bcx
.to_str
(),
matches_to_str
(
bcx
,
m
),
...
...
@@ -659,11 +667,11 @@ pub fn enter_rec_or_struct<'r>(bcx: block,
pub
fn
enter_tup
<
'r
>
(
bcx
:
block
,
dm
:
DefMap
,
m
:
&
[
@
Match
<
'r
>
],
m
:
&
[
Match
<
'r
>
],
col
:
uint
,
val
:
ValueRef
,
n_elts
:
uint
)
->
~
[
@
Match
<
'r
>
]
{
->
~
[
Match
<
'r
>
]
{
debug!
(
"enter_tup(bcx=%s, m=%s, col=%u, val=%?)"
,
bcx
.to_str
(),
matches_to_str
(
bcx
,
m
),
...
...
@@ -685,11 +693,11 @@ pub fn enter_tup<'r>(bcx: block,
pub
fn
enter_tuple_struct
<
'r
>
(
bcx
:
block
,
dm
:
DefMap
,
m
:
&
[
@
Match
<
'r
>
],
m
:
&
[
Match
<
'r
>
],
col
:
uint
,
val
:
ValueRef
,
n_elts
:
uint
)
->
~
[
@
Match
<
'r
>
]
{
->
~
[
Match
<
'r
>
]
{
debug!
(
"enter_tuple_struct(bcx=%s, m=%s, col=%u, val=%?)"
,
bcx
.to_str
(),
matches_to_str
(
bcx
,
m
),
...
...
@@ -711,10 +719,10 @@ pub fn enter_tuple_struct<'r>(bcx: block,
pub
fn
enter_box
<
'r
>
(
bcx
:
block
,
dm
:
DefMap
,
m
:
&
[
@
Match
<
'r
>
],
m
:
&
[
Match
<
'r
>
],
col
:
uint
,
val
:
ValueRef
)
->
~
[
@
Match
<
'r
>
]
{
->
~
[
Match
<
'r
>
]
{
debug!
(
"enter_box(bcx=%s, m=%s, col=%u, val=%?)"
,
bcx
.to_str
(),
matches_to_str
(
bcx
,
m
),
...
...
@@ -738,10 +746,10 @@ pub fn enter_box<'r>(bcx: block,
pub
fn
enter_uniq
<
'r
>
(
bcx
:
block
,
dm
:
DefMap
,
m
:
&
[
@
Match
<
'r
>
],
m
:
&
[
Match
<
'r
>
],
col
:
uint
,
val
:
ValueRef
)
->
~
[
@
Match
<
'r
>
]
{
->
~
[
Match
<
'r
>
]
{
debug!
(
"enter_uniq(bcx=%s, m=%s, col=%u, val=%?)"
,
bcx
.to_str
(),
matches_to_str
(
bcx
,
m
),
...
...
@@ -765,10 +773,10 @@ pub fn enter_uniq<'r>(bcx: block,
pub
fn
enter_region
<
'r
>
(
bcx
:
block
,
dm
:
DefMap
,
m
:
&
[
@
Match
<
'r
>
],
m
:
&
[
Match
<
'r
>
],
col
:
uint
,
val
:
ValueRef
)
->
~
[
@
Match
<
'r
>
]
{
->
~
[
Match
<
'r
>
]
{
debug!
(
"enter_region(bcx=%s, m=%s, col=%u, val=%?)"
,
bcx
.to_str
(),
matches_to_str
(
bcx
,
m
),
...
...
@@ -793,7 +801,7 @@ pub fn enter_region<'r>(bcx: block,
// Returns the options in one column of matches. An option is something that
// needs to be conditionally matched at runtime; for example, the discriminant
// on a set of enum variants or a literal.
pub
fn
get_options
(
bcx
:
block
,
m
:
&
[
@
Match
],
col
:
uint
)
->
~
[
Opt
]
{
pub
fn
get_options
(
bcx
:
block
,
m
:
&
[
Match
],
col
:
uint
)
->
~
[
Opt
]
{
let
ccx
=
bcx
.ccx
();
fn
add_to_set
(
tcx
:
ty
::
ctxt
,
set
:
&
mut
~
[
Opt
],
val
:
Opt
)
{
if
set
.iter
()
.any
(|
l
|
opt_eq
(
tcx
,
l
,
&
val
))
{
return
;}
...
...
@@ -943,7 +951,7 @@ pub fn extract_vec_elems(bcx: block,
// NB: This function does not collect fields from struct-like enum variants.
pub
fn
collect_record_or_struct_fields
(
bcx
:
block
,
m
:
&
[
@
Match
],
m
:
&
[
Match
],
col
:
uint
)
->
~
[
ast
::
ident
]
{
let
mut
fields
:
~
[
ast
::
ident
]
=
~
[];
...
...
@@ -971,7 +979,7 @@ fn extend(idents: &mut ~[ast::ident], field_pats: &[ast::field_pat]) {
}
pub
fn
pats_require_rooting
(
bcx
:
block
,
m
:
&
[
@
Match
],
m
:
&
[
Match
],
col
:
uint
)
->
bool
{
do
m
.iter
()
.any
|
br
|
{
...
...
@@ -982,7 +990,7 @@ pub fn pats_require_rooting(bcx: block,
}
pub
fn
root_pats_as_necessary
(
mut
bcx
:
block
,
m
:
&
[
@
Match
],
m
:
&
[
Match
],
col
:
uint
,
val
:
ValueRef
)
->
block
{
...
...
@@ -1012,23 +1020,23 @@ pub fn root_pats_as_necessary(mut bcx: block,
)
)
pub
fn
any_box_pat
(
m
:
&
[
@
Match
],
col
:
uint
)
->
bool
{
pub
fn
any_box_pat
(
m
:
&
[
Match
],
col
:
uint
)
->
bool
{
any_pat!
(
m
,
ast
::
pat_box
(
_
))
}
pub
fn
any_uniq_pat
(
m
:
&
[
@
Match
],
col
:
uint
)
->
bool
{
pub
fn
any_uniq_pat
(
m
:
&
[
Match
],
col
:
uint
)
->
bool
{
any_pat!
(
m
,
ast
::
pat_uniq
(
_
))
}
pub
fn
any_region_pat
(
m
:
&
[
@
Match
],
col
:
uint
)
->
bool
{
pub
fn
any_region_pat
(
m
:
&
[
Match
],
col
:
uint
)
->
bool
{
any_pat!
(
m
,
ast
::
pat_region
(
_
))
}
pub
fn
any_tup_pat
(
m
:
&
[
@
Match
],
col
:
uint
)
->
bool
{
pub
fn
any_tup_pat
(
m
:
&
[
Match
],
col
:
uint
)
->
bool
{
any_pat!
(
m
,
ast
::
pat_tup
(
_
))
}
pub
fn
any_tuple_struct_pat
(
bcx
:
block
,
m
:
&
[
@
Match
],
col
:
uint
)
->
bool
{
pub
fn
any_tuple_struct_pat
(
bcx
:
block
,
m
:
&
[
Match
],
col
:
uint
)
->
bool
{
do
m
.iter
()
.any
|
br
|
{
let
pat
=
br
.pats
[
col
];
match
pat
.node
{
...
...
@@ -1046,7 +1054,7 @@ pub fn any_tuple_struct_pat(bcx: block, m: &[@Match], col: uint) -> bool {
pub
type
mk_fail
=
@
fn
()
->
BasicBlockRef
;
pub
fn
pick_col
(
m
:
&
[
@
Match
])
->
uint
{
pub
fn
pick_col
(
m
:
&
[
Match
])
->
uint
{
fn
score
(
p
:
&
ast
::
pat
)
->
uint
{
match
p
.node
{
ast
::
pat_lit
(
_
)
|
ast
::
pat_enum
(
_
,
_
)
|
ast
::
pat_range
(
_
,
_
)
=>
1u
,
...
...
@@ -1201,7 +1209,7 @@ fn insert_lllocals(bcx: block,
pub
fn
compile_guard
(
bcx
:
block
,
guard_expr
:
@
ast
::
expr
,
data
:
&
ArmData
,
m
:
&
[
@
Match
],
m
:
&
[
Match
],
vals
:
&
[
ValueRef
],
chk
:
Option
<
mk_fail
>
)
->
block
{
...
...
@@ -1214,8 +1222,10 @@ pub fn compile_guard(bcx: block,
let
mut
bcx
=
bcx
;
let
mut
temp_cleanups
=
~
[];
bcx
=
store_non_ref_bindings
(
bcx
,
&
data
.bindings_map
,
Some
(
&
mut
temp_cleanups
));
bcx
=
insert_lllocals
(
bcx
,
&
data
.bindings_map
,
BindLocal
,
false
);
bcx
=
store_non_ref_bindings
(
bcx
,
data
.bindings_map
,
Some
(
&
mut
temp_cleanups
));
bcx
=
insert_lllocals
(
bcx
,
data
.bindings_map
,
BindLocal
,
false
);
let
val
=
unpack_result!
(
bcx
,
{
do
with_scope_result
(
bcx
,
guard_expr
.info
(),
...
...
@@ -1254,7 +1264,7 @@ fn drop_bindings(bcx: block, data: &ArmData) -> block {
}
pub
fn
compile_submatch
(
bcx
:
block
,
m
:
&
[
@
Match
],
m
:
&
[
Match
],
vals
:
&
[
ValueRef
],
chk
:
Option
<
mk_fail
>
)
{
debug!
(
"compile_submatch(bcx=%s, m=%s, vals=%?)"
,
...
...
@@ -1276,12 +1286,15 @@ pub fn compile_submatch(bcx: block,
return
;
}
if
m
[
0
]
.pats
.len
()
==
0u
{
let
data
=
m
[
0
]
.data
;
let
data
=
&
m
[
0
]
.data
;
match
data
.arm.guard
{
Some
(
guard_expr
)
=>
{
bcx
=
compile_guard
(
bcx
,
guard_expr
,
m
[
0
]
.data
,
bcx
=
compile_guard
(
bcx
,
guard_expr
,
&
m
[
0
]
.data
,
m
.slice
(
1
,
m
.len
()),
vals
,
chk
);
vals
,
chk
);
}
_
=>
()
}
...
...
@@ -1291,13 +1304,23 @@ pub fn compile_submatch(bcx: block,
let
col
=
pick_col
(
m
);
let
val
=
vals
[
col
];
let
m
=
{
if
has_nested_bindings
(
m
,
col
)
{
expand_nested_bindings
(
bcx
,
m
,
col
,
val
)
}
else
{
m
.to_owned
()
}
};
if
has_nested_bindings
(
m
,
col
)
{
let
expanded
=
expand_nested_bindings
(
bcx
,
m
,
col
,
val
);
compile_submatch_continue
(
bcx
,
expanded
,
vals
,
chk
,
col
,
val
)
}
else
{
compile_submatch_continue
(
bcx
,
m
,
vals
,
chk
,
col
,
val
)
}
}
fn
compile_submatch_continue
(
mut
bcx
:
block
,
m
:
&
[
Match
],
vals
:
&
[
ValueRef
],
chk
:
Option
<
mk_fail
>
,
col
:
uint
,
val
:
ValueRef
)
{
let
tcx
=
bcx
.tcx
();
let
dm
=
tcx
.def_map
;
let
vals_left
=
vec
::
append
(
vals
.slice
(
0u
,
col
)
.to_owned
(),
vals
.slice
(
col
+
1u
,
vals
.len
()));
...
...
@@ -1670,12 +1693,17 @@ pub fn trans_match_inner(scope_cx: block,
for
arms
.iter
()
.advance
|
arm
|
{
let
body
=
scope_block
(
bcx
,
arm
.body
.info
(),
"case_body"
);
let
bindings_map
=
create_bindings_map
(
bcx
,
arm
.pats
[
0
]);
let
arm_data
=
@
ArmData
{
bodycx
:
body
,
arm
:
arm
,
bindings_map
:
bindings_map
};
arm_datas
.push
(
arm_data
);
let
arm_data
=
ArmData
{
bodycx
:
body
,
arm
:
arm
,
bindings_map
:
@
bindings_map
};
arm_datas
.push
(
arm_data
.clone
());
for
arm
.pats
.iter
()
.advance
|
p
|
{
matches
.push
(
@
Match
{
pats
:
~
[
*
p
],
data
:
arm_data
});
matches
.push
(
Match
{
pats
:
~
[
*
p
],
data
:
arm_data
.clone
(),
});
}
}
...
...
@@ -1703,11 +1731,11 @@ pub fn trans_match_inner(scope_cx: block,
// is just to reduce code space. See extensive comment at the start
// of the file for more details.
if
arm_data
.arm.guard
.is_none
()
{
bcx
=
store_non_ref_bindings
(
bcx
,
&
arm_data
.bindings_map
,
None
);
bcx
=
store_non_ref_bindings
(
bcx
,
arm_data
.bindings_map
,
None
);
}
// insert bindings into the lllocals map and add cleanups
bcx
=
insert_lllocals
(
bcx
,
&
arm_data
.bindings_map
,
BindLocal
,
true
);
bcx
=
insert_lllocals
(
bcx
,
arm_data
.bindings_map
,
BindLocal
,
true
);
bcx
=
controlflow
::
trans_block
(
bcx
,
&
arm_data
.arm.body
,
dest
);
bcx
=
trans_block_cleanups
(
bcx
,
block_cleanups
(
arm_data
.bodycx
));
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录