Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
3657ae13
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,发现更多精彩内容 >>
提交
3657ae13
编写于
12月 28, 2014
作者:
N
Niko Matsakis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Don't normalize associated types when in region binders, wait until we instantiate
them. Also fix some assertions and handling of builtin bounds.
上级
2bbd2f9c
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
214 addition
and
85 deletion
+214
-85
src/librustc/middle/traits/fulfill.rs
src/librustc/middle/traits/fulfill.rs
+7
-0
src/librustc/middle/traits/select.rs
src/librustc/middle/traits/select.rs
+30
-8
src/librustc/middle/ty.rs
src/librustc/middle/ty.rs
+16
-5
src/librustc_typeck/check/assoc.rs
src/librustc_typeck/check/assoc.rs
+24
-2
src/librustc_typeck/check/closure.rs
src/librustc_typeck/check/closure.rs
+10
-3
src/librustc_typeck/check/method/confirm.rs
src/librustc_typeck/check/method/confirm.rs
+10
-9
src/librustc_typeck/check/method/mod.rs
src/librustc_typeck/check/method/mod.rs
+10
-8
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/mod.rs
+87
-42
src/librustc_typeck/check/regionmanip.rs
src/librustc_typeck/check/regionmanip.rs
+7
-6
src/librustc_typeck/check/wf.rs
src/librustc_typeck/check/wf.rs
+1
-2
src/libsyntax/visit.rs
src/libsyntax/visit.rs
+12
-0
未找到文件。
src/librustc/middle/traits/fulfill.rs
浏览文件 @
3657ae13
...
...
@@ -109,6 +109,10 @@ pub fn normalize_associated_type<'a>(&mut self,
cause
:
ObligationCause
<
'tcx
>
)
->
Ty
<
'tcx
>
{
debug!
(
"normalize_associated_type(trait_ref={}, item_name={})"
,
trait_ref
.repr
(
infcx
.tcx
),
item_name
.repr
(
infcx
.tcx
));
assert
!
(
!
trait_ref
.has_escaping_regions
());
let
ty_var
=
infcx
.next_ty_var
();
...
...
@@ -120,6 +124,9 @@ pub fn normalize_associated_type<'a>(&mut self,
});
let
obligation
=
Obligation
::
new
(
cause
,
projection
.as_predicate
());
self
.register_predicate
(
infcx
,
obligation
);
debug!
(
"normalize_associated_type: result={}"
,
ty_var
.repr
(
infcx
.tcx
));
ty_var
}
...
...
src/librustc/middle/traits/select.rs
浏览文件 @
3657ae13
...
...
@@ -1141,7 +1141,11 @@ fn builtin_bound(&mut self,
obligation
:
&
TraitObligation
<
'tcx
>
)
->
Result
<
BuiltinBoundConditions
<
'tcx
>
,
SelectionError
<
'tcx
>>
{
// TODO seems like we ought to skolemize here, oder?
// Note: these tests operate on types that may contain bound
// regions. To be proper, we ought to skolemize here, but we
// forego the skolemization and defer it until the
// confirmation step.
let
self_ty
=
self
.infcx
.shallow_resolve
(
obligation
.predicate
.0
.self_ty
());
return
match
self_ty
.sty
{
ty
::
ty_infer
(
ty
::
IntVar
(
_
))
|
...
...
@@ -1627,13 +1631,31 @@ fn vtable_builtin_data(&mut self,
->
VtableBuiltinData
<
PredicateObligation
<
'tcx
>>
{
let
derived_cause
=
self
.derived_cause
(
obligation
,
BuiltinDerivedObligation
);
let
obligations
=
nested
.iter
()
.map
(|
&
t
|
{
util
::
predicate_for_builtin_bound
(
self
.tcx
(),
derived_cause
.clone
(),
bound
,
obligation
.recursion_depth
+
1
,
t
)
let
obligations
=
nested
.iter
()
.map
(|
&
bound_ty
|
{
// the obligation might be higher-ranked, e.g. for<'a> &'a
// int : Copy. In that case, we will wind up with
// late-bound regions in the `nested` vector. So for each
// one we instantiate to a skolemized region, do our work
// to produce something like `&'0 int : Copy`, and then
// re-bind it. This is a bit of busy-work but preserves
// the invariant that we only manipulate free regions, not
// bound ones.
self
.infcx
.try
(|
snapshot
|
{
let
(
skol_ty
,
skol_map
)
=
self
.infcx
()
.skolemize_late_bound_regions
(
&
ty
::
Binder
(
bound_ty
),
snapshot
);
let
skol_predicate
=
util
::
predicate_for_builtin_bound
(
self
.tcx
(),
derived_cause
.clone
(),
bound
,
obligation
.recursion_depth
+
1
,
skol_ty
);
match
skol_predicate
{
Ok
(
skol_predicate
)
=>
Ok
(
self
.infcx
()
.plug_leaks
(
skol_map
,
snapshot
,
&
skol_predicate
)),
Err
(
ErrorReported
)
=>
Err
(
ErrorReported
)
}
})
})
.collect
::
<
Result
<
_
,
_
>>
();
let
mut
obligations
=
match
obligations
{
Ok
(
o
)
=>
o
,
...
...
src/librustc/middle/ty.rs
浏览文件 @
3657ae13
...
...
@@ -6903,8 +6903,19 @@ fn has_regions_escaping_depth(&self, depth: u32) -> bool {
impl
<
'tcx
>
RegionEscape
for
TraitRef
<
'tcx
>
{
fn
has_regions_escaping_depth
(
&
self
,
depth
:
u32
)
->
bool
{
self
.substs.types
.iter
()
.any
(|
t
|
t
.has_regions_escaping_depth
(
depth
))
&&
self
.substs
.regions
()
.iter
()
.any
(|
t
|
t
.has_regions_escaping_depth
(
depth
))
self
.substs.types
.iter
()
.any
(|
t
|
t
.has_regions_escaping_depth
(
depth
))
||
self
.substs.regions
.has_regions_escaping_depth
(
depth
)
}
}
impl
<
'tcx
>
RegionEscape
for
subst
::
RegionSubsts
{
fn
has_regions_escaping_depth
(
&
self
,
depth
:
u32
)
->
bool
{
match
*
self
{
subst
::
ErasedRegions
=>
false
,
subst
::
NonerasedRegions
(
ref
r
)
=>
{
r
.iter
()
.any
(|
t
|
t
.has_regions_escaping_depth
(
depth
))
}
}
}
}
...
...
@@ -6921,7 +6932,7 @@ fn has_regions_escaping_depth(&self, depth: u32) -> bool {
}
impl
<
'tcx
>
RegionEscape
for
TraitPredicate
<
'tcx
>
{
fn
has_regions_escaping_depth
(
&
self
,
depth
:
u
int
)
->
bool
{
fn
has_regions_escaping_depth
(
&
self
,
depth
:
u
32
)
->
bool
{
self
.trait_ref
.has_regions_escaping_depth
(
depth
)
}
}
...
...
@@ -6933,14 +6944,14 @@ fn has_regions_escaping_depth(&self, depth: u32) -> bool {
}
impl
<
'tcx
>
RegionEscape
for
ProjectionPredicate
<
'tcx
>
{
fn
has_regions_escaping_depth
(
&
self
,
depth
:
u
int
)
->
bool
{
fn
has_regions_escaping_depth
(
&
self
,
depth
:
u
32
)
->
bool
{
self
.projection_ty
.has_regions_escaping_depth
(
depth
)
||
self
.ty
.has_regions_escaping_depth
(
depth
)
}
}
impl
<
'tcx
>
RegionEscape
for
ProjectionTy
<
'tcx
>
{
fn
has_regions_escaping_depth
(
&
self
,
depth
:
u
int
)
->
bool
{
fn
has_regions_escaping_depth
(
&
self
,
depth
:
u
32
)
->
bool
{
self
.trait_ref
.has_regions_escaping_depth
(
depth
)
}
}
...
...
src/librustc_typeck/check/assoc.rs
浏览文件 @
3657ae13
...
...
@@ -33,7 +33,8 @@ pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
let
mut
normalizer
=
AssociatedTypeNormalizer
{
span
:
span
,
body_id
:
body_id
,
infcx
:
infcx
,
fulfillment_cx
:
fulfillment_cx
};
fulfillment_cx
:
fulfillment_cx
,
region_binders
:
0
};
value
.fold_with
(
&
mut
normalizer
)
}
...
...
@@ -42,6 +43,7 @@ struct AssociatedTypeNormalizer<'a,'tcx:'a> {
fulfillment_cx
:
&
'a
mut
FulfillmentContext
<
'tcx
>
,
span
:
Span
,
body_id
:
ast
::
NodeId
,
region_binders
:
uint
,
}
impl
<
'a
,
'tcx
>
TypeFolder
<
'tcx
>
for
AssociatedTypeNormalizer
<
'a
,
'tcx
>
{
...
...
@@ -49,9 +51,29 @@ fn tcx(&self) -> &ty::ctxt<'tcx> {
self
.infcx.tcx
}
fn
enter_region_binder
(
&
mut
self
)
{
self
.region_binders
+=
1
;
}
fn
exit_region_binder
(
&
mut
self
)
{
self
.region_binders
-=
1
;
}
fn
fold_ty
(
&
mut
self
,
ty
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
// We don't want to normalize associated types that occur inside of region
// binders, because they may contain bound regions, and we can't cope with that.
//
// Example:
//
// for<'a> fn(<T as Foo<&'a>>::A)
//
// Instead of normalizing `<T as Foo<&'a>>::A` here, we'll
// normalize it when we instantiate those bound regions (which
// should occur eventually).
let
no_region_binders
=
self
.region_binders
==
0
;
match
ty
.sty
{
ty
::
ty_projection
(
ref
data
)
=>
{
ty
::
ty_projection
(
ref
data
)
if
no_region_binders
=>
{
let
cause
=
ObligationCause
::
new
(
self
.span
,
...
...
src/librustc_typeck/check/closure.rs
浏览文件 @
3657ae13
...
...
@@ -14,6 +14,7 @@
use
astconv
;
use
middle
::
infer
;
use
middle
::
region
::
CodeExtent
;
use
middle
::
subst
;
use
middle
::
ty
::{
mod
,
ToPolyTraitRef
,
Ty
};
use
rscope
::
RegionScope
;
...
...
@@ -132,10 +133,13 @@ fn check_unboxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
fcx
.write_ty
(
expr
.id
,
closure_type
);
let
fn_sig
=
ty
::
liberate_late_bound_regions
(
fcx
.tcx
(),
CodeExtent
::
from_node_id
(
body
.id
),
&
fn_ty
.sig
);
check_fn
(
fcx
.ccx
,
ast
::
Unsafety
::
Normal
,
expr
.id
,
&
fn_
ty
.
sig
,
&
fn_sig
,
decl
,
expr
.id
,
&*
body
,
...
...
@@ -310,7 +314,7 @@ fn check_boxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
decl
,
abi
::
Rust
,
expected_sig
);
let
f
ty
_sig
=
fn_ty
.sig
.clone
();
let
f
n
_sig
=
fn_ty
.sig
.clone
();
let
fty
=
ty
::
mk_closure
(
tcx
,
fn_ty
);
debug!
(
"check_expr_fn fty={}"
,
fcx
.infcx
()
.ty_to_string
(
fty
));
...
...
@@ -325,10 +329,13 @@ fn check_boxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
ty
::
UniqTraitStore
=>
(
ast
::
Unsafety
::
Normal
,
expr
.id
)
};
let
fn_sig
=
ty
::
liberate_late_bound_regions
(
tcx
,
CodeExtent
::
from_node_id
(
body
.id
),
&
fn_sig
);
check_fn
(
fcx
.ccx
,
inherited_style
,
inherited_style_id
,
&
f
ty
_sig
,
&
f
n
_sig
,
&*
decl
,
expr
.id
,
&*
body
,
...
...
src/librustc_typeck/check/method/confirm.rs
浏览文件 @
3657ae13
...
...
@@ -424,17 +424,18 @@ fn instantiate_method_sig(&mut self,
debug!
(
"method_bounds after subst = {}"
,
method_bounds
.repr
(
self
.tcx
()));
// Substitute the type/early-bound-regions into the method
// signature. In addition, the method signature may bind
// late-bound regions, so instantiate those.
let
method_sig
=
self
.fcx
.instantiate_type_scheme
(
self
.span
,
&
all_substs
,
&
pick
.method_ty.fty.sig
);
debug!
(
"late-bound lifetimes from method substituted, method_sig={}"
,
// Instantiate late-bound regions and substitute the trait
// parameters into the method type to get the actual method type.
//
// NB: Instantiate late-bound regions first so that
// `instantiate_type_scheme` can normalize associated types that
// may reference those regions.
let
method_sig
=
self
.replace_late_bound_regions_with_fresh_var
(
&
pick
.method_ty.fty.sig
);
debug!
(
"late-bound lifetimes from method instantiated, method_sig={}"
,
method_sig
.repr
(
self
.tcx
()));
let
method_sig
=
self
.
replace_late_bound_regions_with_fresh_var
(
&
method_sig
);
debug!
(
"
late-bound lifetimes from method instantia
ted, method_sig={}"
,
let
method_sig
=
self
.
fcx
.instantiate_type_scheme
(
self
.span
,
&
all_substs
,
&
method_sig
);
debug!
(
"
type scheme substitu
ted, method_sig={}"
,
method_sig
.repr
(
self
.tcx
()));
InstantiatedMethodSig
{
...
...
src/librustc_typeck/check/method/mod.rs
浏览文件 @
3657ae13
...
...
@@ -190,19 +190,21 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>,
debug!
(
"lookup_in_trait_adjusted: method_num={} method_ty={}"
,
method_num
,
method_ty
.repr
(
fcx
.tcx
()));
// Substitute the trait parameters into the method type and
// instantiate late-bound regions to get the actual method type.
let
bare_fn_ty
=
fcx
.instantiate_type_scheme
(
span
,
&
trait_ref
.substs
,
&
method_ty
.fty
);
// Instantiate late-bound regions and substitute the trait
// parameters into the method type to get the actual method type.
//
// NB: Instantiate late-bound regions first so that
// `instantiate_type_scheme` can normalize associated types that
// may reference those regions.
let
fn_sig
=
fcx
.infcx
()
.replace_late_bound_regions_with_fresh_var
(
span
,
infer
::
FnCall
,
&
bare_fn_ty
.sig
)
.0
;
&
method_ty
.fty.sig
)
.0
;
let
fn_sig
=
fcx
.instantiate_type_scheme
(
span
,
&
trait_ref
.substs
,
&
fn_sig
);
let
transformed_self_ty
=
fn_sig
.inputs
[
0
];
let
fty
=
ty
::
mk_bare_fn
(
tcx
,
None
,
tcx
.mk_bare_fn
(
ty
::
BareFnTy
{
sig
:
ty
::
Binder
(
fn_sig
),
unsafety
:
bare_fn_
ty
.unsafety
,
abi
:
bare_fn_
ty
.abi
.clone
(),
unsafety
:
method_ty
.f
ty.unsafety
,
abi
:
method_ty
.f
ty.abi
.clone
(),
}));
debug!
(
"lookup_in_trait_adjusted: matched method fty={} obligation={}"
,
...
...
src/librustc_typeck/check/mod.rs
浏览文件 @
3657ae13
...
...
@@ -432,13 +432,15 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
ty
::
ty_bare_fn
(
_
,
ref
fn_ty
)
=>
{
let
inh
=
Inherited
::
new
(
ccx
.tcx
,
param_env
);
// Compute the fty from point of view of inside fn
// (replace any type-scheme with a type, and normalize
// associated types appearing in the fn signature).
let
fn_ty
=
fn_ty
.subst
(
ccx
.tcx
,
&
inh
.param_env.free_substs
);
let
fn_ty
=
inh
.normalize_associated_types_in
(
body
.span
,
body
.id
,
&
fn_ty
);
let
fcx
=
check_fn
(
ccx
,
fn_ty
.unsafety
,
id
,
&
fn_ty
.sig
,
// Compute the fty from point of view of inside fn.
let
fn_sig
=
fn_ty
.sig
.subst
(
ccx
.tcx
,
&
inh
.param_env.free_substs
);
let
fn_sig
=
liberate_late_bound_regions
(
ccx
.tcx
,
CodeExtent
::
from_node_id
(
body
.id
),
&
fn_sig
);
let
fn_sig
=
inh
.normalize_associated_types_in
(
body
.span
,
body
.id
,
&
fn_sig
);
let
fcx
=
check_fn
(
ccx
,
fn_ty
.unsafety
,
id
,
&
fn_sig
,
decl
,
id
,
body
,
&
inh
);
vtable
::
select_all_fcx_obligations_or_error
(
&
fcx
);
...
...
@@ -542,7 +544,7 @@ fn visit_item(&mut self, _: &ast::Item) { }
fn
check_fn
<
'a
,
'tcx
>
(
ccx
:
&
'a
CrateCtxt
<
'a
,
'tcx
>
,
unsafety
:
ast
::
Unsafety
,
unsafety_id
:
ast
::
NodeId
,
fn_sig
:
&
ty
::
Poly
FnSig
<
'tcx
>
,
fn_sig
:
&
ty
::
FnSig
<
'tcx
>
,
decl
:
&
ast
::
FnDecl
,
fn_id
:
ast
::
NodeId
,
body
:
&
ast
::
Block
,
...
...
@@ -552,10 +554,6 @@ fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
let
tcx
=
ccx
.tcx
;
let
err_count_on_creation
=
tcx
.sess
.err_count
();
// First, we have to replace any bound regions in the fn type with free ones.
// The free region references will be bound the node_id of the body block.
let
fn_sig
=
liberate_late_bound_regions
(
tcx
,
CodeExtent
::
from_node_id
(
body
.id
),
fn_sig
);
let
arg_tys
=
fn_sig
.inputs
[];
let
ret_ty
=
fn_sig
.output
;
...
...
@@ -1161,39 +1159,80 @@ fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
}
}
// We now need to check that the signature of the impl method is
// compatible with that of the trait method. We do this by
// checking that `impl_fty <: trait_fty`.
//
// FIXME. Unfortunately, this doesn't quite work right now because
// associated type normalization is not integrated into subtype
// checks. For the comparison to be valid, we need to
// normalize the associated types in the impl/trait methods
// first. However, because function types bind regions, just
// calling `normalize_associated_types_in` would have no effect on
// any associated types appearing in the fn arguments or return
// type.
// Compute skolemized form of impl and trait method tys.
let
impl_fty
=
ty
::
mk_bare_fn
(
tcx
,
None
,
tcx
.mk_bare_fn
(
impl_m
.fty
.clone
()));
let
impl_fty
=
impl_fty
.subst
(
tcx
,
impl_to_skol_substs
);
let
trait_fty
=
ty
::
mk_bare_fn
(
tcx
,
None
,
tcx
.mk_bare_fn
(
trait_m
.fty
.clone
()));
let
trait_fty
=
trait_fty
.subst
(
tcx
,
&
trait_to_skol_substs
);
let
trait_fty
=
assoc
::
normalize_associated_types_in
(
&
infcx
,
&
mut
fulfillment_cx
,
impl_m_span
,
impl_m_body_id
,
&
trait_fty
);
// Check the impl method type IM is a subtype of the trait method
// type TM. To see why this makes sense, think of a vtable. The
// expected type of the function pointers in the vtable is the
// type TM of the trait method. The actual type will be the type
// IM of the impl method. Because we know that IM <: TM, that
// means that anywhere a TM is expected, a IM will do instead. In
// other words, anyone expecting to call a method with the type
// from the trait, can safely call a method with the type from the
// impl instead.
debug!
(
"checking trait method for compatibility: impl ty {}, trait ty {}"
,
impl_fty
.repr
(
tcx
),
trait_fty
.repr
(
tcx
));
match
infer
::
mk_subty
(
&
infcx
,
false
,
infer
::
MethodCompatCheck
(
impl_m_span
),
impl_fty
,
trait_fty
)
{
Ok
(())
=>
{}
Err
(
ref
terr
)
=>
{
let
err
=
infcx
.try
(|
snapshot
|
{
let
origin
=
infer
::
MethodCompatCheck
(
impl_m_span
);
let
(
impl_sig
,
_
)
=
infcx
.replace_late_bound_regions_with_fresh_var
(
impl_m_span
,
infer
::
HigherRankedType
,
&
impl_m
.fty.sig
);
let
impl_sig
=
impl_sig
.subst
(
tcx
,
impl_to_skol_substs
);
let
impl_sig
=
assoc
::
normalize_associated_types_in
(
&
infcx
,
&
mut
fulfillment_cx
,
impl_m_span
,
impl_m_body_id
,
&
impl_sig
);
let
impl_fty
=
ty
::
mk_bare_fn
(
tcx
,
None
,
ty
::
BareFnTy
{
unsafety
:
impl_m
.fty.unsafety
,
abi
:
impl_m
.fty.abi
,
sig
:
ty
::
Binder
(
impl_sig
)
});
debug!
(
"compare_impl_method: impl_fty={}"
,
impl_fty
.repr
(
tcx
));
let
(
trait_sig
,
skol_map
)
=
infcx
.skolemize_late_bound_regions
(
&
trait_m
.fty.sig
,
snapshot
);
let
trait_sig
=
trait_sig
.subst
(
tcx
,
&
trait_to_skol_substs
);
let
trait_sig
=
assoc
::
normalize_associated_types_in
(
&
infcx
,
&
mut
fulfillment_cx
,
impl_m_span
,
impl_m_body_id
,
&
trait_sig
);
let
trait_fty
=
ty
::
mk_bare_fn
(
tcx
,
None
,
ty
::
BareFnTy
{
unsafety
:
trait_m
.fty.unsafety
,
abi
:
trait_m
.fty.abi
,
sig
:
ty
::
Binder
(
trait_sig
)
});
debug!
(
"compare_impl_method: trait_fty={}"
,
trait_fty
.repr
(
tcx
));
try!
(
infer
::
mk_subty
(
&
infcx
,
false
,
origin
,
impl_fty
,
trait_fty
));
infcx
.leak_check
(
&
skol_map
,
snapshot
)
});
match
err
{
Ok
(())
=>
{
}
Err
(
terr
)
=>
{
debug!
(
"checking trait method for compatibility: impl ty {}, trait ty {}"
,
impl_fty
.repr
(
tcx
),
trait_fty
.repr
(
tcx
));
span_err!
(
tcx
.sess
,
impl_m_span
,
E0053
,
"method `{}` has an incompatible type for trait: {}"
,
token
::
get_name
(
trait_m
.name
),
ty
::
type_err_to_str
(
tcx
,
terr
));
ty
::
note_and_explain_type_err
(
tcx
,
terr
)
;
"method `{}` has an incompatible type for trait: {}"
,
token
::
get_name
(
trait_m
.name
),
ty
::
type_err_to_str
(
tcx
,
&
terr
));
return
;
}
}
...
...
@@ -1791,7 +1830,7 @@ fn register_unsize_obligations(&self,
/// Also returns the substitution from the type parameters on `def_id` to the fresh variables.
/// Registers any trait obligations specified on `def_id` at the same time.
///
/// Note that function is only intended to be used with types (notably, not
impl
s). This is
/// Note that function is only intended to be used with types (notably, not
fn
s). This is
/// because it doesn't do any instantiation of late-bound regions.
pub
fn
instantiate_type
(
&
self
,
span
:
Span
,
...
...
@@ -3061,12 +3100,18 @@ fn check_call(fcx: &FnCtxt,
}
};
// Replace any bound regions that appear in the function
// signature with region variables
// Replace any late-bound regions that appear in the function
// signature with region variables. We also have to
// renormalize the associated types at this point, since they
// previously appeared within a `Binder<>` and hence would not
// have been normalized before.
let
fn_sig
=
fcx
.infcx
()
.replace_late_bound_regions_with_fresh_var
(
call_expr
.span
,
infer
::
FnCall
,
fn_sig
)
.0
;
let
fn_sig
=
fcx
.normalize_associated_types_in
(
call_expr
.span
,
&
fn_sig
);
// Call the generic checker.
check_argument_types
(
fcx
,
...
...
src/librustc_typeck/check/regionmanip.rs
浏览文件 @
3657ae13
...
...
@@ -104,7 +104,8 @@ fn accumulate_from_ty(&mut self, ty: Ty<'tcx>) {
ty
::
ty_enum
(
def_id
,
substs
)
|
ty
::
ty_struct
(
def_id
,
substs
)
=>
{
self
.accumulate_from_adt
(
ty
,
def_id
,
substs
)
let
item_scheme
=
ty
::
lookup_item_type
(
self
.tcx
,
def_id
);
self
.accumulate_from_adt
(
ty
,
def_id
,
&
item_scheme
.generics
,
substs
)
}
ty
::
ty_vec
(
t
,
_
)
|
...
...
@@ -127,7 +128,9 @@ fn accumulate_from_ty(&mut self, ty: Ty<'tcx>) {
// TODO What region constraints are necessary here, if any??
// this seems like a minimal requirement:
self
.accumulate_from_ty
(
data
.trait_ref
.self_ty
());
let
trait_def
=
ty
::
lookup_trait_def
(
self
.tcx
,
data
.trait_ref.def_id
);
self
.accumulate_from_adt
(
ty
,
data
.trait_ref.def_id
,
&
trait_def
.generics
,
&
data
.trait_ref.substs
)
}
ty
::
ty_tup
(
ref
tuptys
)
=>
{
...
...
@@ -222,14 +225,12 @@ fn push_param_constraint(&mut self,
fn
accumulate_from_adt
(
&
mut
self
,
ty
:
Ty
<
'tcx
>
,
def_id
:
ast
::
DefId
,
generics
:
&
ty
::
Generics
<
'tcx
>
,
substs
:
&
Substs
<
'tcx
>
)
{
// The generic declarations from the type, appropriately
// substituted for the actual substitutions.
let
generics
=
ty
::
lookup_item_type
(
self
.tcx
,
def_id
)
.generics
.subst
(
self
.tcx
,
substs
);
let
generics
=
generics
.subst
(
self
.tcx
,
substs
);
// Variance of each type/region parameter.
let
variances
=
ty
::
item_variances
(
self
.tcx
,
def_id
);
...
...
src/librustc_typeck/check/wf.rs
浏览文件 @
3657ae13
...
...
@@ -349,8 +349,7 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
//
// (I believe we should do the same for traits, but
// that will require an RFC. -nmatsakis)
let
bounds
=
type_scheme
.generics
.to_bounds
(
self
.tcx
(),
substs
);
let
bounds
=
type_scheme
.generics
.to_bounds
(
self
.tcx
(),
substs
);
let
bounds
=
filter_to_trait_obligations
(
bounds
);
self
.fcx
.add_obligations_for_parameters
(
traits
::
ObligationCause
::
new
(
self
.span
,
...
...
src/libsyntax/visit.rs
浏览文件 @
3657ae13
...
...
@@ -133,6 +133,9 @@ fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment)
fn
visit_path_parameters
(
&
mut
self
,
path_span
:
Span
,
path_parameters
:
&
'v
PathParameters
)
{
walk_path_parameters
(
self
,
path_span
,
path_parameters
)
}
fn
visit_assoc_type_binding
(
&
mut
self
,
type_binding
:
&
'v
TypeBinding
)
{
walk_assoc_type_binding
(
self
,
type_binding
)
}
fn
visit_attribute
(
&
mut
self
,
_
attr
:
&
'v
Attribute
)
{}
}
...
...
@@ -467,6 +470,9 @@ pub fn walk_path_parameters<'v, V: Visitor<'v>>(visitor: &mut V,
for
lifetime
in
data
.lifetimes
.iter
()
{
visitor
.visit_lifetime_ref
(
lifetime
);
}
for
binding
in
data
.bindings
.iter
()
{
visitor
.visit_assoc_type_binding
(
&**
binding
);
}
}
ast
::
ParenthesizedParameters
(
ref
data
)
=>
{
for
typ
in
data
.inputs
.iter
()
{
...
...
@@ -479,6 +485,12 @@ pub fn walk_path_parameters<'v, V: Visitor<'v>>(visitor: &mut V,
}
}
pub
fn
walk_assoc_type_binding
<
'v
,
V
:
Visitor
<
'v
>>
(
visitor
:
&
mut
V
,
type_binding
:
&
'v
TypeBinding
)
{
visitor
.visit_ident
(
type_binding
.span
,
type_binding
.ident
);
visitor
.visit_ty
(
&*
type_binding
.ty
);
}
pub
fn
walk_pat
<
'v
,
V
:
Visitor
<
'v
>>
(
visitor
:
&
mut
V
,
pattern
:
&
'v
Pat
)
{
match
pattern
.node
{
PatEnum
(
ref
path
,
ref
children
)
=>
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录