Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
4b25f085
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,发现更多精彩内容 >>
提交
4b25f085
编写于
8月 04, 2016
作者:
E
Eduard Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc: move trait objects from TraitRef to ExistentialTraitRef.
上级
5ef6af09
变更
39
展开全部
隐藏空白更改
内联
并排
Showing
39 changed file
with
682 addition
and
792 deletion
+682
-792
src/librustc/infer/mod.rs
src/librustc/infer/mod.rs
+2
-6
src/librustc/traits/coherence.rs
src/librustc/traits/coherence.rs
+2
-2
src/librustc/traits/project.rs
src/librustc/traits/project.rs
+3
-4
src/librustc/traits/select.rs
src/librustc/traits/select.rs
+23
-26
src/librustc/ty/context.rs
src/librustc/ty/context.rs
+5
-20
src/librustc/ty/error.rs
src/librustc/ty/error.rs
+1
-1
src/librustc/ty/fast_reject.rs
src/librustc/ty/fast_reject.rs
+1
-1
src/librustc/ty/flags.rs
src/librustc/ty/flags.rs
+8
-13
src/librustc/ty/fold.rs
src/librustc/ty/fold.rs
+0
-9
src/librustc/ty/item_path.rs
src/librustc/ty/item_path.rs
+1
-1
src/librustc/ty/mod.rs
src/librustc/ty/mod.rs
+4
-2
src/librustc/ty/relate.rs
src/librustc/ty/relate.rs
+53
-36
src/librustc/ty/structural_impls.rs
src/librustc/ty/structural_impls.rs
+61
-29
src/librustc/ty/sty.rs
src/librustc/ty/sty.rs
+105
-75
src/librustc/ty/util.rs
src/librustc/ty/util.rs
+5
-5
src/librustc/ty/walk.rs
src/librustc/ty/walk.rs
+3
-3
src/librustc/ty/wf.rs
src/librustc/ty/wf.rs
+9
-14
src/librustc/util/ppaux.rs
src/librustc/util/ppaux.rs
+55
-49
src/librustc_metadata/astencode.rs
src/librustc_metadata/astencode.rs
+0
-49
src/librustc_metadata/tydecode.rs
src/librustc_metadata/tydecode.rs
+37
-24
src/librustc_metadata/tyencode.rs
src/librustc_metadata/tyencode.rs
+34
-33
src/librustc_trans/base.rs
src/librustc_trans/base.rs
+3
-8
src/librustc_trans/collector.rs
src/librustc_trans/collector.rs
+1
-2
src/librustc_trans/debuginfo/metadata.rs
src/librustc_trans/debuginfo/metadata.rs
+1
-1
src/librustc_trans/trans_item.rs
src/librustc_trans/trans_item.rs
+4
-4
src/librustc_typeck/astconv.rs
src/librustc_typeck/astconv.rs
+187
-276
src/librustc_typeck/check/cast.rs
src/librustc_typeck/check/cast.rs
+1
-1
src/librustc_typeck/check/closure.rs
src/librustc_typeck/check/closure.rs
+5
-6
src/librustc_typeck/check/method/confirm.rs
src/librustc_typeck/check/method/confirm.rs
+11
-9
src/librustc_typeck/check/method/mod.rs
src/librustc_typeck/check/method/mod.rs
+1
-3
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/method/probe.rs
+15
-22
src/librustc_typeck/check/method/suggest.rs
src/librustc_typeck/check/method/suggest.rs
+1
-1
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/regionck.rs
+2
-2
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/coherence/mod.rs
+1
-1
src/librustc_typeck/coherence/orphan.rs
src/librustc_typeck/coherence/orphan.rs
+1
-1
src/librustc_typeck/coherence/overlap.rs
src/librustc_typeck/coherence/overlap.rs
+2
-2
src/librustc_typeck/collect.rs
src/librustc_typeck/collect.rs
+13
-21
src/librustc_typeck/variance/constraints.rs
src/librustc_typeck/variance/constraints.rs
+3
-6
src/librustdoc/clean/mod.rs
src/librustdoc/clean/mod.rs
+18
-24
未找到文件。
src/librustc/infer/mod.rs
浏览文件 @
4b25f085
...
...
@@ -1248,9 +1248,7 @@ pub fn fresh_substs_for_generics(&self,
generics
:
&
ty
::
Generics
<
'tcx
>
)
->
&
'tcx
subst
::
Substs
<
'tcx
>
{
let
type_defs
=
generics
.types
.as_full_slice
();
let
region_defs
=
generics
.regions
.as_full_slice
();
let
substs
=
Substs
::
from_param_defs
(
region_defs
,
type_defs
,
|
def
|
{
let
substs
=
Substs
::
from_generics
(
generics
,
|
def
,
_
|
{
self
.region_var_for_def
(
span
,
def
)
},
|
def
,
substs
|
{
self
.type_var_for_def
(
span
,
def
,
substs
)
...
...
@@ -1271,9 +1269,7 @@ pub fn fresh_substs_for_trait(&self,
assert
!
(
generics
.types
.len
(
subst
::
SelfSpace
)
==
1
);
assert
!
(
generics
.types
.len
(
subst
::
FnSpace
)
==
0
);
let
type_defs
=
generics
.types
.as_full_slice
();
let
region_defs
=
generics
.regions
.as_full_slice
();
let
substs
=
Substs
::
from_param_defs
(
region_defs
,
type_defs
,
|
def
|
{
let
substs
=
Substs
::
from_generics
(
generics
,
|
def
,
_
|
{
self
.region_var_for_def
(
span
,
def
)
},
|
def
,
substs
|
{
if
def
.space
==
subst
::
SelfSpace
{
...
...
src/librustc/traits/coherence.rs
浏览文件 @
4b25f085
...
...
@@ -231,7 +231,7 @@ fn fundamental_ty(tcx: TyCtxt, ty: Ty) -> bool {
ty
::
TyEnum
(
def
,
_
)
|
ty
::
TyStruct
(
def
,
_
)
=>
def
.is_fundamental
(),
ty
::
TyTrait
(
ref
data
)
=>
tcx
.has_attr
(
data
.principal
_
def_id
(),
"fundamental"
),
tcx
.has_attr
(
data
.principal
.
def_id
(),
"fundamental"
),
_
=>
false
}
...
...
@@ -275,7 +275,7 @@ fn ty_is_local_constructor(tcx: TyCtxt, ty: Ty, infer_is_local: InferIsLocal)->
}
ty
::
TyTrait
(
ref
tt
)
=>
{
tt
.principal
_
def_id
()
.is_local
()
tt
.principal
.
def_id
()
.is_local
()
}
ty
::
TyError
=>
{
...
...
src/librustc/traits/project.rs
浏览文件 @
4b25f085
...
...
@@ -1133,10 +1133,9 @@ fn confirm_object_candidate<'cx, 'gcx, 'tcx>(
object_ty
)
}
};
let
projection_bounds
=
data
.projection_bounds_with_self_ty
(
selcx
.tcx
(),
object_ty
);
let
env_predicates
=
projection_bounds
.iter
()
.map
(|
p
|
p
.to_predicate
())
.collect
();
let
env_predicates
=
data
.projection_bounds
.iter
()
.map
(|
p
|
{
p
.with_self_ty
(
selcx
.tcx
(),
object_ty
)
.to_predicate
()
})
.collect
();
let
env_predicate
=
{
let
env_predicates
=
elaborate_predicates
(
selcx
.tcx
(),
env_predicates
);
...
...
src/librustc/traits/select.rs
浏览文件 @
4b25f085
...
...
@@ -1528,7 +1528,7 @@ fn assemble_candidates_from_object_ty(&mut self,
ty
::
TyTrait
(
ref
data
)
=>
{
match
this
.tcx
()
.lang_items
.to_builtin_kind
(
obligation
.predicate
.def_id
())
{
Some
(
bound
@
ty
::
BoundSend
)
|
Some
(
bound
@
ty
::
BoundSync
)
=>
{
if
data
.b
ounds.b
uiltin_bounds
.contains
(
&
bound
)
{
if
data
.builtin_bounds
.contains
(
&
bound
)
{
debug!
(
"assemble_candidates_from_object_ty: matched builtin bound,
\
pushing candidate"
);
candidates
.vec
.push
(
BuiltinObjectCandidate
);
...
...
@@ -1538,7 +1538,7 @@ fn assemble_candidates_from_object_ty(&mut self,
_
=>
{}
}
data
.principal
_trait_ref_
with_self_ty
(
this
.tcx
(),
self_ty
)
data
.principal
.
with_self_ty
(
this
.tcx
(),
self_ty
)
}
ty
::
TyInfer
(
ty
::
TyVar
(
_
))
=>
{
debug!
(
"assemble_candidates_from_object_ty: ambiguous"
);
...
...
@@ -1622,7 +1622,7 @@ fn assemble_candidates_for_unsizing(&mut self,
// We always upcast when we can because of reason
// #2 (region bounds).
data_a
.principal
.def_id
()
==
data_a
.principal
.def_id
()
&&
data_a
.b
ounds.builtin_bounds
.is_superset
(
&
data_b
.bounds
.builtin_bounds
)
data_a
.b
uiltin_bounds
.is_superset
(
&
data_b
.builtin_bounds
)
}
// T -> Trait.
...
...
@@ -2179,10 +2179,9 @@ fn confirm_default_impl_object_candidate(&mut self,
match
self_ty
.sty
{
ty
::
TyTrait
(
ref
data
)
=>
{
// OK to skip the binder, it is reintroduced below
let
input_types
=
data
.principal
.skip_binder
()
.substs.types
.get_slice
(
TypeSpace
);
let
assoc_types
=
data
.bounds.projection_bounds
.iter
()
.map
(|
pb
|
pb
.skip_binder
()
.ty
);
let
input_types
=
data
.principal
.skip_binder
()
.input_types
();
let
assoc_types
=
data
.projection_bounds
.iter
()
.map
(|
pb
|
pb
.skip_binder
()
.ty
);
let
all_types
:
Vec
<
_
>
=
input_types
.iter
()
.cloned
()
.chain
(
assoc_types
)
.collect
();
...
...
@@ -2315,7 +2314,7 @@ fn confirm_object_candidate(&mut self,
let
self_ty
=
self
.infcx
.shallow_resolve
(
*
obligation
.self_ty
()
.skip_binder
());
let
poly_trait_ref
=
match
self_ty
.sty
{
ty
::
TyTrait
(
ref
data
)
=>
{
data
.principal
_trait_ref_
with_self_ty
(
self
.tcx
(),
self_ty
)
data
.principal
.
with_self_ty
(
self
.tcx
(),
self_ty
)
}
_
=>
{
span_bug!
(
obligation
.cause.span
,
...
...
@@ -2487,13 +2486,12 @@ fn confirm_builtin_unsize_candidate(&mut self,
// Trait+Kx+'a -> Trait+Ky+'b (upcasts).
(
&
ty
::
TyTrait
(
ref
data_a
),
&
ty
::
TyTrait
(
ref
data_b
))
=>
{
// See assemble_candidates_for_unsizing for more info.
let
bounds
=
ty
::
ExistentialBounds
{
region_bound
:
data_b
.bounds.region_bound
,
builtin_bounds
:
data_b
.bounds.builtin_bounds
,
projection_bounds
:
data_a
.bounds.projection_bounds
.clone
(),
};
let
new_trait
=
tcx
.mk_trait
(
data_a
.principal
.clone
(),
bounds
);
let
new_trait
=
tcx
.mk_trait
(
ty
::
TraitObject
{
principal
:
data_a
.principal
,
region_bound
:
data_b
.region_bound
,
builtin_bounds
:
data_b
.builtin_bounds
,
projection_bounds
:
data_a
.projection_bounds
.clone
(),
});
let
origin
=
TypeOrigin
::
Misc
(
obligation
.cause.span
);
let
InferOk
{
obligations
,
..
}
=
self
.infcx
.sub_types
(
false
,
origin
,
new_trait
,
target
)
...
...
@@ -2504,8 +2502,8 @@ fn confirm_builtin_unsize_candidate(&mut self,
let
cause
=
ObligationCause
::
new
(
obligation
.cause.span
,
obligation
.cause.body_id
,
ObjectCastObligation
(
target
));
let
outlives
=
ty
::
OutlivesPredicate
(
data_a
.
bounds.
region_bound
,
data_b
.
bounds.
region_bound
);
let
outlives
=
ty
::
OutlivesPredicate
(
data_a
.region_bound
,
data_b
.region_bound
);
nested
.push
(
Obligation
::
with_depth
(
cause
,
obligation
.recursion_depth
+
1
,
ty
::
Binder
(
outlives
)
.to_predicate
()));
...
...
@@ -2513,12 +2511,12 @@ fn confirm_builtin_unsize_candidate(&mut self,
// T -> Trait.
(
_
,
&
ty
::
TyTrait
(
ref
data
))
=>
{
let
mut
object_dids
=
Some
(
data
.principal
_
def_id
())
.into_iter
();
let
mut
object_dids
=
Some
(
data
.principal
.
def_id
())
.into_iter
();
// FIXME(#33243)
// data.b
ounds.b
uiltin_bounds.iter().flat_map(|bound| {
// data.builtin_bounds.iter().flat_map(|bound| {
// tcx.lang_items.from_builtin_kind(bound).ok()
// })
// .chain(Some(data.principal
_
def_id()));
// .chain(Some(data.principal
.
def_id()));
if
let
Some
(
did
)
=
object_dids
.find
(|
did
|
{
!
tcx
.is_object_safe
(
*
did
)
})
{
...
...
@@ -2535,10 +2533,10 @@ fn confirm_builtin_unsize_candidate(&mut self,
};
// Create the obligation for casting from T to Trait.
push
(
data
.principal
_trait_ref_
with_self_ty
(
tcx
,
source
)
.to_predicate
());
push
(
data
.principal
.
with_self_ty
(
tcx
,
source
)
.to_predicate
());
// We can only make objects from sized types.
let
mut
builtin_bounds
=
data
.b
ounds.b
uiltin_bounds
;
let
mut
builtin_bounds
=
data
.builtin_bounds
;
builtin_bounds
.insert
(
ty
::
BoundSized
);
// Create additional obligations for all the various builtin
...
...
@@ -2554,14 +2552,13 @@ fn confirm_builtin_unsize_candidate(&mut self,
}
// Create obligations for the projection predicates.
for
bound
in
data
.projection_bounds_with_self_ty
(
tcx
,
source
)
{
push
(
bound
.to_predicate
());
for
bound
in
&
data
.projection_bounds
{
push
(
bound
.
with_self_ty
(
tcx
,
source
)
.
to_predicate
());
}
// If the type is `Foo+'a`, ensures that the type
// being cast to `Foo+'a` outlives `'a`:
let
outlives
=
ty
::
OutlivesPredicate
(
source
,
data
.bounds.region_bound
);
let
outlives
=
ty
::
OutlivesPredicate
(
source
,
data
.region_bound
);
push
(
ty
::
Binder
(
outlives
)
.to_predicate
());
}
...
...
src/librustc/ty/context.rs
浏览文件 @
4b25f085
...
...
@@ -27,9 +27,9 @@
use
traits
;
use
ty
::{
self
,
TraitRef
,
Ty
,
TypeAndMut
};
use
ty
::{
TyS
,
TypeVariants
};
use
ty
::{
AdtDef
,
ClosureSubsts
,
ExistentialBounds
,
Region
};
use
ty
::{
AdtDef
,
ClosureSubsts
,
Region
};
use
hir
::
FreevarMap
;
use
ty
::{
BareFnTy
,
InferTy
,
ParamTy
,
ProjectionTy
,
Trait
Ty
};
use
ty
::{
BareFnTy
,
InferTy
,
ParamTy
,
ProjectionTy
,
Trait
Object
};
use
ty
::{
TyVar
,
TyVid
,
IntVar
,
IntVid
,
FloatVar
,
FloatVid
};
use
ty
::
TypeVariants
::
*
;
use
ty
::
layout
::{
Layout
,
TargetDataLayout
};
...
...
@@ -1150,12 +1150,6 @@ fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool {
region
:
mk_region
(
Region
,
keep_local
)
->
Region
);
fn
bound_list_is_sorted
(
bounds
:
&
[
ty
::
PolyProjectionPredicate
])
->
bool
{
bounds
.is_empty
()
||
bounds
[
1
..
]
.iter
()
.enumerate
()
.all
(
|(
index
,
bound
)|
bounds
[
index
]
.sort_key
()
<=
bound
.sort_key
())
}
impl
<
'a
,
'gcx
,
'tcx
>
TyCtxt
<
'a
,
'gcx
,
'tcx
>
{
/// Create an unsafe fn ty based on a safe fn ty.
pub
fn
safe_to_unsafe_fn_ty
(
self
,
bare_fn
:
&
BareFnTy
<
'tcx
>
)
->
Ty
<
'tcx
>
{
...
...
@@ -1288,18 +1282,9 @@ pub fn mk_fn_ptr(self, fty: &'tcx BareFnTy<'tcx>) -> Ty<'tcx> {
self
.mk_ty
(
TyFnPtr
(
fty
))
}
pub
fn
mk_trait
(
self
,
principal
:
ty
::
PolyTraitRef
<
'tcx
>
,
bounds
:
ExistentialBounds
<
'tcx
>
)
->
Ty
<
'tcx
>
{
assert
!
(
bound_list_is_sorted
(
&
bounds
.projection_bounds
));
let
inner
=
box
TraitTy
{
principal
:
principal
,
bounds
:
bounds
};
self
.mk_ty
(
TyTrait
(
inner
))
pub
fn
mk_trait
(
self
,
mut
obj
:
TraitObject
<
'tcx
>
)
->
Ty
<
'tcx
>
{
obj
.projection_bounds
.sort_by
(|
a
,
b
|
a
.sort_key
()
.cmp
(
&
b
.sort_key
()));
self
.mk_ty
(
TyTrait
(
box
obj
))
}
pub
fn
mk_projection
(
self
,
...
...
src/librustc/ty/error.rs
浏览文件 @
4b25f085
...
...
@@ -243,7 +243,7 @@ fn sort_string(&self, tcx: TyCtxt<'a, 'gcx, 'lcx>) -> String {
ty
::
TyFnDef
(
..
)
=>
format!
(
"fn item"
),
ty
::
TyFnPtr
(
_
)
=>
"fn pointer"
.to_string
(),
ty
::
TyTrait
(
ref
inner
)
=>
{
format!
(
"trait {}"
,
tcx
.item_path_str
(
inner
.principal
_
def_id
()))
format!
(
"trait {}"
,
tcx
.item_path_str
(
inner
.principal
.
def_id
()))
}
ty
::
TyStruct
(
def
,
_
)
=>
{
format!
(
"struct `{}`"
,
tcx
.item_path_str
(
def
.did
))
...
...
src/librustc/ty/fast_reject.rs
浏览文件 @
4b25f085
...
...
@@ -61,7 +61,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
ty
::
TyArray
(
..
)
|
ty
::
TySlice
(
_
)
=>
Some
(
VecSimplifiedType
),
ty
::
TyRawPtr
(
_
)
=>
Some
(
PtrSimplifiedType
),
ty
::
TyTrait
(
ref
trait_info
)
=>
{
Some
(
TraitSimplifiedType
(
trait_info
.principal
_
def_id
()))
Some
(
TraitSimplifiedType
(
trait_info
.principal
.
def_id
()))
}
ty
::
TyStruct
(
def
,
_
)
=>
{
Some
(
StructSimplifiedType
(
def
.did
))
...
...
src/librustc/ty/flags.rs
浏览文件 @
4b25f085
...
...
@@ -116,17 +116,16 @@ fn add_sty(&mut self, st: &ty::TypeVariants) {
self
.add_substs
(
substs
);
}
&
ty
::
TyTrait
(
box
ty
::
TraitTy
{
ref
principal
,
ref
bounds
}
)
=>
{
&
ty
::
TyTrait
(
ref
obj
)
=>
{
let
mut
computation
=
FlagComputation
::
new
();
computation
.add_substs
(
principal
.0
.substs
);
for
projection_bound
in
&
bounds
.projection_bounds
{
computation
.add_substs
(
obj
.principal
.skip_binder
()
.substs
);
for
projection_bound
in
&
obj
.projection_bounds
{
let
mut
proj_computation
=
FlagComputation
::
new
();
proj_computation
.add_
projection_predicate
(
&
projection_bound
.0
);
proj_computation
.add_
existential_projection
(
&
projection_bound
.0
);
self
.add_bound_computation
(
&
proj_computation
);
}
self
.add_bound_computation
(
&
computation
);
self
.add_bounds
(
bounds
);
self
.add_region
(
obj
.region_bound
);
}
&
ty
::
TyBox
(
tt
)
|
&
ty
::
TyArray
(
tt
,
_
)
|
&
ty
::
TySlice
(
tt
)
=>
{
...
...
@@ -199,9 +198,9 @@ fn add_region(&mut self, r: ty::Region) {
}
}
fn
add_
projection_predicate
(
&
mut
self
,
projection_predicate
:
&
ty
::
ProjectionPredicate
)
{
self
.add_
projection_ty
(
&
projection_predicate
.projection_ty
);
self
.add_ty
(
projection
_predicate
.ty
);
fn
add_
existential_projection
(
&
mut
self
,
projection
:
&
ty
::
ExistentialProjection
)
{
self
.add_
substs
(
projection
.trait_ref.substs
);
self
.add_ty
(
projection
.ty
);
}
fn
add_projection_ty
(
&
mut
self
,
projection_ty
:
&
ty
::
ProjectionTy
)
{
...
...
@@ -214,8 +213,4 @@ fn add_substs(&mut self, substs: &subst::Substs) {
self
.add_region
(
r
);
}
}
fn
add_bounds
(
&
mut
self
,
bounds
:
&
ty
::
ExistentialBounds
)
{
self
.add_region
(
bounds
.region_bound
);
}
}
src/librustc/ty/fold.rs
浏览文件 @
4b25f085
...
...
@@ -140,10 +140,6 @@ fn fold_mt(&mut self, t: &ty::TypeAndMut<'tcx>) -> ty::TypeAndMut<'tcx> {
t
.super_fold_with
(
self
)
}
fn
fold_trait_ref
(
&
mut
self
,
t
:
&
ty
::
TraitRef
<
'tcx
>
)
->
ty
::
TraitRef
<
'tcx
>
{
t
.super_fold_with
(
self
)
}
fn
fold_impl_header
(
&
mut
self
,
imp
:
&
ty
::
ImplHeader
<
'tcx
>
)
->
ty
::
ImplHeader
<
'tcx
>
{
imp
.super_fold_with
(
self
)
}
...
...
@@ -177,11 +173,6 @@ fn fold_region(&mut self, r: ty::Region) -> ty::Region {
r
.super_fold_with
(
self
)
}
fn
fold_existential_bounds
(
&
mut
self
,
s
:
&
ty
::
ExistentialBounds
<
'tcx
>
)
->
ty
::
ExistentialBounds
<
'tcx
>
{
s
.super_fold_with
(
self
)
}
fn
fold_autoref
(
&
mut
self
,
ar
:
&
adjustment
::
AutoRef
<
'tcx
>
)
->
adjustment
::
AutoRef
<
'tcx
>
{
ar
.super_fold_with
(
self
)
...
...
src/librustc/ty/item_path.rs
浏览文件 @
4b25f085
...
...
@@ -322,7 +322,7 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option<DefId> {
ty
::
TyStruct
(
adt_def
,
_
)
|
ty
::
TyEnum
(
adt_def
,
_
)
=>
Some
(
adt_def
.did
),
ty
::
TyTrait
(
ref
data
)
=>
Some
(
data
.principal
_
def_id
()),
ty
::
TyTrait
(
ref
data
)
=>
Some
(
data
.principal
.
def_id
()),
ty
::
TyArray
(
subty
,
_
)
|
ty
::
TySlice
(
subty
)
|
...
...
src/librustc/ty/mod.rs
浏览文件 @
4b25f085
...
...
@@ -54,11 +54,13 @@
use
hir
::
intravisit
::
Visitor
;
pub
use
self
::
sty
::{
Binder
,
DebruijnIndex
};
pub
use
self
::
sty
::{
BuiltinBound
,
BuiltinBounds
,
ExistentialBounds
};
pub
use
self
::
sty
::{
BuiltinBound
,
BuiltinBounds
};
pub
use
self
::
sty
::{
BareFnTy
,
FnSig
,
PolyFnSig
};
pub
use
self
::
sty
::{
ClosureTy
,
InferTy
,
ParamTy
,
ProjectionTy
,
Trait
Ty
};
pub
use
self
::
sty
::{
ClosureTy
,
InferTy
,
ParamTy
,
ProjectionTy
,
Trait
Object
};
pub
use
self
::
sty
::{
ClosureSubsts
,
TypeAndMut
};
pub
use
self
::
sty
::{
TraitRef
,
TypeVariants
,
PolyTraitRef
};
pub
use
self
::
sty
::{
ExistentialTraitRef
,
PolyExistentialTraitRef
};
pub
use
self
::
sty
::{
ExistentialProjection
,
PolyExistentialProjection
};
pub
use
self
::
sty
::{
BoundRegion
,
EarlyBoundRegion
,
FreeRegion
,
Region
};
pub
use
self
::
sty
::
Issue32330
;
pub
use
self
::
sty
::{
TyVid
,
IntVid
,
FloatVid
,
RegionVid
,
SkolemizedRegionVid
};
...
...
src/librustc/ty/relate.rs
浏览文件 @
4b25f085
...
...
@@ -326,24 +326,33 @@ fn relate<'a, 'gcx, R>(relation: &mut R,
}
}
impl
<
'tcx
>
Relate
<
'tcx
>
for
ty
::
ProjectionPredicate
<
'tcx
>
{
impl
<
'tcx
>
Relate
<
'tcx
>
for
ty
::
ExistentialProjection
<
'tcx
>
{
fn
relate
<
'a
,
'gcx
,
R
>
(
relation
:
&
mut
R
,
a
:
&
ty
::
ProjectionPredicate
<
'tcx
>
,
b
:
&
ty
::
ProjectionPredicate
<
'tcx
>
)
->
RelateResult
<
'tcx
,
ty
::
ProjectionPredicate
<
'tcx
>>
a
:
&
ty
::
ExistentialProjection
<
'tcx
>
,
b
:
&
ty
::
ExistentialProjection
<
'tcx
>
)
->
RelateResult
<
'tcx
,
ty
::
ExistentialProjection
<
'tcx
>>
where
R
:
TypeRelation
<
'a
,
'gcx
,
'tcx
>
,
'gcx
:
'a
+
'tcx
,
'tcx
:
'a
{
let
projection_ty
=
relation
.relate
(
&
a
.projection_ty
,
&
b
.projection_ty
)
?
;
let
ty
=
relation
.relate
(
&
a
.ty
,
&
b
.ty
)
?
;
Ok
(
ty
::
ProjectionPredicate
{
projection_ty
:
projection_ty
,
ty
:
ty
})
if
a
.item_name
!=
b
.item_name
{
Err
(
TypeError
::
ProjectionNameMismatched
(
expected_found
(
relation
,
&
a
.item_name
,
&
b
.item_name
)))
}
else
{
let
trait_ref
=
relation
.relate
(
&
a
.trait_ref
,
&
b
.trait_ref
)
?
;
let
ty
=
relation
.relate
(
&
a
.ty
,
&
b
.ty
)
?
;
Ok
(
ty
::
ExistentialProjection
{
trait_ref
:
trait_ref
,
item_name
:
a
.item_name
,
ty
:
ty
})
}
}
}
impl
<
'tcx
>
Relate
<
'tcx
>
for
Vec
<
ty
::
Poly
ProjectionPredicate
<
'tcx
>>
{
impl
<
'tcx
>
Relate
<
'tcx
>
for
Vec
<
ty
::
Poly
ExistentialProjection
<
'tcx
>>
{
fn
relate
<
'a
,
'gcx
,
R
>
(
relation
:
&
mut
R
,
a
:
&
Vec
<
ty
::
Poly
ProjectionPredicate
<
'tcx
>>
,
b
:
&
Vec
<
ty
::
Poly
ProjectionPredicate
<
'tcx
>>
)
->
RelateResult
<
'tcx
,
Vec
<
ty
::
Poly
ProjectionPredicate
<
'tcx
>>>
a
:
&
Vec
<
ty
::
Poly
ExistentialProjection
<
'tcx
>>
,
b
:
&
Vec
<
ty
::
Poly
ExistentialProjection
<
'tcx
>>
)
->
RelateResult
<
'tcx
,
Vec
<
ty
::
Poly
ExistentialProjection
<
'tcx
>>>
where
R
:
TypeRelation
<
'a
,
'gcx
,
'tcx
>
,
'gcx
:
'a
+
'tcx
,
'tcx
:
'a
{
// To be compatible, `a` and `b` must be for precisely the
...
...
@@ -361,27 +370,6 @@ fn relate<'a, 'gcx, R>(relation: &mut R,
}
}
impl
<
'tcx
>
Relate
<
'tcx
>
for
ty
::
ExistentialBounds
<
'tcx
>
{
fn
relate
<
'a
,
'gcx
,
R
>
(
relation
:
&
mut
R
,
a
:
&
ty
::
ExistentialBounds
<
'tcx
>
,
b
:
&
ty
::
ExistentialBounds
<
'tcx
>
)
->
RelateResult
<
'tcx
,
ty
::
ExistentialBounds
<
'tcx
>>
where
R
:
TypeRelation
<
'a
,
'gcx
,
'tcx
>
,
'gcx
:
'a
+
'tcx
,
'tcx
:
'a
{
let
r
=
relation
.with_cause
(
Cause
::
ExistentialRegionBound
,
|
relation
|
relation
.relate_with_variance
(
ty
::
Contravariant
,
&
a
.region_bound
,
&
b
.region_bound
))
?
;
let
nb
=
relation
.relate
(
&
a
.builtin_bounds
,
&
b
.builtin_bounds
)
?
;
let
pb
=
relation
.relate
(
&
a
.projection_bounds
,
&
b
.projection_bounds
)
?
;
Ok
(
ty
::
ExistentialBounds
{
region_bound
:
r
,
builtin_bounds
:
nb
,
projection_bounds
:
pb
})
}
}
impl
<
'tcx
>
Relate
<
'tcx
>
for
ty
::
BuiltinBounds
{
fn
relate
<
'a
,
'gcx
,
R
>
(
relation
:
&
mut
R
,
a
:
&
ty
::
BuiltinBounds
,
...
...
@@ -416,6 +404,23 @@ fn relate<'a, 'gcx, R>(relation: &mut R,
}
}
impl
<
'tcx
>
Relate
<
'tcx
>
for
ty
::
ExistentialTraitRef
<
'tcx
>
{
fn
relate
<
'a
,
'gcx
,
R
>
(
relation
:
&
mut
R
,
a
:
&
ty
::
ExistentialTraitRef
<
'tcx
>
,
b
:
&
ty
::
ExistentialTraitRef
<
'tcx
>
)
->
RelateResult
<
'tcx
,
ty
::
ExistentialTraitRef
<
'tcx
>>
where
R
:
TypeRelation
<
'a
,
'gcx
,
'tcx
>
,
'gcx
:
'a
+
'tcx
,
'tcx
:
'a
{
// Different traits cannot be related
if
a
.def_id
!=
b
.def_id
{
Err
(
TypeError
::
Traits
(
expected_found
(
relation
,
&
a
.def_id
,
&
b
.def_id
)))
}
else
{
let
substs
=
relate_item_substs
(
relation
,
a
.def_id
,
a
.substs
,
b
.substs
)
?
;
Ok
(
ty
::
ExistentialTraitRef
{
def_id
:
a
.def_id
,
substs
:
substs
})
}
}
}
impl
<
'tcx
>
Relate
<
'tcx
>
for
Ty
<
'tcx
>
{
fn
relate
<
'a
,
'gcx
,
R
>
(
relation
:
&
mut
R
,
a
:
&
Ty
<
'tcx
>
,
...
...
@@ -478,11 +483,23 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
Ok
(
tcx
.mk_enum
(
a_def
,
substs
))
}
(
&
ty
::
TyTrait
(
ref
a_
),
&
ty
::
TyTrait
(
ref
b_
))
=>
(
&
ty
::
TyTrait
(
ref
a_
obj
),
&
ty
::
TyTrait
(
ref
b_obj
))
=>
{
let
principal
=
relation
.relate
(
&
a_
.principal
,
&
b_
.principal
)
?
;
let
bounds
=
relation
.relate
(
&
a_
.bounds
,
&
b_
.bounds
)
?
;
Ok
(
tcx
.mk_trait
(
principal
,
bounds
))
let
principal
=
relation
.relate
(
&
a_obj
.principal
,
&
b_obj
.principal
)
?
;
let
r
=
relation
.with_cause
(
Cause
::
ExistentialRegionBound
,
|
relation
|
relation
.relate_with_variance
(
ty
::
Contravariant
,
&
a_obj
.region_bound
,
&
b_obj
.region_bound
))
?
;
let
nb
=
relation
.relate
(
&
a_obj
.builtin_bounds
,
&
b_obj
.builtin_bounds
)
?
;
let
pb
=
relation
.relate
(
&
a_obj
.projection_bounds
,
&
b_obj
.projection_bounds
)
?
;
Ok
(
tcx
.mk_trait
(
ty
::
TraitObject
{
principal
:
principal
,
region_bound
:
r
,
builtin_bounds
:
nb
,
projection_bounds
:
pb
}))
}
(
&
ty
::
TyStruct
(
a_def
,
a_substs
),
&
ty
::
TyStruct
(
b_def
,
b_substs
))
...
...
src/librustc/ty/structural_impls.rs
浏览文件 @
4b25f085
...
...
@@ -10,7 +10,7 @@
use
infer
::
type_variable
;
use
ty
::
subst
::{
self
,
VecPerParamSpace
};
use
ty
::{
self
,
Lift
,
T
raitRef
,
T
y
,
TyCtxt
};
use
ty
::{
self
,
Lift
,
Ty
,
TyCtxt
};
use
ty
::
fold
::{
TypeFoldable
,
TypeFolder
,
TypeVisitor
};
use
std
::
rc
::
Rc
;
...
...
@@ -80,10 +80,20 @@ fn lift_to_tcx(&self, _: TyCtxt) -> Option<ty::Region> {
}
}
impl
<
'a
,
'tcx
>
Lift
<
'tcx
>
for
TraitRef
<
'a
>
{
type
Lifted
=
TraitRef
<
'tcx
>
;
fn
lift_to_tcx
<
'b
,
'gcx
>
(
&
self
,
tcx
:
TyCtxt
<
'b
,
'gcx
,
'tcx
>
)
->
Option
<
TraitRef
<
'tcx
>>
{
tcx
.lift
(
&
self
.substs
)
.map
(|
substs
|
TraitRef
{
impl
<
'a
,
'tcx
>
Lift
<
'tcx
>
for
ty
::
TraitRef
<
'a
>
{
type
Lifted
=
ty
::
TraitRef
<
'tcx
>
;
fn
lift_to_tcx
<
'b
,
'gcx
>
(
&
self
,
tcx
:
TyCtxt
<
'b
,
'gcx
,
'tcx
>
)
->
Option
<
Self
::
Lifted
>
{
tcx
.lift
(
&
self
.substs
)
.map
(|
substs
|
ty
::
TraitRef
{
def_id
:
self
.def_id
,
substs
:
substs
})
}
}
impl
<
'a
,
'tcx
>
Lift
<
'tcx
>
for
ty
::
ExistentialTraitRef
<
'a
>
{
type
Lifted
=
ty
::
ExistentialTraitRef
<
'tcx
>
;
fn
lift_to_tcx
<
'b
,
'gcx
>
(
&
self
,
tcx
:
TyCtxt
<
'b
,
'gcx
,
'tcx
>
)
->
Option
<
Self
::
Lifted
>
{
tcx
.lift
(
&
self
.substs
)
.map
(|
substs
|
ty
::
ExistentialTraitRef
{
def_id
:
self
.def_id
,
substs
:
substs
})
...
...
@@ -141,6 +151,19 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
}
}
impl
<
'a
,
'tcx
>
Lift
<
'tcx
>
for
ty
::
ExistentialProjection
<
'a
>
{
type
Lifted
=
ty
::
ExistentialProjection
<
'tcx
>
;
fn
lift_to_tcx
<
'b
,
'gcx
>
(
&
self
,
tcx
:
TyCtxt
<
'b
,
'gcx
,
'tcx
>
)
->
Option
<
Self
::
Lifted
>
{
tcx
.lift
(
&
(
self
.trait_ref
,
self
.ty
))
.map
(|(
trait_ref
,
ty
)|
{
ty
::
ExistentialProjection
{
trait_ref
:
trait_ref
,
item_name
:
self
.item_name
,
ty
:
ty
}
})
}
}
impl
<
'a
,
'tcx
>
Lift
<
'tcx
>
for
ty
::
Predicate
<
'a
>
{
type
Lifted
=
ty
::
Predicate
<
'tcx
>
;
fn
lift_to_tcx
<
'b
,
'gcx
>
(
&
self
,
tcx
:
TyCtxt
<
'b
,
'gcx
,
'tcx
>
)
->
Option
<
Self
::
Lifted
>
{
...
...
@@ -437,16 +460,20 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
}
}
impl
<
'tcx
>
TypeFoldable
<
'tcx
>
for
ty
::
Trait
Ty
<
'tcx
>
{
impl
<
'tcx
>
TypeFoldable
<
'tcx
>
for
ty
::
Trait
Object
<
'tcx
>
{
fn
super_fold_with
<
'gcx
:
'tcx
,
F
:
TypeFolder
<
'gcx
,
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
Self
{
ty
::
Trait
Ty
{
ty
::
Trait
Object
{
principal
:
self
.principal
.fold_with
(
folder
),
bounds
:
self
.bounds
.fold_with
(
folder
),
region_bound
:
self
.region_bound
.fold_with
(
folder
),
builtin_bounds
:
self
.builtin_bounds
,
projection_bounds
:
self
.projection_bounds
.fold_with
(
folder
),
}
}
fn
super_visit_with
<
V
:
TypeVisitor
<
'tcx
>>
(
&
self
,
visitor
:
&
mut
V
)
->
bool
{
self
.principal
.visit_with
(
visitor
)
||
self
.bounds
.visit_with
(
visitor
)
self
.principal
.visit_with
(
visitor
)
||
self
.region_bound
.visit_with
(
visitor
)
||
self
.projection_bounds
.visit_with
(
visitor
)
}
}
...
...
@@ -599,8 +626,17 @@ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F)
}
}
fn
fold_with
<
'gcx
:
'tcx
,
F
:
TypeFolder
<
'gcx
,
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
Self
{
folder
.fold_trait_ref
(
self
)
fn
super_visit_with
<
V
:
TypeVisitor
<
'tcx
>>
(
&
self
,
visitor
:
&
mut
V
)
->
bool
{
self
.substs
.visit_with
(
visitor
)
}
}
impl
<
'tcx
>
TypeFoldable
<
'tcx
>
for
ty
::
ExistentialTraitRef
<
'tcx
>
{
fn
super_fold_with
<
'gcx
:
'tcx
,
F
:
TypeFolder
<
'gcx
,
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
Self
{
ty
::
ExistentialTraitRef
{
def_id
:
self
.def_id
,
substs
:
self
.substs
.fold_with
(
folder
),
}
}
fn
super_visit_with
<
V
:
TypeVisitor
<
'tcx
>>
(
&
self
,
visitor
:
&
mut
V
)
->
bool
{
...
...
@@ -741,24 +777,6 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
}
}
impl
<
'tcx
>
TypeFoldable
<
'tcx
>
for
ty
::
ExistentialBounds
<
'tcx
>
{
fn
super_fold_with
<
'gcx
:
'tcx
,
F
:
TypeFolder
<
'gcx
,
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
Self
{
ty
::
ExistentialBounds
{
region_bound
:
self
.region_bound
.fold_with
(
folder
),
builtin_bounds
:
self
.builtin_bounds
,
projection_bounds
:
self
.projection_bounds
.fold_with
(
folder
),
}
}
fn
fold_with
<
'gcx
:
'tcx
,
F
:
TypeFolder
<
'gcx
,
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
Self
{
folder
.fold_existential_bounds
(
self
)
}
fn
super_visit_with
<
V
:
TypeVisitor
<
'tcx
>>
(
&
self
,
visitor
:
&
mut
V
)
->
bool
{
self
.region_bound
.visit_with
(
visitor
)
||
self
.projection_bounds
.visit_with
(
visitor
)
}
}
impl
<
'tcx
>
TypeFoldable
<
'tcx
>
for
ty
::
TypeParameterDef
<
'tcx
>
{
fn
super_fold_with
<
'gcx
:
'tcx
,
F
:
TypeFolder
<
'gcx
,
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
Self
{
ty
::
TypeParameterDef
{
...
...
@@ -893,6 +911,20 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
}
}
impl
<
'tcx
>
TypeFoldable
<
'tcx
>
for
ty
::
ExistentialProjection
<
'tcx
>
{
fn
super_fold_with
<
'gcx
:
'tcx
,
F
:
TypeFolder
<
'gcx
,
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
Self
{
ty
::
ExistentialProjection
{
trait_ref
:
self
.trait_ref
.fold_with
(
folder
),
item_name
:
self
.item_name
,
ty
:
self
.ty
.fold_with
(
folder
),
}
}
fn
super_visit_with
<
V
:
TypeVisitor
<
'tcx
>>
(
&
self
,
visitor
:
&
mut
V
)
->
bool
{
self
.trait_ref
.visit_with
(
visitor
)
||
self
.ty
.visit_with
(
visitor
)
}
}
impl
<
'tcx
>
TypeFoldable
<
'tcx
>
for
ty
::
ProjectionTy
<
'tcx
>
{
fn
super_fold_with
<
'gcx
:
'tcx
,
F
:
TypeFolder
<
'gcx
,
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
Self
{
ty
::
ProjectionTy
{
...
...
src/librustc/ty/sty.rs
浏览文件 @
4b25f085
...
...
@@ -152,7 +152,7 @@ pub enum TypeVariants<'tcx> {
TyFnPtr
(
&
'tcx
BareFnTy
<
'tcx
>
),
/// A trait, defined with `trait`.
TyTrait
(
Box
<
Trait
Ty
<
'tcx
>>
),
TyTrait
(
Box
<
Trait
Object
<
'tcx
>>
),
/// The anonymous type of a closure. Used to represent the type of
/// `|a| a`.
...
...
@@ -291,57 +291,11 @@ fn decode<D: Decoder>(d: &mut D) -> Result<ClosureSubsts<'tcx>, D::Error> {
}
#[derive(Clone,
PartialEq,
Eq,
Hash)]
pub
struct
TraitTy
<
'tcx
>
{
pub
principal
:
ty
::
PolyTraitRef
<
'tcx
>
,
pub
bounds
:
ExistentialBounds
<
'tcx
>
,
}
impl
<
'a
,
'gcx
,
'tcx
>
TraitTy
<
'tcx
>
{
pub
fn
principal_def_id
(
&
self
)
->
DefId
{
self
.principal
.0
.def_id
}
/// Object types don't have a self-type specified. Therefore, when
/// we convert the principal trait-ref into a normal trait-ref,
/// you must give *some* self-type. A common choice is `mk_err()`
/// or some skolemized type.
pub
fn
principal_trait_ref_with_self_ty
(
&
self
,
tcx
:
TyCtxt
<
'a
,
'gcx
,
'tcx
>
,
self_ty
:
Ty
<
'tcx
>
)
->
ty
::
PolyTraitRef
<
'tcx
>
{
// otherwise the escaping regions would be captured by the binder
assert
!
(
!
self_ty
.has_escaping_regions
());
ty
::
Binder
(
TraitRef
{
def_id
:
self
.principal
.0
.def_id
,
substs
:
tcx
.mk_substs
(
self
.principal
.0
.substs
.with_self_ty
(
self_ty
)),
})
}
pub
fn
projection_bounds_with_self_ty
(
&
self
,
tcx
:
TyCtxt
<
'a
,
'gcx
,
'tcx
>
,
self_ty
:
Ty
<
'tcx
>
)
->
Vec
<
ty
::
PolyProjectionPredicate
<
'tcx
>>
{
// otherwise the escaping regions would be captured by the binders
assert
!
(
!
self_ty
.has_escaping_regions
());
self
.bounds.projection_bounds
.iter
()
.map
(|
in_poly_projection_predicate
|
{
let
in_projection_ty
=
&
in_poly_projection_predicate
.0
.projection_ty
;
let
substs
=
tcx
.mk_substs
(
in_projection_ty
.trait_ref.substs
.with_self_ty
(
self_ty
));
let
trait_ref
=
ty
::
TraitRef
::
new
(
in_projection_ty
.trait_ref.def_id
,
substs
);
let
projection_ty
=
ty
::
ProjectionTy
{
trait_ref
:
trait_ref
,
item_name
:
in_projection_ty
.item_name
};
ty
::
Binder
(
ty
::
ProjectionPredicate
{
projection_ty
:
projection_ty
,
ty
:
in_poly_projection_predicate
.0
.ty
})
})
.collect
()
}
pub
struct
TraitObject
<
'tcx
>
{
pub
principal
:
PolyExistentialTraitRef
<
'tcx
>
,
pub
region_bound
:
ty
::
Region
,
pub
builtin_bounds
:
BuiltinBounds
,
pub
projection_bounds
:
Vec
<
PolyExistentialProjection
<
'tcx
>>
,
}
/// A complete reference to a trait. These take numerous guises in syntax,
...
...
@@ -392,6 +346,70 @@ pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> {
}
}
/// An existential reference to a trait, where `Self` is erased.
/// For example, the trait object `Trait<'a, 'b, X, Y>` is:
///
/// exists T. T: Trait<'a, 'b, X, Y>
///
/// The substitutions don't include the erased `Self`, only trait
/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
#[derive(Copy,
Clone,
PartialEq,
Eq,
Hash)]
pub
struct
ExistentialTraitRef
<
'tcx
>
{
pub
def_id
:
DefId
,
pub
substs
:
&
'tcx
Substs
<
'tcx
>
,
}
impl
<
'a
,
'gcx
,
'tcx
>
ExistentialTraitRef
<
'tcx
>
{
pub
fn
erase_self_ty
(
tcx
:
TyCtxt
<
'a
,
'gcx
,
'tcx
>
,
trait_ref
:
ty
::
TraitRef
<
'tcx
>
)
->
ty
::
ExistentialTraitRef
<
'tcx
>
{
let
mut
substs
=
trait_ref
.substs
.clone
();
substs
.types
.pop
(
subst
::
SelfSpace
);
ty
::
ExistentialTraitRef
{
def_id
:
trait_ref
.def_id
,
substs
:
tcx
.mk_substs
(
substs
)
}
}
pub
fn
input_types
(
&
self
)
->
&
[
Ty
<
'tcx
>
]
{
// Select only the "input types" from a trait-reference. For
// now this is all the types that appear in the
// trait-reference, but it should eventually exclude
// associated types.
self
.substs.types
.as_full_slice
()
}
}
pub
type
PolyExistentialTraitRef
<
'tcx
>
=
Binder
<
ExistentialTraitRef
<
'tcx
>>
;
impl
<
'a
,
'gcx
,
'tcx
>
PolyExistentialTraitRef
<
'tcx
>
{
pub
fn
def_id
(
&
self
)
->
DefId
{
self
.0
.def_id
}
pub
fn
input_types
(
&
self
)
->
&
[
Ty
<
'tcx
>
]
{
// FIXME(#20664) every use of this fn is probably a bug, it should yield Binder<>
self
.0
.input_types
()
}
/// Object types don't have a self-type specified. Therefore, when
/// we convert the principal trait-ref into a normal trait-ref,
/// you must give *some* self-type. A common choice is `mk_err()`
/// or some skolemized type.
pub
fn
with_self_ty
(
&
self
,
tcx
:
TyCtxt
<
'a
,
'gcx
,
'tcx
>
,
self_ty
:
Ty
<
'tcx
>
)
->
ty
::
PolyTraitRef
<
'tcx
>
{
// otherwise the escaping regions would be captured by the binder
assert
!
(
!
self_ty
.has_escaping_regions
());
self
.map_bound
(|
trait_ref
|
TraitRef
{
def_id
:
trait_ref
.def_id
,
substs
:
tcx
.mk_substs
(
trait_ref
.substs
.with_self_ty
(
self_ty
)),
})
}
}
/// Binder is a binder for higher-ranked lifetimes. It is part of the
/// compiler's representation for things like `for<'a> Fn(&'a isize)`
/// (which would be represented by the type `PolyTraitRef ==
...
...
@@ -730,27 +748,40 @@ pub enum InferTy {
FreshFloatTy
(
u32
)
}
/// Bounds suitable for an existentially quantified type parameter
/// such as those that appear in object types or closure types.
#[derive(PartialEq,
Eq,
Hash,
Clone)]
pub
struct
ExistentialBounds
<
'tcx
>
{
pub
region_bound
:
ty
::
Region
,
pub
builtin_bounds
:
BuiltinBounds
,
pub
projection_bounds
:
Vec
<
ty
::
PolyProjectionPredicate
<
'tcx
>>
,
/// A `ProjectionPredicate` for an `ExistentialTraitRef`.
#[derive(Clone,
Copy,
PartialEq,
Eq,
Hash,
Debug)]
pub
struct
ExistentialProjection
<
'tcx
>
{
pub
trait_ref
:
ExistentialTraitRef
<
'tcx
>
,
pub
item_name
:
Name
,
pub
ty
:
Ty
<
'tcx
>
}
impl
<
'tcx
>
ExistentialBounds
<
'tcx
>
{
pub
fn
new
(
region_bound
:
ty
::
Region
,
builtin_bounds
:
BuiltinBounds
,
projection_bounds
:
Vec
<
ty
::
PolyProjectionPredicate
<
'tcx
>>
)
->
Self
{
let
mut
projection_bounds
=
projection_bounds
;
projection_bounds
.sort_by
(|
a
,
b
|
a
.sort_key
()
.cmp
(
&
b
.sort_key
()));
ExistentialBounds
{
region_bound
:
region_bound
,
builtin_bounds
:
builtin_bounds
,
projection_bounds
:
projection_bounds
}
pub
type
PolyExistentialProjection
<
'tcx
>
=
Binder
<
ExistentialProjection
<
'tcx
>>
;
impl
<
'a
,
'tcx
,
'gcx
>
PolyExistentialProjection
<
'tcx
>
{
pub
fn
item_name
(
&
self
)
->
Name
{
self
.0
.item_name
// safe to skip the binder to access a name
}
pub
fn
sort_key
(
&
self
)
->
(
DefId
,
Name
)
{
(
self
.0
.trait_ref.def_id
,
self
.0
.item_name
)
}
pub
fn
with_self_ty
(
&
self
,
tcx
:
TyCtxt
<
'a
,
'gcx
,
'tcx
>
,
self_ty
:
Ty
<
'tcx
>
)
->
ty
::
PolyProjectionPredicate
<
'tcx
>
{
// otherwise the escaping regions would be captured by the binders
assert
!
(
!
self_ty
.has_escaping_regions
());
let
trait_ref
=
self
.map_bound
(|
proj
|
proj
.trait_ref
);
self
.map_bound
(|
proj
|
ty
::
ProjectionPredicate
{
projection_ty
:
ty
::
ProjectionTy
{
trait_ref
:
trait_ref
.with_self_ty
(
tcx
,
self_ty
)
.0
,
item_name
:
proj
.item_name
},
ty
:
proj
.ty
})
}
}
...
...
@@ -1185,7 +1216,7 @@ pub fn is_fn(&self) -> bool {
pub
fn
ty_to_def_id
(
&
self
)
->
Option
<
DefId
>
{
match
self
.sty
{
TyTrait
(
ref
tt
)
=>
Some
(
tt
.principal
_
def_id
()),
TyTrait
(
ref
tt
)
=>
Some
(
tt
.principal
.
def_id
()),
TyStruct
(
def
,
_
)
|
TyEnum
(
def
,
_
)
=>
Some
(
def
.did
),
TyClosure
(
id
,
_
)
=>
Some
(
id
),
...
...
@@ -1209,9 +1240,8 @@ pub fn regions(&self) -> Vec<ty::Region> {
vec!
[
*
region
]
}
TyTrait
(
ref
obj
)
=>
{
let
mut
v
=
vec!
[
obj
.bounds.region_bound
];
v
.extend_from_slice
(
obj
.principal
.skip_binder
()
.substs.regions
.as_full_slice
());
let
mut
v
=
vec!
[
obj
.region_bound
];
v
.extend_from_slice
(
obj
.principal
.skip_binder
()
.substs.regions
.as_full_slice
());
v
}
TyEnum
(
_
,
substs
)
|
...
...
src/librustc/ty/util.rs
浏览文件 @
4b25f085
...
...
@@ -451,21 +451,21 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
// to sort them again by the name, in string form.
// Hash the whole principal trait ref.
self
.def_id
(
data
.principal
_
def_id
());
self
.def_id
(
data
.principal
.
def_id
());
data
.principal
.visit_with
(
self
);
// Hash region and builtin bounds.
data
.
bounds.
region_bound
.visit_with
(
self
);
self
.hash
(
data
.b
ounds.b
uiltin_bounds
);
data
.region_bound
.visit_with
(
self
);
self
.hash
(
data
.builtin_bounds
);
// Only projection bounds are left, sort and hash them.
let
mut
projection_bounds
:
Vec
<
_
>
=
data
.
bounds.
projection_bounds
let
mut
projection_bounds
:
Vec
<
_
>
=
data
.projection_bounds
.iter
()
.map
(|
b
|
(
b
.item_name
()
.as_str
(),
b
))
.collect
();
projection_bounds
.sort_by_key
(|
&
(
ref
name
,
_
)|
name
.clone
());
for
(
name
,
bound
)
in
projection_bounds
{
self
.def_id
(
bound
.0
.
projection_ty.
trait_ref.def_id
);
self
.def_id
(
bound
.0
.trait_ref.def_id
);
self
.hash
(
name
);
bound
.visit_with
(
self
);
}
...
...
src/librustc/ty/walk.rs
浏览文件 @
4b25f085
...
...
@@ -81,9 +81,9 @@ fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
ty
::
TyProjection
(
ref
data
)
=>
{
push_reversed
(
stack
,
data
.trait_ref.substs.types
.as_full_slice
());
}
ty
::
TyTrait
(
box
ty
::
TraitTy
{
ref
principal
,
ref
bounds
}
)
=>
{
push_reversed
(
stack
,
principal
.substs
()
.types
.as_full_slice
());
push_reversed
(
stack
,
&
bounds
.projection_bounds
.iter
()
.map
(|
pred
|
{
ty
::
TyTrait
(
ref
obj
)
=>
{
push_reversed
(
stack
,
obj
.principal
.input_types
());
push_reversed
(
stack
,
&
obj
.projection_bounds
.iter
()
.map
(|
pred
|
{
pred
.0
.ty
})
.collect
::
<
Vec
<
_
>>
());
}
...
...
src/librustc/ty/wf.rs
浏览文件 @
4b25f085
...
...
@@ -406,13 +406,13 @@ fn compute(&mut self, ty0: Ty<'tcx>) -> bool {
// FIXME(#33243): remove RFC1592
self
.out
.push
(
traits
::
Obligation
::
new
(
cause
.clone
(),
ty
::
Predicate
::
ObjectSafe
(
data
.principal
_
def_id
())
ty
::
Predicate
::
ObjectSafe
(
data
.principal
.
def_id
())
));
let
component_traits
=
data
.b
ounds.b
uiltin_bounds
.iter
()
.flat_map
(|
bound
|
{
data
.builtin_bounds
.iter
()
.flat_map
(|
bound
|
{
tcx
.lang_items
.from_builtin_kind
(
bound
)
.ok
()
});
// .chain(Some(data.principal
_
def_id()));
// .chain(Some(data.principal
.
def_id()));
self
.out
.extend
(
component_traits
.map
(|
did
|
{
traits
::
Obligation
::
new
(
cause
.clone
(),
...
...
@@ -476,7 +476,7 @@ fn nominal_obligations(&mut self,
.collect
()
}
fn
from_object_ty
(
&
mut
self
,
ty
:
Ty
<
'tcx
>
,
data
:
&
ty
::
Trait
Ty
<
'tcx
>
)
{
fn
from_object_ty
(
&
mut
self
,
ty
:
Ty
<
'tcx
>
,
data
:
&
ty
::
Trait
Object
<
'tcx
>
)
{
// Imagine a type like this:
//
// trait Foo { }
...
...
@@ -512,10 +512,10 @@ fn from_object_ty(&mut self, ty: Ty<'tcx>, data: &ty::TraitTy<'tcx>) {
if
!
data
.has_escaping_regions
()
{
let
implicit_bounds
=
object_region_bounds
(
self
.infcx.tcx
,
&
data
.principal
,
data
.b
ounds.b
uiltin_bounds
);
data
.principal
,
data
.builtin_bounds
);
let
explicit_bound
=
data
.
bounds.
region_bound
;
let
explicit_bound
=
data
.region_bound
;
for
implicit_bound
in
implicit_bounds
{
let
cause
=
self
.cause
(
traits
::
ReferenceOutlivesReferent
(
ty
));
...
...
@@ -534,7 +534,7 @@ fn from_object_ty(&mut self, ty: Ty<'tcx>, data: &ty::TraitTy<'tcx>) {
/// `ty::required_region_bounds`, see that for more information.
pub
fn
object_region_bounds
<
'a
,
'gcx
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'gcx
,
'tcx
>
,
principal
:
&
ty
::
Poly
TraitRef
<
'tcx
>
,
principal
:
ty
::
PolyExistential
TraitRef
<
'tcx
>
,
others
:
ty
::
BuiltinBounds
)
->
Vec
<
ty
::
Region
>
{
...
...
@@ -543,13 +543,8 @@ pub fn object_region_bounds<'a, 'gcx, 'tcx>(
// a skolemized type.
let
open_ty
=
tcx
.mk_infer
(
ty
::
FreshTy
(
0
));
// Note that we preserve the overall binding levels here.
assert
!
(
!
open_ty
.has_escaping_regions
());
let
substs
=
tcx
.mk_substs
(
principal
.0
.substs
.with_self_ty
(
open_ty
));
let
trait_refs
=
vec!
(
ty
::
Binder
(
ty
::
TraitRef
::
new
(
principal
.0
.def_id
,
substs
)));
let
mut
predicates
=
others
.to_predicates
(
tcx
,
open_ty
);
predicates
.
extend
(
trait_refs
.iter
()
.map
(|
t
|
t
.to_predicate
()
));
predicates
.
push
(
principal
.with_self_ty
(
tcx
,
open_ty
)
.to_predicate
(
));
tcx
.required_region_bounds
(
open_ty
,
predicates
)
}
src/librustc/util/ppaux.rs
浏览文件 @
4b25f085
...
...
@@ -288,7 +288,8 @@ fn in_binder<'a, 'gcx, 'tcx, T, U>(f: &mut fmt::Formatter,
/// projection bounds, so we just stuff them altogether. But in
/// reality we should eventually sort things out better.
#[derive(Clone,
Debug)]
struct
TraitAndProjections
<
'tcx
>
(
ty
::
TraitRef
<
'tcx
>
,
Vec
<
ty
::
ProjectionPredicate
<
'tcx
>>
);
struct
TraitAndProjections
<
'tcx
>
(
ty
::
ExistentialTraitRef
<
'tcx
>
,
Vec
<
ty
::
ProjectionPredicate
<
'tcx
>>
);
impl
<
'tcx
>
TypeFoldable
<
'tcx
>
for
TraitAndProjections
<
'tcx
>
{
fn
super_fold_with
<
'gcx
:
'tcx
,
F
:
TypeFolder
<
'gcx
,
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
Self
{
...
...
@@ -311,24 +312,24 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
impl
<
'tcx
>
fmt
::
Display
for
ty
::
Trait
Ty
<
'tcx
>
{
impl
<
'tcx
>
fmt
::
Display
for
ty
::
Trait
Object
<
'tcx
>
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
let
bounds
=
&
self
.bounds
;
// Generate the main trait ref, including associated types.
ty
::
tls
::
with
(|
tcx
|
{
let
principal
=
tcx
.lift
(
&
self
.principal
.0
)
.expect
(
"could not lift TraitRef for printing"
);
let
projections
=
tcx
.lift
(
&
bounds
.projection_bounds
[
..
])
.expect
(
"could not lift projections for printing"
);
let
projections
=
projections
.into_iter
()
.map
(|
p
|
p
.0
)
.collect
();
let
projections
=
self
.projection_bounds
.iter
()
.map
(|
p
|
{
let
projection
=
tcx
.lift
(
p
)
.expect
(
"could not lift projection for printing"
);
projection
.with_self_ty
(
tcx
,
tcx
.types.err
)
.0
})
.collect
();
let
tap
=
ty
::
Binder
(
TraitAndProjections
(
principal
,
projections
));
in_binder
(
f
,
tcx
,
&
ty
::
Binder
(
""
),
Some
(
tap
))
})
?
;
// Builtin bounds.
for
bound
in
&
bounds
.builtin_bounds
{
for
bound
in
&
self
.builtin_bounds
{
write!
(
f
,
" + {:?}"
,
bound
)
?
;
}
...
...
@@ -337,7 +338,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// use thread-local data of some kind? There are also
// advantages to just showing the region, since it makes
// people aware that it's there.
let
bound
=
bounds
.region_bound
.to_string
();
let
bound
=
self
.region_bound
.to_string
();
if
!
bound
.is_empty
()
{
write!
(
f
,
" + {}"
,
bound
)
?
;
}
...
...
@@ -397,10 +398,13 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// when printing out the debug representation, we don't need
// to enumerate the `for<...>` etc because the debruijn index
// tells you everything you need to know.
match
self
.substs
.self_ty
()
{
None
=>
write!
(
f
,
"{}"
,
*
self
),
Some
(
self_ty
)
=>
write!
(
f
,
"<{:?} as {}>"
,
self_ty
,
*
self
)
}
write!
(
f
,
"<{:?} as {}>"
,
self
.self_ty
(),
*
self
)
}
}
impl
<
'tcx
>
fmt
::
Debug
for
ty
::
ExistentialTraitRef
<
'tcx
>
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
write!
(
f
,
"{}"
,
*
self
)
}
}
...
...
@@ -448,11 +452,38 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
impl
<
'tcx
>
fmt
::
Debug
for
ty
::
Trait
Ty
<
'tcx
>
{
impl
<
'tcx
>
fmt
::
Debug
for
ty
::
Trait
Object
<
'tcx
>
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
write!
(
f
,
"TraitTy({:?},{:?})"
,
self
.principal
,
self
.bounds
)
let
mut
empty
=
true
;
let
mut
maybe_continue
=
|
f
:
&
mut
fmt
::
Formatter
|
{
if
empty
{
empty
=
false
;
Ok
(())
}
else
{
write!
(
f
,
" + "
)
}
};
maybe_continue
(
f
)
?
;
write!
(
f
,
"{:?}"
,
self
.principal
)
?
;
let
region_str
=
format!
(
"{:?}"
,
self
.region_bound
);
if
!
region_str
.is_empty
()
{
maybe_continue
(
f
)
?
;
write!
(
f
,
"{}"
,
region_str
)
?
;
}
for
bound
in
&
self
.builtin_bounds
{
maybe_continue
(
f
)
?
;
write!
(
f
,
"{:?}"
,
bound
)
?
;
}
for
projection_bound
in
&
self
.projection_bounds
{
maybe_continue
(
f
)
?
;
write!
(
f
,
"{:?}"
,
projection_bound
)
?
;
}
Ok
(())
}
}
...
...
@@ -668,38 +699,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
impl
<
'tcx
>
fmt
::
Debug
for
ty
::
ExistentialBounds
<
'tcx
>
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
let
mut
empty
=
true
;
let
mut
maybe_continue
=
|
f
:
&
mut
fmt
::
Formatter
|
{
if
empty
{
empty
=
false
;
Ok
(())
}
else
{
write!
(
f
,
" + "
)
}
};
let
region_str
=
format!
(
"{:?}"
,
self
.region_bound
);
if
!
region_str
.is_empty
()
{
maybe_continue
(
f
)
?
;
write!
(
f
,
"{}"
,
region_str
)
?
;
}
for
bound
in
&
self
.builtin_bounds
{
maybe_continue
(
f
)
?
;
write!
(
f
,
"{:?}"
,
bound
)
?
;
}
for
projection_bound
in
&
self
.projection_bounds
{
maybe_continue
(
f
)
?
;
write!
(
f
,
"{:?}"
,
projection_bound
)
?
;
}
Ok
(())
}
}
impl
fmt
::
Display
for
ty
::
BuiltinBounds
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
let
mut
bounds
=
self
.iter
();
...
...
@@ -819,6 +818,13 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
impl
<
'tcx
>
fmt
::
Display
for
ty
::
ExistentialTraitRef
<
'tcx
>
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
parameterized
(
f
,
self
.substs
,
self
.def_id
,
Ns
::
Type
,
&
[],
|
tcx
|
Some
(
tcx
.lookup_trait_def
(
self
.def_id
)
.generics
.clone
()))
}
}
impl
<
'tcx
>
fmt
::
Display
for
ty
::
TypeVariants
<
'tcx
>
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
match
*
self
{
...
...
src/librustc_metadata/astencode.rs
浏览文件 @
4b25f085
...
...
@@ -524,16 +524,8 @@ pub fn encode_cast_kind(ebml_w: &mut Encoder, kind: cast::CastKind) {
trait
rbml_writer_helpers
<
'tcx
>
{
fn
emit_region
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
,
r
:
ty
::
Region
);
fn
emit_ty
<
'a
>
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
<
'a
,
'tcx
>
,
ty
:
Ty
<
'tcx
>
);
fn
emit_tys
<
'a
>
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
<
'a
,
'tcx
>
,
tys
:
&
[
Ty
<
'tcx
>
]);
fn
emit_predicate
<
'a
>
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
<
'a
,
'tcx
>
,
predicate
:
&
ty
::
Predicate
<
'tcx
>
);
fn
emit_trait_ref
<
'a
>
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
<
'a
,
'tcx
>
,
ty
:
&
ty
::
TraitRef
<
'tcx
>
);
fn
emit_substs
<
'a
>
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
<
'a
,
'tcx
>
,
substs
:
&
subst
::
Substs
<
'tcx
>
);
fn
emit_existential_bounds
<
'b
>
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
<
'b
,
'tcx
>
,
bounds
:
&
ty
::
ExistentialBounds
<
'tcx
>
);
fn
emit_builtin_bounds
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
,
bounds
:
&
ty
::
BuiltinBounds
);
fn
emit_upvar_capture
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
,
capture
:
&
ty
::
UpvarCapture
);
fn
emit_auto_adjustment
<
'a
>
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
<
'a
,
'tcx
>
,
adj
:
&
adjustment
::
AutoAdjustment
<
'tcx
>
);
...
...
@@ -556,39 +548,6 @@ fn emit_ty<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>, ty: Ty<'tcx>) {
ty
)));
}
fn
emit_tys
<
'b
>
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
<
'b
,
'tcx
>
,
tys
:
&
[
Ty
<
'tcx
>
])
{
self
.emit_from_vec
(
tys
,
|
this
,
ty
|
Ok
(
this
.emit_ty
(
ecx
,
*
ty
)));
}
fn
emit_trait_ref
<
'b
>
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
<
'b
,
'tcx
>
,
trait_ref
:
&
ty
::
TraitRef
<
'tcx
>
)
{
self
.emit_opaque
(|
this
|
Ok
(
tyencode
::
enc_trait_ref
(
&
mut
this
.cursor
,
&
ecx
.ty_str_ctxt
(),
*
trait_ref
)));
}
fn
emit_predicate
<
'b
>
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
<
'b
,
'tcx
>
,
predicate
:
&
ty
::
Predicate
<
'tcx
>
)
{
self
.emit_opaque
(|
this
|
{
Ok
(
tyencode
::
enc_predicate
(
&
mut
this
.cursor
,
&
ecx
.ty_str_ctxt
(),
predicate
))
});
}
fn
emit_existential_bounds
<
'b
>
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
<
'b
,
'tcx
>
,
bounds
:
&
ty
::
ExistentialBounds
<
'tcx
>
)
{
self
.emit_opaque
(|
this
|
Ok
(
tyencode
::
enc_existential_bounds
(
&
mut
this
.cursor
,
&
ecx
.ty_str_ctxt
(),
bounds
)));
}
fn
emit_builtin_bounds
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
,
bounds
:
&
ty
::
BuiltinBounds
)
{
self
.emit_opaque
(|
this
|
Ok
(
tyencode
::
enc_builtin_bounds
(
&
mut
this
.cursor
,
&
ecx
.ty_str_ctxt
(),
bounds
)));
}
fn
emit_upvar_capture
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
,
capture
:
&
ty
::
UpvarCapture
)
{
use
rustc_serialize
::
Encoder
;
...
...
@@ -879,8 +838,6 @@ fn read_poly_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
->
ty
::
PolyTraitRef
<
'tcx
>
;
fn
read_predicate
<
'a
,
'b
>
(
&
mut
self
,
dcx
:
&
DecodeContext
<
'a
,
'b
,
'tcx
>
)
->
ty
::
Predicate
<
'tcx
>
;
fn
read_existential_bounds
<
'a
,
'b
>
(
&
mut
self
,
dcx
:
&
DecodeContext
<
'a
,
'b
,
'tcx
>
)
->
ty
::
ExistentialBounds
<
'tcx
>
;
fn
read_substs
<
'a
,
'b
>
(
&
mut
self
,
dcx
:
&
DecodeContext
<
'a
,
'b
,
'tcx
>
)
->
subst
::
Substs
<
'tcx
>
;
fn
read_upvar_capture
(
&
mut
self
,
dcx
:
&
DecodeContext
)
...
...
@@ -988,12 +945,6 @@ fn read_predicate<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
self
.read_ty_encoded
(
dcx
,
|
decoder
|
decoder
.parse_predicate
())
}
fn
read_existential_bounds
<
'b
,
'c
>
(
&
mut
self
,
dcx
:
&
DecodeContext
<
'b
,
'c
,
'tcx
>
)
->
ty
::
ExistentialBounds
<
'tcx
>
{
self
.read_ty_encoded
(
dcx
,
|
decoder
|
decoder
.parse_existential_bounds
())
}
fn
read_substs
<
'b
,
'c
>
(
&
mut
self
,
dcx
:
&
DecodeContext
<
'b
,
'c
,
'tcx
>
)
->
subst
::
Substs
<
'tcx
>
{
self
.read_opaque
(|
_
,
doc
|
{
...
...
src/librustc_metadata/tydecode.rs
浏览文件 @
4b25f085
...
...
@@ -307,6 +307,12 @@ pub fn parse_trait_ref(&mut self) -> ty::TraitRef<'tcx> {
ty
::
TraitRef
{
def_id
:
def
,
substs
:
substs
}
}
pub
fn
parse_existential_trait_ref
(
&
mut
self
)
->
ty
::
ExistentialTraitRef
<
'tcx
>
{
let
def
=
self
.parse_def
();
let
substs
=
self
.tcx
.mk_substs
(
self
.parse_substs
());
ty
::
ExistentialTraitRef
{
def_id
:
def
,
substs
:
substs
}
}
pub
fn
parse_ty
(
&
mut
self
)
->
Ty
<
'tcx
>
{
let
tcx
=
self
.tcx
;
match
self
.next
()
{
...
...
@@ -340,10 +346,30 @@ pub fn parse_ty(&mut self) -> Ty<'tcx> {
}
'x'
=>
{
assert_eq!
(
self
.next
(),
'['
);
let
trait_ref
=
ty
::
Binder
(
self
.parse_trait_ref
());
let
bounds
=
self
.parse_existential_bounds
();
let
trait_ref
=
ty
::
Binder
(
self
.parse_existential_trait_ref
());
let
builtin_bounds
=
self
.parse_builtin_bounds
();
let
region_bound
=
self
.parse_region
();
let
mut
projection_bounds
=
Vec
::
new
();
loop
{
match
self
.next
()
{
'P'
=>
{
let
bound
=
self
.parse_existential_projection
();
projection_bounds
.push
(
ty
::
Binder
(
bound
));
}
'.'
=>
{
break
;
}
c
=>
{
bug!
(
"parse_bounds: bad bounds ('{}')"
,
c
)
}
}
}
assert_eq!
(
self
.next
(),
']'
);
return
tcx
.mk_trait
(
trait_ref
,
bounds
);
return
tcx
.mk_trait
(
ty
::
TraitObject
{
principal
:
trait_ref
,
region_bound
:
region_bound
,
builtin_bounds
:
builtin_bounds
,
projection_bounds
:
projection_bounds
});
}
'p'
=>
{
assert_eq!
(
self
.next
(),
'['
);
...
...
@@ -588,6 +614,14 @@ fn parse_projection_predicate(&mut self) -> ty::ProjectionPredicate<'tcx> {
}
}
fn
parse_existential_projection
(
&
mut
self
)
->
ty
::
ExistentialProjection
<
'tcx
>
{
ty
::
ExistentialProjection
{
trait_ref
:
self
.parse_existential_trait_ref
(),
item_name
:
token
::
intern
(
&
self
.parse_str
(
'|'
)),
ty
:
self
.parse_ty
(),
}
}
pub
fn
parse_type_param_def
(
&
mut
self
)
->
ty
::
TypeParameterDef
<
'tcx
>
{
let
name
=
self
.parse_name
(
':'
);
let
def_id
=
self
.parse_def
();
...
...
@@ -649,27 +683,6 @@ fn parse_object_lifetime_default(&mut self) -> ty::ObjectLifetimeDefault {
}
}
pub
fn
parse_existential_bounds
(
&
mut
self
)
->
ty
::
ExistentialBounds
<
'tcx
>
{
let
builtin_bounds
=
self
.parse_builtin_bounds
();
let
region_bound
=
self
.parse_region
();
let
mut
projection_bounds
=
Vec
::
new
();
loop
{
match
self
.next
()
{
'P'
=>
{
projection_bounds
.push
(
ty
::
Binder
(
self
.parse_projection_predicate
()));
}
'.'
=>
{
break
;
}
c
=>
{
bug!
(
"parse_bounds: bad bounds ('{}')"
,
c
)
}
}
}
ty
::
ExistentialBounds
::
new
(
region_bound
,
builtin_bounds
,
projection_bounds
)
}
fn
parse_builtin_bounds
(
&
mut
self
)
->
ty
::
BuiltinBounds
{
let
mut
builtin_bounds
=
ty
::
BuiltinBounds
::
empty
();
loop
{
...
...
src/librustc_metadata/tyencode.rs
浏览文件 @
4b25f085
...
...
@@ -104,11 +104,26 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx
enc_substs
(
w
,
cx
,
substs
);
write!
(
w
,
"]"
);
}
ty
::
TyTrait
(
box
ty
::
TraitTy
{
ref
principal
,
ref
bounds
})
=>
{
ty
::
TyTrait
(
ref
obj
)
=>
{
write!
(
w
,
"x["
);
enc_trait_ref
(
w
,
cx
,
principal
.0
);
enc_existential_bounds
(
w
,
cx
,
bounds
);
enc_existential_trait_ref
(
w
,
cx
,
obj
.principal
.0
);
enc_builtin_bounds
(
w
,
cx
,
&
obj
.builtin_bounds
);
enc_region
(
w
,
cx
,
obj
.region_bound
);
// Encode projection_bounds in a stable order
let
mut
projection_bounds
:
Vec
<
_
>
=
obj
.projection_bounds
.iter
()
.map
(|
b
|
(
b
.item_name
()
.as_str
(),
b
))
.collect
();
projection_bounds
.sort_by_key
(|
&
(
ref
name
,
_
)|
name
.clone
());
for
tp
in
projection_bounds
.iter
()
.map
(|
&
(
_
,
tp
)|
tp
)
{
write!
(
w
,
"P"
);
enc_existential_projection
(
w
,
cx
,
&
tp
.0
);
}
write!
(
w
,
"."
);
write!
(
w
,
"]"
);
}
ty
::
TyTuple
(
ts
)
=>
{
...
...
@@ -344,6 +359,12 @@ pub fn enc_trait_ref<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
enc_substs
(
w
,
cx
,
s
.substs
);
}
fn
enc_existential_trait_ref
<
'a
,
'tcx
>
(
w
:
&
mut
Cursor
<
Vec
<
u8
>>
,
cx
:
&
ctxt
<
'a
,
'tcx
>
,
s
:
ty
::
ExistentialTraitRef
<
'tcx
>
)
{
write!
(
w
,
"{}|"
,
(
cx
.ds
)(
cx
.tcx
,
s
.def_id
));
enc_substs
(
w
,
cx
,
s
.substs
);
}
fn
enc_unsafety
(
w
:
&
mut
Cursor
<
Vec
<
u8
>>
,
p
:
hir
::
Unsafety
)
{
match
p
{
hir
::
Unsafety
::
Normal
=>
write!
(
w
,
"n"
),
...
...
@@ -386,7 +407,7 @@ fn enc_fn_sig<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
enc_ty
(
w
,
cx
,
fsig
.0
.output
);
}
pub
fn
enc_builtin_bounds
(
w
:
&
mut
Cursor
<
Vec
<
u8
>>
,
_
cx
:
&
ctxt
,
bs
:
&
ty
::
BuiltinBounds
)
{
fn
enc_builtin_bounds
(
w
:
&
mut
Cursor
<
Vec
<
u8
>>
,
_
cx
:
&
ctxt
,
bs
:
&
ty
::
BuiltinBounds
)
{
for
bound
in
bs
{
match
bound
{
ty
::
BoundSend
=>
write!
(
w
,
"S"
),
...
...
@@ -399,28 +420,6 @@ pub fn enc_builtin_bounds(w: &mut Cursor<Vec<u8>>, _cx: &ctxt, bs: &ty::BuiltinB
write!
(
w
,
"."
);
}
pub
fn
enc_existential_bounds
<
'a
,
'tcx
>
(
w
:
&
mut
Cursor
<
Vec
<
u8
>>
,
cx
:
&
ctxt
<
'a
,
'tcx
>
,
bs
:
&
ty
::
ExistentialBounds
<
'tcx
>
)
{
enc_builtin_bounds
(
w
,
cx
,
&
bs
.builtin_bounds
);
enc_region
(
w
,
cx
,
bs
.region_bound
);
// Encode projection_bounds in a stable order
let
mut
projection_bounds
:
Vec
<
_
>
=
bs
.projection_bounds
.iter
()
.map
(|
b
|
(
b
.item_name
()
.as_str
(),
b
))
.collect
();
projection_bounds
.sort_by_key
(|
&
(
ref
name
,
_
)|
name
.clone
());
for
tp
in
projection_bounds
.iter
()
.map
(|
&
(
_
,
tp
)|
tp
)
{
write!
(
w
,
"P"
);
enc_projection_predicate
(
w
,
cx
,
&
tp
.0
);
}
write!
(
w
,
"."
);
}
pub
fn
enc_type_param_def
<
'a
,
'tcx
>
(
w
:
&
mut
Cursor
<
Vec
<
u8
>>
,
cx
:
&
ctxt
<
'a
,
'tcx
>
,
v
:
&
ty
::
TypeParameterDef
<
'tcx
>
)
{
write!
(
w
,
"{}:{}|{}|{}|{}|"
,
...
...
@@ -489,7 +488,9 @@ pub fn enc_predicate<'a, 'tcx>(w: &mut Cursor<Vec<u8>>,
}
ty
::
Predicate
::
Projection
(
ty
::
Binder
(
ref
data
))
=>
{
write!
(
w
,
"p"
);
enc_projection_predicate
(
w
,
cx
,
data
);
enc_trait_ref
(
w
,
cx
,
data
.projection_ty.trait_ref
);
write!
(
w
,
"{}|"
,
data
.projection_ty.item_name
);
enc_ty
(
w
,
cx
,
data
.ty
);
}
ty
::
Predicate
::
WellFormed
(
data
)
=>
{
write!
(
w
,
"w"
);
...
...
@@ -509,10 +510,10 @@ pub fn enc_predicate<'a, 'tcx>(w: &mut Cursor<Vec<u8>>,
}
}
fn
enc_
projection_predicate
<
'a
,
'tcx
>
(
w
:
&
mut
Cursor
<
Vec
<
u8
>>
,
cx
:
&
ctxt
<
'a
,
'tcx
>
,
data
:
&
ty
::
ProjectionPredicate
<
'tcx
>
)
{
enc_
trait_ref
(
w
,
cx
,
data
.projection_ty
.trait_ref
);
write!
(
w
,
"{}|"
,
data
.
projection_ty.
item_name
);
fn
enc_
existential_projection
<
'a
,
'tcx
>
(
w
:
&
mut
Cursor
<
Vec
<
u8
>>
,
cx
:
&
ctxt
<
'a
,
'tcx
>
,
data
:
&
ty
::
ExistentialProjection
<
'tcx
>
)
{
enc_
existential_trait_ref
(
w
,
cx
,
data
.trait_ref
);
write!
(
w
,
"{}|"
,
data
.item_name
);
enc_ty
(
w
,
cx
,
data
.ty
);
}
src/librustc_trans/base.rs
浏览文件 @
4b25f085
...
...
@@ -562,14 +562,9 @@ pub fn unsized_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>,
// change to the vtable.
old_info
.expect
(
"unsized_info: missing old info for trait upcast"
)
}
(
_
,
&
ty
::
TyTrait
(
box
ty
::
TraitTy
{
ref
principal
,
..
}))
=>
{
// Note that we preserve binding levels here:
let
substs
=
principal
.0
.substs
.with_self_ty
(
source
)
.erase_regions
();
let
substs
=
ccx
.tcx
()
.mk_substs
(
substs
);
let
trait_ref
=
ty
::
Binder
(
ty
::
TraitRef
{
def_id
:
principal
.def_id
(),
substs
:
substs
,
});
(
_
,
&
ty
::
TyTrait
(
ref
data
))
=>
{
let
trait_ref
=
data
.principal
.with_self_ty
(
ccx
.tcx
(),
source
);
let
trait_ref
=
ccx
.tcx
()
.erase_regions
(
&
trait_ref
);
consts
::
ptrcast
(
meth
::
get_vtable
(
ccx
,
trait_ref
),
Type
::
vtable_ptr
(
ccx
))
}
...
...
src/librustc_trans/collector.rs
浏览文件 @
4b25f085
...
...
@@ -1055,8 +1055,7 @@ fn create_trans_items_for_vtable_methods<'a, 'tcx>(scx: &SharedCrateContext<'a,
assert
!
(
!
trait_ty
.needs_subst
()
&&
!
impl_ty
.needs_subst
());
if
let
ty
::
TyTrait
(
ref
trait_ty
)
=
trait_ty
.sty
{
let
poly_trait_ref
=
trait_ty
.principal_trait_ref_with_self_ty
(
scx
.tcx
(),
impl_ty
);
let
poly_trait_ref
=
trait_ty
.principal
.with_self_ty
(
scx
.tcx
(),
impl_ty
);
// Walk all methods of the trait, including those of its supertraits
for
trait_ref
in
traits
::
supertraits
(
scx
.tcx
(),
poly_trait_ref
)
{
...
...
src/librustc_trans/debuginfo/metadata.rs
浏览文件 @
4b25f085
...
...
@@ -627,7 +627,7 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
// But it does not describe the trait's methods.
let
def_id
=
match
trait_type
.sty
{
ty
::
TyTrait
(
ref
data
)
=>
data
.principal
_
def_id
(),
ty
::
TyTrait
(
ref
data
)
=>
data
.principal
.
def_id
(),
_
=>
{
bug!
(
"debuginfo: Unexpected trait-object type in
\
trait_pointer_metadata(): {:?}"
,
...
...
src/librustc_trans/trans_item.rs
浏览文件 @
4b25f085
...
...
@@ -476,10 +476,10 @@ pub fn push_unique_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
output
.push
(
']'
);
},
ty
::
TyTrait
(
ref
trait_data
)
=>
{
push_item_name
(
tcx
,
trait_data
.principal
.
skip_binder
()
.def_id
,
output
);
push_item_name
(
tcx
,
trait_data
.principal
.
def_id
()
,
output
);
push_type_params
(
tcx
,
&
trait_data
.principal
.skip_binder
()
.substs.types
,
&
trait_data
.
bounds.
projection_bounds
,
&
trait_data
.projection_bounds
,
output
);
},
ty
::
TyFnDef
(
_
,
_
,
&
ty
::
BareFnTy
{
unsafety
,
abi
,
ref
sig
}
)
|
...
...
@@ -562,7 +562,7 @@ fn push_item_name(tcx: TyCtxt,
fn
push_type_params
<
'a
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
types
:
&
'tcx
subst
::
VecPerParamSpace
<
Ty
<
'tcx
>>
,
projections
:
&
[
ty
::
Poly
ProjectionPredicate
<
'tcx
>
],
projections
:
&
[
ty
::
Poly
ExistentialProjection
<
'tcx
>
],
output
:
&
mut
String
)
{
if
types
.is_empty
()
&&
projections
.is_empty
()
{
return
;
...
...
@@ -577,7 +577,7 @@ fn push_type_params<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
for
projection
in
projections
{
let
projection
=
projection
.skip_binder
();
let
name
=
&
projection
.
projection_ty.
item_name
.as_str
();
let
name
=
&
projection
.item_name
.as_str
();
output
.push_str
(
name
);
output
.push_str
(
"="
);
push_unique_type_name
(
tcx
,
projection
.ty
,
output
);
...
...
src/librustc_typeck/astconv.rs
浏览文件 @
4b25f085
此差异已折叠。
点击以展开。
src/librustc_typeck/check/cast.rs
浏览文件 @
4b25f085
...
...
@@ -78,7 +78,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
fn
unsize_kind
(
&
self
,
t
:
Ty
<
'tcx
>
)
->
Option
<
UnsizeKind
<
'tcx
>>
{
match
t
.sty
{
ty
::
TySlice
(
_
)
|
ty
::
TyStr
=>
Some
(
UnsizeKind
::
Length
),
ty
::
TyTrait
(
ref
tty
)
=>
Some
(
UnsizeKind
::
Vtable
(
tty
.principal
_
def_id
())),
ty
::
TyTrait
(
ref
tty
)
=>
Some
(
UnsizeKind
::
Vtable
(
tty
.principal
.
def_id
())),
ty
::
TyStruct
(
def
,
substs
)
=>
{
// FIXME(arielb1): do some kind of normalization
match
def
.struct_variant
()
.fields
.last
()
{
...
...
src/librustc_typeck/check/closure.rs
浏览文件 @
4b25f085
...
...
@@ -102,12 +102,11 @@ fn deduce_expectations_from_expected_type(&self, expected_ty: Ty<'tcx>)
match
expected_ty
.sty
{
ty
::
TyTrait
(
ref
object_type
)
=>
{
let
proj_bounds
=
object_type
.projection_bounds_with_self_ty
(
self
.tcx
,
self
.tcx.types.err
);
let
sig
=
proj_bounds
.iter
()
.filter_map
(|
pb
|
self
.deduce_sig_from_projection
(
pb
))
.next
();
let
kind
=
self
.tcx.lang_items
.fn_trait_kind
(
object_type
.principal_def_id
());
let
sig
=
object_type
.projection_bounds
.iter
()
.filter_map
(|
pb
|
{
let
pb
=
pb
.with_self_ty
(
self
.tcx
,
self
.tcx.types.err
);
self
.deduce_sig_from_projection
(
&
pb
)
})
.next
();
let
kind
=
self
.tcx.lang_items
.fn_trait_kind
(
object_type
.principal
.def_id
());
(
sig
,
kind
)
}
ty
::
TyInfer
(
ty
::
TyVar
(
vid
))
=>
{
...
...
src/librustc_typeck/check/method/confirm.rs
浏览文件 @
4b25f085
...
...
@@ -210,7 +210,7 @@ fn fresh_receiver_substs(&mut self,
probe
::
ObjectPick
=>
{
let
trait_def_id
=
pick
.item
.container
()
.id
();
self
.extract_
trait_ref
(
self_ty
,
|
this
,
object_ty
,
data
|
{
self
.extract_
existential_trait_ref
(
self_ty
,
|
this
,
object_ty
,
principal
|
{
// The object data has no entry for the Self
// Type. For the purposes of this method call, we
// substitute the object type itself. This
...
...
@@ -222,9 +222,9 @@ fn fresh_receiver_substs(&mut self,
// been ruled out when we deemed the trait to be
// "object safe".
let
original_poly_trait_ref
=
data
.principal_trait_ref_
with_self_ty
(
this
.tcx
,
object_ty
);
principal
.
with_self_ty
(
this
.tcx
,
object_ty
);
let
upcast_poly_trait_ref
=
this
.upcast
(
original_poly_trait_ref
.clone
()
,
trait_def_id
);
this
.upcast
(
original_poly_trait_ref
,
trait_def_id
);
let
upcast_trait_ref
=
this
.replace_late_bound_regions_with_fresh_var
(
&
upcast_poly_trait_ref
);
debug!
(
"original_poly_trait_ref={:?} upcast_trait_ref={:?} target_trait={:?}"
,
...
...
@@ -276,8 +276,12 @@ fn fresh_receiver_substs(&mut self,
}
}
fn
extract_trait_ref
<
R
,
F
>
(
&
mut
self
,
self_ty
:
Ty
<
'tcx
>
,
mut
closure
:
F
)
->
R
where
F
:
FnMut
(
&
mut
ConfirmContext
<
'a
,
'gcx
,
'tcx
>
,
Ty
<
'tcx
>
,
&
ty
::
TraitTy
<
'tcx
>
)
->
R
,
fn
extract_existential_trait_ref
<
R
,
F
>
(
&
mut
self
,
self_ty
:
Ty
<
'tcx
>
,
mut
closure
:
F
)
->
R
where
F
:
FnMut
(
&
mut
ConfirmContext
<
'a
,
'gcx
,
'tcx
>
,
Ty
<
'tcx
>
,
ty
::
PolyExistentialTraitRef
<
'tcx
>
)
->
R
,
{
// If we specified that this is an object method, then the
// self-type ought to be something that can be dereferenced to
...
...
@@ -288,7 +292,7 @@ fn extract_trait_ref<R, F>(&mut self, self_ty: Ty<'tcx>, mut closure: F) -> R wh
self
.fcx
.autoderef
(
self
.span
,
self_ty
)
.filter_map
(|(
ty
,
_
)|
{
match
ty
.sty
{
ty
::
TyTrait
(
ref
data
)
=>
Some
(
closure
(
self
,
ty
,
&
data
)),
ty
::
TyTrait
(
ref
data
)
=>
Some
(
closure
(
self
,
ty
,
data
.principal
)),
_
=>
None
,
}
})
...
...
@@ -331,9 +335,7 @@ fn instantiate_method_substs(&mut self,
// parameters from the type and those from the method.
//
// FIXME -- permit users to manually specify lifetimes
let
type_defs
=
method
.generics.types
.as_full_slice
();
let
region_defs
=
method
.generics.regions
.as_full_slice
();
subst
::
Substs
::
from_param_defs
(
region_defs
,
type_defs
,
|
def
|
{
subst
::
Substs
::
from_generics
(
&
method
.generics
,
|
def
,
_
|
{
if
def
.space
!=
subst
::
FnSpace
{
substs
.region_for_def
(
def
)
}
else
{
...
...
src/librustc_typeck/check/method/mod.rs
浏览文件 @
4b25f085
...
...
@@ -189,9 +189,7 @@ pub fn lookup_method_in_trait_adjusted(&self,
assert
!
(
trait_def
.generics.regions
.is_empty
());
// Construct a trait-reference `self_ty : Trait<input_tys>`
let
type_defs
=
trait_def
.generics.types
.as_full_slice
();
let
region_defs
=
trait_def
.generics.regions
.as_full_slice
();
let
substs
=
subst
::
Substs
::
from_param_defs
(
region_defs
,
type_defs
,
|
def
|
{
let
substs
=
subst
::
Substs
::
from_generics
(
&
trait_def
.generics
,
|
def
,
_
|
{
self
.region_var_for_def
(
span
,
def
)
},
|
def
,
substs
|
{
if
def
.space
==
subst
::
SelfSpace
{
...
...
src/librustc_typeck/check/method/probe.rs
浏览文件 @
4b25f085
...
...
@@ -290,8 +290,8 @@ fn assemble_probe(&mut self, self_ty: Ty<'tcx>) {
match
self_ty
.sty
{
ty
::
TyTrait
(
box
ref
data
)
=>
{
self
.assemble_inherent_candidates_from_object
(
self_ty
,
data
);
self
.assemble_inherent_impl_candidates_for_type
(
data
.principal
_
def_id
());
self
.assemble_inherent_candidates_from_object
(
self_ty
,
data
.principal
);
self
.assemble_inherent_impl_candidates_for_type
(
data
.principal
.
def_id
());
}
ty
::
TyEnum
(
def
,
_
)
|
ty
::
TyStruct
(
def
,
_
)
=>
{
...
...
@@ -445,7 +445,7 @@ fn assemble_inherent_impl_probe(&mut self, impl_def_id: DefId) {
fn
assemble_inherent_candidates_from_object
(
&
mut
self
,
self_ty
:
Ty
<
'tcx
>
,
data
:
&
ty
::
TraitTy
<
'tcx
>
)
{
principal
:
ty
::
PolyExistentialTraitRef
<
'tcx
>
)
{
debug!
(
"assemble_inherent_candidates_from_object(self_ty={:?})"
,
self_ty
);
...
...
@@ -456,7 +456,7 @@ fn assemble_inherent_candidates_from_object(&mut self,
// a substitution that replaces `Self` with the object type
// itself. Hence, a `&self` method will wind up with an
// argument type like `&Trait`.
let
trait_ref
=
data
.principal_trait_ref_
with_self_ty
(
self
.tcx
,
self_ty
);
let
trait_ref
=
principal
.
with_self_ty
(
self
.tcx
,
self_ty
);
self
.elaborate_bounds
(
&
[
trait_ref
],
|
this
,
new_trait_ref
,
item
|
{
let
new_trait_ref
=
this
.erase_late_bound_regions
(
&
new_trait_ref
);
...
...
@@ -1227,15 +1227,16 @@ fn xform_method_self_ty(&self,
return
impl_ty
;
}
let
placeholder
;
let
mut
substs
=
substs
;
if
!
method
.generics.types
.is_empty_in
(
subst
::
FnSpace
)
||
!
method
.generics.regions
.is_empty_in
(
subst
::
FnSpace
)
{
let
type_defs
=
method
.generics.types
.as_full_slice
();
let
region_defs
=
method
.generics.regions
.as_full_slice
();
placeholder
=
subst
::
Substs
::
from_param_defs
(
region_defs
,
type_defs
,
|
def
|
{
// Erase any late-bound regions from the method and substitute
// in the values from the substitution.
let
xform_self_ty
=
method
.fty.sig
.input
(
0
);
let
xform_self_ty
=
self
.erase_late_bound_regions
(
&
xform_self_ty
);
if
method
.generics.types
.is_empty_in
(
subst
::
FnSpace
)
&&
method
.generics.regions
.is_empty_in
(
subst
::
FnSpace
)
{
xform_self_ty
.subst
(
self
.tcx
,
substs
)
}
else
{
let
substs
=
subst
::
Substs
::
from_generics
(
&
method
.generics
,
|
def
,
_
|
{
if
def
.space
!=
subst
::
FnSpace
{
substs
.region_for_def
(
def
)
}
else
{
...
...
@@ -1250,16 +1251,8 @@ fn xform_method_self_ty(&self,
self
.type_var_for_def
(
self
.span
,
def
,
cur_substs
)
}
});
substs
=
&
placeholder
;
xform_self_ty
.subst
(
self
.tcx
,
&
substs
)
}
// Erase any late-bound regions from the method and substitute
// in the values from the substitution.
let
xform_self_ty
=
method
.fty.sig
.input
(
0
);
let
xform_self_ty
=
self
.erase_late_bound_regions
(
&
xform_self_ty
);
let
xform_self_ty
=
xform_self_ty
.subst
(
self
.tcx
,
substs
);
xform_self_ty
}
/// Get the type of an impl and generate substitutions with placeholders.
...
...
src/librustc_typeck/check/method/suggest.rs
浏览文件 @
4b25f085
...
...
@@ -358,7 +358,7 @@ fn is_local(ty: Ty) -> bool {
match
ty
.sty
{
ty
::
TyEnum
(
def
,
_
)
|
ty
::
TyStruct
(
def
,
_
)
=>
def
.did
.is_local
(),
ty
::
TyTrait
(
ref
tr
)
=>
tr
.principal
_
def_id
()
.is_local
(),
ty
::
TyTrait
(
ref
tr
)
=>
tr
.principal
.
def_id
()
.is_local
(),
ty
::
TyParam
(
_
)
=>
true
,
...
...
src/librustc_typeck/check/regionck.rs
浏览文件 @
4b25f085
...
...
@@ -824,11 +824,11 @@ fn walk_cast(&mut self,
}
/*From:*/
(
_
,
/*To: */
&
ty
::
TyTrait
(
box
ty
::
TraitTy
{
ref
bounds
,
..
}
))
=>
{
/*To: */
&
ty
::
TyTrait
(
ref
obj
))
=>
{
// When T is existentially quantified as a trait
// `Foo+'to`, it must outlive the region bound `'to`.
self
.type_must_outlive
(
infer
::
RelateObjectBound
(
cast_expr
.span
),
from_ty
,
bounds
.region_bound
);
from_ty
,
obj
.region_bound
);
}
/*From:*/
(
&
ty
::
TyBox
(
from_referent_ty
),
...
...
src/librustc_typeck/coherence/mod.rs
浏览文件 @
4b25f085
...
...
@@ -75,7 +75,7 @@ fn get_base_type_def_id(&self, span: Span, ty: Ty<'tcx>) -> Option<DefId> {
}
TyTrait
(
ref
t
)
=>
{
Some
(
t
.principal
_
def_id
())
Some
(
t
.principal
.
def_id
())
}
TyBox
(
_
)
=>
{
...
...
src/librustc_typeck/coherence/orphan.rs
浏览文件 @
4b25f085
...
...
@@ -80,7 +80,7 @@ fn check_item(&self, item: &hir::Item) {
self
.check_def_id
(
item
,
def
.did
);
}
ty
::
TyTrait
(
ref
data
)
=>
{
self
.check_def_id
(
item
,
data
.principal
_
def_id
());
self
.check_def_id
(
item
,
data
.principal
.
def_id
());
}
ty
::
TyBox
(
..
)
=>
{
match
self
.tcx.lang_items
.require_owned_box
()
{
...
...
src/librustc_typeck/coherence/overlap.rs
浏览文件 @
4b25f085
...
...
@@ -168,14 +168,14 @@ fn visit_item(&mut self, item: &'v hir::Item) {
// This is something like impl Trait1 for Trait2. Illegal
// if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
if
!
self
.tcx
.is_object_safe
(
data
.principal
_
def_id
())
{
if
!
self
.tcx
.is_object_safe
(
data
.principal
.
def_id
())
{
// This is an error, but it will be
// reported by wfcheck. Ignore it
// here. This is tested by
// `coherence-impl-trait-for-trait-object-safe.rs`.
}
else
{
let
mut
supertrait_def_ids
=
traits
::
supertrait_def_ids
(
self
.tcx
,
data
.principal
_
def_id
());
traits
::
supertrait_def_ids
(
self
.tcx
,
data
.principal
.
def_id
());
if
supertrait_def_ids
.any
(|
d
|
d
==
trait_def_id
)
{
span_err!
(
self
.tcx.sess
,
item
.span
,
E0371
,
"the object type `{}` automatically
\
...
...
src/librustc_typeck/collect.rs
浏览文件 @
4b25f085
...
...
@@ -722,7 +722,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
AstConv
::
instantiate_mono_trait_ref
(
&
ccx
.icx
(
&
()),
&
ExplicitRscope
,
ast_trait_ref
,
None
);
tcx
.mk_self_type
()
);
tcx
.record_trait_has_default_impl
(
trait_ref
.def_id
);
...
...
@@ -752,7 +752,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
AstConv
::
instantiate_mono_trait_ref
(
&
ccx
.icx
(
&
ty_predicates
),
&
ExplicitRscope
,
ast_trait_ref
,
Some
(
selfty
)
)
selfty
)
});
tcx
.impl_trait_refs
.borrow_mut
()
.insert
(
def_id
,
trait_ref
);
...
...
@@ -1815,10 +1815,12 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
let
mut
projections
=
Vec
::
new
();
let
trait_ref
=
conv_poly_trait_ref
(
&
ccx
.icx
(
&
(
base_predicates
,
ast_generics
)),
ty
,
poly_trait_ref
,
&
mut
projections
);
AstConv
::
instantiate_poly_trait_ref
(
&
ccx
.icx
(
&
(
base_predicates
,
ast_generics
)),
&
ExplicitRscope
,
poly_trait_ref
,
ty
,
&
mut
projections
);
result
.predicates
.push
(
trait_ref
.to_predicate
());
...
...
@@ -2069,7 +2071,7 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
let
mut
trait_bounds
:
Vec
<
_
>
=
trait_bounds
.iter
()
.map
(|
&
bound
|
{
astconv
.instantiate_poly_trait_ref
(
&
rscope
,
bound
,
Some
(
param_ty
)
,
param_ty
,
&
mut
projection_bounds
)
})
.collect
();
...
...
@@ -2100,7 +2102,10 @@ fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>,
match
*
bound
{
hir
::
TraitTyParamBound
(
ref
tr
,
hir
::
TraitBoundModifier
::
None
)
=>
{
let
mut
projections
=
Vec
::
new
();
let
pred
=
conv_poly_trait_ref
(
astconv
,
param_ty
,
tr
,
&
mut
projections
);
let
pred
=
astconv
.instantiate_poly_trait_ref
(
&
ExplicitRscope
,
tr
,
param_ty
,
&
mut
projections
);
projections
.into_iter
()
.map
(|
p
|
p
.to_predicate
())
.chain
(
Some
(
pred
.to_predicate
()))
...
...
@@ -2117,19 +2122,6 @@ fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>,
}
}
fn
conv_poly_trait_ref
<
'gcx
:
'tcx
,
'tcx
>
(
astconv
:
&
AstConv
<
'gcx
,
'tcx
>
,
param_ty
:
Ty
<
'tcx
>
,
trait_ref
:
&
hir
::
PolyTraitRef
,
projections
:
&
mut
Vec
<
ty
::
PolyProjectionPredicate
<
'tcx
>>
)
->
ty
::
PolyTraitRef
<
'tcx
>
{
AstConv
::
instantiate_poly_trait_ref
(
astconv
,
&
ExplicitRscope
,
trait_ref
,
Some
(
param_ty
),
projections
)
}
fn
compute_type_scheme_of_foreign_fn_decl
<
'a
,
'tcx
>
(
ccx
:
&
CrateCtxt
<
'a
,
'tcx
>
,
id
:
DefId
,
...
...
src/librustc_typeck/variance/constraints.rs
浏览文件 @
4b25f085
...
...
@@ -396,19 +396,16 @@ fn add_constraints_from_ty(&mut self,
ty
::
TyTrait
(
ref
data
)
=>
{
let
poly_trait_ref
=
data
.principal_trait_ref_with_self_ty
(
self
.tcx
(),
self
.tcx
()
.types.err
);
data
.principal
.with_self_ty
(
self
.tcx
(),
self
.tcx
()
.types.err
);
// The type `Foo<T+'a>` is contravariant w/r/t `'a`:
let
contra
=
self
.contravariant
(
variance
);
self
.add_constraints_from_region
(
generics
,
data
.
bounds.
region_bound
,
contra
);
self
.add_constraints_from_region
(
generics
,
data
.region_bound
,
contra
);
// Ignore the SelfSpace, it is erased.
self
.add_constraints_from_trait_ref
(
generics
,
poly_trait_ref
.0
,
variance
);
let
projections
=
data
.projection_bounds_with_self_ty
(
self
.tcx
(),
self
.tcx
()
.types.err
);
for
projection
in
&
projections
{
for
projection
in
&
data
.projection_bounds
{
self
.add_constraints_from_ty
(
generics
,
projection
.0
.ty
,
self
.invariant
);
}
}
...
...
src/librustdoc/clean/mod.rs
浏览文件 @
4b25f085
...
...
@@ -630,26 +630,6 @@ fn clean(&self, cx: &DocContext) -> TyParamBound {
}
}
impl
<
'tcx
>
Clean
<
(
Vec
<
TyParamBound
>
,
Vec
<
TypeBinding
>
)
>
for
ty
::
ExistentialBounds
<
'tcx
>
{
fn
clean
(
&
self
,
cx
:
&
DocContext
)
->
(
Vec
<
TyParamBound
>
,
Vec
<
TypeBinding
>
)
{
let
mut
tp_bounds
=
vec!
[];
self
.region_bound
.clean
(
cx
)
.map
(|
b
|
tp_bounds
.push
(
RegionBound
(
b
)));
for
bb
in
&
self
.builtin_bounds
{
tp_bounds
.push
(
bb
.clean
(
cx
));
}
let
mut
bindings
=
vec!
[];
for
&
ty
::
Binder
(
ref
pb
)
in
&
self
.projection_bounds
{
bindings
.push
(
TypeBinding
{
name
:
pb
.projection_ty.item_name
.clean
(
cx
),
ty
:
pb
.ty
.clean
(
cx
)
});
}
(
tp_bounds
,
bindings
)
}
}
fn
external_path_params
(
cx
:
&
DocContext
,
trait_did
:
Option
<
DefId
>
,
bindings
:
Vec
<
TypeBinding
>
,
substs
:
&
subst
::
Substs
)
->
PathParameters
{
let
lifetimes
=
substs
.regions
.get_slice
(
subst
::
TypeSpace
)
...
...
@@ -1848,12 +1828,26 @@ fn clean(&self, cx: &DocContext) -> Type {
is_generic
:
false
,
}
}
ty
::
TyTrait
(
box
ty
::
TraitTy
{
ref
principal
,
ref
bounds
}
)
=>
{
let
did
=
principal
.def_id
();
ty
::
TyTrait
(
ref
obj
)
=>
{
let
did
=
obj
.
principal
.def_id
();
inline
::
record_extern_fqn
(
cx
,
did
,
TypeTrait
);
let
(
typarams
,
bindings
)
=
bounds
.clean
(
cx
);
let
mut
typarams
=
vec!
[];
obj
.region_bound
.clean
(
cx
)
.map
(|
b
|
typarams
.push
(
RegionBound
(
b
)));
for
bb
in
&
obj
.builtin_bounds
{
typarams
.push
(
bb
.clean
(
cx
));
}
let
mut
bindings
=
vec!
[];
for
&
ty
::
Binder
(
ref
pb
)
in
&
obj
.projection_bounds
{
bindings
.push
(
TypeBinding
{
name
:
pb
.item_name
.clean
(
cx
),
ty
:
pb
.ty
.clean
(
cx
)
});
}
let
path
=
external_path
(
cx
,
&
cx
.tcx
()
.item_name
(
did
)
.as_str
(),
Some
(
did
),
bindings
,
principal
.substs
()
);
Some
(
did
),
bindings
,
obj
.principal
.0
.substs
);
ResolvedPath
{
path
:
path
,
typarams
:
Some
(
typarams
),
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录