Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
4fe735b3
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,发现更多精彩内容 >>
提交
4fe735b3
编写于
10月 21, 2020
作者:
L
LeSeulArtichaut
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
TypeVisitor: use `ControlFlow` in rustc_{infer,lint,trait_selection}
上级
2c85b6fa
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
106 addition
and
82 deletion
+106
-82
compiler/rustc_infer/src/infer/error_reporting/mod.rs
compiler/rustc_infer/src/infer/error_reporting/mod.rs
+2
-1
compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
...er/error_reporting/nice_region_error/static_impl_trait.rs
+4
-2
compiler/rustc_infer/src/infer/nll_relate/mod.rs
compiler/rustc_infer/src/infer/nll_relate/mod.rs
+5
-4
compiler/rustc_infer/src/infer/resolve.rs
compiler/rustc_infer/src/infer/resolve.rs
+5
-3
compiler/rustc_infer/src/lib.rs
compiler/rustc_infer/src/lib.rs
+1
-0
compiler/rustc_infer/src/traits/structural_impls.rs
compiler/rustc_infer/src/traits/structural_impls.rs
+2
-1
compiler/rustc_lint/src/lib.rs
compiler/rustc_lint/src/lib.rs
+1
-0
compiler/rustc_lint/src/types.rs
compiler/rustc_lint/src/types.rs
+8
-3
compiler/rustc_trait_selection/src/lib.rs
compiler/rustc_trait_selection/src/lib.rs
+1
-0
compiler/rustc_trait_selection/src/opaque_types.rs
compiler/rustc_trait_selection/src/opaque_types.rs
+10
-8
compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
...ler/rustc_trait_selection/src/traits/const_evaluatable.rs
+25
-18
compiler/rustc_trait_selection/src/traits/object_safety.rs
compiler/rustc_trait_selection/src/traits/object_safety.rs
+22
-12
compiler/rustc_trait_selection/src/traits/structural_match.rs
...iler/rustc_trait_selection/src/traits/structural_match.rs
+20
-30
未找到文件。
compiler/rustc_infer/src/infer/error_reporting/mod.rs
浏览文件 @
4fe735b3
...
...
@@ -71,6 +71,7 @@
};
use
rustc_span
::{
BytePos
,
DesugaringKind
,
Pos
,
Span
};
use
rustc_target
::
spec
::
abi
;
use
std
::
ops
::
ControlFlow
;
use
std
::{
cmp
,
fmt
};
mod
note
;
...
...
@@ -1497,7 +1498,7 @@ fn add_labels_for_types(
}
impl
<
'tcx
>
ty
::
fold
::
TypeVisitor
<
'tcx
>
for
OpaqueTypesVisitor
<
'tcx
>
{
fn
visit_ty
(
&
mut
self
,
t
:
Ty
<
'tcx
>
)
->
bool
{
fn
visit_ty
(
&
mut
self
,
t
:
Ty
<
'tcx
>
)
->
ControlFlow
<
(),
()
>
{
if
let
Some
((
kind
,
def_id
))
=
TyCategory
::
from_ty
(
t
)
{
let
span
=
self
.tcx
.def_span
(
def_id
);
// Avoid cluttering the output when the "found" and error span overlap:
...
...
compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
浏览文件 @
4fe735b3
...
...
@@ -15,6 +15,8 @@
use
rustc_span
::
symbol
::
Ident
;
use
rustc_span
::{
MultiSpan
,
Span
};
use
std
::
ops
::
ControlFlow
;
impl
<
'a
,
'tcx
>
NiceRegionError
<
'a
,
'tcx
>
{
/// Print the error message for lifetime errors when the return type is a static `impl Trait`,
/// `dyn Trait` or if a method call on a trait object introduces a static requirement.
...
...
@@ -472,13 +474,13 @@ fn suggest_constrain_dyn_trait_in_impl(
struct
TraitObjectVisitor
(
Vec
<
DefId
>
);
impl
TypeVisitor
<
'_
>
for
TraitObjectVisitor
{
fn
visit_ty
(
&
mut
self
,
t
:
Ty
<
'_
>
)
->
bool
{
fn
visit_ty
(
&
mut
self
,
t
:
Ty
<
'_
>
)
->
ControlFlow
<
(),
()
>
{
match
t
.kind
()
{
ty
::
Dynamic
(
preds
,
RegionKind
::
ReStatic
)
=>
{
if
let
Some
(
def_id
)
=
preds
.principal_def_id
()
{
self
.0
.push
(
def_id
);
}
false
ControlFlow
::
CONTINUE
}
_
=>
t
.super_visit_with
(
self
),
}
...
...
compiler/rustc_infer/src/infer/nll_relate/mod.rs
浏览文件 @
4fe735b3
...
...
@@ -30,6 +30,7 @@
use
rustc_middle
::
ty
::
relate
::{
self
,
Relate
,
RelateResult
,
TypeRelation
};
use
rustc_middle
::
ty
::{
self
,
InferConst
,
Ty
,
TyCtxt
};
use
std
::
fmt
::
Debug
;
use
std
::
ops
::
ControlFlow
;
#[derive(PartialEq)]
pub
enum
NormalizationStrategy
{
...
...
@@ -740,15 +741,15 @@ struct ScopeInstantiator<'me, 'tcx> {
}
impl
<
'me
,
'tcx
>
TypeVisitor
<
'tcx
>
for
ScopeInstantiator
<
'me
,
'tcx
>
{
fn
visit_binder
<
T
:
TypeFoldable
<
'tcx
>>
(
&
mut
self
,
t
:
&
ty
::
Binder
<
T
>
)
->
bool
{
fn
visit_binder
<
T
:
TypeFoldable
<
'tcx
>>
(
&
mut
self
,
t
:
&
ty
::
Binder
<
T
>
)
->
ControlFlow
<
(),
()
>
{
self
.target_index
.shift_in
(
1
);
t
.super_visit_with
(
self
);
self
.target_index
.shift_out
(
1
);
false
ControlFlow
::
CONTINUE
}
fn
visit_region
(
&
mut
self
,
r
:
ty
::
Region
<
'tcx
>
)
->
bool
{
fn
visit_region
(
&
mut
self
,
r
:
ty
::
Region
<
'tcx
>
)
->
ControlFlow
<
(),
()
>
{
let
ScopeInstantiator
{
bound_region_scope
,
next_region
,
..
}
=
self
;
match
r
{
...
...
@@ -759,7 +760,7 @@ fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
_
=>
{}
}
false
ControlFlow
::
CONTINUE
}
}
...
...
compiler/rustc_infer/src/infer/resolve.rs
浏览文件 @
4fe735b3
...
...
@@ -3,6 +3,8 @@
use
rustc_middle
::
ty
::
fold
::{
TypeFolder
,
TypeVisitor
};
use
rustc_middle
::
ty
::{
self
,
Const
,
InferConst
,
Ty
,
TyCtxt
,
TypeFoldable
};
use
std
::
ops
::
ControlFlow
;
///////////////////////////////////////////////////////////////////////////
// OPPORTUNISTIC VAR RESOLVER
...
...
@@ -121,7 +123,7 @@ pub fn new(infcx: &'a InferCtxt<'a, 'tcx>) -> Self {
}
impl
<
'a
,
'tcx
>
TypeVisitor
<
'tcx
>
for
UnresolvedTypeFinder
<
'a
,
'tcx
>
{
fn
visit_ty
(
&
mut
self
,
t
:
Ty
<
'tcx
>
)
->
bool
{
fn
visit_ty
(
&
mut
self
,
t
:
Ty
<
'tcx
>
)
->
ControlFlow
<
(),
()
>
{
let
t
=
self
.infcx
.shallow_resolve
(
t
);
if
t
.has_infer_types
()
{
if
let
ty
::
Infer
(
infer_ty
)
=
*
t
.kind
()
{
...
...
@@ -143,7 +145,7 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
None
};
self
.first_unresolved
=
Some
((
t
,
ty_var_span
));
true
// Halt visiting.
ControlFlow
::
BREAK
}
else
{
// Otherwise, visit its contents.
t
.super_visit_with
(
self
)
...
...
@@ -151,7 +153,7 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
}
else
{
// All type variables in inference types must already be resolved,
// - no need to visit the contents, continue visiting.
false
ControlFlow
::
CONTINUE
}
}
}
...
...
compiler/rustc_infer/src/lib.rs
浏览文件 @
4fe735b3
...
...
@@ -22,6 +22,7 @@
#![feature(never_type)]
#![feature(or_patterns)]
#![feature(in_band_lifetimes)]
#![feature(control_flow_enum)]
#![recursion_limit
=
"512"
]
// For rustdoc
#[macro_use]
...
...
compiler/rustc_infer/src/traits/structural_impls.rs
浏览文件 @
4fe735b3
...
...
@@ -4,6 +4,7 @@
use
rustc_middle
::
ty
::
fold
::{
TypeFoldable
,
TypeFolder
,
TypeVisitor
};
use
std
::
fmt
;
use
std
::
ops
::
ControlFlow
;
// Structural impls for the structs in `traits`.
...
...
@@ -68,7 +69,7 @@ fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
}
}
fn
super_visit_with
<
V
:
TypeVisitor
<
'tcx
>>
(
&
self
,
visitor
:
&
mut
V
)
->
bool
{
fn
super_visit_with
<
V
:
TypeVisitor
<
'tcx
>>
(
&
self
,
visitor
:
&
mut
V
)
->
ControlFlow
<
(),
()
>
{
self
.predicate
.visit_with
(
visitor
)
}
}
compiler/rustc_lint/src/lib.rs
浏览文件 @
4fe735b3
...
...
@@ -37,6 +37,7 @@
#![feature(or_patterns)]
#![feature(half_open_range_patterns)]
#![feature(exclusive_range_pattern)]
#![feature(control_flow_enum)]
#![recursion_limit
=
"256"
]
#[macro_use]
...
...
compiler/rustc_lint/src/types.rs
浏览文件 @
4fe735b3
...
...
@@ -18,6 +18,7 @@
use
rustc_target
::
spec
::
abi
::
Abi
as
SpecAbi
;
use
std
::
cmp
;
use
std
::
ops
::
ControlFlow
;
use
tracing
::
debug
;
declare_lint!
{
...
...
@@ -1135,11 +1136,11 @@ struct ProhibitOpaqueTypes<'a, 'tcx> {
};
impl
<
'a
,
'tcx
>
ty
::
fold
::
TypeVisitor
<
'tcx
>
for
ProhibitOpaqueTypes
<
'a
,
'tcx
>
{
fn
visit_ty
(
&
mut
self
,
ty
:
Ty
<
'tcx
>
)
->
bool
{
fn
visit_ty
(
&
mut
self
,
ty
:
Ty
<
'tcx
>
)
->
ControlFlow
<
(),
()
>
{
match
ty
.kind
()
{
ty
::
Opaque
(
..
)
=>
{
self
.ty
=
Some
(
ty
);
true
ControlFlow
::
BREAK
}
// Consider opaque types within projections FFI-safe if they do not normalize
// to more opaque types.
...
...
@@ -1148,7 +1149,11 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
// If `ty` is a opaque type directly then `super_visit_with` won't invoke
// this function again.
if
ty
.has_opaque_types
()
{
self
.visit_ty
(
ty
)
}
else
{
false
}
if
ty
.has_opaque_types
()
{
self
.visit_ty
(
ty
)
}
else
{
ControlFlow
::
CONTINUE
}
}
_
=>
ty
.super_visit_with
(
self
),
}
...
...
compiler/rustc_trait_selection/src/lib.rs
浏览文件 @
4fe735b3
...
...
@@ -19,6 +19,7 @@
#![feature(never_type)]
#![feature(crate_visibility_modifier)]
#![feature(or_patterns)]
#![feature(control_flow_enum)]
#![recursion_limit
=
"512"
]
// For rustdoc
#[macro_use]
...
...
compiler/rustc_trait_selection/src/opaque_types.rs
浏览文件 @
4fe735b3
...
...
@@ -15,6 +15,8 @@
use
rustc_session
::
config
::
nightly_options
;
use
rustc_span
::
Span
;
use
std
::
ops
::
ControlFlow
;
pub
type
OpaqueTypeMap
<
'tcx
>
=
DefIdMap
<
OpaqueTypeDecl
<
'tcx
>>
;
/// Information about the opaque types whose values we
...
...
@@ -691,26 +693,26 @@ impl<'tcx, OP> TypeVisitor<'tcx> for ConstrainOpaqueTypeRegionVisitor<OP>
where
OP
:
FnMut
(
ty
::
Region
<
'tcx
>
),
{
fn
visit_binder
<
T
:
TypeFoldable
<
'tcx
>>
(
&
mut
self
,
t
:
&
ty
::
Binder
<
T
>
)
->
bool
{
fn
visit_binder
<
T
:
TypeFoldable
<
'tcx
>>
(
&
mut
self
,
t
:
&
ty
::
Binder
<
T
>
)
->
ControlFlow
<
(),
()
>
{
t
.as_ref
()
.skip_binder
()
.visit_with
(
self
);
false
// keep visiting
ControlFlow
::
CONTINUE
}
fn
visit_region
(
&
mut
self
,
r
:
ty
::
Region
<
'tcx
>
)
->
bool
{
fn
visit_region
(
&
mut
self
,
r
:
ty
::
Region
<
'tcx
>
)
->
ControlFlow
<
(),
()
>
{
match
*
r
{
// ignore bound regions, keep visiting
ty
::
ReLateBound
(
_
,
_
)
=>
false
,
ty
::
ReLateBound
(
_
,
_
)
=>
ControlFlow
::
CONTINUE
,
_
=>
{
(
self
.op
)(
r
);
false
ControlFlow
::
CONTINUE
}
}
}
fn
visit_ty
(
&
mut
self
,
ty
:
Ty
<
'tcx
>
)
->
bool
{
fn
visit_ty
(
&
mut
self
,
ty
:
Ty
<
'tcx
>
)
->
ControlFlow
<
(),
()
>
{
// We're only interested in types involving regions
if
!
ty
.flags
()
.intersects
(
ty
::
TypeFlags
::
HAS_FREE_REGIONS
)
{
return
false
;
// keep visiting
return
ControlFlow
::
CONTINUE
;
}
match
ty
.kind
()
{
...
...
@@ -745,7 +747,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
}
}
false
ControlFlow
::
CONTINUE
}
}
...
...
compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
浏览文件 @
4fe735b3
...
...
@@ -24,6 +24,7 @@
use
rustc_span
::
Span
;
use
std
::
cmp
;
use
std
::
ops
::
ControlFlow
;
/// Check if a given constant can be evaluated.
pub
fn
is_const_evaluatable
<
'cx
,
'tcx
>
(
...
...
@@ -86,9 +87,11 @@ enum FailureKind {
failure_kind
=
cmp
::
min
(
failure_kind
,
FailureKind
::
MentionsParam
);
}
false
ControlFlow
::
CONTINUE
}
Node
::
Binop
(
_
,
_
,
_
)
|
Node
::
UnaryOp
(
_
,
_
)
|
Node
::
FunctionCall
(
_
,
_
)
=>
{
ControlFlow
::
CONTINUE
}
Node
::
Binop
(
_
,
_
,
_
)
|
Node
::
UnaryOp
(
_
,
_
)
|
Node
::
FunctionCall
(
_
,
_
)
=>
false
,
});
match
failure_kind
{
...
...
@@ -564,29 +567,33 @@ pub(super) fn try_unify_abstract_consts<'tcx>(
// on `ErrorReported`.
}
// FIXME: Use `std::ops::ControlFlow` instead of `bool` here.
pub
fn
walk_abstract_const
<
'tcx
,
F
>
(
tcx
:
TyCtxt
<
'tcx
>
,
ct
:
AbstractConst
<
'tcx
>
,
mut
f
:
F
)
->
bool
pub
fn
walk_abstract_const
<
'tcx
,
F
>
(
tcx
:
TyCtxt
<
'tcx
>
,
ct
:
AbstractConst
<
'tcx
>
,
mut
f
:
F
,
)
->
ControlFlow
<
(),
()
>
where
F
:
FnMut
(
Node
<
'tcx
>
)
->
bool
,
F
:
FnMut
(
Node
<
'tcx
>
)
->
ControlFlow
<
(),
()
>
,
{
fn
recurse
<
'tcx
>
(
tcx
:
TyCtxt
<
'tcx
>
,
ct
:
AbstractConst
<
'tcx
>
,
f
:
&
mut
dyn
FnMut
(
Node
<
'tcx
>
)
->
bool
,
)
->
bool
{
f
:
&
mut
dyn
FnMut
(
Node
<
'tcx
>
)
->
ControlFlow
<
(),
()
>
,
)
->
ControlFlow
<
(),
()
>
{
let
root
=
ct
.root
();
f
(
root
)
||
match
root
{
Node
::
Leaf
(
_
)
=>
false
,
Node
::
Binop
(
_
,
l
,
r
)
=>
{
recurse
(
tcx
,
ct
.subtree
(
l
),
f
)
||
recurse
(
tcx
,
ct
.subtree
(
r
),
f
)
}
Node
::
UnaryOp
(
_
,
v
)
=>
recurse
(
tcx
,
ct
.subtree
(
v
),
f
),
Node
::
FunctionCall
(
func
,
args
)
=>
{
recurse
(
tcx
,
ct
.subtree
(
func
),
f
)
||
args
.iter
()
.any
(|
&
arg
|
recurse
(
tcx
,
ct
.subtree
(
arg
),
f
))
}
f
(
root
)
?
;
match
root
{
Node
::
Leaf
(
_
)
=>
ControlFlow
::
CONTINUE
,
Node
::
Binop
(
_
,
l
,
r
)
=>
{
recurse
(
tcx
,
ct
.subtree
(
l
),
f
)
?
;
recurse
(
tcx
,
ct
.subtree
(
r
),
f
)
}
Node
::
UnaryOp
(
_
,
v
)
=>
recurse
(
tcx
,
ct
.subtree
(
v
),
f
),
Node
::
FunctionCall
(
func
,
args
)
=>
{
recurse
(
tcx
,
ct
.subtree
(
func
),
f
)
?
;
args
.iter
()
.try_for_each
(|
&
arg
|
recurse
(
tcx
,
ct
.subtree
(
arg
),
f
))
}
}
}
recurse
(
tcx
,
ct
,
&
mut
f
)
...
...
compiler/rustc_trait_selection/src/traits/object_safety.rs
浏览文件 @
4fe735b3
...
...
@@ -27,6 +27,7 @@
use
std
::
array
;
use
std
::
iter
;
use
std
::
ops
::
ControlFlow
;
pub
use
crate
::
traits
::{
MethodViolationCode
,
ObjectSafetyViolation
};
...
...
@@ -770,9 +771,15 @@ struct IllegalSelfTypeVisitor<'tcx> {
}
impl
<
'tcx
>
TypeVisitor
<
'tcx
>
for
IllegalSelfTypeVisitor
<
'tcx
>
{
fn
visit_ty
(
&
mut
self
,
t
:
Ty
<
'tcx
>
)
->
bool
{
fn
visit_ty
(
&
mut
self
,
t
:
Ty
<
'tcx
>
)
->
ControlFlow
<
(),
()
>
{
match
t
.kind
()
{
ty
::
Param
(
_
)
=>
t
==
self
.tcx.types.self_param
,
ty
::
Param
(
_
)
=>
{
if
t
==
self
.tcx.types.self_param
{
ControlFlow
::
BREAK
}
else
{
ControlFlow
::
CONTINUE
}
}
ty
::
Projection
(
ref
data
)
=>
{
// This is a projected type `<Foo as SomeTrait>::X`.
...
...
@@ -796,7 +803,7 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
self
.supertraits
.as_ref
()
.unwrap
()
.contains
(
&
projection_trait_ref
);
if
is_supertrait_of_current_trait
{
false
// do not walk contained types, do not report error, do collect $200
ControlFlow
::
CONTINUE
// do not walk contained types, do not report error, do collect $200
}
else
{
t
.super_visit_with
(
self
)
// DO walk contained types, POSSIBLY reporting an error
}
...
...
@@ -805,11 +812,9 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
}
}
fn
visit_const
(
&
mut
self
,
ct
:
&
ty
::
Const
<
'tcx
>
)
->
bool
{
fn
visit_const
(
&
mut
self
,
ct
:
&
ty
::
Const
<
'tcx
>
)
->
ControlFlow
<
(),
()
>
{
// First check if the type of this constant references `Self`.
if
self
.visit_ty
(
ct
.ty
)
{
return
true
;
}
self
.visit_ty
(
ct
.ty
)
?
;
// Constants can only influence object safety if they reference `Self`.
// This is only possible for unevaluated constants, so we walk these here.
...
...
@@ -830,14 +835,16 @@ fn visit_const(&mut self, ct: &ty::Const<'tcx>) -> bool {
let
leaf
=
leaf
.subst
(
self
.tcx
,
ct
.substs
);
self
.visit_const
(
leaf
)
}
Node
::
Binop
(
..
)
|
Node
::
UnaryOp
(
..
)
|
Node
::
FunctionCall
(
_
,
_
)
=>
false
,
Node
::
Binop
(
..
)
|
Node
::
UnaryOp
(
..
)
|
Node
::
FunctionCall
(
_
,
_
)
=>
{
ControlFlow
::
CONTINUE
}
})
}
else
{
false
ControlFlow
::
CONTINUE
}
}
fn
visit_predicate
(
&
mut
self
,
pred
:
ty
::
Predicate
<
'tcx
>
)
->
bool
{
fn
visit_predicate
(
&
mut
self
,
pred
:
ty
::
Predicate
<
'tcx
>
)
->
ControlFlow
<
(),
()
>
{
if
let
ty
::
PredicateAtom
::
ConstEvaluatable
(
def
,
substs
)
=
pred
.skip_binders
()
{
// FIXME(const_evaluatable_checked): We should probably deduplicate the logic for
// `AbstractConst`s here, it might make sense to change `ConstEvaluatable` to
...
...
@@ -849,10 +856,12 @@ fn visit_predicate(&mut self, pred: ty::Predicate<'tcx>) -> bool {
let
leaf
=
leaf
.subst
(
self
.tcx
,
ct
.substs
);
self
.visit_const
(
leaf
)
}
Node
::
Binop
(
..
)
|
Node
::
UnaryOp
(
..
)
|
Node
::
FunctionCall
(
_
,
_
)
=>
false
,
Node
::
Binop
(
..
)
|
Node
::
UnaryOp
(
..
)
|
Node
::
FunctionCall
(
_
,
_
)
=>
{
ControlFlow
::
CONTINUE
}
})
}
else
{
false
ControlFlow
::
CONTINUE
}
}
else
{
pred
.super_visit_with
(
self
)
...
...
@@ -861,6 +870,7 @@ fn visit_predicate(&mut self, pred: ty::Predicate<'tcx>) -> bool {
}
value
.visit_with
(
&
mut
IllegalSelfTypeVisitor
{
tcx
,
trait_def_id
,
supertraits
:
None
})
==
ControlFlow
::
BREAK
}
pub
fn
provide
(
providers
:
&
mut
ty
::
query
::
Providers
)
{
...
...
compiler/rustc_trait_selection/src/traits/structural_match.rs
浏览文件 @
4fe735b3
...
...
@@ -8,6 +8,7 @@
use
rustc_middle
::
ty
::
query
::
Providers
;
use
rustc_middle
::
ty
::{
self
,
AdtDef
,
Ty
,
TyCtxt
,
TypeFoldable
,
TypeVisitor
};
use
rustc_span
::
Span
;
use
std
::
ops
::
ControlFlow
;
#[derive(Debug)]
pub
enum
NonStructuralMatchTy
<
'tcx
>
{
...
...
@@ -134,38 +135,38 @@ fn type_marked_structural(&self, adt_ty: Ty<'tcx>) -> bool {
}
impl
<
'a
,
'tcx
>
TypeVisitor
<
'tcx
>
for
Search
<
'a
,
'tcx
>
{
fn
visit_ty
(
&
mut
self
,
ty
:
Ty
<
'tcx
>
)
->
bool
{
fn
visit_ty
(
&
mut
self
,
ty
:
Ty
<
'tcx
>
)
->
ControlFlow
<
(),
()
>
{
debug!
(
"Search visiting ty: {:?}"
,
ty
);
let
(
adt_def
,
substs
)
=
match
*
ty
.kind
()
{
ty
::
Adt
(
adt_def
,
substs
)
=>
(
adt_def
,
substs
),
ty
::
Param
(
_
)
=>
{
self
.found
=
Some
(
NonStructuralMatchTy
::
Param
);
return
true
;
// Stop visiting.
return
ControlFlow
::
BREAK
;
}
ty
::
Dynamic
(
..
)
=>
{
self
.found
=
Some
(
NonStructuralMatchTy
::
Dynamic
);
return
true
;
// Stop visiting.
return
ControlFlow
::
BREAK
;
}
ty
::
Foreign
(
_
)
=>
{
self
.found
=
Some
(
NonStructuralMatchTy
::
Foreign
);
return
true
;
// Stop visiting.
return
ControlFlow
::
BREAK
;
}
ty
::
Opaque
(
..
)
=>
{
self
.found
=
Some
(
NonStructuralMatchTy
::
Opaque
);
return
true
;
// Stop visiting.
return
ControlFlow
::
BREAK
;
}
ty
::
Projection
(
..
)
=>
{
self
.found
=
Some
(
NonStructuralMatchTy
::
Projection
);
return
true
;
// Stop visiting.
return
ControlFlow
::
BREAK
;
}
ty
::
Generator
(
..
)
|
ty
::
GeneratorWitness
(
..
)
=>
{
self
.found
=
Some
(
NonStructuralMatchTy
::
Generator
);
return
true
;
// Stop visiting.
return
ControlFlow
::
BREAK
;
}
ty
::
Closure
(
..
)
=>
{
self
.found
=
Some
(
NonStructuralMatchTy
::
Closure
);
return
true
;
// Stop visiting.
return
ControlFlow
::
BREAK
;
}
ty
::
RawPtr
(
..
)
=>
{
// structural-match ignores substructure of
...
...
@@ -182,39 +183,31 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
// Even though `NonStructural` does not implement `PartialEq`,
// structural equality on `T` does not recur into the raw
// pointer. Therefore, one can still use `C` in a pattern.
// (But still tell the caller to continue search.)
return
false
;
return
ControlFlow
::
CONTINUE
;
}
ty
::
FnDef
(
..
)
|
ty
::
FnPtr
(
..
)
=>
{
// Types of formals and return in `fn(_) -> _` are also irrelevant;
// so we do not recur into them via `super_visit_with`
//
// (But still tell the caller to continue search.)
return
false
;
return
ControlFlow
::
CONTINUE
;
}
ty
::
Array
(
_
,
n
)
if
{
n
.try_eval_usize
(
self
.tcx
(),
ty
::
ParamEnv
::
reveal_all
())
==
Some
(
0
)
}
=>
{
// rust-lang/rust#62336: ignore type of contents
// for empty array.
//
// (But still tell the caller to continue search.)
return
false
;
return
ControlFlow
::
CONTINUE
;
}
ty
::
Bool
|
ty
::
Char
|
ty
::
Int
(
_
)
|
ty
::
Uint
(
_
)
|
ty
::
Float
(
_
)
|
ty
::
Str
|
ty
::
Never
=>
{
// These primitive types are always structural match.
//
// `Never` is kind of special here, but as it is not inhabitable, this should be fine.
//
// (But still tell the caller to continue search.)
return
false
;
return
ControlFlow
::
CONTINUE
;
}
ty
::
Array
(
..
)
|
ty
::
Slice
(
_
)
|
ty
::
Ref
(
..
)
|
ty
::
Tuple
(
..
)
=>
{
// First check all contained types and then tell the caller to continue searching.
ty
.super_visit_with
(
self
);
return
false
;
return
ControlFlow
::
CONTINUE
;
}
ty
::
Infer
(
_
)
|
ty
::
Placeholder
(
_
)
|
ty
::
Bound
(
..
)
=>
{
bug!
(
"unexpected type during structural-match checking: {:?}"
,
ty
);
...
...
@@ -223,22 +216,19 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
self
.tcx
()
.sess
.delay_span_bug
(
self
.span
,
"ty::Error in structural-match check"
);
// We still want to check other types after encountering an error,
// as this may still emit relevant errors.
//
// So we continue searching here.
return
false
;
return
ControlFlow
::
CONTINUE
;
}
};
if
!
self
.seen
.insert
(
adt_def
.did
)
{
debug!
(
"Search already seen adt_def: {:?}"
,
adt_def
);
// Let caller continue its search.
return
false
;
return
ControlFlow
::
CONTINUE
;
}
if
!
self
.type_marked_structural
(
ty
)
{
debug!
(
"Search found ty: {:?}"
,
ty
);
self
.found
=
Some
(
NonStructuralMatchTy
::
Adt
(
&
adt_def
));
return
true
;
// Halt visiting!
return
ControlFlow
::
BREAK
;
}
// structural-match does not care about the
...
...
@@ -258,16 +248,16 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
let
ty
=
self
.tcx
()
.normalize_erasing_regions
(
ty
::
ParamEnv
::
empty
(),
field_ty
);
debug!
(
"structural-match ADT: field_ty={:?}, ty={:?}"
,
field_ty
,
ty
);
if
ty
.visit_with
(
self
)
{
if
ty
.visit_with
(
self
)
==
ControlFlow
::
BREAK
{
// found an ADT without structural-match; halt visiting!
assert
!
(
self
.found
.is_some
());
return
true
;
return
ControlFlow
::
BREAK
;
}
}
// Even though we do not want to recur on substs, we do
// want our caller to continue its own search.
false
ControlFlow
::
CONTINUE
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录