Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
ffa52693
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,发现更多精彩内容 >>
提交
ffa52693
编写于
9月 19, 2019
作者:
A
Alex Zatelepin
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
address review comments
上级
c474c6e8
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
37 addition
and
39 deletion
+37
-39
src/librustc/hir/lowering/expr.rs
src/librustc/hir/lowering/expr.rs
+13
-15
src/librustc_typeck/check/expr.rs
src/librustc_typeck/check/expr.rs
+20
-20
src/test/ui/try-block/try-block-bad-type.stderr
src/test/ui/try-block/try-block-bad-type.stderr
+4
-4
未找到文件。
src/librustc/hir/lowering/expr.rs
浏览文件 @
ffa52693
...
...
@@ -392,36 +392,34 @@ fn lower_expr_while_in_loop_scope(
)
}
/// Desugar `try { <stmts>; <expr> }` into `{ <stmts>; ::std::ops::Try::from_ok(<expr>) }`,
/// `try { <stmts>; }` into `{ <stmts>; ::std::ops::Try::from_ok(()) }`
/// and save the block id to use it as a break target for desugaring of the `?` operator.
fn
lower_expr_try_block
(
&
mut
self
,
body
:
&
Block
)
->
hir
::
ExprKind
{
self
.with_catch_scope
(
body
.id
,
|
this
|
{
let
mut
block
=
this
.lower_block
(
body
,
true
)
.into_inner
();
let
tail_expr
=
block
.expr
.take
()
.map_or_else
(
||
{
let
unit_span
=
this
.mark_span_with_reason
(
DesugaringKind
::
TryBlock
,
this
.sess
.source_map
()
.end_point
(
body
.span
),
None
);
this
.expr_unit
(
unit_span
)
},
|
x
:
P
<
hir
::
Expr
>
|
x
.into_inner
(),
);
let
from_ok_span
=
this
.mark_span_with_reason
(
let
try_span
=
this
.mark_span_with_reason
(
DesugaringKind
::
TryBlock
,
tail_expr
.span
,
body
.span
,
this
.allow_try_trait
.clone
(),
);
// Final expression of the block (if present) or `()` with span at the end of block
let
tail_expr
=
block
.expr
.take
()
.map_or_else
(
||
this
.expr_unit
(
this
.sess
.source_map
()
.end_point
(
try_span
)),
|
x
:
P
<
hir
::
Expr
>
|
x
.into_inner
(),
);
let
ok_wrapped_span
=
this
.mark_span_with_reason
(
DesugaringKind
::
TryBlock
,
tail_expr
.span
,
None
);
// `::std::ops::Try::from_ok($tail_expr)`
block
.expr
=
Some
(
this
.wrap_in_try_constructor
(
sym
::
from_ok
,
from_ok
_span
,
tail_expr
,
ok_wrapped_span
));
sym
::
from_ok
,
try
_span
,
tail_expr
,
ok_wrapped_span
));
hir
::
ExprKind
::
Block
(
P
(
block
),
None
)
})
...
...
src/librustc_typeck/check/expr.rs
浏览文件 @
ffa52693
...
...
@@ -151,20 +151,18 @@ fn check_expr_with_expectation_and_needs(
debug!
(
">> type-checking: expr={:?} expected={:?}"
,
expr
,
expected
);
// If when desugaring the try block we ok-wrapped an expression that diverges
// (e.g. `try { return }`) then technically the ok-wrapping expression is unreachable.
// But since it is autogenerated code the resulting warning is confusing for the user
// so we want avoid generating it.
// Ditto for the autogenerated `Try::from_ok(())` at the end of e.g. `try { return; }`.
let
(
is_try_block_ok_wrapped_expr
,
is_try_block_generated_expr
)
=
match
expr
.node
{
ExprKind
::
Call
(
_
,
ref
args
)
if
expr
.span
.is_desugaring
(
DesugaringKind
::
TryBlock
)
=>
{
(
true
,
args
.len
()
==
1
&&
args
[
0
]
.span
.is_desugaring
(
DesugaringKind
::
TryBlock
))
}
_
=>
(
false
,
false
),
// True if `expr` is a `Try::from_ok(())` that is a result of desugaring a try block
// without the final expr (e.g. `try { return; }`). We don't want to generate an
// unreachable_code lint for it since warnings for autogenerated code are confusing.
let
is_try_block_generated_unit_expr
=
match
expr
.node
{
ExprKind
::
Call
(
_
,
ref
args
)
if
expr
.span
.is_desugaring
(
DesugaringKind
::
TryBlock
)
=>
args
.len
()
==
1
&&
args
[
0
]
.span
.is_desugaring
(
DesugaringKind
::
TryBlock
),
_
=>
false
,
};
// Warn for expressions after diverging siblings.
if
!
is_try_block_generated_expr
{
if
!
is_try_block_generated_
unit_
expr
{
self
.warn_if_unreachable
(
expr
.hir_id
,
expr
.span
,
"expression"
);
}
...
...
@@ -177,15 +175,17 @@ fn check_expr_with_expectation_and_needs(
let
ty
=
self
.check_expr_kind
(
expr
,
expected
,
needs
);
// Warn for non-block expressions with diverging children.
if
!
is_try_block_ok_wrapped_expr
{
match
expr
.kind
{
ExprKind
::
Block
(
..
)
|
ExprKind
::
Loop
(
..
)
|
ExprKind
::
Match
(
..
)
=>
{},
ExprKind
::
Call
(
ref
callee
,
_
)
=>
self
.warn_if_unreachable
(
expr
.hir_id
,
callee
.span
,
"call"
),
ExprKind
::
MethodCall
(
_
,
ref
span
,
_
)
=>
self
.warn_if_unreachable
(
expr
.hir_id
,
*
span
,
"call"
),
_
=>
self
.warn_if_unreachable
(
expr
.hir_id
,
expr
.span
,
"expression"
),
}
match
expr
.kind
{
ExprKind
::
Block
(
..
)
|
ExprKind
::
Loop
(
..
)
|
ExprKind
::
Match
(
..
)
=>
{},
// If `expr` is a result of desugaring the try block and is an ok-wrapped
// diverging expression (e.g. it arose from desugaring of `try { return }`),
// we skip issuing a warning because it is autogenerated code.
ExprKind
::
Call
(
..
)
if
expr
.span
.is_desugaring
(
DesugaringKind
::
TryBlock
)
=>
{},
ExprKind
::
Call
(
ref
callee
,
_
)
=>
self
.warn_if_unreachable
(
expr
.hir_id
,
callee
.span
,
"call"
),
ExprKind
::
MethodCall
(
_
,
ref
span
,
_
)
=>
self
.warn_if_unreachable
(
expr
.hir_id
,
*
span
,
"call"
),
_
=>
self
.warn_if_unreachable
(
expr
.hir_id
,
expr
.span
,
"expression"
),
}
// Any expression that produces a value of type `!` must have diverged
...
...
src/test/ui/try-block/try-block-bad-type.stderr
浏览文件 @
ffa52693
...
...
@@ -32,18 +32,18 @@ LL | let res: Result<i32, i32> = try { };
found type `()`
error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
--> $DIR/try-block-bad-type.rs:17:2
5
--> $DIR/try-block-bad-type.rs:17:2
3
|
LL | let res: () = try { };
|
^ the trait `std::ops::Try` is not implemented for `()`
|
^^
^ the trait `std::ops::Try` is not implemented for `()`
|
= note: required by `std::ops::Try::from_ok`
error[E0277]: the trait bound `i32: std::ops::Try` is not satisfied
--> $DIR/try-block-bad-type.rs:19:2
6
--> $DIR/try-block-bad-type.rs:19:2
4
|
LL | let res: i32 = try { 5 };
|
^ the trait `std::ops::Try` is not implemented for `i32`
|
^^^^
^ the trait `std::ops::Try` is not implemented for `i32`
|
= note: required by `std::ops::Try::from_ok`
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录