Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
d3b31065
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,发现更多精彩内容 >>
未验证
提交
d3b31065
编写于
1月 14, 2021
作者:
M
Mara Bos
提交者:
GitHub
1月 14, 2021
浏览文件
操作
浏览文件
下载
差异文件
Rollup merge of #80017 - camelid:sugg-rest-pattern, r=estebank
Suggest `_` and `..` if a pattern has too few fields Fixes #80010.
上级
8ac21fb2
e8c87935
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
291 addition
and
7 deletion
+291
-7
compiler/rustc_typeck/src/check/pat.rs
compiler/rustc_typeck/src/check/pat.rs
+52
-5
src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr
...ructuring-assignment/tuple_struct_destructure_fail.stderr
+18
-0
src/test/ui/error-codes/E0023.stderr
src/test/ui/error-codes/E0023.stderr
+7
-2
src/test/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr
...sues/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr
+9
-0
src/test/ui/issues/issue-72574-2.stderr
src/test/ui/issues/issue-72574-2.stderr
+5
-0
src/test/ui/match/match-pattern-field-mismatch.stderr
src/test/ui/match/match-pattern-field-mismatch.stderr
+9
-0
src/test/ui/pattern/issue-74539.stderr
src/test/ui/pattern/issue-74539.stderr
+5
-0
src/test/ui/pattern/pat-tuple-underfield.rs
src/test/ui/pattern/pat-tuple-underfield.rs
+55
-0
src/test/ui/pattern/pat-tuple-underfield.stderr
src/test/ui/pattern/pat-tuple-underfield.stderr
+131
-0
未找到文件。
compiler/rustc_typeck/src/check/pat.rs
浏览文件 @
d3b31065
...
...
@@ -15,6 +15,7 @@
use
rustc_span
::
lev_distance
::
find_best_match_for_name
;
use
rustc_span
::
source_map
::{
Span
,
Spanned
};
use
rustc_span
::
symbol
::
Ident
;
use
rustc_span
::{
BytePos
,
DUMMY_SP
};
use
rustc_trait_selection
::
traits
::{
ObligationCause
,
Pattern
};
use
std
::
cmp
;
...
...
@@ -1001,7 +1002,7 @@ fn e0023(
// More generally, the expected type wants a tuple variant with one field of an
// N-arity-tuple, e.g., `V_i((p_0, .., p_N))`. Meanwhile, the user supplied a pattern
// with the subpatterns directly in the tuple variant pattern, e.g., `V_i(p_0, .., p_N)`.
let
missing_parenthes
i
s
=
match
(
&
expected
.kind
(),
fields
,
had_err
)
{
let
missing_parenthes
e
s
=
match
(
&
expected
.kind
(),
fields
,
had_err
)
{
// #67037: only do this if we could successfully type-check the expected type against
// the tuple struct pattern. Otherwise the substs could get out of range on e.g.,
// `let P() = U;` where `P != U` with `struct P<T>(T);`.
...
...
@@ -1014,13 +1015,13 @@ fn e0023(
}
_
=>
false
,
};
if
missing_parenthes
i
s
{
if
missing_parenthes
e
s
{
let
(
left
,
right
)
=
match
subpats
{
// This is the zero case; we aim to get the "hi" part of the `QPath`'s
// span as the "lo" and then the "hi" part of the pattern's span as the "hi".
// This looks like:
//
// help: missing parenthes
i
s
// help: missing parenthes
e
s
// |
// L | let A(()) = A(());
// | ^ ^
...
...
@@ -1029,17 +1030,63 @@ fn e0023(
// last sub-pattern. In the case of `A(x)` the first and last may coincide.
// This looks like:
//
// help: missing parenthes
i
s
// help: missing parenthes
e
s
// |
// L | let A((x, y)) = A((1, 2));
// | ^ ^
[
first
,
..
]
=>
(
first
.span
.shrink_to_lo
(),
subpats
.last
()
.unwrap
()
.span
),
};
err
.multipart_suggestion
(
"missing parenthes
i
s"
,
"missing parenthes
e
s"
,
vec!
[(
left
,
"("
.to_string
()),
(
right
.shrink_to_hi
(),
")"
.to_string
())],
Applicability
::
MachineApplicable
,
);
}
else
if
fields
.len
()
>
subpats
.len
()
{
let
after_fields_span
=
if
pat_span
==
DUMMY_SP
{
pat_span
}
else
{
pat_span
.with_hi
(
pat_span
.hi
()
-
BytePos
(
1
))
.shrink_to_hi
()
};
let
all_fields_span
=
match
subpats
{
[]
=>
after_fields_span
,
[
field
]
=>
field
.span
,
[
first
,
..
,
last
]
=>
first
.span
.to
(
last
.span
),
};
// Check if all the fields in the pattern are wildcards.
let
all_wildcards
=
subpats
.iter
()
.all
(|
pat
|
matches!
(
pat
.kind
,
PatKind
::
Wild
));
let
mut
wildcard_sugg
=
vec!
[
"_"
;
fields
.len
()
-
subpats
.len
()]
.join
(
", "
);
if
!
subpats
.is_empty
()
{
wildcard_sugg
=
String
::
from
(
", "
)
+
&
wildcard_sugg
;
}
err
.span_suggestion_verbose
(
after_fields_span
,
"use `_` to explicitly ignore each field"
,
wildcard_sugg
,
Applicability
::
MaybeIncorrect
,
);
// Only suggest `..` if more than one field is missing
// or the pattern consists of all wildcards.
if
fields
.len
()
-
subpats
.len
()
>
1
||
all_wildcards
{
if
subpats
.is_empty
()
||
all_wildcards
{
err
.span_suggestion_verbose
(
all_fields_span
,
"use `..` to ignore all fields"
,
String
::
from
(
".."
),
Applicability
::
MaybeIncorrect
,
);
}
else
{
err
.span_suggestion_verbose
(
after_fields_span
,
"use `..` to ignore the rest of the fields"
,
String
::
from
(
", .."
),
Applicability
::
MaybeIncorrect
,
);
}
}
}
err
.emit
();
...
...
src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr
浏览文件 @
d3b31065
...
...
@@ -31,6 +31,15 @@ LL | struct TupleStruct<S, T>(S, T);
...
LL | TupleStruct(_) = TupleStruct(1, 2);
| ^^^^^^^^^^^^^^ expected 2 fields, found 1
|
help: use `_` to explicitly ignore each field
|
LL | TupleStruct(_, _) = TupleStruct(1, 2);
| ^^^
help: use `..` to ignore all fields
|
LL | TupleStruct(..) = TupleStruct(1, 2);
| ^^
error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields
--> $DIR/tuple_struct_destructure_fail.rs:34:5
...
...
@@ -49,6 +58,15 @@ LL | SingleVariant(S, T)
...
LL | Enum::SingleVariant(_) = Enum::SingleVariant(1, 2);
| ^^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 1
|
help: use `_` to explicitly ignore each field
|
LL | Enum::SingleVariant(_, _) = Enum::SingleVariant(1, 2);
| ^^^
help: use `..` to ignore all fields
|
LL | Enum::SingleVariant(..) = Enum::SingleVariant(1, 2);
| ^^
error[E0070]: invalid left-hand side of assignment
--> $DIR/tuple_struct_destructure_fail.rs:40:12
...
...
src/test/ui/error-codes/E0023.stderr
浏览文件 @
d3b31065
...
...
@@ -6,6 +6,11 @@ LL | Apple(String, String),
...
LL | Fruit::Apple(a) => {},
| ^^^^^^^^^^^^^^^ expected 2 fields, found 1
|
help: use `_` to explicitly ignore each field
|
LL | Fruit::Apple(a, _) => {},
| ^^^
error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields
--> $DIR/E0023.rs:12:9
...
...
@@ -34,7 +39,7 @@ LL | Orange((String, String)),
LL | Fruit::Orange(a, b) => {},
| ^^^^^^^^^^^^^^^^^^^ expected 1 field, found 2
|
help: missing parenthes
i
s
help: missing parenthes
e
s
|
LL | Fruit::Orange((a, b)) => {},
| ^ ^
...
...
@@ -48,7 +53,7 @@ LL | Banana(()),
LL | Fruit::Banana() => {},
| ^^^^^^^^^^^^^^^ expected 1 field, found 0
|
help: missing parenthes
i
s
help: missing parenthes
e
s
|
LL | Fruit::Banana(()) => {},
| ^ ^
...
...
src/test/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr
浏览文件 @
d3b31065
...
...
@@ -17,6 +17,15 @@ LL | struct P<T>(T); // 1 type parameter wanted
...
LL | let P() = U {};
| ^^^ expected 1 field, found 0
|
help: use `_` to explicitly ignore each field
|
LL | let P(_) = U {};
| ^
help: use `..` to ignore all fields
|
LL | let P(..) = U {};
| ^^
error: aborting due to 2 previous errors
...
...
src/test/ui/issues/issue-72574-2.stderr
浏览文件 @
d3b31065
...
...
@@ -26,6 +26,11 @@ LL | struct Binder(i32, i32, i32);
...
LL | Binder(_a, _x @ ..) => {}
| ^^^^^^^^^^^^^^^^^^^ expected 3 fields, found 2
|
help: use `_` to explicitly ignore each field
|
LL | Binder(_a, _x @ .., _) => {}
| ^^^
error: aborting due to 3 previous errors
...
...
src/test/ui/match/match-pattern-field-mismatch.stderr
浏览文件 @
d3b31065
...
...
@@ -6,6 +6,15 @@ LL | Rgb(usize, usize, usize),
...
LL | Color::Rgb(_, _) => { }
| ^^^^^^^^^^^^^^^^ expected 3 fields, found 2
|
help: use `_` to explicitly ignore each field
|
LL | Color::Rgb(_, _, _) => { }
| ^^^
help: use `..` to ignore all fields
|
LL | Color::Rgb(..) => { }
| ^^
error: aborting due to previous error
...
...
src/test/ui/pattern/issue-74539.stderr
浏览文件 @
d3b31065
...
...
@@ -26,6 +26,11 @@ LL | A(u8, u8),
...
LL | E::A(x @ ..) => {
| ^^^^^^^^^^^^ expected 2 fields, found 1
|
help: use `_` to explicitly ignore each field
|
LL | E::A(x @ .., _) => {
| ^^^
error: aborting due to 3 previous errors
...
...
src/test/ui/pattern/pat-tuple-underfield.rs
0 → 100644
浏览文件 @
d3b31065
struct
S
(
i32
,
f32
);
enum
E
{
S
(
i32
,
f32
),
}
struct
Point4
(
i32
,
i32
,
i32
,
i32
);
fn
main
()
{
match
S
(
0
,
1.0
)
{
S
(
x
)
=>
{}
//~^ ERROR this pattern has 1 field, but the corresponding tuple struct has 2 fields
//~| HELP use `_` to explicitly ignore each field
}
match
S
(
0
,
1.0
)
{
S
(
_
)
=>
{}
//~^ ERROR this pattern has 1 field, but the corresponding tuple struct has 2 fields
//~| HELP use `_` to explicitly ignore each field
//~| HELP use `..` to ignore all fields
}
match
S
(
0
,
1.0
)
{
S
()
=>
{}
//~^ ERROR this pattern has 0 fields, but the corresponding tuple struct has 2 fields
//~| HELP use `_` to explicitly ignore each field
//~| HELP use `..` to ignore all fields
}
match
E
::
S
(
0
,
1.0
)
{
E
::
S
(
x
)
=>
{}
//~^ ERROR this pattern has 1 field, but the corresponding tuple variant has 2 fields
//~| HELP use `_` to explicitly ignore each field
}
match
E
::
S
(
0
,
1.0
)
{
E
::
S
(
_
)
=>
{}
//~^ ERROR this pattern has 1 field, but the corresponding tuple variant has 2 fields
//~| HELP use `_` to explicitly ignore each field
//~| HELP use `..` to ignore all fields
}
match
E
::
S
(
0
,
1.0
)
{
E
::
S
()
=>
{}
//~^ ERROR this pattern has 0 fields, but the corresponding tuple variant has 2 fields
//~| HELP use `_` to explicitly ignore each field
//~| HELP use `..` to ignore all fields
}
match
E
::
S
(
0
,
1.0
)
{
E
::
S
=>
{}
//~^ ERROR expected unit struct, unit variant or constant, found tuple variant `E::S`
//~| HELP use the tuple variant pattern syntax instead
}
match
Point4
(
0
,
1
,
2
,
3
)
{
Point4
(
a
,
_
)
=>
{}
//~^ ERROR this pattern has 2 fields, but the corresponding tuple struct has 4 fields
//~| HELP use `_` to explicitly ignore each field
//~| HELP use `..` to ignore the rest of the fields
}
}
src/test/ui/pattern/pat-tuple-underfield.stderr
0 → 100644
浏览文件 @
d3b31065
error[E0532]: expected unit struct, unit variant or constant, found tuple variant `E::S`
--> $DIR/pat-tuple-underfield.rs:44:9
|
LL | S(i32, f32),
| ----------- `E::S` defined here
...
LL | E::S => {}
| ^^^^ help: use the tuple variant pattern syntax instead: `E::S(_, _)`
error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields
--> $DIR/pat-tuple-underfield.rs:9:9
|
LL | struct S(i32, f32);
| ------------------- tuple struct defined here
...
LL | S(x) => {}
| ^^^^ expected 2 fields, found 1
|
help: use `_` to explicitly ignore each field
|
LL | S(x, _) => {}
| ^^^
error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields
--> $DIR/pat-tuple-underfield.rs:14:9
|
LL | struct S(i32, f32);
| ------------------- tuple struct defined here
...
LL | S(_) => {}
| ^^^^ expected 2 fields, found 1
|
help: use `_` to explicitly ignore each field
|
LL | S(_, _) => {}
| ^^^
help: use `..` to ignore all fields
|
LL | S(..) => {}
| ^^
error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 2 fields
--> $DIR/pat-tuple-underfield.rs:20:9
|
LL | struct S(i32, f32);
| ------------------- tuple struct defined here
...
LL | S() => {}
| ^^^ expected 2 fields, found 0
|
help: use `_` to explicitly ignore each field
|
LL | S(_, _) => {}
| ^^^^
help: use `..` to ignore all fields
|
LL | S(..) => {}
| ^^
error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
--> $DIR/pat-tuple-underfield.rs:27:9
|
LL | S(i32, f32),
| ----------- tuple variant defined here
...
LL | E::S(x) => {}
| ^^^^^^^ expected 2 fields, found 1
|
help: use `_` to explicitly ignore each field
|
LL | E::S(x, _) => {}
| ^^^
error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
--> $DIR/pat-tuple-underfield.rs:32:9
|
LL | S(i32, f32),
| ----------- tuple variant defined here
...
LL | E::S(_) => {}
| ^^^^^^^ expected 2 fields, found 1
|
help: use `_` to explicitly ignore each field
|
LL | E::S(_, _) => {}
| ^^^
help: use `..` to ignore all fields
|
LL | E::S(..) => {}
| ^^
error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 2 fields
--> $DIR/pat-tuple-underfield.rs:38:9
|
LL | S(i32, f32),
| ----------- tuple variant defined here
...
LL | E::S() => {}
| ^^^^^^ expected 2 fields, found 0
|
help: use `_` to explicitly ignore each field
|
LL | E::S(_, _) => {}
| ^^^^
help: use `..` to ignore all fields
|
LL | E::S(..) => {}
| ^^
error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 4 fields
--> $DIR/pat-tuple-underfield.rs:50:9
|
LL | struct Point4(i32, i32, i32, i32);
| ---------------------------------- tuple struct defined here
...
LL | Point4( a , _ ) => {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 4 fields, found 2
|
help: use `_` to explicitly ignore each field
|
LL | Point4( a , _ , _, _) => {}
| ^^^^^^
help: use `..` to ignore the rest of the fields
|
LL | Point4( a , _ , ..) => {}
| ^^^^
error: aborting due to 8 previous errors
Some errors have detailed explanations: E0023, E0532.
For more information about an error, try `rustc --explain E0023`.
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录