Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
bd800181
R
Rust
项目概览
int
/
Rust
12 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
bd800181
编写于
4月 04, 2021
作者:
L
LeSeulArtichaut
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Move THIR structure definitions to `rustc_middle`
上级
70cb58ce
变更
26
展开全部
隐藏空白更改
内联
并排
Showing
26 changed file
with
833 addition
and
825 deletion
+833
-825
compiler/rustc_middle/src/lib.rs
compiler/rustc_middle/src/lib.rs
+1
-0
compiler/rustc_middle/src/thir.rs
compiler/rustc_middle/src/thir.rs
+743
-0
compiler/rustc_mir_build/src/build/block.rs
compiler/rustc_mir_build/src/build/block.rs
+1
-1
compiler/rustc_mir_build/src/build/expr/as_constant.rs
compiler/rustc_mir_build/src/build/expr/as_constant.rs
+1
-1
compiler/rustc_mir_build/src/build/expr/as_operand.rs
compiler/rustc_mir_build/src/build/expr/as_operand.rs
+1
-1
compiler/rustc_mir_build/src/build/expr/as_place.rs
compiler/rustc_mir_build/src/build/expr/as_place.rs
+1
-1
compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+1
-1
compiler/rustc_mir_build/src/build/expr/as_temp.rs
compiler/rustc_mir_build/src/build/expr/as_temp.rs
+1
-1
compiler/rustc_mir_build/src/build/expr/category.rs
compiler/rustc_mir_build/src/build/expr/category.rs
+1
-1
compiler/rustc_mir_build/src/build/expr/into.rs
compiler/rustc_mir_build/src/build/expr/into.rs
+2
-3
compiler/rustc_mir_build/src/build/expr/stmt.rs
compiler/rustc_mir_build/src/build/expr/stmt.rs
+1
-1
compiler/rustc_mir_build/src/build/matches/mod.rs
compiler/rustc_mir_build/src/build/matches/mod.rs
+3
-3
compiler/rustc_mir_build/src/build/matches/simplify.rs
compiler/rustc_mir_build/src/build/matches/simplify.rs
+2
-2
compiler/rustc_mir_build/src/build/matches/test.rs
compiler/rustc_mir_build/src/build/matches/test.rs
+1
-1
compiler/rustc_mir_build/src/build/matches/util.rs
compiler/rustc_mir_build/src/build/matches/util.rs
+1
-1
compiler/rustc_mir_build/src/build/mod.rs
compiler/rustc_mir_build/src/build/mod.rs
+4
-2
compiler/rustc_mir_build/src/build/scope.rs
compiler/rustc_mir_build/src/build/scope.rs
+2
-1
compiler/rustc_mir_build/src/thir/cx/block.rs
compiler/rustc_mir_build/src/thir/cx/block.rs
+2
-2
compiler/rustc_mir_build/src/thir/cx/expr.rs
compiler/rustc_mir_build/src/thir/cx/expr.rs
+6
-3
compiler/rustc_mir_build/src/thir/cx/mod.rs
compiler/rustc_mir_build/src/thir/cx/mod.rs
+4
-2
compiler/rustc_mir_build/src/thir/mod.rs
compiler/rustc_mir_build/src/thir/mod.rs
+0
-426
compiler/rustc_mir_build/src/thir/pattern/check_match.rs
compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+5
-4
compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+2
-1
compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
+4
-4
compiler/rustc_mir_build/src/thir/pattern/mod.rs
compiler/rustc_mir_build/src/thir/pattern/mod.rs
+17
-334
compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
+26
-28
未找到文件。
compiler/rustc_middle/src/lib.rs
浏览文件 @
bd800181
...
...
@@ -83,6 +83,7 @@
pub
mod
lint
;
pub
mod
middle
;
pub
mod
mir
;
pub
mod
thir
;
pub
mod
traits
;
pub
mod
ty
;
...
...
compiler/rustc_middle/src/thir.rs
0 → 100644
浏览文件 @
bd800181
此差异已折叠。
点击以展开。
compiler/rustc_mir_build/src/build/block.rs
浏览文件 @
bd800181
use
crate
::
build
::
matches
::
ArmHasGuard
;
use
crate
::
build
::
ForGuard
::
OutsideGuard
;
use
crate
::
build
::{
BlockAnd
,
BlockAndExtension
,
BlockFrame
,
Builder
};
use
crat
e
::
thir
::
*
;
use
rustc_middl
e
::
thir
::
*
;
use
rustc_middle
::
mir
::
*
;
use
rustc_session
::
lint
::
builtin
::
UNSAFE_OP_IN_UNSAFE_FN
;
use
rustc_session
::
lint
::
Level
;
...
...
compiler/rustc_mir_build/src/build/expr/as_constant.rs
浏览文件 @
bd800181
//! See docs in build/expr/mod.rs
use
crate
::
build
::
Builder
;
use
crat
e
::
thir
::
*
;
use
rustc_middl
e
::
thir
::
*
;
use
rustc_middle
::
mir
::
*
;
use
rustc_middle
::
ty
::
CanonicalUserTypeAnnotation
;
...
...
compiler/rustc_mir_build/src/build/expr/as_operand.rs
浏览文件 @
bd800181
...
...
@@ -2,7 +2,7 @@
use
crate
::
build
::
expr
::
category
::
Category
;
use
crate
::
build
::{
BlockAnd
,
BlockAndExtension
,
Builder
};
use
crat
e
::
thir
::
*
;
use
rustc_middl
e
::
thir
::
*
;
use
rustc_middle
::
middle
::
region
;
use
rustc_middle
::
mir
::
*
;
...
...
compiler/rustc_mir_build/src/build/expr/as_place.rs
浏览文件 @
bd800181
...
...
@@ -3,7 +3,7 @@
use
crate
::
build
::
expr
::
category
::
Category
;
use
crate
::
build
::
ForGuard
::{
OutsideGuard
,
RefWithinGuard
};
use
crate
::
build
::{
BlockAnd
,
BlockAndExtension
,
Builder
};
use
crat
e
::
thir
::
*
;
use
rustc_middl
e
::
thir
::
*
;
use
rustc_hir
::
def_id
::
DefId
;
use
rustc_hir
::
HirId
;
use
rustc_middle
::
hir
::
place
::
ProjectionKind
as
HirProjectionKind
;
...
...
compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
浏览文件 @
bd800181
...
...
@@ -5,7 +5,7 @@
use
crate
::
build
::
expr
::
as_place
::
PlaceBase
;
use
crate
::
build
::
expr
::
category
::{
Category
,
RvalueFunc
};
use
crate
::
build
::{
BlockAnd
,
BlockAndExtension
,
Builder
};
use
crat
e
::
thir
::
*
;
use
rustc_middl
e
::
thir
::
*
;
use
rustc_middle
::
middle
::
region
;
use
rustc_middle
::
mir
::
AssertKind
;
use
rustc_middle
::
mir
::
Place
;
...
...
compiler/rustc_mir_build/src/build/expr/as_temp.rs
浏览文件 @
bd800181
...
...
@@ -2,7 +2,7 @@
use
crate
::
build
::
scope
::
DropKind
;
use
crate
::
build
::{
BlockAnd
,
BlockAndExtension
,
Builder
};
use
crat
e
::
thir
::
*
;
use
rustc_middl
e
::
thir
::
*
;
use
rustc_data_structures
::
stack
::
ensure_sufficient_stack
;
use
rustc_middle
::
middle
::
region
;
use
rustc_middle
::
mir
::
*
;
...
...
compiler/rustc_mir_build/src/build/expr/category.rs
浏览文件 @
bd800181
use
crat
e
::
thir
::
*
;
use
rustc_middl
e
::
thir
::
*
;
#[derive(Debug,
PartialEq)]
crate
enum
Category
{
...
...
compiler/rustc_mir_build/src/build/expr/into.rs
浏览文件 @
bd800181
...
...
@@ -2,7 +2,7 @@
use
crate
::
build
::
expr
::
category
::{
Category
,
RvalueFunc
};
use
crate
::
build
::{
BlockAnd
,
BlockAndExtension
,
BlockFrame
,
Builder
};
use
crat
e
::
thir
::
*
;
use
rustc_middl
e
::
thir
::
*
;
use
rustc_ast
::
InlineAsmOptions
;
use
rustc_data_structures
::
fx
::
FxHashMap
;
use
rustc_data_structures
::
stack
::
ensure_sufficient_stack
;
...
...
@@ -337,8 +337,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block
.unit
()
}
ExprKind
::
InlineAsm
{
template
,
ref
operands
,
options
,
line_spans
}
=>
{
use
crate
::
thir
;
use
rustc_middle
::
mir
;
use
rustc_middle
::{
mir
,
thir
};
let
operands
=
operands
.into_iter
()
.map
(|
op
|
match
*
op
{
...
...
compiler/rustc_mir_build/src/build/expr/stmt.rs
浏览文件 @
bd800181
use
crate
::
build
::
scope
::
BreakableTarget
;
use
crate
::
build
::{
BlockAnd
,
BlockAndExtension
,
BlockFrame
,
Builder
};
use
crat
e
::
thir
::
*
;
use
rustc_middl
e
::
thir
::
*
;
use
rustc_middle
::
middle
::
region
;
use
rustc_middle
::
mir
::
*
;
...
...
compiler/rustc_mir_build/src/build/matches/mod.rs
浏览文件 @
bd800181
...
...
@@ -10,7 +10,6 @@
use
crate
::
build
::
ForGuard
::{
self
,
OutsideGuard
,
RefWithinGuard
};
use
crate
::
build
::{
BlockAnd
,
BlockAndExtension
,
Builder
};
use
crate
::
build
::{
GuardFrame
,
GuardFrameLocal
,
LocalsForNode
};
use
crate
::
thir
::{
self
,
*
};
use
rustc_data_structures
::{
fx
::{
FxHashSet
,
FxIndexMap
},
stack
::
ensure_sufficient_stack
,
...
...
@@ -19,6 +18,7 @@
use
rustc_index
::
bit_set
::
BitSet
;
use
rustc_middle
::
middle
::
region
;
use
rustc_middle
::
mir
::
*
;
use
rustc_middle
::
thir
::{
self
,
*
};
use
rustc_middle
::
ty
::{
self
,
CanonicalUserTypeAnnotation
,
Ty
};
use
rustc_span
::
symbol
::
Symbol
;
use
rustc_span
::
Span
;
...
...
@@ -432,7 +432,7 @@ pub(super) fn expr_into_pattern(
..
},
ascription
:
thir
::
pattern
::
Ascription
{
user_ty
:
pat_ascription_ty
,
variance
:
_
,
user_ty_span
},
thir
::
Ascription
{
user_ty
:
pat_ascription_ty
,
variance
:
_
,
user_ty_span
},
}
=>
{
let
place
=
self
.storage_live_binding
(
block
,
var
,
irrefutable_pat
.span
,
OutsideGuard
,
true
);
...
...
@@ -687,7 +687,7 @@ pub(super) fn visit_primary_bindings(
PatKind
::
AscribeUserType
{
ref
subpattern
,
ascription
:
thir
::
pattern
::
Ascription
{
ref
user_ty
,
user_ty_span
,
variance
:
_
},
ascription
:
thir
::
Ascription
{
ref
user_ty
,
user_ty_span
,
variance
:
_
},
}
=>
{
// This corresponds to something like
//
...
...
compiler/rustc_mir_build/src/build/matches/simplify.rs
浏览文件 @
bd800181
...
...
@@ -15,8 +15,8 @@
use
crate
::
build
::
expr
::
as_place
::
PlaceBuilder
;
use
crate
::
build
::
matches
::{
Ascription
,
Binding
,
Candidate
,
MatchPair
};
use
crate
::
build
::
Builder
;
use
crate
::
thir
::{
self
,
*
};
use
rustc_hir
::
RangeEnd
;
use
rustc_middle
::
thir
::{
self
,
*
};
use
rustc_middle
::
ty
;
use
rustc_middle
::
ty
::
layout
::
IntegerExt
;
use
rustc_target
::
abi
::{
Integer
,
Size
};
...
...
@@ -152,7 +152,7 @@ fn simplify_match_pair<'pat>(
match
*
match_pair
.pattern.kind
{
PatKind
::
AscribeUserType
{
ref
subpattern
,
ascription
:
thir
::
pattern
::
Ascription
{
variance
,
user_ty
,
user_ty_span
},
ascription
:
thir
::
Ascription
{
variance
,
user_ty
,
user_ty_span
},
}
=>
{
// Apply the type ascription to the value at `match_pair.place`, which is the
candidate
.ascriptions
.push
(
Ascription
{
...
...
compiler/rustc_mir_build/src/build/matches/test.rs
浏览文件 @
bd800181
...
...
@@ -9,11 +9,11 @@
use
crate
::
build
::
matches
::{
Candidate
,
MatchPair
,
Test
,
TestKind
};
use
crate
::
build
::
Builder
;
use
crate
::
thir
::
pattern
::
compare_const_vals
;
use
crate
::
thir
::
*
;
use
rustc_data_structures
::
fx
::
FxIndexMap
;
use
rustc_hir
::{
LangItem
,
RangeEnd
};
use
rustc_index
::
bit_set
::
BitSet
;
use
rustc_middle
::
mir
::
*
;
use
rustc_middle
::
thir
::
*
;
use
rustc_middle
::
ty
::
subst
::{
GenericArg
,
Subst
};
use
rustc_middle
::
ty
::
util
::
IntTypeExt
;
use
rustc_middle
::
ty
::{
self
,
adjustment
::
PointerCast
,
Ty
,
TyCtxt
};
...
...
compiler/rustc_mir_build/src/build/matches/util.rs
浏览文件 @
bd800181
use
crate
::
build
::
expr
::
as_place
::
PlaceBuilder
;
use
crate
::
build
::
matches
::
MatchPair
;
use
crate
::
build
::
Builder
;
use
crate
::
thir
::
*
;
use
rustc_middle
::
mir
::
*
;
use
rustc_middle
::
thir
::
*
;
use
rustc_middle
::
ty
;
use
smallvec
::
SmallVec
;
use
std
::
convert
::
TryInto
;
...
...
compiler/rustc_mir_build/src/build/mod.rs
浏览文件 @
bd800181
use
crate
::
build
;
use
crate
::
build
::
expr
::
as_place
::
PlaceBuilder
;
use
crate
::
build
::
scope
::
DropKind
;
use
crate
::
thir
::{
build_thir
,
BindingMode
,
Expr
,
ExprId
,
LintLevel
,
Pat
,
PatKind
,
Thir
};
use
crate
::
thir
::
build_thir
;
use
crate
::
thir
::
pattern
::
pat_from_hir
;
use
rustc_attr
::{
self
as
attr
,
UnwindAttr
};
use
rustc_errors
::
ErrorReported
;
use
rustc_hir
as
hir
;
...
...
@@ -13,6 +14,7 @@
use
rustc_middle
::
hir
::
place
::
PlaceBase
as
HirPlaceBase
;
use
rustc_middle
::
middle
::
region
;
use
rustc_middle
::
mir
::
*
;
use
rustc_middle
::
thir
::{
BindingMode
,
Expr
,
ExprId
,
LintLevel
,
PatKind
,
Thir
};
use
rustc_middle
::
ty
::
subst
::
Subst
;
use
rustc_middle
::
ty
::{
self
,
Ty
,
TyCtxt
,
TypeFoldable
,
TypeckResults
};
use
rustc_span
::
symbol
::{
kw
,
sym
};
...
...
@@ -1016,7 +1018,7 @@ fn args_and_body(
Node
::
Pat
(
pat
)
|
Node
::
Binding
(
pat
)
=>
pat
,
node
=>
bug!
(
"pattern became {:?}"
,
node
),
};
let
pattern
=
Pat
::
from_hir
(
tcx
,
self
.param_env
,
self
.typeck_results
,
pat
);
let
pattern
=
pat_
from_hir
(
tcx
,
self
.param_env
,
self
.typeck_results
,
pat
);
let
original_source_scope
=
self
.source_scope
;
let
span
=
pattern
.span
;
self
.set_correct_source_scope_for_arg
(
arg
.hir_id
,
original_source_scope
,
span
);
...
...
compiler/rustc_mir_build/src/build/scope.rs
浏览文件 @
bd800181
...
...
@@ -82,11 +82,12 @@
*/
use
crate
::
build
::{
BlockAnd
,
BlockAndExtension
,
BlockFrame
,
Builder
,
CFG
};
use
crate
::
thir
::{
Expr
,
LintLevel
};
use
rustc_data_structures
::
fx
::
FxHashMap
;
use
rustc_index
::
vec
::
IndexVec
;
use
rustc_middle
::
middle
::
region
;
use
rustc_middle
::
mir
::
*
;
use
rustc_middle
::
thir
::{
Expr
,
LintLevel
};
use
rustc_span
::{
Span
,
DUMMY_SP
};
#[derive(Debug)]
...
...
compiler/rustc_mir_build/src/thir/cx/block.rs
浏览文件 @
bd800181
use
crate
::
thir
::
cx
::
Cx
;
use
crate
::
thir
::{
self
,
*
};
use
rustc_hir
as
hir
;
use
rustc_middle
::
middle
::
region
;
use
rustc_middle
::
thir
::
*
;
use
rustc_middle
::
ty
;
use
rustc_index
::
vec
::
Idx
;
...
...
@@ -81,7 +81,7 @@ fn mirror_stmts(
ty
:
pattern
.ty
,
span
:
pattern
.span
,
kind
:
Box
::
new
(
PatKind
::
AscribeUserType
{
ascription
:
thir
::
pattern
::
Ascription
{
ascription
:
Ascription
{
user_ty
:
PatTyProj
::
from_user_type
(
user_ty
),
user_ty_span
:
ty
.span
,
variance
:
ty
::
Variance
::
Covariant
,
...
...
compiler/rustc_mir_build/src/thir/cx/expr.rs
浏览文件 @
bd800181
use
crate
::
thir
::
cx
::
Cx
;
use
crate
::
thir
::
util
::
UserAnnotatedTyHelpers
;
use
crate
::
thir
::
*
;
use
rustc_data_structures
::
stack
::
ensure_sufficient_stack
;
use
rustc_hir
as
hir
;
use
rustc_hir
::
def
::{
CtorKind
,
CtorOf
,
DefKind
,
Res
};
...
...
@@ -8,14 +7,18 @@
use
rustc_middle
::
hir
::
place
::
Place
as
HirPlace
;
use
rustc_middle
::
hir
::
place
::
PlaceBase
as
HirPlaceBase
;
use
rustc_middle
::
hir
::
place
::
ProjectionKind
as
HirProjectionKind
;
use
rustc_middle
::
middle
::
region
;
use
rustc_middle
::
mir
::
interpret
::
Scalar
;
use
rustc_middle
::
mir
::
BorrowKind
;
use
rustc_middle
::
mir
::{
BinOp
,
BorrowKind
,
Field
,
UnOp
};
use
rustc_middle
::
thir
::
*
;
use
rustc_middle
::
ty
::
adjustment
::{
Adjust
,
Adjustment
,
AutoBorrow
,
AutoBorrowMutability
,
PointerCast
,
};
use
rustc_middle
::
ty
::
subst
::{
InternalSubsts
,
SubstsRef
};
use
rustc_middle
::
ty
::{
self
,
AdtKind
,
Ty
};
use
rustc_middle
::
ty
::{
self
,
AdtKind
,
Ty
,
UpvarSubsts
,
UserType
};
use
rustc_span
::
def_id
::
DefId
;
use
rustc_span
::
Span
;
use
rustc_target
::
abi
::
VariantIdx
;
impl
<
'tcx
>
Cx
<
'tcx
>
{
crate
fn
mirror_expr
(
&
mut
self
,
expr
:
&
'tcx
hir
::
Expr
<
'tcx
>
)
->
ExprId
{
...
...
compiler/rustc_mir_build/src/thir/cx/mod.rs
浏览文件 @
bd800181
...
...
@@ -3,7 +3,7 @@
//! etc., and instead goes through the `Cx` for most of its work.
use
crate
::
thir
::
util
::
UserAnnotatedTyHelpers
;
use
crate
::
thir
::
*
;
use
crate
::
thir
::
pattern
::
pat_from_hir
;
use
rustc_ast
as
ast
;
use
rustc_hir
as
hir
;
...
...
@@ -11,7 +11,9 @@
use
rustc_hir
::
Node
;
use
rustc_middle
::
middle
::
region
;
use
rustc_middle
::
mir
::
interpret
::{
LitToConstError
,
LitToConstInput
};
use
rustc_middle
::
thir
::
*
;
use
rustc_middle
::
ty
::{
self
,
Ty
,
TyCtxt
};
use
rustc_span
::
Span
;
pub
fn
build_thir
<
'tcx
>
(
tcx
:
TyCtxt
<
'tcx
>
,
...
...
@@ -79,7 +81,7 @@ fn new(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalDefId>) -> Cx<'tcx> {
Node
::
Pat
(
p
)
|
Node
::
Binding
(
p
)
=>
p
,
node
=>
bug!
(
"pattern became {:?}"
,
node
),
};
Pat
::
from_hir
(
self
.tcx
,
self
.param_env
,
self
.typeck_results
(),
p
)
pat_
from_hir
(
self
.tcx
,
self
.param_env
,
self
.typeck_results
(),
p
)
}
}
...
...
compiler/rustc_mir_build/src/thir/mod.rs
浏览文件 @
bd800181
...
...
@@ -4,438 +4,12 @@
//! unit-tested and separated from the Rust source and compiler data
//! structures.
use
rustc_ast
::{
InlineAsmOptions
,
InlineAsmTemplatePiece
};
use
rustc_hir
as
hir
;
use
rustc_hir
::
def_id
::
DefId
;
use
rustc_index
::
newtype_index
;
use
rustc_index
::
vec
::
IndexVec
;
use
rustc_middle
::
infer
::
canonical
::
Canonical
;
use
rustc_middle
::
middle
::
region
;
use
rustc_middle
::
mir
::{
BinOp
,
BorrowKind
,
FakeReadCause
,
Field
,
UnOp
};
use
rustc_middle
::
ty
::
adjustment
::
PointerCast
;
use
rustc_middle
::
ty
::
subst
::
SubstsRef
;
use
rustc_middle
::
ty
::{
AdtDef
,
Const
,
Ty
,
UpvarSubsts
,
UserType
};
use
rustc_span
::
Span
;
use
rustc_target
::
abi
::
VariantIdx
;
use
rustc_target
::
asm
::
InlineAsmRegOrRegClass
;
use
std
::
ops
::
Index
;
crate
mod
constant
;
crate
mod
cx
;
pub
use
cx
::
build_thir
;
crate
mod
pattern
;
pub
use
self
::
pattern
::{
Ascription
,
BindingMode
,
FieldPat
,
Pat
,
PatKind
,
PatRange
,
PatTyProj
};
mod
util
;
pub
mod
visit
;
newtype_index!
{
pub
struct
ArmId
{
DEBUG_FORMAT
=
"a{}"
}
}
newtype_index!
{
pub
struct
ExprId
{
DEBUG_FORMAT
=
"e{}"
}
}
newtype_index!
{
pub
struct
StmtId
{
DEBUG_FORMAT
=
"s{}"
}
}
macro_rules!
thir_with_elements
{
(
$
(
$name:ident
:
$id:ty
=>
$value:ty
,)
*
)
=>
{
pub
struct
Thir
<
'tcx
>
{
$
(
$name
:
IndexVec
<
$id
,
$value
>
,
)
*
}
impl
<
'tcx
>
Thir
<
'tcx
>
{
fn
new
()
->
Thir
<
'tcx
>
{
Thir
{
$
(
$name
:
IndexVec
::
new
(),
)
*
}
}
}
$
(
impl
<
'tcx
>
Index
<
$id
>
for
Thir
<
'tcx
>
{
type
Output
=
$value
;
fn
index
(
&
self
,
index
:
$id
)
->
&
Self
::
Output
{
&
self
.
$name
[
index
]
}
}
)
*
}
}
thir_with_elements!
{
arms
:
ArmId
=>
Arm
<
'tcx
>
,
exprs
:
ExprId
=>
Expr
<
'tcx
>
,
stmts
:
StmtId
=>
Stmt
<
'tcx
>
,
}
#[derive(Copy,
Clone,
Debug)]
pub
enum
LintLevel
{
Inherited
,
Explicit
(
hir
::
HirId
),
}
#[derive(Debug)]
pub
struct
Block
{
pub
targeted_by_break
:
bool
,
pub
region_scope
:
region
::
Scope
,
pub
opt_destruction_scope
:
Option
<
region
::
Scope
>
,
pub
span
:
Span
,
pub
stmts
:
Box
<
[
StmtId
]
>
,
pub
expr
:
Option
<
ExprId
>
,
pub
safety_mode
:
BlockSafety
,
}
#[derive(Copy,
Clone,
Debug)]
pub
enum
BlockSafety
{
Safe
,
ExplicitUnsafe
(
hir
::
HirId
),
PushUnsafe
,
PopUnsafe
,
}
#[derive(Debug)]
pub
struct
Stmt
<
'tcx
>
{
pub
kind
:
StmtKind
<
'tcx
>
,
pub
opt_destruction_scope
:
Option
<
region
::
Scope
>
,
}
#[derive(Debug)]
pub
enum
StmtKind
<
'tcx
>
{
Expr
{
/// scope for this statement; may be used as lifetime of temporaries
scope
:
region
::
Scope
,
/// expression being evaluated in this statement
expr
:
ExprId
,
},
Let
{
/// scope for variables bound in this let; covers this and
/// remaining statements in block
remainder_scope
:
region
::
Scope
,
/// scope for the initialization itself; might be used as
/// lifetime of temporaries
init_scope
:
region
::
Scope
,
/// `let <PAT> = ...`
///
/// if a type is included, it is added as an ascription pattern
pattern
:
Pat
<
'tcx
>
,
/// let pat: ty = <INIT> ...
initializer
:
Option
<
ExprId
>
,
/// the lint level for this let-statement
lint_level
:
LintLevel
,
},
}
// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(all(target_arch
=
"x86_64"
,
target_pointer_width
=
"64"
))]
rustc_data_structures
::
static_assert_size!
(
Expr
<
'_
>
,
144
);
/// The Thir trait implementor lowers their expressions (`&'tcx H::Expr`)
/// into instances of this `Expr` enum. This lowering can be done
/// basically as lazily or as eagerly as desired: every recursive
/// reference to an expression in this enum is an `ExprId`, which
/// may in turn be another instance of this enum (boxed), or else an
/// unlowered `&'tcx H::Expr`. Note that instances of `Expr` are very
/// short-lived. They are created by `Thir::to_expr`, analyzed and
/// converted into MIR, and then discarded.
///
/// If you compare `Expr` to the full compiler AST, you will see it is
/// a good bit simpler. In fact, a number of the more straight-forward
/// MIR simplifications are already done in the impl of `Thir`. For
/// example, method calls and overloaded operators are absent: they are
/// expected to be converted into `Expr::Call` instances.
#[derive(Debug)]
pub
struct
Expr
<
'tcx
>
{
/// type of this expression
pub
ty
:
Ty
<
'tcx
>
,
/// lifetime of this expression if it should be spilled into a
/// temporary; should be None only if in a constant context
pub
temp_lifetime
:
Option
<
region
::
Scope
>
,
/// span of the expression in the source
pub
span
:
Span
,
/// kind of expression
pub
kind
:
ExprKind
<
'tcx
>
,
}
#[derive(Debug)]
pub
enum
ExprKind
<
'tcx
>
{
Scope
{
region_scope
:
region
::
Scope
,
lint_level
:
LintLevel
,
value
:
ExprId
,
},
Box
{
value
:
ExprId
,
},
If
{
cond
:
ExprId
,
then
:
ExprId
,
else_opt
:
Option
<
ExprId
>
,
},
Call
{
ty
:
Ty
<
'tcx
>
,
fun
:
ExprId
,
args
:
Box
<
[
ExprId
]
>
,
/// Whether this is from a call in HIR, rather than from an overloaded
/// operator. `true` for overloaded function call.
from_hir_call
:
bool
,
/// This `Span` is the span of the function, without the dot and receiver
/// (e.g. `foo(a, b)` in `x.foo(a, b)`
fn_span
:
Span
,
},
Deref
{
arg
:
ExprId
,
},
// NOT overloaded!
Binary
{
op
:
BinOp
,
lhs
:
ExprId
,
rhs
:
ExprId
,
},
// NOT overloaded!
LogicalOp
{
op
:
LogicalOp
,
lhs
:
ExprId
,
rhs
:
ExprId
,
},
// NOT overloaded!
// LogicalOp is distinct from BinaryOp because of lazy evaluation of the operands.
Unary
{
op
:
UnOp
,
arg
:
ExprId
,
},
// NOT overloaded!
Cast
{
source
:
ExprId
,
},
Use
{
source
:
ExprId
,
},
// Use a lexpr to get a vexpr.
NeverToAny
{
source
:
ExprId
,
},
Pointer
{
cast
:
PointerCast
,
source
:
ExprId
,
},
Loop
{
body
:
ExprId
,
},
Match
{
scrutinee
:
ExprId
,
arms
:
Box
<
[
ArmId
]
>
,
},
Block
{
body
:
Block
,
},
Assign
{
lhs
:
ExprId
,
rhs
:
ExprId
,
},
AssignOp
{
op
:
BinOp
,
lhs
:
ExprId
,
rhs
:
ExprId
,
},
Field
{
lhs
:
ExprId
,
name
:
Field
,
},
Index
{
lhs
:
ExprId
,
index
:
ExprId
,
},
VarRef
{
id
:
hir
::
HirId
,
},
/// Used to represent upvars mentioned in a closure/generator
UpvarRef
{
/// DefId of the closure/generator
closure_def_id
:
DefId
,
/// HirId of the root variable
var_hir_id
:
hir
::
HirId
,
},
Borrow
{
borrow_kind
:
BorrowKind
,
arg
:
ExprId
,
},
/// A `&raw [const|mut] $place_expr` raw borrow resulting in type `*[const|mut] T`.
AddressOf
{
mutability
:
hir
::
Mutability
,
arg
:
ExprId
,
},
Break
{
label
:
region
::
Scope
,
value
:
Option
<
ExprId
>
,
},
Continue
{
label
:
region
::
Scope
,
},
Return
{
value
:
Option
<
ExprId
>
,
},
ConstBlock
{
value
:
&
'tcx
Const
<
'tcx
>
,
},
Repeat
{
value
:
ExprId
,
count
:
&
'tcx
Const
<
'tcx
>
,
},
Array
{
fields
:
Box
<
[
ExprId
]
>
,
},
Tuple
{
fields
:
Box
<
[
ExprId
]
>
,
},
Adt
{
adt_def
:
&
'tcx
AdtDef
,
variant_index
:
VariantIdx
,
substs
:
SubstsRef
<
'tcx
>
,
/// Optional user-given substs: for something like `let x =
/// Bar::<T> { ... }`.
user_ty
:
Option
<
Canonical
<
'tcx
,
UserType
<
'tcx
>>>
,
fields
:
Box
<
[
FieldExpr
]
>
,
base
:
Option
<
FruInfo
<
'tcx
>>
,
},
PlaceTypeAscription
{
source
:
ExprId
,
/// Type that the user gave to this expression
user_ty
:
Option
<
Canonical
<
'tcx
,
UserType
<
'tcx
>>>
,
},
ValueTypeAscription
{
source
:
ExprId
,
/// Type that the user gave to this expression
user_ty
:
Option
<
Canonical
<
'tcx
,
UserType
<
'tcx
>>>
,
},
Closure
{
closure_id
:
DefId
,
substs
:
UpvarSubsts
<
'tcx
>
,
upvars
:
Box
<
[
ExprId
]
>
,
movability
:
Option
<
hir
::
Movability
>
,
fake_reads
:
Vec
<
(
ExprId
,
FakeReadCause
,
hir
::
HirId
)
>
,
},
Literal
{
literal
:
&
'tcx
Const
<
'tcx
>
,
user_ty
:
Option
<
Canonical
<
'tcx
,
UserType
<
'tcx
>>>
,
/// The `DefId` of the `const` item this literal
/// was produced from, if this is not a user-written
/// literal value.
const_id
:
Option
<
DefId
>
,
},
/// A literal containing the address of a `static`.
///
/// This is only distinguished from `Literal` so that we can register some
/// info for diagnostics.
StaticRef
{
literal
:
&
'tcx
Const
<
'tcx
>
,
def_id
:
DefId
,
},
InlineAsm
{
template
:
&
'tcx
[
InlineAsmTemplatePiece
],
operands
:
Box
<
[
InlineAsmOperand
<
'tcx
>
]
>
,
options
:
InlineAsmOptions
,
line_spans
:
&
'tcx
[
Span
],
},
/// An expression taking a reference to a thread local.
ThreadLocalRef
(
DefId
),
LlvmInlineAsm
{
asm
:
&
'tcx
hir
::
LlvmInlineAsmInner
,
outputs
:
Box
<
[
ExprId
]
>
,
inputs
:
Box
<
[
ExprId
]
>
,
},
Yield
{
value
:
ExprId
,
},
}
#[derive(Debug)]
pub
struct
FieldExpr
{
pub
name
:
Field
,
pub
expr
:
ExprId
,
}
#[derive(Debug)]
pub
struct
FruInfo
<
'tcx
>
{
pub
base
:
ExprId
,
pub
field_types
:
Box
<
[
Ty
<
'tcx
>
]
>
,
}
#[derive(Debug)]
pub
struct
Arm
<
'tcx
>
{
pub
pattern
:
Pat
<
'tcx
>
,
pub
guard
:
Option
<
Guard
<
'tcx
>>
,
pub
body
:
ExprId
,
pub
lint_level
:
LintLevel
,
pub
scope
:
region
::
Scope
,
pub
span
:
Span
,
}
#[derive(Debug)]
pub
enum
Guard
<
'tcx
>
{
If
(
ExprId
),
IfLet
(
Pat
<
'tcx
>
,
ExprId
),
}
#[derive(Copy,
Clone,
Debug)]
pub
enum
LogicalOp
{
And
,
Or
,
}
#[derive(Debug)]
pub
enum
InlineAsmOperand
<
'tcx
>
{
In
{
reg
:
InlineAsmRegOrRegClass
,
expr
:
ExprId
,
},
Out
{
reg
:
InlineAsmRegOrRegClass
,
late
:
bool
,
expr
:
Option
<
ExprId
>
,
},
InOut
{
reg
:
InlineAsmRegOrRegClass
,
late
:
bool
,
expr
:
ExprId
,
},
SplitInOut
{
reg
:
InlineAsmRegOrRegClass
,
late
:
bool
,
in_expr
:
ExprId
,
out_expr
:
Option
<
ExprId
>
,
},
Const
{
value
:
&
'tcx
Const
<
'tcx
>
,
span
:
Span
,
},
SymFn
{
expr
:
ExprId
,
},
SymStatic
{
def_id
:
DefId
,
},
}
compiler/rustc_mir_build/src/thir/pattern/check_match.rs
浏览文件 @
bd800181
use
super
::
usefulness
::{
compute_match_usefulness
,
expand_pattern
,
MatchArm
,
MatchCheckCtxt
,
Reachability
,
compute_match_usefulness
,
expand_pattern
,
is_wildcard
,
MatchArm
,
MatchCheckCtxt
,
Reachability
,
UsefulnessReport
,
};
use
super
::{
PatCtxt
,
Pat
Kind
,
Pat
ternError
};
use
super
::{
PatCtxt
,
PatternError
};
use
rustc_arena
::
TypedArena
;
use
rustc_ast
::
Mutability
;
...
...
@@ -12,6 +12,7 @@
use
rustc_hir
::
def_id
::
DefId
;
use
rustc_hir
::
intravisit
::{
self
,
NestedVisitorMap
,
Visitor
};
use
rustc_hir
::{
HirId
,
Pat
};
use
rustc_middle
::
thir
::
PatKind
;
use
rustc_middle
::
ty
::{
self
,
Ty
,
TyCtxt
};
use
rustc_session
::
lint
::
builtin
::
BINDINGS_WITH_VARIANT_NAME
;
use
rustc_session
::
lint
::
builtin
::{
IRREFUTABLE_LET_PATTERNS
,
UNREACHABLE_PATTERNS
};
...
...
@@ -344,7 +345,7 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pa
/// Checks for common cases of "catchall" patterns that may not be intended as such.
fn
pat_is_catchall
(
pat
:
&
super
::
Pat
<
'_
>
)
->
bool
{
use
super
::
PatKind
::
*
;
use
PatKind
::
*
;
match
&*
pat
.kind
{
Binding
{
subpattern
:
None
,
..
}
=>
true
,
Binding
{
subpattern
:
Some
(
s
),
..
}
|
Deref
{
subpattern
:
s
}
=>
pat_is_catchall
(
s
),
...
...
@@ -514,7 +515,7 @@ fn non_exhaustive_match<'p, 'tcx>(
if
(
scrut_ty
==
cx
.tcx.types.usize
||
scrut_ty
==
cx
.tcx.types.isize
)
&&
!
is_empty_match
&&
witnesses
.len
()
==
1
&&
witnesses
[
0
]
.is_wildcard
(
)
&&
is_wildcard
(
&
witnesses
[
0
]
)
{
err
.note
(
&
format!
(
"`{}` does not have a fixed maximum value,
\
...
...
compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
浏览文件 @
bd800181
...
...
@@ -2,6 +2,7 @@
use
rustc_index
::
vec
::
Idx
;
use
rustc_infer
::
infer
::{
InferCtxt
,
TyCtxtInferExt
};
use
rustc_middle
::
mir
::
Field
;
use
rustc_middle
::
thir
::{
FieldPat
,
Pat
,
PatKind
};
use
rustc_middle
::
ty
::
print
::
with_no_trimmed_paths
;
use
rustc_middle
::
ty
::{
self
,
AdtDef
,
Ty
,
TyCtxt
};
use
rustc_session
::
lint
;
...
...
@@ -12,7 +13,7 @@
use
std
::
cell
::
Cell
;
use
super
::
{
FieldPat
,
Pat
,
PatCtxt
,
PatKind
}
;
use
super
::
PatCtxt
;
impl
<
'a
,
'tcx
>
PatCtxt
<
'a
,
'tcx
>
{
/// Converts an evaluated constant to a pattern (if possible).
...
...
compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
浏览文件 @
bd800181
...
...
@@ -46,8 +46,7 @@
use
self
::
SliceKind
::
*
;
use
super
::
compare_const_vals
;
use
super
::
usefulness
::{
MatchCheckCtxt
,
PatCtxt
};
use
super
::{
FieldPat
,
Pat
,
PatKind
,
PatRange
};
use
super
::
usefulness
::{
is_wildcard
,
MatchCheckCtxt
,
PatCtxt
};
use
rustc_data_structures
::
captures
::
Captures
;
use
rustc_index
::
vec
::
Idx
;
...
...
@@ -55,6 +54,7 @@
use
rustc_hir
::{
HirId
,
RangeEnd
};
use
rustc_middle
::
mir
::
interpret
::
ConstValue
;
use
rustc_middle
::
mir
::
Field
;
use
rustc_middle
::
thir
::{
FieldPat
,
Pat
,
PatKind
,
PatRange
};
use
rustc_middle
::
ty
::
layout
::
IntegerExt
;
use
rustc_middle
::
ty
::{
self
,
Const
,
Ty
,
TyCtxt
};
use
rustc_session
::
lint
;
...
...
@@ -1245,13 +1245,13 @@ pub(super) fn apply(self, pcx: PatCtxt<'_, 'p, 'tcx>, ctor: &Constructor<'tcx>)
// of reporting `[x, _, .., _, y]`, we prefer to report `[x, .., y]`.
// This is incorrect if the size is not known, since `[_, ..]` captures
// arrays of lengths `>= 1` whereas `[..]` captures any length.
while
!
prefix
.is_empty
()
&&
prefix
.last
()
.unwrap
()
.is_wildcard
(
)
{
while
!
prefix
.is_empty
()
&&
is_wildcard
(
prefix
.last
()
.unwrap
()
)
{
prefix
.pop
();
}
}
let
suffix
:
Vec
<
_
>
=
if
slice
.array_len
.is_some
()
{
// Same as above.
subpatterns
.skip_while
(
Pat
::
is_wildcard
)
.collect
()
subpatterns
.skip_while
(
is_wildcard
)
.collect
()
}
else
{
subpatterns
.collect
()
};
...
...
compiler/rustc_mir_build/src/thir/pattern/mod.rs
浏览文件 @
bd800181
...
...
@@ -11,7 +11,7 @@
use
rustc_errors
::
struct_span_err
;
use
rustc_hir
as
hir
;
use
rustc_hir
::
def
::{
Ctor
Kind
,
Ctor
Of
,
DefKind
,
Res
};
use
rustc_hir
::
def
::{
CtorOf
,
DefKind
,
Res
};
use
rustc_hir
::
pat_util
::
EnumerateAndAdjustIterator
;
use
rustc_hir
::
RangeEnd
;
use
rustc_index
::
vec
::
Idx
;
...
...
@@ -19,16 +19,12 @@
use
rustc_middle
::
mir
::
interpret
::{
ErrorHandled
,
LitToConstError
,
LitToConstInput
};
use
rustc_middle
::
mir
::
UserTypeProjection
;
use
rustc_middle
::
mir
::{
BorrowKind
,
Field
,
Mutability
};
use
rustc_middle
::
thir
::{
Ascription
,
BindingMode
,
FieldPat
,
Pat
,
PatKind
,
PatRange
,
PatTyProj
};
use
rustc_middle
::
ty
::
subst
::{
GenericArg
,
SubstsRef
};
use
rustc_middle
::
ty
::{
self
,
AdtDef
,
DefIdTree
,
Region
,
Ty
,
TyCtxt
,
UserType
};
use
rustc_middle
::
ty
::{
CanonicalUserType
,
CanonicalUserTypeAnnotation
,
CanonicalUserTypeAnnotations
,
};
use
rustc_span
::{
Span
,
Symbol
,
DUMMY_SP
};
use
rustc_target
::
abi
::
VariantIdx
;
use
rustc_span
::{
Span
,
Symbol
};
use
std
::
cmp
::
Ordering
;
use
std
::
fmt
;
#[derive(Clone,
Debug)]
crate
enum
PatternError
{
...
...
@@ -39,317 +35,6 @@
NonConstPath
(
Span
),
}
#[derive(Copy,
Clone,
Debug,
PartialEq)]
pub
enum
BindingMode
{
ByValue
,
ByRef
(
BorrowKind
),
}
#[derive(Clone,
Debug,
PartialEq)]
pub
struct
FieldPat
<
'tcx
>
{
pub
field
:
Field
,
pub
pattern
:
Pat
<
'tcx
>
,
}
#[derive(Clone,
Debug,
PartialEq)]
pub
struct
Pat
<
'tcx
>
{
pub
ty
:
Ty
<
'tcx
>
,
pub
span
:
Span
,
pub
kind
:
Box
<
PatKind
<
'tcx
>>
,
}
impl
<
'tcx
>
Pat
<
'tcx
>
{
pub
(
crate
)
fn
wildcard_from_ty
(
ty
:
Ty
<
'tcx
>
)
->
Self
{
Pat
{
ty
,
span
:
DUMMY_SP
,
kind
:
Box
::
new
(
PatKind
::
Wild
)
}
}
}
#[derive(Copy,
Clone,
Debug,
PartialEq)]
pub
struct
PatTyProj
<
'tcx
>
{
pub
user_ty
:
CanonicalUserType
<
'tcx
>
,
}
impl
<
'tcx
>
PatTyProj
<
'tcx
>
{
pub
(
crate
)
fn
from_user_type
(
user_annotation
:
CanonicalUserType
<
'tcx
>
)
->
Self
{
Self
{
user_ty
:
user_annotation
}
}
pub
(
crate
)
fn
user_ty
(
self
,
annotations
:
&
mut
CanonicalUserTypeAnnotations
<
'tcx
>
,
inferred_ty
:
Ty
<
'tcx
>
,
span
:
Span
,
)
->
UserTypeProjection
{
UserTypeProjection
{
base
:
annotations
.push
(
CanonicalUserTypeAnnotation
{
span
,
user_ty
:
self
.user_ty
,
inferred_ty
,
}),
projs
:
Vec
::
new
(),
}
}
}
#[derive(Copy,
Clone,
Debug,
PartialEq)]
pub
struct
Ascription
<
'tcx
>
{
pub
user_ty
:
PatTyProj
<
'tcx
>
,
/// Variance to use when relating the type `user_ty` to the **type of the value being
/// matched**. Typically, this is `Variance::Covariant`, since the value being matched must
/// have a type that is some subtype of the ascribed type.
///
/// Note that this variance does not apply for any bindings within subpatterns. The type
/// assigned to those bindings must be exactly equal to the `user_ty` given here.
///
/// The only place where this field is not `Covariant` is when matching constants, where
/// we currently use `Contravariant` -- this is because the constant type just needs to
/// be "comparable" to the type of the input value. So, for example:
///
/// ```text
/// match x { "foo" => .. }
/// ```
///
/// requires that `&'static str <: T_x`, where `T_x` is the type of `x`. Really, we should
/// probably be checking for a `PartialEq` impl instead, but this preserves the behavior
/// of the old type-check for now. See #57280 for details.
pub
variance
:
ty
::
Variance
,
pub
user_ty_span
:
Span
,
}
#[derive(Clone,
Debug,
PartialEq)]
pub
enum
PatKind
<
'tcx
>
{
Wild
,
AscribeUserType
{
ascription
:
Ascription
<
'tcx
>
,
subpattern
:
Pat
<
'tcx
>
,
},
/// `x`, `ref x`, `x @ P`, etc.
Binding
{
mutability
:
Mutability
,
name
:
Symbol
,
mode
:
BindingMode
,
var
:
hir
::
HirId
,
ty
:
Ty
<
'tcx
>
,
subpattern
:
Option
<
Pat
<
'tcx
>>
,
/// Is this the leftmost occurrence of the binding, i.e., is `var` the
/// `HirId` of this pattern?
is_primary
:
bool
,
},
/// `Foo(...)` or `Foo{...}` or `Foo`, where `Foo` is a variant name from an ADT with
/// multiple variants.
Variant
{
adt_def
:
&
'tcx
AdtDef
,
substs
:
SubstsRef
<
'tcx
>
,
variant_index
:
VariantIdx
,
subpatterns
:
Vec
<
FieldPat
<
'tcx
>>
,
},
/// `(...)`, `Foo(...)`, `Foo{...}`, or `Foo`, where `Foo` is a variant name from an ADT with
/// a single variant.
Leaf
{
subpatterns
:
Vec
<
FieldPat
<
'tcx
>>
,
},
/// `box P`, `&P`, `&mut P`, etc.
Deref
{
subpattern
:
Pat
<
'tcx
>
,
},
/// One of the following:
/// * `&str`, which will be handled as a string pattern and thus exhaustiveness
/// checking will detect if you use the same string twice in different patterns.
/// * integer, bool, char or float, which will be handled by exhaustivenes to cover exactly
/// its own value, similar to `&str`, but these values are much simpler.
/// * Opaque constants, that must not be matched structurally. So anything that does not derive
/// `PartialEq` and `Eq`.
Constant
{
value
:
&
'tcx
ty
::
Const
<
'tcx
>
,
},
Range
(
PatRange
<
'tcx
>
),
/// Matches against a slice, checking the length and extracting elements.
/// irrefutable when there is a slice pattern and both `prefix` and `suffix` are empty.
/// e.g., `&[ref xs @ ..]`.
Slice
{
prefix
:
Vec
<
Pat
<
'tcx
>>
,
slice
:
Option
<
Pat
<
'tcx
>>
,
suffix
:
Vec
<
Pat
<
'tcx
>>
,
},
/// Fixed match against an array; irrefutable.
Array
{
prefix
:
Vec
<
Pat
<
'tcx
>>
,
slice
:
Option
<
Pat
<
'tcx
>>
,
suffix
:
Vec
<
Pat
<
'tcx
>>
,
},
/// An or-pattern, e.g. `p | q`.
/// Invariant: `pats.len() >= 2`.
Or
{
pats
:
Vec
<
Pat
<
'tcx
>>
,
},
}
#[derive(Copy,
Clone,
Debug,
PartialEq)]
pub
struct
PatRange
<
'tcx
>
{
pub
lo
:
&
'tcx
ty
::
Const
<
'tcx
>
,
pub
hi
:
&
'tcx
ty
::
Const
<
'tcx
>
,
pub
end
:
RangeEnd
,
}
impl
<
'tcx
>
fmt
::
Display
for
Pat
<
'tcx
>
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
<
'_
>
)
->
fmt
::
Result
{
// Printing lists is a chore.
let
mut
first
=
true
;
let
mut
start_or_continue
=
|
s
|
{
if
first
{
first
=
false
;
""
}
else
{
s
}
};
let
mut
start_or_comma
=
||
start_or_continue
(
", "
);
match
*
self
.kind
{
PatKind
::
Wild
=>
write!
(
f
,
"_"
),
PatKind
::
AscribeUserType
{
ref
subpattern
,
..
}
=>
write!
(
f
,
"{}: _"
,
subpattern
),
PatKind
::
Binding
{
mutability
,
name
,
mode
,
ref
subpattern
,
..
}
=>
{
let
is_mut
=
match
mode
{
BindingMode
::
ByValue
=>
mutability
==
Mutability
::
Mut
,
BindingMode
::
ByRef
(
bk
)
=>
{
write!
(
f
,
"ref "
)
?
;
matches!
(
bk
,
BorrowKind
::
Mut
{
..
})
}
};
if
is_mut
{
write!
(
f
,
"mut "
)
?
;
}
write!
(
f
,
"{}"
,
name
)
?
;
if
let
Some
(
ref
subpattern
)
=
*
subpattern
{
write!
(
f
,
" @ {}"
,
subpattern
)
?
;
}
Ok
(())
}
PatKind
::
Variant
{
ref
subpatterns
,
..
}
|
PatKind
::
Leaf
{
ref
subpatterns
}
=>
{
let
variant
=
match
*
self
.kind
{
PatKind
::
Variant
{
adt_def
,
variant_index
,
..
}
=>
{
Some
(
&
adt_def
.variants
[
variant_index
])
}
_
=>
{
if
let
ty
::
Adt
(
adt
,
_
)
=
self
.ty
.kind
()
{
if
!
adt
.is_enum
()
{
Some
(
&
adt
.variants
[
VariantIdx
::
new
(
0
)])
}
else
{
None
}
}
else
{
None
}
}
};
if
let
Some
(
variant
)
=
variant
{
write!
(
f
,
"{}"
,
variant
.ident
)
?
;
// Only for Adt we can have `S {...}`,
// which we handle separately here.
if
variant
.ctor_kind
==
CtorKind
::
Fictive
{
write!
(
f
,
" {{ "
)
?
;
let
mut
printed
=
0
;
for
p
in
subpatterns
{
if
let
PatKind
::
Wild
=
*
p
.pattern.kind
{
continue
;
}
let
name
=
variant
.fields
[
p
.field
.index
()]
.ident
;
write!
(
f
,
"{}{}: {}"
,
start_or_comma
(),
name
,
p
.pattern
)
?
;
printed
+=
1
;
}
if
printed
<
variant
.fields
.len
()
{
write!
(
f
,
"{}.."
,
start_or_comma
())
?
;
}
return
write!
(
f
,
" }}"
);
}
}
let
num_fields
=
variant
.map_or
(
subpatterns
.len
(),
|
v
|
v
.fields
.len
());
if
num_fields
!=
0
||
variant
.is_none
()
{
write!
(
f
,
"("
)
?
;
for
i
in
0
..
num_fields
{
write!
(
f
,
"{}"
,
start_or_comma
())
?
;
// Common case: the field is where we expect it.
if
let
Some
(
p
)
=
subpatterns
.get
(
i
)
{
if
p
.field
.index
()
==
i
{
write!
(
f
,
"{}"
,
p
.pattern
)
?
;
continue
;
}
}
// Otherwise, we have to go looking for it.
if
let
Some
(
p
)
=
subpatterns
.iter
()
.find
(|
p
|
p
.field
.index
()
==
i
)
{
write!
(
f
,
"{}"
,
p
.pattern
)
?
;
}
else
{
write!
(
f
,
"_"
)
?
;
}
}
write!
(
f
,
")"
)
?
;
}
Ok
(())
}
PatKind
::
Deref
{
ref
subpattern
}
=>
{
match
self
.ty
.kind
()
{
ty
::
Adt
(
def
,
_
)
if
def
.is_box
()
=>
write!
(
f
,
"box "
)
?
,
ty
::
Ref
(
_
,
_
,
mutbl
)
=>
{
write!
(
f
,
"&{}"
,
mutbl
.prefix_str
())
?
;
}
_
=>
bug!
(
"{} is a bad Deref pattern type"
,
self
.ty
),
}
write!
(
f
,
"{}"
,
subpattern
)
}
PatKind
::
Constant
{
value
}
=>
write!
(
f
,
"{}"
,
value
),
PatKind
::
Range
(
PatRange
{
lo
,
hi
,
end
})
=>
{
write!
(
f
,
"{}"
,
lo
)
?
;
write!
(
f
,
"{}"
,
end
)
?
;
write!
(
f
,
"{}"
,
hi
)
}
PatKind
::
Slice
{
ref
prefix
,
ref
slice
,
ref
suffix
}
|
PatKind
::
Array
{
ref
prefix
,
ref
slice
,
ref
suffix
}
=>
{
write!
(
f
,
"["
)
?
;
for
p
in
prefix
{
write!
(
f
,
"{}{}"
,
start_or_comma
(),
p
)
?
;
}
if
let
Some
(
ref
slice
)
=
*
slice
{
write!
(
f
,
"{}"
,
start_or_comma
())
?
;
match
*
slice
.kind
{
PatKind
::
Wild
=>
{}
_
=>
write!
(
f
,
"{}"
,
slice
)
?
,
}
write!
(
f
,
".."
)
?
;
}
for
p
in
suffix
{
write!
(
f
,
"{}{}"
,
start_or_comma
(),
p
)
?
;
}
write!
(
f
,
"]"
)
}
PatKind
::
Or
{
ref
pats
}
=>
{
for
pat
in
pats
{
write!
(
f
,
"{}{}"
,
start_or_continue
(
" | "
),
pat
)
?
;
}
Ok
(())
}
}
}
}
crate
struct
PatCtxt
<
'a
,
'tcx
>
{
crate
tcx
:
TyCtxt
<
'tcx
>
,
crate
param_env
:
ty
::
ParamEnv
<
'tcx
>
,
...
...
@@ -358,22 +43,20 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
include_lint_checks
:
bool
,
}
impl
<
'a
,
'tcx
>
Pat
<
'tcx
>
{
crate
fn
from_hir
(
tcx
:
TyCtxt
<
'tcx
>
,
param_env
:
ty
::
ParamEnv
<
'tcx
>
,
typeck_results
:
&
'a
ty
::
TypeckResults
<
'tcx
>
,
pat
:
&
'tcx
hir
::
Pat
<
'tcx
>
,
)
->
Self
{
let
mut
pcx
=
PatCtxt
::
new
(
tcx
,
param_env
,
typeck_results
);
let
result
=
pcx
.lower_pattern
(
pat
);
if
!
pcx
.errors
.is_empty
()
{
let
msg
=
format!
(
"encountered errors lowering pattern: {:?}"
,
pcx
.errors
);
tcx
.sess
.delay_span_bug
(
pat
.span
,
&
msg
);
}
debug!
(
"Pat::from_hir({:?}) = {:?}"
,
pat
,
result
);
result
}
crate
fn
pat_from_hir
<
'a
,
'tcx
>
(
tcx
:
TyCtxt
<
'tcx
>
,
param_env
:
ty
::
ParamEnv
<
'tcx
>
,
typeck_results
:
&
'a
ty
::
TypeckResults
<
'tcx
>
,
pat
:
&
'tcx
hir
::
Pat
<
'tcx
>
,
)
->
Pat
<
'tcx
>
{
let
mut
pcx
=
PatCtxt
::
new
(
tcx
,
param_env
,
typeck_results
);
let
result
=
pcx
.lower_pattern
(
pat
);
if
!
pcx
.errors
.is_empty
()
{
let
msg
=
format!
(
"encountered errors lowering pattern: {:?}"
,
pcx
.errors
);
tcx
.sess
.delay_span_bug
(
pat
.span
,
&
msg
);
}
debug!
(
"pat_from_hir({:?}) = {:?}"
,
pat
,
result
);
result
}
impl
<
'a
,
'tcx
>
PatCtxt
<
'a
,
'tcx
>
{
...
...
compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
浏览文件 @
bd800181
...
...
@@ -284,7 +284,6 @@
use
self
::
WitnessPreference
::
*
;
use
super
::
deconstruct_pat
::{
Constructor
,
Fields
,
SplitWildcard
};
use
super
::{
Pat
,
PatKind
};
use
super
::{
PatternFoldable
,
PatternFolder
};
use
rustc_data_structures
::
captures
::
Captures
;
...
...
@@ -294,6 +293,7 @@
use
rustc_hir
::
def_id
::
DefId
;
use
rustc_hir
::
HirId
;
use
rustc_middle
::
ty
::{
self
,
Ty
,
TyCtxt
};
use
rustc_middle
::
thir
::{
Pat
,
PatKind
};
use
rustc_span
::
Span
;
use
smallvec
::{
smallvec
,
SmallVec
};
...
...
@@ -382,31 +382,29 @@ fn fold_pattern(&mut self, pat: &Pat<'tcx>) -> Pat<'tcx> {
}
}
impl
<
'tcx
>
Pat
<
'tcx
>
{
pub
(
super
)
fn
is_wildcard
(
&
self
)
->
bool
{
matches!
(
*
self
.kind
,
PatKind
::
Binding
{
subpattern
:
None
,
..
}
|
PatKind
::
Wild
)
}
pub
(
super
)
fn
is_wildcard
(
pat
:
&
Pat
<
'_
>
)
->
bool
{
matches!
(
*
pat
.kind
,
PatKind
::
Binding
{
subpattern
:
None
,
..
}
|
PatKind
::
Wild
)
}
fn
is_or_pat
(
&
self
)
->
bool
{
matches!
(
*
self
.kind
,
PatKind
::
Or
{
..
})
}
fn
is_or_pat
(
pat
:
&
Pat
<
'_
>
)
->
bool
{
matches!
(
*
pat
.kind
,
PatKind
::
Or
{
..
})
}
/// Recursively expand this pattern into its subpatterns. Only useful for or-patterns.
fn
expand_or_pat
(
&
self
)
->
Vec
<&
Self
>
{
fn
expand
<
'p
,
'tcx
>
(
pat
:
&
'p
Pat
<
'tcx
>
,
vec
:
&
mut
Vec
<&
'p
Pat
<
'tcx
>>
)
{
if
let
PatKind
::
Or
{
pats
}
=
pat
.kind
.as_ref
()
{
for
pat
in
pats
{
expand
(
pat
,
vec
);
}
}
else
{
vec
.push
(
pat
)
/// Recursively expand this pattern into its subpatterns. Only useful for or-patterns.
fn
expand_or_pat
<
'p
,
'tcx
>
(
pat
:
&
'p
Pat
<
'tcx
>
)
->
Vec
<&
'p
Pat
<
'tcx
>>
{
fn
expand
<
'p
,
'tcx
>
(
pat
:
&
'p
Pat
<
'tcx
>
,
vec
:
&
mut
Vec
<&
'p
Pat
<
'tcx
>>
)
{
if
let
PatKind
::
Or
{
pats
}
=
pat
.kind
.as_ref
()
{
for
pat
in
pats
{
expand
(
pat
,
vec
);
}
}
else
{
vec
.push
(
pat
)
}
let
mut
pats
=
Vec
::
new
();
expand
(
self
,
&
mut
pats
);
pats
}
let
mut
pats
=
Vec
::
new
();
expand
(
pat
,
&
mut
pats
);
pats
}
/// A row of a matrix. Rows of len 1 are very common, which is why `SmallVec[_; 2]`
...
...
@@ -451,7 +449,7 @@ fn iter(&self) -> impl Iterator<Item = &Pat<'tcx>> {
// Recursively expand the first pattern into its subpatterns. Only useful if the pattern is an
// or-pattern. Panics if `self` is empty.
fn
expand_or_pat
<
'a
>
(
&
'a
self
)
->
impl
Iterator
<
Item
=
PatStack
<
'p
,
'tcx
>>
+
Captures
<
'a
>
{
self
.head
()
.expand_or_pat
(
)
.into_iter
()
.map
(
move
|
pat
|
{
expand_or_pat
(
self
.head
()
)
.into_iter
()
.map
(
move
|
pat
|
{
let
mut
new_patstack
=
PatStack
::
from_pattern
(
pat
);
new_patstack
.pats
.extend_from_slice
(
&
self
.pats
[
1
..
]);
new_patstack
...
...
@@ -525,7 +523,7 @@ pub(super) fn column_count(&self) -> Option<usize> {
/// Pushes a new row to the matrix. If the row starts with an or-pattern, this recursively
/// expands it.
fn
push
(
&
mut
self
,
row
:
PatStack
<
'p
,
'tcx
>
)
{
if
!
row
.is_empty
()
&&
row
.head
()
.is_or_pat
(
)
{
if
!
row
.is_empty
()
&&
is_or_pat
(
row
.head
()
)
{
for
row
in
row
.expand_or_pat
()
{
self
.patterns
.push
(
row
);
}
...
...
@@ -760,7 +758,7 @@ fn fill_spans(set: &SubPatSet<'_, '_>, spans: &mut Vec<Span>) {
}
}
SubPatSet
::
Alt
{
subpats
,
pat
,
alt_count
,
..
}
=>
{
let
expanded
=
pat
.expand_or_pat
(
);
let
expanded
=
expand_or_pat
(
pat
);
for
i
in
0
..*
alt_count
{
let
sub_set
=
subpats
.get
(
&
i
)
.unwrap_or
(
&
SubPatSet
::
Empty
);
if
sub_set
.is_empty
()
{
...
...
@@ -1118,7 +1116,7 @@ fn is_useful<'p, 'tcx>(
let
pcx
=
PatCtxt
{
cx
,
ty
,
span
:
v
.head
()
.span
,
is_top_level
};
// If the first pattern is an or-pattern, expand it.
let
ret
=
if
v
.head
()
.is_or_pat
(
)
{
let
ret
=
if
is_or_pat
(
v
.head
()
)
{
debug!
(
"expanding or-pattern"
);
let
v_head
=
v
.head
();
let
vs
:
Vec
<
_
>
=
v
.expand_or_pat
()
.collect
();
...
...
@@ -1174,7 +1172,7 @@ fn is_useful<'p, 'tcx>(
#[derive(Clone,
Copy)]
crate
struct
MatchArm
<
'p
,
'tcx
>
{
/// The pattern must have been lowered through `check_match::MatchVisitor::lower_pattern`.
crate
pat
:
&
'p
super
::
Pat
<
'tcx
>
,
crate
pat
:
&
'p
Pat
<
'tcx
>
,
crate
hir_id
:
HirId
,
crate
has_guard
:
bool
,
}
...
...
@@ -1196,7 +1194,7 @@ fn is_useful<'p, 'tcx>(
crate
arm_usefulness
:
Vec
<
(
MatchArm
<
'p
,
'tcx
>
,
Reachability
)
>
,
/// If the match is exhaustive, this is empty. If not, this contains witnesses for the lack of
/// exhaustiveness.
crate
non_exhaustiveness_witnesses
:
Vec
<
super
::
Pat
<
'tcx
>>
,
crate
non_exhaustiveness_witnesses
:
Vec
<
Pat
<
'tcx
>>
,
}
/// The entrypoint for the usefulness algorithm. Computes whether a match is exhaustive and which
...
...
@@ -1232,7 +1230,7 @@ fn is_useful<'p, 'tcx>(
})
.collect
();
let
wild_pattern
=
cx
.pattern_arena
.alloc
(
super
::
Pat
::
wildcard_from_ty
(
scrut_ty
));
let
wild_pattern
=
cx
.pattern_arena
.alloc
(
Pat
::
wildcard_from_ty
(
scrut_ty
));
let
v
=
PatStack
::
from_pattern
(
wild_pattern
);
let
usefulness
=
is_useful
(
cx
,
&
matrix
,
&
v
,
ConstructWitness
,
scrut_hir_id
,
false
,
true
);
let
non_exhaustiveness_witnesses
=
match
usefulness
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录