Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
fd35770e
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
fd35770e
编写于
2月 24, 2022
作者:
M
Michael Howell
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
diagnostic: suggest parens when users want logical ops, but get closures
上级
4b043fab
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
151 addition
and
3 deletion
+151
-3
compiler/rustc_parse/src/parser/expr.rs
compiler/rustc_parse/src/parser/expr.rs
+16
-2
src/test/ui/parser/expr-as-stmt.fixed
src/test/ui/parser/expr-as-stmt.fixed
+27
-0
src/test/ui/parser/expr-as-stmt.rs
src/test/ui/parser/expr-as-stmt.rs
+27
-0
src/test/ui/parser/expr-as-stmt.stderr
src/test/ui/parser/expr-as-stmt.stderr
+81
-1
未找到文件。
compiler/rustc_parse/src/parser/expr.rs
浏览文件 @
fd35770e
...
...
@@ -372,10 +372,17 @@ fn should_continue_as_assoc_expr(&mut self, lhs: &Expr) -> bool {
self
.sess.ambiguous_block_expr_parse
.borrow_mut
()
.insert
(
sp
,
lhs
.span
);
false
}
(
true
,
Some
(
AssocOp
::
LAnd
))
=>
{
(
true
,
Some
(
AssocOp
::
LAnd
))
|
(
true
,
Some
(
AssocOp
::
LOr
))
|
(
true
,
Some
(
AssocOp
::
BitOr
))
=>
{
// `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }`. Separated from the
// above due to #74233.
// These cases are ambiguous and can't be identified in the parser alone.
//
// Bitwise AND is left out because guessing intent is hard. We can make
// suggestions based on the assumption that double-refs are rarely intentional,
// and closures are distinct enough that they don't get mixed up with their
// return value.
let
sp
=
self
.sess
.source_map
()
.start_point
(
self
.token.span
);
self
.sess.ambiguous_block_expr_parse
.borrow_mut
()
.insert
(
sp
,
lhs
.span
);
false
...
...
@@ -1244,7 +1251,14 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
}
else
if
self
.check
(
&
token
::
OpenDelim
(
token
::
Brace
))
{
self
.parse_block_expr
(
None
,
lo
,
BlockCheckMode
::
Default
,
attrs
)
}
else
if
self
.check
(
&
token
::
BinOp
(
token
::
Or
))
||
self
.check
(
&
token
::
OrOr
)
{
self
.parse_closure_expr
(
attrs
)
self
.parse_closure_expr
(
attrs
)
.map_err
(|
mut
err
|
{
// If the input is something like `if a { 1 } else { 2 } | if a { 3 } else { 4 }`
// then suggest parens around the lhs.
if
let
Some
(
sp
)
=
self
.sess.ambiguous_block_expr_parse
.borrow
()
.get
(
&
lo
)
{
self
.sess
.expr_parentheses_needed
(
&
mut
err
,
*
sp
);
}
err
})
}
else
if
self
.check
(
&
token
::
OpenDelim
(
token
::
Bracket
))
{
self
.parse_array_or_repeat_expr
(
attrs
,
token
::
Bracket
)
}
else
if
self
.check_path
()
{
...
...
src/test/ui/parser/expr-as-stmt.fixed
浏览文件 @
fd35770e
...
...
@@ -37,4 +37,31 @@ fn qux() -> u32 {
//~^ ERROR mismatched types
}
fn space_cadet() -> bool {
({ true }) | { true } //~ ERROR E0308
//~^ ERROR expected parameter name
}
fn revenge_from_mars() -> bool {
({ true }) && { true } //~ ERROR E0308
//~^ ERROR mismatched types
}
fn attack_from_mars() -> bool {
({ true }) || { true } //~ ERROR E0308
//~^ ERROR mismatched types
}
// This gets corrected by adding a semicolon, instead of parens.
// It's placed here to help keep track of the way this diagnostic
// needs to interact with type checking to avoid MachineApplicable
// suggestions that actually break stuff.
//
// If you're wondering what happens if that `foo()` is a `true` like
// all the ones above use? Nothing. It makes neither suggestion in
// that case.
fn asteroids() -> impl FnOnce() -> bool {
{ foo(); } || { true } //~ ERROR E0308
}
fn main() {}
src/test/ui/parser/expr-as-stmt.rs
浏览文件 @
fd35770e
...
...
@@ -37,4 +37,31 @@ fn qux() -> u32 {
//~^ ERROR mismatched types
}
fn
space_cadet
()
->
bool
{
{
true
}
|
{
true
}
//~ ERROR E0308
//~^ ERROR expected parameter name
}
fn
revenge_from_mars
()
->
bool
{
{
true
}
&&
{
true
}
//~ ERROR E0308
//~^ ERROR mismatched types
}
fn
attack_from_mars
()
->
bool
{
{
true
}
||
{
true
}
//~ ERROR E0308
//~^ ERROR mismatched types
}
// This gets corrected by adding a semicolon, instead of parens.
// It's placed here to help keep track of the way this diagnostic
// needs to interact with type checking to avoid MachineApplicable
// suggestions that actually break stuff.
//
// If you're wondering what happens if that `foo()` is a `true` like
// all the ones above use? Nothing. It makes neither suggestion in
// that case.
fn
asteroids
()
->
impl
FnOnce
()
->
bool
{
{
foo
()
}
||
{
true
}
//~ ERROR E0308
}
fn
main
()
{}
src/test/ui/parser/expr-as-stmt.stderr
浏览文件 @
fd35770e
...
...
@@ -44,6 +44,25 @@ LL | _ => 1,
LL ~ }) > 0
|
error: expected parameter name, found `{`
--> $DIR/expr-as-stmt.rs:41:16
|
LL | { true } | { true }
| ^ expected parameter name
|
help: parentheses are required to parse this as an expression
|
LL | ({ true }) | { true }
| + +
error[E0308]: mismatched types
--> $DIR/expr-as-stmt.rs:64:7
|
LL | { foo() } || { true }
| ^^^^^- help: consider using a semicolon here: `;`
| |
| expected `()`, found `i32`
error[E0308]: mismatched types
--> $DIR/expr-as-stmt.rs:8:6
|
...
...
@@ -121,7 +140,68 @@ help: parentheses are required to parse this as an expression
LL | ({2}) - 2
| + +
error: aborting due to 11 previous errors
error[E0308]: mismatched types
--> $DIR/expr-as-stmt.rs:41:7
|
LL | { true } | { true }
| ^^^^ expected `()`, found `bool`
|
help: you might have meant to return this value
|
LL | { return true; } | { true }
| ++++++ +
error[E0308]: mismatched types
--> $DIR/expr-as-stmt.rs:46:7
|
LL | { true } && { true }
| ^^^^ expected `()`, found `bool`
|
help: you might have meant to return this value
|
LL | { return true; } && { true }
| ++++++ +
error[E0308]: mismatched types
--> $DIR/expr-as-stmt.rs:46:14
|
LL | fn revenge_from_mars() -> bool {
| ---- expected `bool` because of return type
LL | { true } && { true }
| ^^^^^^^^^^^ expected `bool`, found `&&bool`
|
help: parentheses are required to parse this as an expression
|
LL | ({ true }) && { true }
| + +
error[E0308]: mismatched types
--> $DIR/expr-as-stmt.rs:51:7
|
LL | { true } || { true }
| ^^^^ expected `()`, found `bool`
|
help: you might have meant to return this value
|
LL | { return true; } || { true }
| ++++++ +
error[E0308]: mismatched types
--> $DIR/expr-as-stmt.rs:51:14
|
LL | fn attack_from_mars() -> bool {
| ---- expected `bool` because of return type
LL | { true } || { true }
| ^^^^^^^^^^^ expected `bool`, found closure
|
= note: expected type `bool`
found closure `[closure@$DIR/expr-as-stmt.rs:51:14: 51:25]`
help: parentheses are required to parse this as an expression
|
LL | ({ true }) || { true }
| + +
error: aborting due to 18 previous errors
Some errors have detailed explanations: E0308, E0600, E0614.
For more information about an error, try `rustc --explain E0308`.
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录