Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
7595fe51
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,发现更多精彩内容 >>
提交
7595fe51
编写于
7月 11, 2011
作者:
M
Marijn Haverbeke
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Implement record patterns
Closes #469.
上级
12cb128a
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
193 addition
and
2 deletion
+193
-2
src/comp/middle/alias.rs
src/comp/middle/alias.rs
+3
-0
src/comp/middle/resolve.rs
src/comp/middle/resolve.rs
+12
-0
src/comp/middle/trans.rs
src/comp/middle/trans.rs
+32
-0
src/comp/middle/typeck.rs
src/comp/middle/typeck.rs
+43
-2
src/comp/syntax/ast.rs
src/comp/syntax/ast.rs
+6
-0
src/comp/syntax/fold.rs
src/comp/syntax/fold.rs
+7
-0
src/comp/syntax/parse/parser.rs
src/comp/syntax/parse/parser.rs
+39
-0
src/comp/syntax/print/pprust.rs
src/comp/syntax/print/pprust.rs
+16
-0
src/comp/syntax/visit.rs
src/comp/syntax/visit.rs
+3
-0
src/comp/syntax/walk.rs
src/comp/syntax/walk.rs
+3
-0
src/test/compile-fail/bad-record-pat-2.rs
src/test/compile-fail/bad-record-pat-2.rs
+7
-0
src/test/compile-fail/bad-record-pat.rs
src/test/compile-fail/bad-record-pat.rs
+7
-0
src/test/run-pass/record-pat.rs
src/test/run-pass/record-pat.rs
+15
-0
未找到文件。
src/comp/middle/alias.rs
浏览文件 @
7595fe51
...
...
@@ -297,6 +297,9 @@ fn walk_pat(&mutable vec[node_id] found, &@ast::pat p) {
case
(
ast
::
pat_tag
(
_
,
?
children
))
{
for
(
@
ast
::
pat
child
in
children
)
{
walk_pat
(
found
,
child
);
}
}
case
(
ast
::
pat_rec
(
?
fields
,
_
))
{
for
(
ast
::
field_pat
f
in
fields
)
{
walk_pat
(
found
,
f
.pat
);
}
}
case
(
_
)
{
}
}
}
...
...
src/comp/middle/resolve.rs
浏览文件 @
7595fe51
...
...
@@ -313,6 +313,9 @@ fn walk_pat(&env e, &scopes sc, &@ast::pat pat) {
}
}
}
case
(
ast
::
pat_rec
(
?
fields
,
_
))
{
for
(
ast
::
field_pat
f
in
fields
)
{
walk_pat
(
e
,
sc
,
f
.pat
);
}
}
case
(
_
)
{
}
}
}
...
...
@@ -707,6 +710,12 @@ fn lookup_in_pat(&ident name, &ast::pat pat) -> option::t[def] {
if
(
!
option
::
is_none
(
found
))
{
ret
found
;
}
}
}
case
(
ast
::
pat_rec
(
?
fields
,
_
))
{
for
(
ast
::
field_pat
f
in
fields
)
{
auto
found
=
lookup_in_pat
(
name
,
*
f
.pat
);
if
(
!
option
::
is_none
(
found
))
{
ret
found
;
}
}
}
}
ret
none
[
def
];
}
...
...
@@ -1261,6 +1270,9 @@ fn walk_pat(checker ch, &@ast::pat p) {
case
(
ast
::
pat_tag
(
_
,
?
children
))
{
for
(
@
ast
::
pat
child
in
children
)
{
walk_pat
(
ch
,
child
);
}
}
case
(
ast
::
pat_rec
(
?
fields
,
_
))
{
for
(
ast
::
field_pat
f
in
fields
)
{
walk_pat
(
ch
,
f
.pat
);
}
}
case
(
_
)
{
}
}
}
...
...
src/comp/middle/trans.rs
浏览文件 @
7595fe51
...
...
@@ -4839,6 +4839,23 @@ fn trans_pat_match(&@block_ctxt cx, &@ast::pat pat, ValueRef llval,
}
ret
rslt
(
matched_cx
,
llval
);
}
case
(
ast
::
pat_rec
(
?
field_pats
,
_
))
{
auto
bcx
=
cx
;
auto
ccx
=
cx
.fcx.lcx.ccx
;
auto
rec_ty
=
pat_ty
(
ccx
.tcx
,
pat
);
auto
fields
=
alt
(
ty
::
struct
(
ccx
.tcx
,
rec_ty
))
{
ty
::
ty_rec
(
?
fields
)
{
fields
}
};
for
(
ast
::
field_pat
f
in
field_pats
)
{
let
uint
ix
=
ty
::
field_idx
(
ccx
.sess
,
f
.pat.span
,
f
.ident
,
fields
);
auto
r
=
GEP_tup_like
(
bcx
,
rec_ty
,
llval
,
~
[
0
,
ix
as
int
]);
auto
v
=
load_if_immediate
(
r
.bcx
,
r
.val
,
pat_ty
(
ccx
.tcx
,
f
.pat
));
bcx
=
trans_pat_match
(
r
.bcx
,
f
.pat
,
v
,
next_cx
)
.bcx
;
}
ret
rslt
(
bcx
,
llval
);
}
}
}
...
...
@@ -4896,6 +4913,21 @@ fn trans_pat_binding(&@block_ctxt cx, &@ast::pat pat, ValueRef llval,
}
ret
rslt
(
this_cx
,
llval
);
}
case
(
ast
::
pat_rec
(
?
field_pats
,
_
))
{
auto
bcx
=
cx
;
auto
ccx
=
cx
.fcx.lcx.ccx
;
auto
rec_ty
=
pat_ty
(
ccx
.tcx
,
pat
);
auto
fields
=
alt
(
ty
::
struct
(
ccx
.tcx
,
rec_ty
))
{
ty
::
ty_rec
(
?
fields
)
{
fields
}
};
for
(
ast
::
field_pat
f
in
field_pats
)
{
let
uint
ix
=
ty
::
field_idx
(
ccx
.sess
,
f
.pat.span
,
f
.ident
,
fields
);
auto
r
=
GEP_tup_like
(
bcx
,
rec_ty
,
llval
,
~
[
0
,
ix
as
int
]);
bcx
=
trans_pat_binding
(
bcx
,
f
.pat
,
r
.val
,
true
,
bound
)
.bcx
;
}
ret
rslt
(
bcx
,
llval
);
}
}
}
...
...
src/comp/middle/typeck.rs
浏览文件 @
7595fe51
...
...
@@ -1278,6 +1278,11 @@ fn replace_expr_type(&@fn_ctxt fcx, &@ast::expr expr,
write
::
ty_fixup
(
fcx
,
expr
.id
,
tup
(
new_tps
,
new_tyt
._1
));
}
// FIXME remove once std::ivec::find makes it into a snapshot
fn
ivec_find
[
T
](
fn
(
&
T
)
->
bool
f
,
&
T
[]
v
)
->
option
::
t
[
T
]
{
for
(
T
elt
in
v
)
{
if
(
f
(
elt
))
{
ret
some
[
T
](
elt
);
}
}
ret
none
[
T
];
}
// AST fragment checking
fn
check_lit
(
@
crate_ctxt
ccx
,
&@
ast
::
lit
lit
)
->
ty
::
t
{
...
...
@@ -1395,16 +1400,52 @@ fn check_pat(&@fn_ctxt fcx, &ast::pat_id_map map, &@ast::pat pat,
case
(
_
)
{
// FIXME: Switch expected and actual in this message? I
// can never tell.
fcx
.ccx.tcx.sess
.span_fatal
(
pat
.span
,
#
fmt
(
"mismatched types:
\
expected
tag, found %s
"
,
expected
%s, found tag
"
,
ty_to_str
(
fcx
.ccx.tcx
,
expected
)));
}
}
write
::
ty_fixup
(
fcx
,
pat
.id
,
path_tpot
);
}
case
(
ast
::
pat_rec
(
?
fields
,
?
etc
))
{
auto
ex_fields
;
alt
(
structure_of
(
fcx
,
pat
.span
,
expected
))
{
case
(
ty
::
ty_rec
(
?
fields
))
{
ex_fields
=
fields
;
}
case
(
_
)
{
fcx
.ccx.tcx.sess
.span_fatal
(
pat
.span
,
#
fmt
(
"mismatched types: expected %s,
\
found record"
,
ty_to_str
(
fcx
.ccx.tcx
,
expected
)));
}
};
auto
f_count
=
ivec
::
len
(
fields
);
auto
ex_f_count
=
ivec
::
len
(
ex_fields
);
if
(
ex_f_count
<
f_count
||
(
!
etc
&&
ex_f_count
>
f_count
))
{
fcx
.ccx.tcx.sess
.span_fatal
(
pat
.span
,
#
fmt
(
"mismatched types: expected a record
\
with %u fields, found one with %u
\
fields"
,
ex_f_count
,
f_count
));
}
fn
matches
(
&
str
name
,
&
ty
::
field
f
)
->
bool
{
ret
str
::
eq
(
name
,
f
.ident
);
}
for
(
ast
::
field_pat
f
in
fields
)
{
alt
(
ivec_find
(
bind
matches
(
f
.ident
,
_
),
ex_fields
))
{
some
(
?
field
)
{
check_pat
(
fcx
,
map
,
f
.pat
,
field
.mt.ty
);
}
none
{
fcx
.ccx.tcx.sess
.span_fatal
(
pat
.span
,
#
fmt
(
"mismatched types: did not
\
expect a record with a field %s"
,
f
.ident
));
}
}
}
write
::
ty_only_fixup
(
fcx
,
pat
.id
,
expected
);
}
}
}
...
...
src/comp/syntax/ast.rs
浏览文件 @
7595fe51
...
...
@@ -118,11 +118,14 @@ fn def_id_of_def(def d) -> def_id {
pat_
node
,
span
span
);
type
field_pat
=
rec
(
ident
ident
,
@
pat
pat
);
tag
pat_
{
pat_wild
;
pat_bind
(
ident
);
pat_lit
(
@
lit
);
pat_tag
(
path
,
(
@
pat
)[]);
pat_rec
(
field_pat
[],
bool
);
}
type
pat_id_map
=
std
::
map
::
hashmap
[
str
,
ast
::
node_id
];
...
...
@@ -137,6 +140,9 @@ fn walk(&pat_id_map map, &@pat pat) {
pat_tag
(
_
,
?
sub
)
{
for
(
@
pat
p
in
sub
)
{
walk
(
map
,
p
);
}
}
pat_rec
(
?
fields
,
_
)
{
for
(
field_pat
f
in
fields
)
{
walk
(
map
,
f
.pat
);
}
}
_
{}
}
}
...
...
src/comp/syntax/fold.rs
浏览文件 @
7595fe51
...
...
@@ -267,6 +267,13 @@ fn noop_fold_pat(&pat_ p, ast_fold fld) -> pat_ {
case
(
pat_tag
(
?
pth
,
?
pats
))
{
pat_tag
(
fld
.fold_path
(
pth
),
ivec
::
map
(
fld
.fold_pat
,
pats
))
}
case
(
pat_rec
(
?
fields
,
?
etc
))
{
auto
fs
=
~
[];
for
(
ast
::
field_pat
f
in
fields
)
{
fs
+=
~
[
rec
(
ident
=
f
.ident
,
pat
=
fld
.fold_pat
(
f
.pat
))];
}
pat_rec
(
fs
,
etc
)
}
};
}
...
...
src/comp/syntax/parse/parser.rs
浏览文件 @
7595fe51
...
...
@@ -1455,6 +1455,45 @@ fn parse_pat(&parser p) -> @ast::pat {
}
}
}
case
(
token
::
LBRACE
)
{
p
.bump
();
auto
fields
=
~
[];
auto
etc
=
false
;
auto
first
=
true
;
while
(
p
.peek
()
!=
token
::
RBRACE
)
{
if
(
p
.peek
()
==
token
::
DOT
)
{
p
.bump
();
expect
(
p
,
token
::
DOT
);
expect
(
p
,
token
::
DOT
);
if
(
p
.peek
()
!=
token
::
RBRACE
)
{
p
.fatal
(
"expecting }, found "
+
token
::
to_str
(
p
.get_reader
(),
p
.peek
()));
}
etc
=
true
;
break
;
}
if
(
first
)
{
first
=
false
;
}
else
{
expect
(
p
,
token
::
COMMA
);
}
auto
fieldname
=
parse_ident
(
p
);
auto
subpat
;
if
(
p
.peek
()
==
token
::
COLON
)
{
p
.bump
();
subpat
=
parse_pat
(
p
);
}
else
{
if
(
p
.get_bad_expr_words
()
.contains_key
(
fieldname
))
{
p
.fatal
(
"found "
+
fieldname
+
" in binding position"
);
}
subpat
=
@
rec
(
id
=
p
.get_id
(),
node
=
ast
::
pat_bind
(
fieldname
),
span
=
rec
(
lo
=
lo
,
hi
=
hi
));
}
fields
+=
~
[
rec
(
ident
=
fieldname
,
pat
=
subpat
)];
}
hi
=
p
.get_hi_pos
();
p
.bump
();
pat
=
ast
::
pat_rec
(
fields
,
etc
);
}
case
(
?
tok
)
{
if
(
!
is_ident
(
tok
)
||
is_word
(
p
,
"true"
)
||
is_word
(
p
,
"false"
))
{
auto
lit
=
parse_lit
(
p
);
...
...
src/comp/syntax/print/pprust.rs
浏览文件 @
7595fe51
...
...
@@ -1120,6 +1120,22 @@ fn print_pat(&ps s, &@ast::pat pat) {
pclose
(
s
);
}
}
case
(
ast
::
pat_rec
(
?
fields
,
?
etc
))
{
bopen
(
s
);
fn
print_field
(
&
ps
s
,
&
ast
::
field_pat
f
)
{
cbox
(
s
,
indent_unit
);
word
(
s
.s
,
f
.ident
);
word
(
s
.s
,
":"
);
print_pat
(
s
,
f
.pat
);
end
(
s
);
}
fn
get_span
(
&
ast
::
field_pat
f
)
->
codemap
::
span
{
ret
f
.pat.span
;
}
commasep_cmnt_ivec
(
s
,
consistent
,
fields
,
print_field
,
get_span
);
if
(
etc
)
{
space
(
s
.s
);
word
(
s
.s
,
"..."
);
}
bclose
(
s
,
pat
.span
);
}
}
s
.ann
.post
(
ann_node
);
}
...
...
src/comp/syntax/visit.rs
浏览文件 @
7595fe51
...
...
@@ -190,6 +190,9 @@ fn visit_pat[E](&@pat p, &E e, &vt[E] v) {
for
(
@
ty
tp
in
path
.node.types
)
{
v
.visit_ty
(
tp
,
e
,
v
);
}
for
(
@
pat
child
in
children
)
{
v
.visit_pat
(
child
,
e
,
v
);
}
}
case
(
pat_rec
(
?
fields
,
_
))
{
for
(
field_pat
f
in
fields
)
{
v
.visit_pat
(
f
.pat
,
e
,
v
);
}
}
case
(
_
)
{
}
}
}
...
...
src/comp/syntax/walk.rs
浏览文件 @
7595fe51
...
...
@@ -189,6 +189,9 @@ fn walk_pat(&ast_visitor v, &@ast::pat p) {
for
(
@
ast
::
ty
tp
in
path
.node.types
)
{
walk_ty
(
v
,
tp
);
}
for
(
@
ast
::
pat
child
in
children
)
{
walk_pat
(
v
,
child
);
}
}
case
(
ast
::
pat_rec
(
?
fields
,
_
))
{
for
(
ast
::
field_pat
f
in
fields
)
{
walk_pat
(
v
,
f
.pat
);
}
}
case
(
_
)
{
}
}
v
.visit_pat_post
(
p
);
...
...
src/test/compile-fail/bad-record-pat-2.rs
0 → 100644
浏览文件 @
7595fe51
// error-pattern:did not expect a record with a field q
fn
main
()
{
alt
rec
(
x
=
1
,
y
=
2
)
{
{
x
,
q
}
{}
}
}
src/test/compile-fail/bad-record-pat.rs
0 → 100644
浏览文件 @
7595fe51
// error-pattern:expected a record with 2 fields, found one with 1
fn
main
()
{
alt
rec
(
x
=
1
,
y
=
2
)
{
{
x
}
{}
}
}
src/test/run-pass/record-pat.rs
0 → 100644
浏览文件 @
7595fe51
tag
t1
{
a
(
int
);
b
(
uint
);
}
type
t2
=
rec
(
t1
x
,
int
y
);
tag
t3
{
c
(
t2
,
uint
);
}
fn
m
(
&
t3
in
)
->
int
{
alt
in
{
c
({
x
:
a
(
?
m
)
...
},
_
)
{
ret
m
;
}
c
({
x
:
b
(
?
m
),
y
},
?
z
)
{
ret
(
m
+
z
)
as
int
+
y
;
}
}
}
fn
main
()
{
assert
m
(
c
(
rec
(
x
=
a
(
10
),
y
=
5
),
4u
))
==
10
;
assert
m
(
c
(
rec
(
x
=
b
(
10u
),
y
=
5
),
4u
))
==
19
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录