Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
373b9d62
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,发现更多精彩内容 >>
提交
373b9d62
编写于
7月 25, 2014
作者:
P
Pythoner6
提交者:
Joseph Martin
8月 29, 2014
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add support for labeled while loops.
上级
5419b2ca
变更
21
隐藏空白更改
内联
并排
Showing
21 changed file
with
97 addition
and
24 deletion
+97
-24
src/librustc/lint/builtin.rs
src/librustc/lint/builtin.rs
+2
-2
src/librustc/middle/cfg/construct.rs
src/librustc/middle/cfg/construct.rs
+1
-1
src/librustc/middle/check_loop.rs
src/librustc/middle/check_loop.rs
+1
-1
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/expr_use_visitor.rs
+1
-1
src/librustc/middle/liveness.rs
src/librustc/middle/liveness.rs
+1
-1
src/librustc/middle/region.rs
src/librustc/middle/region.rs
+1
-1
src/librustc/middle/resolve.rs
src/librustc/middle/resolve.rs
+1
-1
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/debuginfo.rs
+1
-1
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/expr.rs
+1
-1
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/mod.rs
+1
-1
src/librustc/middle/typeck/check/regionck.rs
src/librustc/middle/typeck/check/regionck.rs
+1
-1
src/libsyntax/ast.rs
src/libsyntax/ast.rs
+2
-1
src/libsyntax/ext/expand.rs
src/libsyntax/ext/expand.rs
+6
-0
src/libsyntax/fold.rs
src/libsyntax/fold.rs
+7
-5
src/libsyntax/parse/parser.rs
src/libsyntax/parse/parser.rs
+7
-4
src/libsyntax/print/pprust.rs
src/libsyntax/print/pprust.rs
+5
-1
src/libsyntax/visit.rs
src/libsyntax/visit.rs
+1
-1
src/test/run-pass/hygienic-labels-in-let.rs
src/test/run-pass/hygienic-labels-in-let.rs
+17
-0
src/test/run-pass/hygienic-labels.rs
src/test/run-pass/hygienic-labels.rs
+12
-0
src/test/run-pass/labeled-break.rs
src/test/run-pass/labeled-break.rs
+6
-0
src/test/run-pass/while-label.rs
src/test/run-pass/while-label.rs
+22
-0
未找到文件。
src/librustc/lint/builtin.rs
浏览文件 @
373b9d62
...
...
@@ -58,7 +58,7 @@ fn get_lints(&self) -> LintArray {
fn
check_expr
(
&
mut
self
,
cx
:
&
Context
,
e
:
&
ast
::
Expr
)
{
match
e
.node
{
ast
::
ExprWhile
(
cond
,
_
)
=>
{
ast
::
ExprWhile
(
cond
,
_
,
_
)
=>
{
match
cond
.node
{
ast
::
ExprLit
(
lit
)
=>
{
match
lit
.node
{
...
...
@@ -1073,7 +1073,7 @@ fn get_lints(&self) -> LintArray {
fn
check_expr
(
&
mut
self
,
cx
:
&
Context
,
e
:
&
ast
::
Expr
)
{
let
(
value
,
msg
,
struct_lit_needs_parens
)
=
match
e
.node
{
ast
::
ExprIf
(
cond
,
_
,
_
)
=>
(
cond
,
"`if` condition"
,
true
),
ast
::
ExprWhile
(
cond
,
_
)
=>
(
cond
,
"`while` condition"
,
true
),
ast
::
ExprWhile
(
cond
,
_
,
_
)
=>
(
cond
,
"`while` condition"
,
true
),
ast
::
ExprMatch
(
head
,
_
)
=>
(
head
,
"`match` head expression"
,
true
),
ast
::
ExprRet
(
Some
(
value
))
=>
(
value
,
"`return` value"
,
false
),
ast
::
ExprAssign
(
_
,
value
)
=>
(
value
,
"assigned value"
,
false
),
...
...
src/librustc/middle/cfg/construct.rs
浏览文件 @
373b9d62
...
...
@@ -227,7 +227,7 @@ fn expr(&mut self, expr: Gc<ast::Expr>, pred: CFGIndex) -> CFGIndex {
self
.add_node
(
expr
.id
,
[
then_exit
,
else_exit
])
// 4, 5
}
ast
::
ExprWhile
(
ref
cond
,
ref
body
)
=>
{
ast
::
ExprWhile
(
ref
cond
,
ref
body
,
_
)
=>
{
//
// [pred]
// |
...
...
src/librustc/middle/check_loop.rs
浏览文件 @
373b9d62
...
...
@@ -35,7 +35,7 @@ fn visit_item(&mut self, i: &ast::Item, _cx: Context) {
fn
visit_expr
(
&
mut
self
,
e
:
&
ast
::
Expr
,
cx
:
Context
)
{
match
e
.node
{
ast
::
ExprWhile
(
ref
e
,
ref
b
)
=>
{
ast
::
ExprWhile
(
ref
e
,
ref
b
,
_
)
=>
{
self
.visit_expr
(
&**
e
,
cx
);
self
.visit_block
(
&**
b
,
Loop
);
}
...
...
src/librustc/middle/expr_use_visitor.rs
浏览文件 @
373b9d62
...
...
@@ -410,7 +410,7 @@ pub fn walk_expr(&mut self, expr: &ast::Expr) {
self
.walk_block
(
&**
blk
);
}
ast
::
ExprWhile
(
ref
cond_expr
,
ref
blk
)
=>
{
ast
::
ExprWhile
(
ref
cond_expr
,
ref
blk
,
_
)
=>
{
self
.consume_expr
(
&**
cond_expr
);
self
.walk_block
(
&**
blk
);
}
...
...
src/librustc/middle/liveness.rs
浏览文件 @
373b9d62
...
...
@@ -1017,7 +1017,7 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
self
.propagate_through_expr
(
&**
cond
,
ln
)
}
ExprWhile
(
ref
cond
,
ref
blk
)
=>
{
ExprWhile
(
ref
cond
,
ref
blk
,
_
)
=>
{
self
.propagate_through_loop
(
expr
,
WhileLoop
(
cond
.clone
()),
&**
blk
,
...
...
src/librustc/middle/region.rs
浏览文件 @
373b9d62
...
...
@@ -496,7 +496,7 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor,
visitor
.region_maps
.mark_as_terminating_scope
(
body
.id
);
}
ast
::
ExprWhile
(
expr
,
body
)
=>
{
ast
::
ExprWhile
(
expr
,
body
,
_
)
=>
{
visitor
.region_maps
.mark_as_terminating_scope
(
expr
.id
);
visitor
.region_maps
.mark_as_terminating_scope
(
body
.id
);
}
...
...
src/librustc/middle/resolve.rs
浏览文件 @
373b9d62
...
...
@@ -5622,7 +5622,7 @@ fn resolve_expr(&mut self, expr: &Expr) {
visit
::
walk_expr
(
self
,
expr
,
());
}
ExprLoop
(
_
,
Some
(
label
))
=>
{
ExprLoop
(
_
,
Some
(
label
))
|
ExprWhile
(
_
,
_
,
Some
(
label
))
=>
{
self
.with_label_rib
(|
this
|
{
let
def_like
=
DlDef
(
DefLabel
(
expr
.id
));
...
...
src/librustc/middle/trans/debuginfo.rs
浏览文件 @
373b9d62
...
...
@@ -3489,7 +3489,7 @@ fn walk_expr(cx: &CrateContext,
}
}
ast
::
ExprWhile
(
ref
cond_exp
,
ref
loop_body
)
=>
{
ast
::
ExprWhile
(
ref
cond_exp
,
ref
loop_body
,
_
)
=>
{
walk_expr
(
cx
,
&**
cond_exp
,
scope_stack
,
scope_map
);
with_new_scope
(
cx
,
...
...
src/librustc/middle/trans/expr.rs
浏览文件 @
373b9d62
...
...
@@ -900,7 +900,7 @@ fn trans_rvalue_stmt_unadjusted<'a>(bcx: &'a Block<'a>,
ast
::
ExprRet
(
ex
)
=>
{
controlflow
::
trans_ret
(
bcx
,
ex
)
}
ast
::
ExprWhile
(
ref
cond
,
ref
body
)
=>
{
ast
::
ExprWhile
(
ref
cond
,
ref
body
,
_
)
=>
{
controlflow
::
trans_while
(
bcx
,
expr
.id
,
&**
cond
,
&**
body
)
}
ast
::
ExprForLoop
(
ref
pat
,
ref
head
,
ref
body
,
_
)
=>
{
...
...
src/librustc/middle/typeck/check/mod.rs
浏览文件 @
373b9d62
...
...
@@ -3757,7 +3757,7 @@ fn check_struct_enum_variant(fcx: &FnCtxt,
check_then_else
(
fcx
,
&**
cond
,
&**
then_blk
,
opt_else_expr
.clone
(),
id
,
expr
.span
,
expected
);
}
ast
::
ExprWhile
(
ref
cond
,
ref
body
)
=>
{
ast
::
ExprWhile
(
ref
cond
,
ref
body
,
_
)
=>
{
check_expr_has_type
(
fcx
,
&**
cond
,
ty
::
mk_bool
());
check_block_no_value
(
fcx
,
&**
body
);
let
cond_ty
=
fcx
.expr_ty
(
&**
cond
);
...
...
src/librustc/middle/typeck/check/regionck.rs
浏览文件 @
373b9d62
...
...
@@ -749,7 +749,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
rcx
.set_repeating_scope
(
repeating_scope
);
}
ast
::
ExprWhile
(
ref
cond
,
ref
body
)
=>
{
ast
::
ExprWhile
(
ref
cond
,
ref
body
,
_
)
=>
{
let
repeating_scope
=
rcx
.set_repeating_scope
(
cond
.id
);
rcx
.visit_expr
(
&**
cond
,
());
...
...
src/libsyntax/ast.rs
浏览文件 @
373b9d62
...
...
@@ -524,7 +524,8 @@ pub enum Expr_ {
ExprLit
(
Gc
<
Lit
>
),
ExprCast
(
Gc
<
Expr
>
,
P
<
Ty
>
),
ExprIf
(
Gc
<
Expr
>
,
P
<
Block
>
,
Option
<
Gc
<
Expr
>>
),
ExprWhile
(
Gc
<
Expr
>
,
P
<
Block
>
),
// FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
ExprWhile
(
Gc
<
Expr
>
,
P
<
Block
>
,
Option
<
Ident
>
),
// FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
ExprForLoop
(
Gc
<
Pat
>
,
Gc
<
Expr
>
,
P
<
Block
>
,
Option
<
Ident
>
),
// Conditionless loop (can be exited with break, cont, or ret)
...
...
src/libsyntax/ext/expand.rs
浏览文件 @
373b9d62
...
...
@@ -66,6 +66,12 @@ fn expand_expr(e: Gc<ast::Expr>, fld: &mut MacroExpander) -> Gc<ast::Expr> {
}
}
ast
::
ExprWhile
(
cond
,
body
,
opt_ident
)
=>
{
let
cond
=
fld
.fold_expr
(
cond
);
let
(
body
,
opt_ident
)
=
expand_loop_block
(
body
,
opt_ident
,
fld
);
fld
.cx
.expr
(
e
.span
,
ast
::
ExprWhile
(
cond
,
body
,
opt_ident
))
}
ast
::
ExprLoop
(
loop_block
,
opt_ident
)
=>
{
let
(
loop_block
,
opt_ident
)
=
expand_loop_block
(
loop_block
,
opt_ident
,
fld
);
fld
.cx
.expr
(
e
.span
,
ast
::
ExprLoop
(
loop_block
,
opt_ident
))
...
...
src/libsyntax/fold.rs
浏览文件 @
373b9d62
...
...
@@ -1132,18 +1132,20 @@ pub fn noop_fold_expr<T: Folder>(e: Gc<Expr>, folder: &mut T) -> Gc<Expr> {
folder
.fold_block
(
tr
),
fl
.map
(|
x
|
folder
.fold_expr
(
x
)))
}
ExprWhile
(
cond
,
body
)
=>
{
ExprWhile
(
folder
.fold_expr
(
cond
),
folder
.fold_block
(
body
))
ExprWhile
(
cond
,
body
,
opt_ident
)
=>
{
ExprWhile
(
folder
.fold_expr
(
cond
),
folder
.fold_block
(
body
),
opt_ident
.map
(|
i
|
folder
.fold_ident
(
i
)))
}
ExprForLoop
(
pat
,
iter
,
body
,
ref
maybe
_ident
)
=>
{
ExprForLoop
(
pat
,
iter
,
body
,
ref
opt
_ident
)
=>
{
ExprForLoop
(
folder
.fold_pat
(
pat
),
folder
.fold_expr
(
iter
),
folder
.fold_block
(
body
),
maybe
_ident
.map
(|
i
|
folder
.fold_ident
(
i
)))
opt
_ident
.map
(|
i
|
folder
.fold_ident
(
i
)))
}
ExprLoop
(
body
,
opt_ident
)
=>
{
ExprLoop
(
folder
.fold_block
(
body
),
opt_ident
.map
(|
x
|
folder
.fold_ident
(
x
)))
opt_ident
.map
(|
i
|
folder
.fold_ident
(
i
)))
}
ExprMatch
(
expr
,
ref
arms
)
=>
{
ExprMatch
(
folder
.fold_expr
(
expr
),
...
...
src/libsyntax/parse/parser.rs
浏览文件 @
373b9d62
...
...
@@ -2094,19 +2094,22 @@ pub fn parse_bottom_expr(&mut self) -> Gc<Expr> {
return
self
.parse_for_expr
(
None
);
}
if
self
.eat_keyword
(
keywords
::
While
)
{
return
self
.parse_while_expr
();
return
self
.parse_while_expr
(
None
);
}
if
Parser
::
token_is_lifetime
(
&
self
.token
)
{
let
lifetime
=
self
.get_lifetime
();
self
.bump
();
self
.expect
(
&
token
::
COLON
);
if
self
.eat_keyword
(
keywords
::
While
)
{
return
self
.parse_while_expr
(
Some
(
lifetime
))
}
if
self
.eat_keyword
(
keywords
::
For
)
{
return
self
.parse_for_expr
(
Some
(
lifetime
))
}
if
self
.eat_keyword
(
keywords
::
Loop
)
{
return
self
.parse_loop_expr
(
Some
(
lifetime
))
}
self
.fatal
(
"expected `
for`
or `loop` after a label"
)
self
.fatal
(
"expected `
while`, `for`,
or `loop` after a label"
)
}
if
self
.eat_keyword
(
keywords
::
Loop
)
{
return
self
.parse_loop_expr
(
None
);
...
...
@@ -2762,12 +2765,12 @@ pub fn parse_for_expr(&mut self, opt_ident: Option<ast::Ident>) -> Gc<Expr> {
self
.mk_expr
(
lo
,
hi
,
ExprForLoop
(
pat
,
expr
,
loop_block
,
opt_ident
))
}
pub
fn
parse_while_expr
(
&
mut
self
)
->
Gc
<
Expr
>
{
pub
fn
parse_while_expr
(
&
mut
self
,
opt_ident
:
Option
<
ast
::
Ident
>
)
->
Gc
<
Expr
>
{
let
lo
=
self
.last_span.lo
;
let
cond
=
self
.parse_expr_res
(
RESTRICT_NO_STRUCT_LITERAL
);
let
body
=
self
.parse_block
();
let
hi
=
body
.span.hi
;
return
self
.mk_expr
(
lo
,
hi
,
ExprWhile
(
cond
,
body
));
return
self
.mk_expr
(
lo
,
hi
,
ExprWhile
(
cond
,
body
,
opt_ident
));
}
pub
fn
parse_loop_expr
(
&
mut
self
,
opt_ident
:
Option
<
ast
::
Ident
>
)
->
Gc
<
Expr
>
{
...
...
src/libsyntax/print/pprust.rs
浏览文件 @
373b9d62
...
...
@@ -1438,7 +1438,11 @@ pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
ast
::
ExprIf
(
ref
test
,
ref
blk
,
elseopt
)
=>
{
try!
(
self
.print_if
(
&**
test
,
&**
blk
,
elseopt
,
false
));
}
ast
::
ExprWhile
(
ref
test
,
ref
blk
)
=>
{
ast
::
ExprWhile
(
ref
test
,
ref
blk
,
opt_ident
)
=>
{
for
ident
in
opt_ident
.iter
()
{
try!
(
self
.print_ident
(
*
ident
));
try!
(
self
.word_space
(
":"
));
}
try!
(
self
.head
(
"while"
));
try!
(
self
.print_expr
(
&**
test
));
try!
(
space
(
&
mut
self
.s
));
...
...
src/libsyntax/visit.rs
浏览文件 @
373b9d62
...
...
@@ -775,7 +775,7 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en
visitor
.visit_block
(
&**
if_block
,
env
.clone
());
walk_expr_opt
(
visitor
,
optional_else
,
env
.clone
())
}
ExprWhile
(
ref
subexpression
,
ref
block
)
=>
{
ExprWhile
(
ref
subexpression
,
ref
block
,
_
)
=>
{
visitor
.visit_expr
(
&**
subexpression
,
env
.clone
());
visitor
.visit_block
(
&**
block
,
env
.clone
())
}
...
...
src/test/run-pass/hygienic-labels-in-let.rs
浏览文件 @
373b9d62
...
...
@@ -19,6 +19,13 @@
}
}
macro_rules!
while_true
{
(
$e
:
expr
)
=>
{
// $e shouldn't be able to interact with this 'x
'x
:
while
1
i
+
1
==
2
{
$e
}
}
}
macro_rules!
run_once
{
(
$e
:
expr
)
=>
{
// ditto
...
...
@@ -49,6 +56,16 @@ pub fn main() {
};
assert_eq!
(
k
,
1
i
);
let
l
:
int
=
{
'x
:
for
_
in
range
(
0
i
,
1
)
{
// ditto
while_true!
(
break
'x
);
i
+=
1
;
}
i
+
1
};
assert_eq!
(
l
,
1
i
);
let
n
:
int
=
{
'x
:
for
_
in
range
(
0
i
,
1
)
{
// ditto
...
...
src/test/run-pass/hygienic-labels.rs
浏览文件 @
373b9d62
...
...
@@ -24,6 +24,13 @@
}
}
macro_rules!
while_x
{
(
$e
:
expr
)
=>
{
// ditto
'x
:
while
1
i
+
1
==
2
{
$e
}
}
}
pub
fn
main
()
{
'x
:
for
_
in
range
(
0
i
,
1
)
{
// this 'x should refer to the outer loop, lexically
...
...
@@ -37,6 +44,11 @@ pub fn main() {
fail
!
(
"break doesn't act hygienically inside infinite loop"
);
}
'x
:
while
1
i
+
1
==
2
{
while_x!
(
break
'x
);
fail
!
(
"break doesn't act hygienically inside infinite while loop"
);
}
'x
:
for
_
in
range
(
0
i
,
1
)
{
// ditto
run_once!
(
continue
'x
);
...
...
src/test/run-pass/labeled-break.rs
浏览文件 @
373b9d62
...
...
@@ -20,4 +20,10 @@ pub fn main() {
break
'bar
;
}
}
'foobar
:
while
1
i
+
1
==
2
{
loop
{
break
'foobar
;
}
}
}
src/test/run-pass/while-label.rs
0 → 100644
浏览文件 @
373b9d62
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub
fn
main
()
{
let
mut
i
=
100
i
;
'w
:
while
1
i
+
1
==
2
{
i
-=
1
;
if
i
==
95
{
break
'w
;
fail
!
(
"Should have broken out of loop"
);
}
}
assert_eq!
(
i
,
95
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录