Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
43d445c8
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,发现更多精彩内容 >>
提交
43d445c8
编写于
12月 20, 2020
作者:
N
Nadrieril
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Pass `Matrix` explicitly instead of via `PatCtxt`
上级
8b38b685
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
48 addition
and
27 deletion
+48
-27
compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
+32
-17
compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
+16
-10
未找到文件。
compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
浏览文件 @
43d445c8
...
...
@@ -19,7 +19,7 @@
use
rustc_middle
::
ty
::
layout
::
IntegerExt
;
use
rustc_middle
::
ty
::{
self
,
Const
,
Ty
,
TyCtxt
};
use
rustc_session
::
lint
;
use
rustc_span
::
DUMMY_SP
;
use
rustc_span
::
{
Span
,
DUMMY_SP
}
;
use
rustc_target
::
abi
::{
Integer
,
Size
,
VariantIdx
};
use
smallvec
::{
smallvec
,
SmallVec
};
...
...
@@ -184,12 +184,18 @@ fn to_pat<'tcx>(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Pat<'tcx> {
}
/// Lint on likely incorrect range patterns (#63987)
pub
(
super
)
fn
lint_overlapping_range_endpoints
(
&
self
,
pcx
:
PatCtxt
<
'_
,
'_
,
'_
>
,
hir_id
:
HirId
)
{
pub
(
super
)
fn
lint_overlapping_range_endpoints
<
'a
,
'tcx
:
'a
>
(
&
self
,
pcx
:
PatCtxt
<
'_
,
'_
,
'tcx
>
,
ctors
:
impl
Iterator
<
Item
=
(
&
'a
Constructor
<
'tcx
>
,
Span
)
>
,
column_count
:
usize
,
hir_id
:
HirId
,
)
{
if
self
.is_singleton
()
{
return
;
}
if
pcx
.matrix
.column_count
()
.unwrap_or
(
0
)
!=
1
{
if
column_count
!=
1
{
// FIXME: for now, only check for overlapping ranges on simple range
// patterns. Otherwise with the current logic the following is detected
// as overlapping:
...
...
@@ -203,9 +209,7 @@ pub(super) fn lint_overlapping_range_endpoints(&self, pcx: PatCtxt<'_, '_, '_>,
return
;
}
let
overlaps
:
Vec
<
_
>
=
pcx
.matrix
.head_ctors_and_spans
(
pcx
.cx
)
let
overlaps
:
Vec
<
_
>
=
ctors
.filter_map
(|(
ctor
,
span
)|
Some
((
ctor
.as_int_range
()
?
,
span
)))
.filter
(|(
range
,
_
)|
self
.suspicious_intersection
(
range
))
.map
(|(
range
,
span
)|
(
self
.intersection
(
&
range
)
.unwrap
(),
span
))
...
...
@@ -655,28 +659,33 @@ pub(super) fn from_pat<'p>(cx: &MatchCheckCtxt<'p, 'tcx>, pat: &'p Pat<'tcx>) ->
/// This function may discard some irrelevant constructors if this preserves behavior and
/// diagnostics. Eg. for the `_` case, we ignore the constructors already present in the
/// matrix, unless all of them are.
pub
(
super
)
fn
split
<
'p
>
(
&
self
,
pcx
:
PatCtxt
<
'_
,
'p
,
'tcx
>
)
->
SmallVec
<
[
Self
;
1
]
>
{
debug!
(
"Constructor::split({:#?}, {:#?})"
,
self
,
pcx
.matrix
);
pub
(
super
)
fn
split
<
'a
>
(
&
self
,
pcx
:
PatCtxt
<
'_
,
'_
,
'tcx
>
,
ctors
:
impl
Iterator
<
Item
=
&
'a
Constructor
<
'tcx
>>
+
Clone
,
)
->
SmallVec
<
[
Self
;
1
]
>
where
'tcx
:
'a
,
{
debug!
(
"Constructor::split({:#?})"
,
self
);
match
self
{
Wildcard
=>
{
let
mut
split_wildcard
=
SplitWildcard
::
new
(
pcx
);
split_wildcard
.split
(
pcx
);
split_wildcard
.split
(
pcx
,
ctors
);
split_wildcard
.into_ctors
(
pcx
)
}
// Fast-track if the range is trivial. In particular, we don't do the overlapping
// ranges check.
IntRange
(
ctor_range
)
if
!
ctor_range
.is_singleton
()
=>
{
let
mut
split_range
=
SplitIntRange
::
new
(
ctor_range
.clone
());
let
intranges
=
pcx
.matrix
.head_ctors
(
pcx
.cx
)
.filter_map
(|
ctor
|
ctor
.as_int_range
());
let
intranges
=
ctors
.filter_map
(|
ctor
|
ctor
.as_int_range
());
split_range
.split
(
intranges
.cloned
());
split_range
.iter
()
.map
(
IntRange
)
.collect
()
}
&
Slice
(
Slice
{
kind
:
VarLen
(
self_prefix
,
self_suffix
),
array_len
})
=>
{
let
mut
split_self
=
SplitVarLenSlice
::
new
(
self_prefix
,
self_suffix
,
array_len
);
let
slices
=
pcx
.matrix
.head_ctors
(
pcx
.cx
)
.filter_map
(|
c
|
c
.as_slice
())
.map
(|
s
|
s
.kind
);
let
slices
=
ctors
.filter_map
(|
c
|
c
.as_slice
())
.map
(|
s
|
s
.kind
);
split_self
.split
(
slices
);
split_self
.iter
()
.map
(
Slice
)
.collect
()
}
...
...
@@ -912,11 +921,17 @@ pub(super) fn new<'p>(pcx: PatCtxt<'_, 'p, 'tcx>) -> Self {
/// Pass a set of constructors relative to which to split this one. Don't call twice, it won't
/// do what you want.
pub
(
super
)
fn
split
(
&
mut
self
,
pcx
:
PatCtxt
<
'_
,
'_
,
'tcx
>
)
{
self
.matrix_ctors
=
pcx
.matrix
.head_ctors
(
pcx
.cx
)
.cloned
()
.filter
(|
c
|
!
c
.is_wildcard
())
.collect
();
pub
(
super
)
fn
split
<
'a
>
(
&
mut
self
,
pcx
:
PatCtxt
<
'_
,
'_
,
'tcx
>
,
ctors
:
impl
Iterator
<
Item
=
&
'a
Constructor
<
'tcx
>>
+
Clone
,
)
where
'tcx
:
'a
,
{
// Since `all_ctors` never contains wildcards, this won't recurse further.
self
.all_ctors
=
self
.all_ctors
.iter
()
.flat_map
(|
ctor
|
ctor
.split
(
pcx
))
.collect
();
self
.all_ctors
=
self
.all_ctors
.iter
()
.flat_map
(|
ctor
|
ctor
.split
(
pcx
,
ctors
.clone
()))
.collect
();
self
.matrix_ctors
=
ctors
.filter
(|
c
|
!
c
.is_wildcard
())
.cloned
()
.collect
();
}
/// Whether there are any value constructors for this type that are not present in the matrix.
...
...
compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
浏览文件 @
43d445c8
...
...
@@ -358,8 +358,6 @@ pub(super) fn is_foreign_non_exhaustive_enum(&self, ty: Ty<'tcx>) -> bool {
#[derive(Copy,
Clone)]
pub
(
super
)
struct
PatCtxt
<
'a
,
'p
,
'tcx
>
{
pub
(
super
)
cx
:
&
'a
MatchCheckCtxt
<
'p
,
'tcx
>
,
/// Current state of the matrix.
pub
(
super
)
matrix
:
&
'a
Matrix
<
'p
,
'tcx
>
,
/// Type of the current column under investigation.
pub
(
super
)
ty
:
Ty
<
'tcx
>
,
/// Span of the current pattern under investigation.
...
...
@@ -538,7 +536,7 @@ fn heads<'a>(&'a self) -> impl Iterator<Item = &'a Pat<'tcx>> + Captures<'p> {
pub
(
super
)
fn
head_ctors
<
'a
>
(
&
'a
self
,
cx
:
&
'a
MatchCheckCtxt
<
'p
,
'tcx
>
,
)
->
impl
Iterator
<
Item
=
&
'a
Constructor
<
'tcx
>>
+
Captures
<
'p
>
{
)
->
impl
Iterator
<
Item
=
&
'a
Constructor
<
'tcx
>>
+
Captures
<
'p
>
+
Clone
{
self
.patterns
.iter
()
.map
(
move
|
r
|
r
.head_ctor
(
cx
))
}
...
...
@@ -804,6 +802,7 @@ fn unsplit_or_pat(self, this_span: Span, or_pat_spans: &[Span]) -> Self {
fn
apply_constructor
<
'p
>
(
self
,
pcx
:
PatCtxt
<
'_
,
'p
,
'tcx
>
,
matrix
:
&
Matrix
<
'p
,
'tcx
>
,
// used to compute missing ctors
ctor
:
&
Constructor
<
'tcx
>
,
ctor_wild_subpatterns
:
&
Fields
<
'p
,
'tcx
>
,
)
->
Self
{
...
...
@@ -811,7 +810,7 @@ fn apply_constructor<'p>(
UsefulWithWitness
(
witnesses
)
=>
{
let
new_witnesses
=
if
ctor
.is_wildcard
()
{
let
mut
split_wildcard
=
SplitWildcard
::
new
(
pcx
);
split_wildcard
.split
(
pcx
);
split_wildcard
.split
(
pcx
,
matrix
.head_ctors
(
pcx
.cx
)
);
let
new_patterns
=
split_wildcard
.report_missing_patterns
(
pcx
);
witnesses
.into_iter
()
...
...
@@ -968,7 +967,7 @@ fn is_useful<'p, 'tcx>(
// FIXME(Nadrieril): Hack to work around type normalization issues (see #72476).
let
ty
=
matrix
.heads
()
.next
()
.map
(|
r
|
r
.ty
)
.unwrap_or
(
v
.head
()
.ty
);
let
pcx
=
PatCtxt
{
cx
,
matrix
,
ty
,
span
:
v
.head
()
.span
,
is_top_level
};
let
pcx
=
PatCtxt
{
cx
,
ty
,
span
:
v
.head
()
.span
,
is_top_level
};
debug!
(
"is_useful_expand_first_col: ty={:#?}, expanding {:#?}"
,
pcx
.ty
,
v
.head
());
...
...
@@ -995,20 +994,27 @@ fn is_useful<'p, 'tcx>(
let
v_ctor
=
v
.head_ctor
(
cx
);
if
let
Constructor
::
IntRange
(
ctor_range
)
=
&
v_ctor
{
// Lint on likely incorrect range patterns (#63987)
ctor_range
.lint_overlapping_range_endpoints
(
pcx
,
hir_id
)
ctor_range
.lint_overlapping_range_endpoints
(
pcx
,
matrix
.head_ctors_and_spans
(
cx
),
matrix
.column_count
()
.unwrap_or
(
0
),
hir_id
,
)
}
// We split the head constructor of `v`.
let
split_ctors
=
v_ctor
.split
(
pcx
);
let
split_ctors
=
v_ctor
.split
(
pcx
,
matrix
.head_ctors
(
cx
)
);
// For each constructor, we compute whether there's a value that starts with it that would
// witness the usefulness of `v`.
let
start_matrix
=
&
matrix
;
let
usefulnesses
=
split_ctors
.into_iter
()
.map
(|
ctor
|
{
// We cache the result of `Fields::wildcards` because it is used a lot.
let
ctor_wild_subpatterns
=
Fields
::
wildcards
(
pcx
,
&
ctor
);
let
matrix
=
pcx
.matrix
.specialize_constructor
(
pcx
,
&
ctor
,
&
ctor_wild_subpatterns
);
let
spec_matrix
=
start_matrix
.specialize_constructor
(
pcx
,
&
ctor
,
&
ctor_wild_subpatterns
);
let
v
=
v
.pop_head_constructor
(
&
ctor_wild_subpatterns
);
let
usefulness
=
is_useful
(
pcx
.cx
,
&
matrix
,
&
v
,
witness_preference
,
hir_id
,
is_under_guard
,
false
);
usefulness
.apply_constructor
(
pcx
,
&
ctor
,
&
ctor_wild_subpatterns
)
is_useful
(
cx
,
&
spec_
matrix
,
&
v
,
witness_preference
,
hir_id
,
is_under_guard
,
false
);
usefulness
.apply_constructor
(
pcx
,
start_matrix
,
&
ctor
,
&
ctor_wild_subpatterns
)
});
Usefulness
::
merge
(
usefulnesses
)
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录