Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
9a33b591
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,发现更多精彩内容 >>
提交
9a33b591
编写于
6月 13, 2020
作者:
B
Bastian Kauschke
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
minimal
上级
104cb878
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
44 addition
and
78 deletion
+44
-78
src/librustc_middle/ty/context.rs
src/librustc_middle/ty/context.rs
+3
-9
src/librustc_middle/ty/mod.rs
src/librustc_middle/ty/mod.rs
+2
-0
src/librustc_trait_selection/traits/fulfill.rs
src/librustc_trait_selection/traits/fulfill.rs
+39
-69
未找到文件。
src/librustc_middle/ty/context.rs
浏览文件 @
9a33b591
...
...
@@ -19,9 +19,9 @@
use
crate
::
ty
::{
self
,
query
,
AdtDef
,
AdtKind
,
BindingMode
,
BoundVar
,
CanonicalPolyFnSig
,
Const
,
ConstVid
,
DefIdTree
,
ExistentialPredicate
,
FloatVar
,
FloatVid
,
GenericParamDefKind
,
InferConst
,
InferTy
,
IntVar
,
IntVid
,
List
,
ParamConst
,
ParamTy
,
PolyFnSig
,
Predicate
,
PredicateInner
,
PredicateKin
t
,
Pr
ojectionTy
,
Region
,
RegionKind
,
ReprOptions
,
TraitObjectVisitor
,
Ty
,
TyKind
,
TyS
,
TyVar
,
TyVid
,
TypeAndMut
,
IntVar
,
IntVid
,
List
,
ParamConst
,
ParamTy
,
PolyFnSig
,
Predicate
,
PredicateInner
,
PredicateKin
d
,
Pr
edicateKint
,
ProjectionTy
,
Region
,
RegionKind
,
ReprOptions
,
TraitObjectVisitor
,
Ty
,
TyKind
,
Ty
S
,
TyVar
,
Ty
Vid
,
TypeAndMut
,
};
use
rustc_ast
::
ast
;
use
rustc_ast
::
expand
::
allocator
::
AllocatorKind
;
...
...
@@ -2030,12 +2030,6 @@ fn borrow<'a>(&'a self) -> &'a Const<'tcx> {
}
}
impl
<
'tcx
>
Borrow
<
PredicateKind
<
'tcx
>>
for
Interned
<
'tcx
,
PredicateKind
<
'tcx
>>
{
fn
borrow
<
'a
>
(
&
'a
self
)
->
&
'a
PredicateKind
<
'tcx
>
{
&
self
.0
}
}
impl
<
'tcx
>
Borrow
<
PredicateKint
<
'tcx
>>
for
Interned
<
'tcx
,
PredicateKint
<
'tcx
>>
{
fn
borrow
<
'a
>
(
&
'a
self
)
->
&
'a
PredicateKint
<
'tcx
>
{
&
self
.0
...
...
src/librustc_middle/ty/mod.rs
浏览文件 @
9a33b591
...
...
@@ -1063,7 +1063,9 @@ fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHas
kind
.hash_stable
(
hcx
,
hasher
);
}
}
impl
<
'tcx
>
Predicate
<
'tcx
>
{
pub
fn
kint
(
self
,
tcx
:
TyCtxt
<
'tcx
>
)
->
&
'tcx
PredicateKint
<
'tcx
>
{
// I am efficient
tcx
.intern_predicate_kint
(
match
*
self
.kind
()
{
...
...
src/librustc_trait_selection/traits/fulfill.rs
浏览文件 @
9a33b591
...
...
@@ -6,7 +6,7 @@
use
rustc_infer
::
traits
::{
TraitEngine
,
TraitEngineExt
as
_
};
use
rustc_middle
::
mir
::
interpret
::
ErrorHandled
;
use
rustc_middle
::
ty
::
error
::
ExpectedFound
;
use
rustc_middle
::
ty
::{
self
,
Const
,
ToPolyTraitRef
,
Ty
,
TypeFoldable
};
use
rustc_middle
::
ty
::{
self
,
Binder
,
Const
,
ToPredicate
,
Ty
,
TypeFoldable
};
use
std
::
marker
::
PhantomData
;
use
super
::
project
;
...
...
@@ -317,9 +317,15 @@ fn process_obligation(
let
infcx
=
self
.selcx
.infcx
();
match
obligation
.predicate
.kind
()
{
ty
::
PredicateKind
::
Trait
(
ref
data
,
_
)
=>
{
let
trait_obligation
=
obligation
.with
(
*
data
);
match
obligation
.predicate
.kint
(
infcx
.tcx
)
{
ty
::
PredicateKint
::
ForAll
(
binder
)
=>
{
let
(
pred
,
_
)
=
infcx
.replace_bound_vars_with_placeholders
(
binder
);
ProcessResult
::
Changed
(
mk_pending
(
vec!
[
obligation
.with
(
pred
.to_predicate
(
infcx
.tcx
)),
]))
}
ty
::
PredicateKint
::
Trait
(
ref
data
,
_
)
=>
{
let
trait_obligation
=
obligation
.with
(
Binder
::
dummy
(
*
data
));
if
obligation
.predicate
.is_global
()
{
// no type variables present, can use evaluation for better caching.
...
...
@@ -352,7 +358,7 @@ fn process_obligation(
// trait selection is because we don't have enough
// information about the types in the trait.
pending_obligation
.stalled_on
=
trait_ref_infer_vars
(
self
.selcx
,
data
.t
o_poly_trait_ref
()
);
trait_ref_infer_vars
(
self
.selcx
,
data
.t
rait_ref
);
debug!
(
"process_predicate: pending obligation {:?} now stalled on {:?}"
,
...
...
@@ -373,64 +379,32 @@ fn process_obligation(
}
}
&
ty
::
PredicateKin
d
::
RegionOutlives
(
binder
)
=>
{
match
infcx
.region_outlives_predicate
(
&
obligation
.cause
,
binder
)
{
&
ty
::
PredicateKin
t
::
RegionOutlives
(
data
)
=>
{
match
infcx
.region_outlives_predicate
(
&
obligation
.cause
,
Binder
::
dummy
(
data
)
)
{
Ok
(())
=>
ProcessResult
::
Changed
(
vec!
[]),
Err
(
_
)
=>
ProcessResult
::
Error
(
CodeSelectionError
(
Unimplemented
)),
}
}
ty
::
PredicateKind
::
TypeOutlives
(
ref
binder
)
=>
{
// Check if there are higher-ranked vars.
match
binder
.no_bound_vars
()
{
// If there are, inspect the underlying type further.
None
=>
{
// Convert from `Binder<OutlivesPredicate<Ty, Region>>` to `Binder<Ty>`.
let
binder
=
binder
.map_bound_ref
(|
pred
|
pred
.0
);
// Check if the type has any bound vars.
match
binder
.no_bound_vars
()
{
// If so, this obligation is an error (for now). Eventually we should be
// able to support additional cases here, like `for<'a> &'a str: 'a`.
// NOTE: this is duplicate-implemented between here and fulfillment.
None
=>
ProcessResult
::
Error
(
CodeSelectionError
(
Unimplemented
)),
// Otherwise, we have something of the form
// `for<'a> T: 'a where 'a not in T`, which we can treat as
// `T: 'static`.
Some
(
t_a
)
=>
{
let
r_static
=
self
.selcx
.tcx
()
.lifetimes.re_static
;
if
self
.register_region_obligations
{
self
.selcx
.infcx
()
.register_region_obligation_with_cause
(
t_a
,
r_static
,
&
obligation
.cause
,
);
}
ProcessResult
::
Changed
(
vec!
[])
}
}
}
// If there aren't, register the obligation.
Some
(
ty
::
OutlivesPredicate
(
t_a
,
r_b
))
=>
{
if
self
.register_region_obligations
{
self
.selcx
.infcx
()
.register_region_obligation_with_cause
(
t_a
,
r_b
,
&
obligation
.cause
,
);
}
ProcessResult
::
Changed
(
vec!
[])
}
ty
::
PredicateKint
::
TypeOutlives
(
ty
::
OutlivesPredicate
(
t_a
,
r_b
))
=>
{
if
self
.register_region_obligations
{
self
.selcx
.infcx
()
.register_region_obligation_with_cause
(
t_a
,
r_b
,
&
obligation
.cause
,
);
}
ProcessResult
::
Changed
(
vec!
[])
}
ty
::
PredicateKin
d
::
Projection
(
ref
data
)
=>
{
let
project_obligation
=
obligation
.with
(
*
data
);
ty
::
PredicateKin
t
::
Projection
(
ref
data
)
=>
{
let
project_obligation
=
obligation
.with
(
Binder
::
dummy
(
*
data
)
);
match
project
::
poly_project_and_unify_type
(
self
.selcx
,
&
project_obligation
)
{
Ok
(
None
)
=>
{
let
tcx
=
self
.selcx
.tcx
();
pending_obligation
.stalled_on
=
trait_ref_infer_vars
(
self
.selcx
,
data
.to_poly_trait_ref
(
tcx
));
pending_obligation
.stalled_on
=
trait_ref_infer_vars
(
self
.selcx
,
data
.projection_ty
.trait_ref
(
infcx
.tcx
),
);
ProcessResult
::
Unchanged
}
Ok
(
Some
(
os
))
=>
ProcessResult
::
Changed
(
mk_pending
(
os
)),
...
...
@@ -438,7 +412,7 @@ fn process_obligation(
}
}
&
ty
::
PredicateKin
d
::
ObjectSafe
(
trait_def_id
)
=>
{
&
ty
::
PredicateKin
t
::
ObjectSafe
(
trait_def_id
)
=>
{
if
!
self
.selcx
.tcx
()
.is_object_safe
(
trait_def_id
)
{
ProcessResult
::
Error
(
CodeSelectionError
(
Unimplemented
))
}
else
{
...
...
@@ -446,7 +420,7 @@ fn process_obligation(
}
}
&
ty
::
PredicateKin
d
::
ClosureKind
(
_
,
closure_substs
,
kind
)
=>
{
&
ty
::
PredicateKin
t
::
ClosureKind
(
_
,
closure_substs
,
kind
)
=>
{
match
self
.selcx
.infcx
()
.closure_kind
(
closure_substs
)
{
Some
(
closure_kind
)
=>
{
if
closure_kind
.extends
(
kind
)
{
...
...
@@ -459,7 +433,7 @@ fn process_obligation(
}
}
&
ty
::
PredicateKin
d
::
WellFormed
(
arg
)
=>
{
&
ty
::
PredicateKin
t
::
WellFormed
(
arg
)
=>
{
match
wf
::
obligations
(
self
.selcx
.infcx
(),
obligation
.param_env
,
...
...
@@ -476,27 +450,24 @@ fn process_obligation(
}
}
&
ty
::
PredicateKin
d
::
Subtype
(
subtype
)
=>
{
&
ty
::
PredicateKin
t
::
Subtype
(
subtype
)
=>
{
match
self
.selcx
.infcx
()
.subtype_predicate
(
&
obligation
.cause
,
obligation
.param_env
,
subtype
,
Binder
::
dummy
(
subtype
)
,
)
{
None
=>
{
// None means that both are unresolved.
pending_obligation
.stalled_on
=
vec!
[
TyOrConstInferVar
::
maybe_from_ty
(
subtype
.
skip_binder
()
.
a
)
.unwrap
(),
TyOrConstInferVar
::
maybe_from_ty
(
subtype
.
skip_binder
()
.
b
)
.unwrap
(),
TyOrConstInferVar
::
maybe_from_ty
(
subtype
.a
)
.unwrap
(),
TyOrConstInferVar
::
maybe_from_ty
(
subtype
.b
)
.unwrap
(),
];
ProcessResult
::
Unchanged
}
Some
(
Ok
(
ok
))
=>
ProcessResult
::
Changed
(
mk_pending
(
ok
.obligations
)),
Some
(
Err
(
err
))
=>
{
let
expected_found
=
ExpectedFound
::
new
(
subtype
.skip_binder
()
.a_is_expected
,
subtype
.skip_binder
()
.a
,
subtype
.skip_binder
()
.b
,
);
let
expected_found
=
ExpectedFound
::
new
(
subtype
.a_is_expected
,
subtype
.a
,
subtype
.b
);
ProcessResult
::
Error
(
FulfillmentErrorCode
::
CodeSubtypeError
(
expected_found
,
err
,
...
...
@@ -505,7 +476,7 @@ fn process_obligation(
}
}
&
ty
::
PredicateKin
d
::
ConstEvaluatable
(
def_id
,
substs
)
=>
{
&
ty
::
PredicateKin
t
::
ConstEvaluatable
(
def_id
,
substs
)
=>
{
match
self
.selcx
.infcx
()
.const_eval_resolve
(
obligation
.param_env
,
def_id
,
...
...
@@ -518,7 +489,7 @@ fn process_obligation(
}
}
ty
::
PredicateKin
d
::
ConstEquate
(
c1
,
c2
)
=>
{
ty
::
PredicateKin
t
::
ConstEquate
(
c1
,
c2
)
=>
{
debug!
(
"equating consts: c1={:?} c2={:?}"
,
c1
,
c2
);
let
stalled_on
=
&
mut
pending_obligation
.stalled_on
;
...
...
@@ -601,12 +572,11 @@ fn process_backedge<'c, I>(
/// Returns the set of inference variables contained in a trait ref.
fn
trait_ref_infer_vars
<
'a
,
'tcx
>
(
selcx
:
&
mut
SelectionContext
<
'a
,
'tcx
>
,
trait_ref
:
ty
::
Poly
TraitRef
<
'tcx
>
,
trait_ref
:
ty
::
TraitRef
<
'tcx
>
,
)
->
Vec
<
TyOrConstInferVar
<
'tcx
>>
{
selcx
.infcx
()
.resolve_vars_if_possible
(
&
trait_ref
)
.skip_binder
()
// ok b/c this check doesn't care about regions
.substs
.iter
()
// FIXME(eddyb) try using `skip_current_subtree` to skip everything that
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录