Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
8a19b234
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,发现更多精彩内容 >>
提交
8a19b234
编写于
9月 15, 2015
作者:
B
bors
浏览文件
操作
浏览文件
下载
差异文件
Auto merge of #28413 - arielb1:deduplication, r=eddyb
clean a few things discovered during my split_ty work r?
@EddyB
上级
3887ca27
5e4704f6
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
140 addition
and
286 deletion
+140
-286
src/librustc/middle/infer/mod.rs
src/librustc/middle/infer/mod.rs
+6
-71
src/librustc/middle/traits/structural_impls.rs
src/librustc/middle/traits/structural_impls.rs
+55
-9
src/librustc/middle/ty/fold.rs
src/librustc/middle/ty/fold.rs
+52
-28
src/librustc/middle/ty/mod.rs
src/librustc/middle/ty/mod.rs
+0
-16
src/librustc/middle/ty/structural_impls.rs
src/librustc/middle/ty/structural_impls.rs
+13
-0
src/librustc_trans/trans/callee.rs
src/librustc_trans/trans/callee.rs
+3
-2
src/librustc_trans/trans/closure.rs
src/librustc_trans/trans/closure.rs
+1
-1
src/librustc_trans/trans/common.rs
src/librustc_trans/trans/common.rs
+4
-115
src/librustc_trans/trans/debuginfo/mod.rs
src/librustc_trans/trans/debuginfo/mod.rs
+2
-1
src/librustc_trans/trans/declare.rs
src/librustc_trans/trans/declare.rs
+1
-2
src/librustc_trans/trans/monomorphize.rs
src/librustc_trans/trans/monomorphize.rs
+1
-39
src/librustc_trans/trans/type_of.rs
src/librustc_trans/trans/type_of.rs
+1
-1
src/librustc_typeck/check/method/mod.rs
src/librustc_typeck/check/method/mod.rs
+1
-1
未找到文件。
src/librustc/middle/infer/mod.rs
浏览文件 @
8a19b234
...
...
@@ -503,7 +503,7 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
{
debug!
(
"normalize_associated_type(t={:?})"
,
value
);
let
value
=
erase_regions
(
tcx
,
value
);
let
value
=
tcx
.erase_regions
(
value
);
if
!
value
.has_projection_types
()
{
return
value
;
...
...
@@ -525,9 +525,7 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
fulfill_cx
.register_predicate_obligation
(
&
infcx
,
obligation
);
}
let
result
=
drain_fulfillment_cx_or_panic
(
DUMMY_SP
,
&
infcx
,
&
mut
fulfill_cx
,
&
result
);
result
drain_fulfillment_cx_or_panic
(
DUMMY_SP
,
&
infcx
,
&
mut
fulfill_cx
,
&
result
)
}
pub
fn
drain_fulfillment_cx_or_panic
<
'a
,
'tcx
,
T
>
(
span
:
Span
,
...
...
@@ -535,7 +533,7 @@ pub fn drain_fulfillment_cx_or_panic<'a,'tcx,T>(span: Span,
fulfill_cx
:
&
mut
traits
::
FulfillmentContext
<
'tcx
>
,
result
:
&
T
)
->
T
where
T
:
TypeFoldable
<
'tcx
>
where
T
:
TypeFoldable
<
'tcx
>
+
HasTypeFlags
{
match
drain_fulfillment_cx
(
infcx
,
fulfill_cx
,
result
)
{
Ok
(
v
)
=>
v
,
...
...
@@ -559,7 +557,7 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
fulfill_cx
:
&
mut
traits
::
FulfillmentContext
<
'tcx
>
,
result
:
&
T
)
->
Result
<
T
,
Vec
<
traits
::
FulfillmentError
<
'tcx
>>>
where
T
:
TypeFoldable
<
'tcx
>
where
T
:
TypeFoldable
<
'tcx
>
+
HasTypeFlags
{
debug!
(
"drain_fulfillment_cx(result={:?})"
,
result
);
...
...
@@ -574,71 +572,8 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
}
}
// Use freshen to simultaneously replace all type variables with
// their bindings and replace all regions with 'static. This is
// sort of overkill because we do not expect there to be any
// unbound type variables, hence no `TyFresh` types should ever be
// inserted.
Ok
(
result
.fold_with
(
&
mut
infcx
.freshener
()))
}
/// Returns an equivalent value with all free regions removed (note
/// that late-bound regions remain, because they are important for
/// subtyping, but they are anonymized and normalized as well). This
/// is a stronger, caching version of `ty::fold::erase_regions`.
pub
fn
erase_regions
<
'tcx
,
T
>
(
cx
:
&
ty
::
ctxt
<
'tcx
>
,
value
:
&
T
)
->
T
where
T
:
TypeFoldable
<
'tcx
>
{
let
value1
=
value
.fold_with
(
&
mut
RegionEraser
(
cx
));
debug!
(
"erase_regions({:?}) = {:?}"
,
value
,
value1
);
return
value1
;
struct
RegionEraser
<
'a
,
'tcx
:
'a
>
(
&
'a
ty
::
ctxt
<
'tcx
>
);
impl
<
'a
,
'tcx
>
TypeFolder
<
'tcx
>
for
RegionEraser
<
'a
,
'tcx
>
{
fn
tcx
(
&
self
)
->
&
ty
::
ctxt
<
'tcx
>
{
self
.0
}
fn
fold_ty
(
&
mut
self
,
ty
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
match
self
.tcx
()
.normalized_cache
.borrow
()
.get
(
&
ty
)
.cloned
()
{
None
=>
{}
Some
(
u
)
=>
return
u
}
let
t_norm
=
ty
::
fold
::
super_fold_ty
(
self
,
ty
);
self
.tcx
()
.normalized_cache
.borrow_mut
()
.insert
(
ty
,
t_norm
);
return
t_norm
;
}
fn
fold_binder
<
T
>
(
&
mut
self
,
t
:
&
ty
::
Binder
<
T
>
)
->
ty
::
Binder
<
T
>
where
T
:
TypeFoldable
<
'tcx
>
{
let
u
=
self
.tcx
()
.anonymize_late_bound_regions
(
t
);
ty
::
fold
::
super_fold_binder
(
self
,
&
u
)
}
fn
fold_region
(
&
mut
self
,
r
:
ty
::
Region
)
->
ty
::
Region
{
// because late-bound regions affect subtyping, we can't
// erase the bound/free distinction, but we can replace
// all free regions with 'static.
//
// Note that we *CAN* replace early-bound regions -- the
// type system never "sees" those, they get substituted
// away. In trans, they will always be erased to 'static
// whenever a substitution occurs.
match
r
{
ty
::
ReLateBound
(
..
)
=>
r
,
_
=>
ty
::
ReStatic
}
}
fn
fold_substs
(
&
mut
self
,
substs
:
&
subst
::
Substs
<
'tcx
>
)
->
subst
::
Substs
<
'tcx
>
{
subst
::
Substs
{
regions
:
subst
::
ErasedRegions
,
types
:
substs
.types
.fold_with
(
self
)
}
}
}
let
result
=
infcx
.resolve_type_vars_if_possible
(
result
);
Ok
(
infcx
.tcx
.erase_regions
(
&
result
))
}
impl
<
'a
,
'tcx
>
InferCtxt
<
'a
,
'tcx
>
{
...
...
src/librustc/middle/traits/structural_impls.rs
浏览文件 @
8a19b234
...
...
@@ -150,6 +150,52 @@ fn has_type_flags(&self, flags: TypeFlags) -> bool {
}
}
impl
<
'tcx
,
N
:
HasTypeFlags
>
HasTypeFlags
for
traits
::
VtableImplData
<
'tcx
,
N
>
{
fn
has_type_flags
(
&
self
,
flags
:
TypeFlags
)
->
bool
{
self
.substs
.has_type_flags
(
flags
)
||
self
.nested
.has_type_flags
(
flags
)
}
}
impl
<
'tcx
,
N
:
HasTypeFlags
>
HasTypeFlags
for
traits
::
VtableClosureData
<
'tcx
,
N
>
{
fn
has_type_flags
(
&
self
,
flags
:
TypeFlags
)
->
bool
{
self
.substs
.has_type_flags
(
flags
)
||
self
.nested
.has_type_flags
(
flags
)
}
}
impl
<
'tcx
,
N
:
HasTypeFlags
>
HasTypeFlags
for
traits
::
VtableDefaultImplData
<
N
>
{
fn
has_type_flags
(
&
self
,
flags
:
TypeFlags
)
->
bool
{
self
.nested
.has_type_flags
(
flags
)
}
}
impl
<
'tcx
,
N
:
HasTypeFlags
>
HasTypeFlags
for
traits
::
VtableBuiltinData
<
N
>
{
fn
has_type_flags
(
&
self
,
flags
:
TypeFlags
)
->
bool
{
self
.nested
.has_type_flags
(
flags
)
}
}
impl
<
'tcx
>
HasTypeFlags
for
traits
::
VtableObjectData
<
'tcx
>
{
fn
has_type_flags
(
&
self
,
flags
:
TypeFlags
)
->
bool
{
self
.upcast_trait_ref
.has_type_flags
(
flags
)
}
}
impl
<
'tcx
,
N
:
HasTypeFlags
>
HasTypeFlags
for
traits
::
Vtable
<
'tcx
,
N
>
{
fn
has_type_flags
(
&
self
,
flags
:
TypeFlags
)
->
bool
{
match
*
self
{
traits
::
VtableImpl
(
ref
v
)
=>
v
.has_type_flags
(
flags
),
traits
::
VtableDefaultImpl
(
ref
t
)
=>
t
.has_type_flags
(
flags
),
traits
::
VtableClosure
(
ref
d
)
=>
d
.has_type_flags
(
flags
),
traits
::
VtableFnPointer
(
ref
d
)
=>
d
.has_type_flags
(
flags
),
traits
::
VtableParam
(
ref
n
)
=>
n
.has_type_flags
(
flags
),
traits
::
VtableBuiltin
(
ref
d
)
=>
d
.has_type_flags
(
flags
),
traits
::
VtableObject
(
ref
d
)
=>
d
.has_type_flags
(
flags
)
}
}
}
impl
<
'tcx
,
O
:
TypeFoldable
<
'tcx
>>
TypeFoldable
<
'tcx
>
for
traits
::
Obligation
<
'tcx
,
O
>
{
fn
fold_with
<
F
:
TypeFolder
<
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
traits
::
Obligation
<
'tcx
,
O
>
{
...
...
@@ -198,6 +244,15 @@ fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::VtableBuiltin
}
}
impl
<
'tcx
>
TypeFoldable
<
'tcx
>
for
traits
::
VtableObjectData
<
'tcx
>
{
fn
fold_with
<
F
:
TypeFolder
<
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
traits
::
VtableObjectData
<
'tcx
>
{
traits
::
VtableObjectData
{
upcast_trait_ref
:
self
.upcast_trait_ref
.fold_with
(
folder
),
vtable_base
:
self
.vtable_base
}
}
}
impl
<
'tcx
,
N
:
TypeFoldable
<
'tcx
>>
TypeFoldable
<
'tcx
>
for
traits
::
Vtable
<
'tcx
,
N
>
{
fn
fold_with
<
F
:
TypeFolder
<
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
traits
::
Vtable
<
'tcx
,
N
>
{
match
*
self
{
...
...
@@ -216,15 +271,6 @@ fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::Vtable<'tcx,
}
}
impl
<
'tcx
>
TypeFoldable
<
'tcx
>
for
traits
::
VtableObjectData
<
'tcx
>
{
fn
fold_with
<
F
:
TypeFolder
<
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
traits
::
VtableObjectData
<
'tcx
>
{
traits
::
VtableObjectData
{
upcast_trait_ref
:
self
.upcast_trait_ref
.fold_with
(
folder
),
vtable_base
:
self
.vtable_base
}
}
}
impl
<
'tcx
,
T
:
TypeFoldable
<
'tcx
>>
TypeFoldable
<
'tcx
>
for
Normalized
<
'tcx
,
T
>
{
fn
fold_with
<
F
:
TypeFolder
<
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
Normalized
<
'tcx
,
T
>
{
Normalized
{
...
...
src/librustc/middle/ty/fold.rs
浏览文件 @
8a19b234
...
...
@@ -37,7 +37,7 @@
use
middle
::
region
;
use
middle
::
subst
;
use
middle
::
ty
::
adjustment
;
use
middle
::
ty
::{
self
,
Binder
,
Ty
,
HasTypeFlags
,
RegionEscape
};
use
middle
::
ty
::{
self
,
Binder
,
Ty
,
RegionEscape
};
use
std
::
fmt
;
use
util
::
nodemap
::{
FnvHashMap
,
FnvHashSet
};
...
...
@@ -588,39 +588,63 @@ fn fold_region(&mut self, r: ty::Region) -> ty::Region {
///////////////////////////////////////////////////////////////////////////
// Region eraser
//
// Replaces all free regions with 'static. Useful in contexts, such as
// method probing, where precise region relationships are not
// important. Note that in trans you should use
// `common::erase_regions` instead.
pub
struct
RegionEraser
<
'a
,
'tcx
:
'a
>
{
tcx
:
&
'a
ty
::
ctxt
<
'tcx
>
,
}
impl
<
'tcx
>
ty
::
ctxt
<
'tcx
>
{
/// Returns an equivalent value with all free regions removed (note
/// that late-bound regions remain, because they are important for
/// subtyping, but they are anonymized and normalized as well)..
pub
fn
erase_regions
<
T
>
(
&
self
,
value
:
&
T
)
->
T
where
T
:
TypeFoldable
<
'tcx
>
{
let
value1
=
value
.fold_with
(
&
mut
RegionEraser
(
self
));
debug!
(
"erase_regions({:?}) = {:?}"
,
value
,
value1
);
return
value1
;
pub
fn
erase_regions
<
'tcx
,
T
:
TypeFoldable
<
'tcx
>>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
t
:
T
)
->
T
{
let
mut
eraser
=
RegionEraser
{
tcx
:
tcx
};
t
.fold_with
(
&
mut
eraser
)
}
struct
RegionEraser
<
'a
,
'tcx
:
'a
>
(
&
'a
ty
::
ctxt
<
'tcx
>
);
impl
<
'a
,
'tcx
>
TypeFolder
<
'tcx
>
for
RegionEraser
<
'a
,
'tcx
>
{
fn
tcx
(
&
self
)
->
&
ty
::
ctxt
<
'tcx
>
{
self
.tcx
}
impl
<
'a
,
'tcx
>
TypeFolder
<
'tcx
>
for
RegionEraser
<
'a
,
'tcx
>
{
fn
tcx
(
&
self
)
->
&
ty
::
ctxt
<
'tcx
>
{
self
.0
}
fn
fold_ty
(
&
mut
self
,
t
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
if
!
t
.has_erasable_regions
()
{
return
t
;
}
fn
fold_ty
(
&
mut
self
,
ty
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
match
self
.tcx
()
.normalized_cache
.borrow
()
.get
(
&
ty
)
.cloned
()
{
None
=>
{}
Some
(
u
)
=>
return
u
}
super_fold_ty
(
self
,
t
)
}
let
t_norm
=
ty
::
fold
::
super_fold_ty
(
self
,
ty
);
self
.tcx
()
.normalized_cache
.borrow_mut
()
.insert
(
ty
,
t_norm
);
return
t_norm
;
}
fn
fold_region
(
&
mut
self
,
r
:
ty
::
Region
)
->
ty
::
Region
{
// because whether or not a region is bound affects subtyping,
// we can't erase the bound/free distinction, but we can
// replace all free regions with 'static
match
r
{
ty
::
ReLateBound
(
..
)
|
ty
::
ReEarlyBound
(
..
)
=>
r
,
_
=>
ty
::
ReStatic
fn
fold_binder
<
T
>
(
&
mut
self
,
t
:
&
ty
::
Binder
<
T
>
)
->
ty
::
Binder
<
T
>
where
T
:
TypeFoldable
<
'tcx
>
{
let
u
=
self
.tcx
()
.anonymize_late_bound_regions
(
t
);
ty
::
fold
::
super_fold_binder
(
self
,
&
u
)
}
fn
fold_region
(
&
mut
self
,
r
:
ty
::
Region
)
->
ty
::
Region
{
// because late-bound regions affect subtyping, we can't
// erase the bound/free distinction, but we can replace
// all free regions with 'static.
//
// Note that we *CAN* replace early-bound regions -- the
// type system never "sees" those, they get substituted
// away. In trans, they will always be erased to 'static
// whenever a substitution occurs.
match
r
{
ty
::
ReLateBound
(
..
)
=>
r
,
_
=>
ty
::
ReStatic
}
}
fn
fold_substs
(
&
mut
self
,
substs
:
&
subst
::
Substs
<
'tcx
>
)
->
subst
::
Substs
<
'tcx
>
{
subst
::
Substs
{
regions
:
subst
::
ErasedRegions
,
types
:
substs
.types
.fold_with
(
self
)
}
}
}
}
}
...
...
src/librustc/middle/ty/mod.rs
浏览文件 @
8a19b234
...
...
@@ -979,18 +979,6 @@ pub fn walk_tys(&self) -> IntoIter<Ty<'tcx>> {
vec
.into_iter
()
}
pub
fn
has_escaping_regions
(
&
self
)
->
bool
{
match
*
self
{
Predicate
::
Trait
(
ref
trait_ref
)
=>
trait_ref
.has_escaping_regions
(),
Predicate
::
Equate
(
ref
p
)
=>
p
.has_escaping_regions
(),
Predicate
::
RegionOutlives
(
ref
p
)
=>
p
.has_escaping_regions
(),
Predicate
::
TypeOutlives
(
ref
p
)
=>
p
.has_escaping_regions
(),
Predicate
::
Projection
(
ref
p
)
=>
p
.has_escaping_regions
(),
Predicate
::
WellFormed
(
p
)
=>
p
.has_escaping_regions
(),
Predicate
::
ObjectSafe
(
_
trait_def_id
)
=>
false
,
}
}
pub
fn
to_opt_poly_trait_ref
(
&
self
)
->
Option
<
PolyTraitRef
<
'tcx
>>
{
match
*
self
{
Predicate
::
Trait
(
ref
t
)
=>
{
...
...
@@ -1037,10 +1025,6 @@ pub fn empty() -> InstantiatedPredicates<'tcx> {
InstantiatedPredicates
{
predicates
:
VecPerParamSpace
::
empty
()
}
}
pub
fn
has_escaping_regions
(
&
self
)
->
bool
{
self
.predicates
.any
(|
p
|
p
.has_escaping_regions
())
}
pub
fn
is_empty
(
&
self
)
->
bool
{
self
.predicates
.is_empty
()
}
...
...
src/librustc/middle/ty/structural_impls.rs
浏览文件 @
8a19b234
...
...
@@ -45,6 +45,12 @@ fn has_regions_escaping_depth(&self, depth: u32) -> bool {
}
}
impl
<
'tcx
>
RegionEscape
for
ty
::
InstantiatedPredicates
<
'tcx
>
{
fn
has_regions_escaping_depth
(
&
self
,
depth
:
u32
)
->
bool
{
self
.predicates
.has_regions_escaping_depth
(
depth
)
}
}
impl
<
'tcx
>
RegionEscape
for
subst
::
Substs
<
'tcx
>
{
fn
has_regions_escaping_depth
(
&
self
,
depth
:
u32
)
->
bool
{
self
.types
.has_regions_escaping_depth
(
depth
)
||
...
...
@@ -179,6 +185,13 @@ fn has_regions_escaping_depth(&self, depth: u32) -> bool {
self
.trait_ref
.has_regions_escaping_depth
(
depth
)
}
}
impl
HasTypeFlags
for
()
{
fn
has_type_flags
(
&
self
,
_
flags
:
TypeFlags
)
->
bool
{
false
}
}
impl
<
'tcx
,
T
:
HasTypeFlags
>
HasTypeFlags
for
Vec
<
T
>
{
fn
has_type_flags
(
&
self
,
flags
:
TypeFlags
)
->
bool
{
self
[
..
]
.has_type_flags
(
flags
)
...
...
src/librustc_trans/trans/callee.rs
浏览文件 @
8a19b234
...
...
@@ -24,6 +24,7 @@
use
llvm
::{
self
,
ValueRef
,
get_params
};
use
middle
::
def
;
use
middle
::
def_id
::{
DefId
,
LOCAL_CRATE
};
use
middle
::
infer
::
normalize_associated_type
;
use
middle
::
subst
;
use
middle
::
subst
::{
Subst
,
Substs
};
use
rustc
::
front
::
map
as
hir_map
;
...
...
@@ -260,7 +261,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
let
tcx
=
ccx
.tcx
();
// Normalize the type for better caching.
let
bare_fn_ty
=
common
::
erase_regions
(
tcx
,
&
bare_fn_ty
);
let
bare_fn_ty
=
tcx
.erase_regions
(
&
bare_fn_ty
);
// If this is an impl of `Fn` or `FnMut` trait, the receiver is `&self`.
let
is_by_ref
=
match
closure_kind
{
...
...
@@ -521,7 +522,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
// Type scheme of the function item (may have type params)
let
fn_type_scheme
=
tcx
.lookup_item_type
(
def_id
);
let
fn_type
=
monomorphize
::
normalize_associated_type
(
tcx
,
&
fn_type_scheme
.ty
);
let
fn_type
=
normalize_associated_type
(
tcx
,
&
fn_type_scheme
.ty
);
// Find the actual function pointer.
let
mut
val
=
{
...
...
src/librustc_trans/trans/closure.rs
浏览文件 @
8a19b234
...
...
@@ -135,7 +135,7 @@ pub fn get_or_create_closure_declaration<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
->
ValueRef
{
// Normalize type so differences in regions and typedefs don't cause
// duplicate declarations
let
substs
=
erase_regions
(
ccx
.tcx
(),
substs
);
let
substs
=
ccx
.tcx
()
.erase_regions
(
substs
);
let
mono_id
=
MonoId
{
def
:
closure_id
,
params
:
&
substs
.func_substs.types
...
...
src/librustc_trans/trans/common.rs
浏览文件 @
8a19b234
...
...
@@ -47,7 +47,6 @@
use
libc
::{
c_uint
,
c_char
};
use
std
::
ffi
::
CString
;
use
std
::
cell
::{
Cell
,
RefCell
};
use
std
::
result
::
Result
as
StdResult
;
use
std
::
vec
::
Vec
;
use
syntax
::
ast
;
use
syntax
::
codemap
::{
DUMMY_SP
,
Span
};
...
...
@@ -56,65 +55,6 @@
pub
use
trans
::
context
::
CrateContext
;
/// Returns an equivalent value with all free regions removed (note
/// that late-bound regions remain, because they are important for
/// subtyping, but they are anonymized and normalized as well). This
/// is a stronger, caching version of `ty::fold::erase_regions`.
pub
fn
erase_regions
<
'tcx
,
T
>
(
cx
:
&
ty
::
ctxt
<
'tcx
>
,
value
:
&
T
)
->
T
where
T
:
TypeFoldable
<
'tcx
>
{
let
value1
=
value
.fold_with
(
&
mut
RegionEraser
(
cx
));
debug!
(
"erase_regions({:?}) = {:?}"
,
value
,
value1
);
return
value1
;
struct
RegionEraser
<
'a
,
'tcx
:
'a
>
(
&
'a
ty
::
ctxt
<
'tcx
>
);
impl
<
'a
,
'tcx
>
TypeFolder
<
'tcx
>
for
RegionEraser
<
'a
,
'tcx
>
{
fn
tcx
(
&
self
)
->
&
ty
::
ctxt
<
'tcx
>
{
self
.0
}
fn
fold_ty
(
&
mut
self
,
ty
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
match
self
.tcx
()
.normalized_cache
.borrow
()
.get
(
&
ty
)
.cloned
()
{
None
=>
{}
Some
(
u
)
=>
return
u
}
let
t_norm
=
ty
::
fold
::
super_fold_ty
(
self
,
ty
);
self
.tcx
()
.normalized_cache
.borrow_mut
()
.insert
(
ty
,
t_norm
);
return
t_norm
;
}
fn
fold_binder
<
T
>
(
&
mut
self
,
t
:
&
ty
::
Binder
<
T
>
)
->
ty
::
Binder
<
T
>
where
T
:
TypeFoldable
<
'tcx
>
{
let
u
=
self
.tcx
()
.anonymize_late_bound_regions
(
t
);
ty
::
fold
::
super_fold_binder
(
self
,
&
u
)
}
fn
fold_region
(
&
mut
self
,
r
:
ty
::
Region
)
->
ty
::
Region
{
// because late-bound regions affect subtyping, we can't
// erase the bound/free distinction, but we can replace
// all free regions with 'static.
//
// Note that we *CAN* replace early-bound regions -- the
// type system never "sees" those, they get substituted
// away. In trans, they will always be erased to 'static
// whenever a substitution occurs.
match
r
{
ty
::
ReLateBound
(
..
)
=>
r
,
_
=>
ty
::
ReStatic
}
}
fn
fold_substs
(
&
mut
self
,
substs
:
&
subst
::
Substs
<
'tcx
>
)
->
subst
::
Substs
<
'tcx
>
{
subst
::
Substs
{
regions
:
subst
::
ErasedRegions
,
types
:
substs
.types
.fold_with
(
self
)
}
}
}
}
/// Is the type's representation size known at compile time?
pub
fn
type_is_sized
<
'tcx
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
ty
:
Ty
<
'tcx
>
)
->
bool
{
ty
.is_sized
(
&
tcx
.empty_parameter_environment
(),
DUMMY_SP
)
...
...
@@ -1043,7 +983,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
let
tcx
=
ccx
.tcx
();
// Remove any references to regions; this helps improve caching.
let
trait_ref
=
erase_regions
(
tcx
,
&
trait_ref
);
let
trait_ref
=
tcx
.erase_regions
(
&
trait_ref
);
// First check the cache.
match
ccx
.trait_cache
()
.borrow
()
.get
(
&
trait_ref
)
{
...
...
@@ -1098,8 +1038,8 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
let
vtable
=
selection
.map
(|
predicate
|
{
fulfill_cx
.register_predicate_obligation
(
&
infcx
,
predicate
);
});
let
vtable
=
erase_regions
(
tcx
,
&
drain_fulfillment_cx_or_panic
(
span
,
&
infcx
,
&
mut
fulfill_cx
,
&
vtable
)
let
vtable
=
infer
::
drain_fulfillment_cx_or_panic
(
span
,
&
infcx
,
&
mut
fulfill_cx
,
&
vtable
);
info!
(
"Cache miss: {:?} => {:?}"
,
trait_ref
,
vtable
);
...
...
@@ -1134,59 +1074,8 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
let
obligation
=
traits
::
Obligation
::
new
(
cause
.clone
(),
predicate
);
fulfill_cx
.register_predicate_obligation
(
&
infcx
,
obligation
);
}
drain_fulfillment_cx
(
&
infcx
,
&
mut
fulfill_cx
,
&
())
.is_ok
()
}
pub
fn
drain_fulfillment_cx_or_panic
<
'a
,
'tcx
,
T
>
(
span
:
Span
,
infcx
:
&
infer
::
InferCtxt
<
'a
,
'tcx
>
,
fulfill_cx
:
&
mut
traits
::
FulfillmentContext
<
'tcx
>
,
result
:
&
T
)
->
T
where
T
:
TypeFoldable
<
'tcx
>
{
match
drain_fulfillment_cx
(
infcx
,
fulfill_cx
,
result
)
{
Ok
(
v
)
=>
v
,
Err
(
errors
)
=>
{
infcx
.tcx.sess
.span_bug
(
span
,
&
format!
(
"Encountered errors `{:?}` fulfilling during trans"
,
errors
));
}
}
}
/// Finishes processes any obligations that remain in the fulfillment
/// context, and then "freshens" and returns `result`. This is
/// primarily used during normalization and other cases where
/// processing the obligations in `fulfill_cx` may cause type
/// inference variables that appear in `result` to be unified, and
/// hence we need to process those obligations to get the complete
/// picture of the type.
pub
fn
drain_fulfillment_cx
<
'a
,
'tcx
,
T
>
(
infcx
:
&
infer
::
InferCtxt
<
'a
,
'tcx
>
,
fulfill_cx
:
&
mut
traits
::
FulfillmentContext
<
'tcx
>
,
result
:
&
T
)
->
StdResult
<
T
,
Vec
<
traits
::
FulfillmentError
<
'tcx
>>>
where
T
:
TypeFoldable
<
'tcx
>
{
debug!
(
"drain_fulfillment_cx(result={:?})"
,
result
);
// In principle, we only need to do this so long as `result`
// contains unbound type parameters. It could be a slight
// optimization to stop iterating early.
match
fulfill_cx
.select_all_or_error
(
infcx
)
{
Ok
(())
=>
{
}
Err
(
errors
)
=>
{
return
Err
(
errors
);
}
}
// Use freshen to simultaneously replace all type variables with
// their bindings and replace all regions with 'static. This is
// sort of overkill because we do not expect there to be any
// unbound type variables, hence no `TyFresh` types should ever be
// inserted.
Ok
(
result
.fold_with
(
&
mut
infcx
.freshener
()))
infer
::
drain_fulfillment_cx
(
&
infcx
,
&
mut
fulfill_cx
,
&
())
.is_ok
()
}
// Key used to lookup values supplied for type parameters in an expr.
...
...
src/librustc_trans/trans/debuginfo/mod.rs
浏览文件 @
8a19b234
...
...
@@ -27,6 +27,7 @@
use
llvm
::
debuginfo
::{
DIFile
,
DIType
,
DIScope
,
DIBuilderRef
,
DISubprogram
,
DIArray
,
DIDescriptor
,
FlagPrototyped
};
use
middle
::
def_id
::
DefId
;
use
middle
::
infer
::
normalize_associated_type
;
use
middle
::
subst
::{
self
,
Substs
};
use
rustc_front
;
use
rustc_front
::
hir
;
...
...
@@ -463,7 +464,7 @@ fn get_template_parameters<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
->
DIArray
{
let
self_type
=
param_substs
.self_ty
();
let
self_type
=
monomorphize
::
normalize_associated_type
(
cx
.tcx
(),
&
self_type
);
let
self_type
=
normalize_associated_type
(
cx
.tcx
(),
&
self_type
);
// Only true for static default methods:
let
has_self_type
=
self_type
.is_some
();
...
...
src/librustc_trans/trans/declare.rs
浏览文件 @
8a19b234
...
...
@@ -26,7 +26,6 @@
use
trans
::
attributes
;
use
trans
::
base
;
use
trans
::
context
::
CrateContext
;
use
trans
::
monomorphize
;
use
trans
::
type_
::
Type
;
use
trans
::
type_of
;
...
...
@@ -104,7 +103,7 @@ pub fn declare_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str,
fn_type
:
ty
::
Ty
<
'tcx
>
)
->
ValueRef
{
debug!
(
"declare_rust_fn(name={:?}, fn_type={:?})"
,
name
,
fn_type
);
let
fn_type
=
monomorphize
::
normalize_associated_type
(
ccx
.tcx
(),
&
fn_type
);
let
fn_type
=
infer
::
normalize_associated_type
(
ccx
.tcx
(),
&
fn_type
);
debug!
(
"declare_rust_fn (after normalised associated types) fn_type={:?}"
,
fn_type
);
...
...
src/librustc_trans/trans/monomorphize.rs
浏览文件 @
8a19b234
...
...
@@ -13,10 +13,9 @@
use
llvm
::
ValueRef
;
use
llvm
;
use
middle
::
def_id
::
DefId
;
use
middle
::
infer
;
use
middle
::
infer
::
normalize_associated_type
;
use
middle
::
subst
;
use
middle
::
subst
::{
Subst
,
Substs
};
use
middle
::
traits
;
use
middle
::
ty
::
fold
::{
TypeFolder
,
TypeFoldable
};
use
trans
::
attributes
;
use
trans
::
base
::{
trans_enum_variant
,
push_ctxt
,
get_item_val
};
...
...
@@ -33,7 +32,6 @@
use
syntax
::
abi
;
use
syntax
::
ast
;
use
syntax
::
codemap
::
DUMMY_SP
;
use
std
::
hash
::{
Hasher
,
Hash
,
SipHasher
};
pub
fn
monomorphic_fn
<
'a
,
'tcx
>
(
ccx
:
&
CrateContext
<
'a
,
'tcx
>
,
...
...
@@ -300,39 +298,3 @@ pub fn field_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
{
normalize_associated_type
(
tcx
,
&
f
.ty
(
tcx
,
param_substs
))
}
/// Removes associated types, if any. Since this during
/// monomorphization, we know that only concrete types are involved,
/// and hence we can be sure that all associated types will be
/// completely normalized away.
pub
fn
normalize_associated_type
<
'tcx
,
T
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
value
:
&
T
)
->
T
where
T
:
TypeFoldable
<
'tcx
>
+
HasTypeFlags
{
debug!
(
"normalize_associated_type(t={:?})"
,
value
);
let
value
=
erase_regions
(
tcx
,
value
);
if
!
value
.has_projection_types
()
{
return
value
;
}
// FIXME(#20304) -- cache
let
infcx
=
infer
::
normalizing_infer_ctxt
(
tcx
,
&
tcx
.tables
);
let
mut
selcx
=
traits
::
SelectionContext
::
new
(
&
infcx
);
let
cause
=
traits
::
ObligationCause
::
dummy
();
let
traits
::
Normalized
{
value
:
result
,
obligations
}
=
traits
::
normalize
(
&
mut
selcx
,
cause
,
&
value
);
debug!
(
"normalize_associated_type: result={:?} obligations={:?}"
,
result
,
obligations
);
let
mut
fulfill_cx
=
infcx
.fulfillment_cx
.borrow_mut
();
for
obligation
in
obligations
{
fulfill_cx
.register_predicate_obligation
(
&
infcx
,
obligation
);
}
let
result
=
drain_fulfillment_cx_or_panic
(
DUMMY_SP
,
&
infcx
,
&
mut
fulfill_cx
,
&
result
);
result
}
src/librustc_trans/trans/type_of.rs
浏览文件 @
8a19b234
...
...
@@ -325,7 +325,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
// Rust types are defined as the same LLVM types. If we don't do
// this then, e.g. `Option<{myfield: bool}>` would be a different
// type than `Option<myrec>`.
let
t_norm
=
erase_regions
(
cx
.tcx
(),
&
t
);
let
t_norm
=
cx
.tcx
()
.erase_regions
(
&
t
);
if
t
!=
t_norm
{
let
llty
=
in_memory_type_of
(
cx
,
t_norm
);
...
...
src/librustc_typeck/check/method/mod.rs
浏览文件 @
8a19b234
...
...
@@ -17,7 +17,7 @@
use
middle
::
privacy
::{
AllPublic
,
DependsOn
,
LastPrivate
,
LastMod
};
use
middle
::
subst
;
use
middle
::
traits
;
use
middle
::
ty
::{
self
,
ToPredicate
,
ToPolyTraitRef
,
TraitRef
};
use
middle
::
ty
::{
self
,
RegionEscape
,
ToPredicate
,
ToPolyTraitRef
,
TraitRef
};
use
middle
::
ty
::
adjustment
::{
AdjustDerefRef
,
AutoDerefRef
,
AutoPtr
};
use
middle
::
infer
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录