Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
b6062bda
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,发现更多精彩内容 >>
提交
b6062bda
编写于
9月 25, 2021
作者:
N
Nadrieril
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Avoid double-deref in `Fields`
上级
71abc956
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
31 addition
and
35 deletion
+31
-35
compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
+30
-33
compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
+1
-2
未找到文件。
compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
浏览文件 @
b6062bda
...
...
@@ -62,7 +62,6 @@
use
rustc_target
::
abi
::{
Integer
,
Size
,
VariantIdx
};
use
smallvec
::{
smallvec
,
SmallVec
};
use
std
::
borrow
::
Cow
;
use
std
::
cmp
::{
self
,
max
,
min
,
Ordering
};
use
std
::
fmt
;
use
std
::
iter
::{
once
,
IntoIterator
};
...
...
@@ -1107,33 +1106,27 @@ pub(super) fn iter_missing<'a, 'p>(
/// because the code mustn't observe that it is uninhabited. In that case that field is not
/// included in `fields`. For that reason, when you have a `mir::Field` you must use
/// `index_with_declared_idx`.
#[derive(Debug,
Clone)]
#[derive(Debug,
Clone
,
Copy
)]
pub
(
super
)
struct
Fields
<
'p
,
'tcx
>
{
fields
:
SmallVec
<
[
&
'p
DeconstructedPat
<
'p
,
'tcx
>
;
2
]
>
,
fields
:
&
'p
[
DeconstructedPat
<
'p
,
'tcx
>
]
,
}
impl
<
'p
,
'tcx
>
Fields
<
'p
,
'tcx
>
{
fn
empty
()
->
Self
{
Fields
{
fields
:
SmallVec
::
new
()
}
Fields
{
fields
:
&
[]
}
}
fn
singleton
(
cx
:
&
MatchCheckCtxt
<
'p
,
'tcx
>
,
field
:
DeconstructedPat
<
'p
,
'tcx
>
)
->
Self
{
let
field
:
&
_
=
cx
.pattern_arena
.alloc
(
field
);
Fields
{
fields
:
s
mallvec!
[
field
]
}
Fields
{
fields
:
s
td
::
slice
::
from_ref
(
field
)
}
}
pub
(
super
)
fn
from_iter
(
cx
:
&
MatchCheckCtxt
<
'p
,
'tcx
>
,
fields
:
impl
IntoIterator
<
Item
=
DeconstructedPat
<
'p
,
'tcx
>>
,
)
->
Self
{
let
fields
:
&
_
=
cx
.pattern_arena
.alloc_from_iter
(
fields
);
Fields
{
fields
:
fields
.into_iter
()
.collect
()
}
}
pub
(
super
)
fn
from_ref_iter
(
fields
:
impl
IntoIterator
<
Item
=
&
'p
DeconstructedPat
<
'p
,
'tcx
>>
,
)
->
Self
{
Fields
{
fields
:
fields
.into_iter
()
.collect
()
}
let
fields
:
&
[
_
]
=
cx
.pattern_arena
.alloc_from_iter
(
fields
);
Fields
{
fields
}
}
fn
wildcards_from_tys
(
...
...
@@ -1222,7 +1215,7 @@ pub(super) fn wildcards(
pub
(
super
)
fn
iter_patterns
<
'a
>
(
&
'a
self
,
)
->
impl
Iterator
<
Item
=
&
'p
DeconstructedPat
<
'p
,
'tcx
>>
+
Captures
<
'a
>
{
self
.fields
.iter
()
.copied
()
self
.fields
.iter
()
}
}
...
...
@@ -1245,9 +1238,8 @@ pub(super) fn new(ctor: Constructor<'tcx>, fields: Fields<'p, 'tcx>, ty: Ty<'tcx
pub
(
crate
)
fn
from_pat
(
cx
:
&
MatchCheckCtxt
<
'p
,
'tcx
>
,
pat
:
&
Pat
<
'tcx
>
)
->
Self
{
let
mkpat
=
|
pat
|
DeconstructedPat
::
from_pat
(
cx
,
pat
);
let
allocpat
=
|
pat
|
&*
cx
.pattern_arena
.alloc
(
mkpat
(
pat
));
let
ctor
;
let
mut
fields
;
let
fields
;
match
pat
.kind
.as_ref
()
{
PatKind
::
AscribeUserType
{
subpattern
,
..
}
=>
return
mkpat
(
subpattern
),
PatKind
::
Binding
{
subpattern
:
Some
(
subpat
),
..
}
=>
return
mkpat
(
subpat
),
...
...
@@ -1263,10 +1255,15 @@ pub(crate) fn from_pat(cx: &MatchCheckCtxt<'p, 'tcx>, pat: &Pat<'tcx>) -> Self {
match
pat
.ty
.kind
()
{
ty
::
Tuple
(
fs
)
=>
{
ctor
=
Single
;
fields
=
Fields
::
wildcards_from_tys
(
cx
,
fs
.iter
()
.map
(|
ty
|
ty
.expect_ty
()));
let
mut
wilds
:
SmallVec
<
[
_
;
2
]
>
=
fs
.iter
()
.map
(|
ty
|
ty
.expect_ty
())
.map
(
DeconstructedPat
::
wildcard
)
.collect
();
for
pat
in
subpatterns
{
fields
.fields
[
pat
.field
.index
()]
=
alloc
pat
(
&
pat
.pattern
);
wilds
[
pat
.field
.index
()]
=
mk
pat
(
&
pat
.pattern
);
}
fields
=
Fields
::
from_iter
(
cx
,
wilds
);
}
ty
::
Adt
(
adt
,
substs
)
if
adt
.is_box
()
=>
{
// The only legal patterns of type `Box` (outside `std`) are `_` and box
...
...
@@ -1306,12 +1303,14 @@ pub(crate) fn from_pat(cx: &MatchCheckCtxt<'p, 'tcx>, pat: &Pat<'tcx>) -> Self {
field_id_to_id
[
field
.index
()]
=
Some
(
i
);
ty
});
fields
=
Fields
::
wildcards_from_tys
(
cx
,
tys
);
let
mut
wilds
:
SmallVec
<
[
_
;
2
]
>
=
tys
.map
(
DeconstructedPat
::
wildcard
)
.collect
();
for
pat
in
subpatterns
{
if
let
Some
(
i
)
=
field_id_to_id
[
pat
.field
.index
()]
{
fields
.fields
[
i
]
=
alloc
pat
(
&
pat
.pattern
);
wilds
[
i
]
=
mk
pat
(
&
pat
.pattern
);
}
}
fields
=
Fields
::
from_iter
(
cx
,
wilds
);
}
_
=>
bug!
(
"pattern has unexpected type: pat: {:?}, ty: {:?}"
,
pat
,
pat
.ty
),
}
...
...
@@ -1510,11 +1509,11 @@ pub(super) fn specialize<'a>(
&
'a
self
,
cx
:
&
MatchCheckCtxt
<
'p
,
'tcx
>
,
other_ctor
:
&
Constructor
<
'tcx
>
,
)
->
Cow
<
'a
,
Fields
<
'p
,
'tcx
>
>
{
)
->
SmallVec
<
[
&
'p
DeconstructedPat
<
'p
,
'tcx
>
;
2
]
>
{
match
(
&
self
.ctor
,
other_ctor
)
{
(
Wildcard
,
_
)
=>
{
// We return a wildcard for each field of `other_ctor`.
Cow
::
Owned
(
Fields
::
wildcards
(
cx
,
self
.ty
,
other_ctor
)
)
Fields
::
wildcards
(
cx
,
self
.ty
,
other_ctor
)
.iter_patterns
()
.collect
(
)
}
(
Slice
(
self_slice
),
Slice
(
other_slice
))
if
self_slice
.arity
()
!=
other_slice
.arity
()
=>
...
...
@@ -1522,8 +1521,8 @@ pub(super) fn specialize<'a>(
// The only tricky case: two slices of different arity. Since `self_slice` covers
// `other_slice`, `self_slice` must be `VarLen`, i.e. of the form
// `[prefix, .., suffix]`. Moreover `other_slice` is guaranteed to have a larger
// arity.
We fill the middle part with enough wildcards to reach the length of the
// new, larger slice.
// arity.
So we fill the middle part with enough wildcards to reach the length of
//
the
new, larger slice.
match
self_slice
.kind
{
FixedLen
(
_
)
=>
bug!
(
"{:?} doesn't cover {:?}"
,
self_slice
,
other_slice
),
VarLen
(
prefix
,
suffix
)
=>
{
...
...
@@ -1531,19 +1530,17 @@ pub(super) fn specialize<'a>(
ty
::
Slice
(
ty
)
|
ty
::
Array
(
ty
,
_
)
=>
ty
,
_
=>
bug!
(
"bad slice pattern {:?} {:?}"
,
self
.ctor
,
self
.ty
),
};
let
prefix
=
self
.fields.fields
[
..
prefix
]
.iter
()
.copied
();
let
suffix
=
self
.fields.fields
[
self_slice
.arity
()
-
suffix
..
]
.iter
()
.copied
();
let
prefix
=
&
self
.fields.fields
[
..
prefix
];
let
suffix
=
&
self
.fields.fields
[
self_slice
.arity
()
-
suffix
..
];
let
wildcard
:
&
_
=
cx
.pattern_arena
.alloc
(
DeconstructedPat
::
wildcard
(
inner_ty
));
let
extra_wildcards
=
other_slice
.arity
()
-
self_slice
.arity
();
let
extra_wildcards
:
&
[
_
]
=
cx
.pattern_arena
.alloc_from_iter
(
(
0
..
extra_wildcards
)
.map
(|
_
|
DeconstructedPat
::
wildcard
(
inner_ty
)),
);
let
fields
=
prefix
.chain
(
extra_wildcards
)
.chain
(
suffix
);
Cow
::
Owned
(
Fields
::
from_ref_iter
(
fields
))
let
extra_wildcards
=
(
0
..
extra_wildcards
)
.map
(|
_
|
wildcard
);
prefix
.iter
()
.chain
(
extra_wildcards
)
.chain
(
suffix
)
.collect
()
}
}
}
_
=>
Cow
::
Borrowed
(
&
self
.fields
),
_
=>
self
.fields
.iter_patterns
()
.collect
(
),
}
}
}
...
...
compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
浏览文件 @
b6062bda
...
...
@@ -407,8 +407,7 @@ fn pop_head_constructor(
)
->
PatStack
<
'p
,
'tcx
>
{
// We pop the head pattern and push the new fields extracted from the arguments of
// `self.head()`.
let
mut
new_fields
:
SmallVec
<
[
_
;
2
]
>
=
self
.head
()
.specialize
(
cx
,
ctor
)
.iter_patterns
()
.collect
();
let
mut
new_fields
:
SmallVec
<
[
_
;
2
]
>
=
self
.head
()
.specialize
(
cx
,
ctor
);
new_fields
.extend_from_slice
(
&
self
.pats
[
1
..
]);
PatStack
::
from_vec
(
new_fields
)
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录