Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
23b8c06f
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,发现更多精彩内容 >>
未验证
提交
23b8c06f
编写于
12月 05, 2019
作者:
M
Mazdak Farrokhzad
提交者:
GitHub
12月 05, 2019
浏览文件
操作
浏览文件
下载
差异文件
Rollup merge of #67044 - Centril:67037, r=estebank
E0023: handle expected != tuple pattern type Fixes #67037. r? @estebank
上级
7945dcdf
4746d373
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
70 addition
and
10 deletion
+70
-10
src/librustc_typeck/check/demand.rs
src/librustc_typeck/check/demand.rs
+13
-3
src/librustc_typeck/check/pat.rs
src/librustc_typeck/check/pat.rs
+14
-7
src/test/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs
...i/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs
+21
-0
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
+22
-0
未找到文件。
src/librustc_typeck/check/demand.rs
浏览文件 @
23b8c06f
...
...
@@ -65,13 +65,13 @@ pub fn demand_eqtype_with_origin(&self,
}
}
pub
fn
demand_eqtype_pat
(
pub
fn
demand_eqtype_pat
_diag
(
&
self
,
cause_span
:
Span
,
expected
:
Ty
<
'tcx
>
,
actual
:
Ty
<
'tcx
>
,
match_expr_span
:
Option
<
Span
>
,
)
{
)
->
Option
<
DiagnosticBuilder
<
'tcx
>>
{
let
cause
=
if
let
Some
(
span
)
=
match_expr_span
{
self
.cause
(
cause_span
,
...
...
@@ -80,9 +80,19 @@ pub fn demand_eqtype_pat(
}
else
{
self
.misc
(
cause_span
)
};
self
.demand_eqtype_with_origin
(
&
cause
,
expected
,
actual
)
.map
(|
mut
err
|
err
.emit
());
self
.demand_eqtype_with_origin
(
&
cause
,
expected
,
actual
)
}
pub
fn
demand_eqtype_pat
(
&
self
,
cause_span
:
Span
,
expected
:
Ty
<
'tcx
>
,
actual
:
Ty
<
'tcx
>
,
match_expr_span
:
Option
<
Span
>
,
)
{
self
.demand_eqtype_pat_diag
(
cause_span
,
expected
,
actual
,
match_expr_span
)
.map
(|
mut
err
|
err
.emit
());
}
pub
fn
demand_coerce
(
&
self
,
expr
:
&
hir
::
Expr
,
...
...
src/librustc_typeck/check/pat.rs
浏览文件 @
23b8c06f
...
...
@@ -703,7 +703,10 @@ fn check_pat_tuple_struct(
let
pat_ty
=
pat_ty
.fn_sig
(
tcx
)
.output
();
let
pat_ty
=
pat_ty
.no_bound_vars
()
.expect
(
"expected fn type"
);
self
.demand_eqtype_pat
(
pat
.span
,
expected
,
pat_ty
,
match_arm_pat_span
);
// Type-check the tuple struct pattern against the expected type.
let
diag
=
self
.demand_eqtype_pat_diag
(
pat
.span
,
expected
,
pat_ty
,
match_arm_pat_span
);
let
had_err
=
diag
.is_some
();
diag
.map
(|
mut
err
|
err
.emit
());
// Type-check subpatterns.
if
subpats
.len
()
==
variant
.fields
.len
()
...
...
@@ -721,7 +724,7 @@ fn check_pat_tuple_struct(
}
}
else
{
// Pattern has wrong number of fields.
self
.e0023
(
pat
.span
,
res
,
qpath
,
subpats
,
&
variant
.fields
,
expected
);
self
.e0023
(
pat
.span
,
res
,
qpath
,
subpats
,
&
variant
.fields
,
expected
,
had_err
);
on_error
();
return
tcx
.types.err
;
}
...
...
@@ -734,8 +737,9 @@ fn e0023(
res
:
Res
,
qpath
:
&
hir
::
QPath
,
subpats
:
&
'tcx
[
P
<
Pat
>
],
fields
:
&
[
ty
::
FieldDef
],
expected
:
Ty
<
'tcx
>
fields
:
&
'tcx
[
ty
::
FieldDef
],
expected
:
Ty
<
'tcx
>
,
had_err
:
bool
,
)
{
let
subpats_ending
=
pluralize!
(
subpats
.len
());
let
fields_ending
=
pluralize!
(
fields
.len
());
...
...
@@ -763,9 +767,12 @@ 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_parenthesis
=
match
expected
.kind
{
ty
::
Adt
(
_
,
substs
)
if
fields
.len
()
==
1
=>
{
let
field_ty
=
fields
[
0
]
.ty
(
self
.tcx
,
substs
);
let
missing_parenthesis
=
match
(
&
expected
.kind
,
fields
,
had_err
)
{
// #67037: only do this if we could sucessfully 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);`.
(
ty
::
Adt
(
_
,
substs
),
[
field
],
false
)
=>
{
let
field_ty
=
self
.field_ty
(
pat_span
,
field
,
substs
);
match
field_ty
.kind
{
ty
::
Tuple
(
_
)
=>
field_ty
.tuple_fields
()
.count
()
==
subpats
.len
(),
_
=>
false
,
...
...
src/test/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs
0 → 100644
浏览文件 @
23b8c06f
// Regression test for #67037.
//
// In type checking patterns, E0023 occurs when the tuple pattern and the expected
// tuple pattern have different number of fields. For example, as below, `P()`,
// the tuple struct pattern, has 0 fields, but requires 1 field.
//
// In emitting E0023, we try to see if this is a case of e.g., `Some(a, b, c)` but where
// the scrutinee was of type `Some((a, b, c))`, and suggest that parenthesis be added.
//
// However, we did not account for the expected type being different than the tuple pattern type.
// This caused an issue when the tuple pattern type (`P<T>`) was generic.
// Specifically, we tried deriving the 0th field's type using the `substs` of the expected type.
// When attempting to substitute `T`, there was no such substitution, so "out of range" occured.
struct
U
{}
// 0 type parameters offered
struct
P
<
T
>
(
T
);
// 1 type parameter wanted
fn
main
()
{
let
P
()
=
U
{};
//~ ERROR mismatched types
//~^ ERROR this pattern has 0 fields, but the corresponding tuple struct has 1 field
}
src/test/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr
0 → 100644
浏览文件 @
23b8c06f
error[E0308]: mismatched types
--> $DIR/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs:19:9
|
LL | let P() = U {};
| ^^^ expected struct `U`, found struct `P`
|
= note: expected struct `U`
found struct `P<_>`
error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 1 field
--> $DIR/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs:19:9
|
LL | struct P<T>(T); // 1 type parameter wanted
| --------------- tuple struct defined here
...
LL | let P() = U {};
| ^^^ expected 1 field, found 0
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0023, E0308.
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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录