Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
f8ea24ed
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,发现更多精彩内容 >>
提交
f8ea24ed
编写于
3月 17, 2016
作者:
E
Eduard Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc: Avoid free functions taking &TyCtxt and &InferCtxt.
上级
d7ee56e8
变更
46
展开全部
隐藏空白更改
内联
并排
Showing
46 changed file
with
765 addition
and
1003 deletion
+765
-1003
src/librustc/infer/bivariate.rs
src/librustc/infer/bivariate.rs
+2
-2
src/librustc/infer/combine.rs
src/librustc/infer/combine.rs
+42
-40
src/librustc/infer/equate.rs
src/librustc/infer/equate.rs
+2
-2
src/librustc/infer/higher_ranked/mod.rs
src/librustc/infer/higher_ranked/mod.rs
+34
-49
src/librustc/infer/lattice.rs
src/librustc/infer/lattice.rs
+1
-2
src/librustc/infer/mod.rs
src/librustc/infer/mod.rs
+83
-186
src/librustc/infer/sub.rs
src/librustc/infer/sub.rs
+2
-2
src/librustc/middle/astconv_util.rs
src/librustc/middle/astconv_util.rs
+22
-21
src/librustc/middle/free_region.rs
src/librustc/middle/free_region.rs
+2
-3
src/librustc/middle/stability.rs
src/librustc/middle/stability.rs
+16
-14
src/librustc/traits/coherence.rs
src/librustc/traits/coherence.rs
+5
-6
src/librustc/traits/error_reporting.rs
src/librustc/traits/error_reporting.rs
+198
-227
src/librustc/traits/fulfill.rs
src/librustc/traits/fulfill.rs
+3
-6
src/librustc/traits/mod.rs
src/librustc/traits/mod.rs
+4
-20
src/librustc/traits/object_safety.rs
src/librustc/traits/object_safety.rs
+59
-69
src/librustc/traits/project.rs
src/librustc/traits/project.rs
+12
-15
src/librustc/traits/select.rs
src/librustc/traits/select.rs
+18
-22
src/librustc/traits/specialize/mod.rs
src/librustc/traits/specialize/mod.rs
+6
-7
src/librustc/traits/util.rs
src/librustc/traits/util.rs
+40
-44
src/librustc/ty/layout.rs
src/librustc/ty/layout.rs
+2
-2
src/librustc/ty/outlives.rs
src/librustc/ty/outlives.rs
+12
-15
src/librustc/ty/sty.rs
src/librustc/ty/sty.rs
+2
-3
src/librustc/ty/wf.rs
src/librustc/ty/wf.rs
+3
-5
src/librustc_const_eval/eval.rs
src/librustc_const_eval/eval.rs
+6
-7
src/librustc_driver/test.rs
src/librustc_driver/test.rs
+2
-5
src/librustc_metadata/encoder.rs
src/librustc_metadata/encoder.rs
+22
-23
src/librustc_mir/mir_map.rs
src/librustc_mir/mir_map.rs
+4
-4
src/librustc_mir/transform/qualify_consts.rs
src/librustc_mir/transform/qualify_consts.rs
+3
-3
src/librustc_mir/transform/type_check.rs
src/librustc_mir/transform/type_check.rs
+11
-13
src/librustc_trans/callee.rs
src/librustc_trans/callee.rs
+1
-2
src/librustc_trans/common.rs
src/librustc_trans/common.rs
+3
-5
src/librustc_trans/meth.rs
src/librustc_trans/meth.rs
+1
-1
src/librustc_typeck/astconv.rs
src/librustc_typeck/astconv.rs
+15
-16
src/librustc_typeck/check/coercion.rs
src/librustc_typeck/check/coercion.rs
+6
-8
src/librustc_typeck/check/compare_method.rs
src/librustc_typeck/check/compare_method.rs
+5
-6
src/librustc_typeck/check/dropck.rs
src/librustc_typeck/check/dropck.rs
+3
-4
src/librustc_typeck/check/method/confirm.rs
src/librustc_typeck/check/method/confirm.rs
+9
-6
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/mod.rs
+37
-60
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/regionck.rs
+14
-16
src/librustc_typeck/check/writeback.rs
src/librustc_typeck/check/writeback.rs
+4
-8
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/coherence/mod.rs
+30
-33
src/librustc_typeck/coherence/overlap.rs
src/librustc_typeck/coherence/overlap.rs
+1
-1
src/librustc_typeck/lib.rs
src/librustc_typeck/lib.rs
+2
-2
src/librustdoc/clean/inline.rs
src/librustdoc/clean/inline.rs
+10
-11
src/librustdoc/clean/mod.rs
src/librustdoc/clean/mod.rs
+4
-4
src/librustdoc/visit_ast.rs
src/librustdoc/visit_ast.rs
+2
-3
未找到文件。
src/librustc/infer/bivariate.rs
浏览文件 @
f8ea24ed
...
...
@@ -25,7 +25,7 @@
//! In particular, it might be enough to say (A,B) are bivariant for
//! all (A,B).
use
super
::
combine
::
{
self
,
CombineFields
}
;
use
super
::
combine
::
CombineFields
;
use
super
::
type_variable
::{
BiTo
};
use
ty
::{
self
,
Ty
,
TyCtxt
};
...
...
@@ -96,7 +96,7 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
}
_
=>
{
combine
::
super_combine_tys
(
self
.fields.infcx
,
self
,
a
,
b
)
self
.fields.infcx
.super_combine_tys
(
self
,
a
,
b
)
}
}
}
...
...
src/librustc/infer/combine.rs
浏览文件 @
f8ea24ed
...
...
@@ -60,11 +60,12 @@ pub struct CombineFields<'a, 'tcx: 'a> {
pub
obligations
:
PredicateObligations
<
'tcx
>
,
}
pub
fn
super_combine_tys
<
'a
,
'tcx
:
'a
,
R
>
(
infcx
:
&
InferCtxt
<
'a
,
'tcx
>
,
relation
:
&
mut
R
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
RelateResult
<
'tcx
,
Ty
<
'tcx
>>
impl
<
'a
,
'tcx
>
InferCtxt
<
'a
,
'tcx
>
{
pub
fn
super_combine_tys
<
R
>
(
&
self
,
relation
:
&
mut
R
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
RelateResult
<
'tcx
,
Ty
<
'tcx
>>
where
R
:
TypeRelation
<
'a
,
'tcx
>
{
let
a_is_expected
=
relation
.a_is_expected
();
...
...
@@ -72,38 +73,38 @@ pub fn super_combine_tys<'a,'tcx:'a,R>(infcx: &InferCtxt<'a, 'tcx>,
match
(
&
a
.sty
,
&
b
.sty
)
{
// Relate integral variables to other types
(
&
ty
::
TyInfer
(
ty
::
IntVar
(
a_id
)),
&
ty
::
TyInfer
(
ty
::
IntVar
(
b_id
)))
=>
{
infcx
.int_unification_table
.borrow_mut
()
.unify_var_var
(
a_id
,
b_id
)
.map_err
(|
e
|
int_unification_error
(
a_is_expected
,
e
))
?
;
self
.int_unification_table
.borrow_mut
()
.unify_var_var
(
a_id
,
b_id
)
.map_err
(|
e
|
int_unification_error
(
a_is_expected
,
e
))
?
;
Ok
(
a
)
}
(
&
ty
::
TyInfer
(
ty
::
IntVar
(
v_id
)),
&
ty
::
TyInt
(
v
))
=>
{
unify_integral_variable
(
infcx
,
a_is_expected
,
v_id
,
IntType
(
v
))
self
.unify_integral_variable
(
a_is_expected
,
v_id
,
IntType
(
v
))
}
(
&
ty
::
TyInt
(
v
),
&
ty
::
TyInfer
(
ty
::
IntVar
(
v_id
)))
=>
{
unify_integral_variable
(
infcx
,
!
a_is_expected
,
v_id
,
IntType
(
v
))
self
.unify_integral_variable
(
!
a_is_expected
,
v_id
,
IntType
(
v
))
}
(
&
ty
::
TyInfer
(
ty
::
IntVar
(
v_id
)),
&
ty
::
TyUint
(
v
))
=>
{
unify_integral_variable
(
infcx
,
a_is_expected
,
v_id
,
UintType
(
v
))
self
.unify_integral_variable
(
a_is_expected
,
v_id
,
UintType
(
v
))
}
(
&
ty
::
TyUint
(
v
),
&
ty
::
TyInfer
(
ty
::
IntVar
(
v_id
)))
=>
{
unify_integral_variable
(
infcx
,
!
a_is_expected
,
v_id
,
UintType
(
v
))
self
.unify_integral_variable
(
!
a_is_expected
,
v_id
,
UintType
(
v
))
}
// Relate floating-point variables to other types
(
&
ty
::
TyInfer
(
ty
::
FloatVar
(
a_id
)),
&
ty
::
TyInfer
(
ty
::
FloatVar
(
b_id
)))
=>
{
infcx
.float_unification_table
.borrow_mut
()
.unify_var_var
(
a_id
,
b_id
)
.map_err
(|
e
|
float_unification_error
(
relation
.a_is_expected
(),
e
))
?
;
self
.float_unification_table
.borrow_mut
()
.unify_var_var
(
a_id
,
b_id
)
.map_err
(|
e
|
float_unification_error
(
relation
.a_is_expected
(),
e
))
?
;
Ok
(
a
)
}
(
&
ty
::
TyInfer
(
ty
::
FloatVar
(
v_id
)),
&
ty
::
TyFloat
(
v
))
=>
{
unify_float_variable
(
infcx
,
a_is_expected
,
v_id
,
v
)
self
.unify_float_variable
(
a_is_expected
,
v_id
,
v
)
}
(
&
ty
::
TyFloat
(
v
),
&
ty
::
TyInfer
(
ty
::
FloatVar
(
v_id
)))
=>
{
unify_float_variable
(
infcx
,
!
a_is_expected
,
v_id
,
v
)
self
.unify_float_variable
(
!
a_is_expected
,
v_id
,
v
)
}
// All other cases of inference are errors
...
...
@@ -119,33 +120,34 @@ pub fn super_combine_tys<'a,'tcx:'a,R>(infcx: &InferCtxt<'a, 'tcx>,
}
}
fn
unify_integral_variable
<
'a
,
'tcx
>
(
infcx
:
&
InferCtxt
<
'a
,
'tcx
>
,
vid_is_expected
:
bool
,
vid
:
ty
::
IntVid
,
val
:
ty
::
IntVarValue
)
->
RelateResult
<
'tcx
,
Ty
<
'tcx
>>
fn
unify_integral_variable
(
&
self
,
vid_is_expected
:
bool
,
vid
:
ty
::
IntVid
,
val
:
ty
::
IntVarValue
)
->
RelateResult
<
'tcx
,
Ty
<
'tcx
>>
{
infcx
.int_unification_table
.borrow_mut
()
.unify_var_value
(
vid
,
val
)
.map_err
(|
e
|
int_unification_error
(
vid_is_expected
,
e
))
?
;
self
.int_unification_table
.borrow_mut
()
.unify_var_value
(
vid
,
val
)
.map_err
(|
e
|
int_unification_error
(
vid_is_expected
,
e
))
?
;
match
val
{
IntType
(
v
)
=>
Ok
(
infcx
.tcx
.mk_mach_int
(
v
)),
UintType
(
v
)
=>
Ok
(
infcx
.tcx
.mk_mach_uint
(
v
)),
IntType
(
v
)
=>
Ok
(
self
.tcx
.mk_mach_int
(
v
)),
UintType
(
v
)
=>
Ok
(
self
.tcx
.mk_mach_uint
(
v
)),
}
}
fn
unify_float_variable
<
'a
,
'tcx
>
(
infcx
:
&
InferCtxt
<
'a
,
'tcx
>
,
vid_is_expected
:
bool
,
vid
:
ty
::
FloatVid
,
val
:
ast
::
FloatTy
)
->
RelateResult
<
'tcx
,
Ty
<
'tcx
>>
fn
unify_float_variable
(
&
self
,
vid_is_expected
:
bool
,
vid
:
ty
::
FloatVid
,
val
:
ast
::
FloatTy
)
->
RelateResult
<
'tcx
,
Ty
<
'tcx
>>
{
infcx
.float_unification_table
.borrow_mut
()
.unify_var_value
(
vid
,
val
)
.map_err
(|
e
|
float_unification_error
(
vid_is_expected
,
e
))
?
;
Ok
(
infcx
.tcx
.mk_mach_float
(
val
))
self
.float_unification_table
.borrow_mut
()
.unify_var_value
(
vid
,
val
)
.map_err
(|
e
|
float_unification_error
(
vid_is_expected
,
e
))
?
;
Ok
(
self
.tcx
.mk_mach_float
(
val
))
}
}
impl
<
'a
,
'tcx
>
CombineFields
<
'a
,
'tcx
>
{
...
...
src/librustc/infer/equate.rs
浏览文件 @
f8ea24ed
...
...
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
super
::
combine
::
{
self
,
CombineFields
}
;
use
super
::
combine
::
CombineFields
;
use
super
::
higher_ranked
::
HigherRankedRelations
;
use
super
::{
Subtype
};
use
super
::
type_variable
::{
EqTo
};
...
...
@@ -74,7 +74,7 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
}
_
=>
{
combine
::
super_combine_tys
(
self
.fields.infcx
,
self
,
a
,
b
)
?
;
self
.fields.infcx
.super_combine_tys
(
self
,
a
,
b
)
?
;
Ok
(
a
)
}
}
...
...
src/librustc/infer/higher_ranked/mod.rs
浏览文件 @
f8ea24ed
...
...
@@ -31,14 +31,6 @@ fn higher_ranked_glb<T>(&self, a: &Binder<T>, b: &Binder<T>) -> RelateResult<'tc
where
T
:
Relate
<
'a
,
'tcx
>
;
}
trait
InferCtxtExt
{
fn
tainted_regions
(
&
self
,
snapshot
:
&
CombinedSnapshot
,
r
:
ty
::
Region
)
->
Vec
<
ty
::
Region
>
;
fn
region_vars_confined_to_snapshot
(
&
self
,
snapshot
:
&
CombinedSnapshot
)
->
Vec
<
ty
::
RegionVid
>
;
}
impl
<
'a
,
'tcx
>
HigherRankedRelations
<
'a
,
'tcx
>
for
CombineFields
<
'a
,
'tcx
>
{
fn
higher_ranked_sub
<
T
>
(
&
self
,
a
:
&
Binder
<
T
>
,
b
:
&
Binder
<
T
>
)
->
RelateResult
<
'tcx
,
Binder
<
T
>>
...
...
@@ -79,23 +71,9 @@ fn higher_ranked_sub<T>(&self, a: &Binder<T>, b: &Binder<T>)
// Presuming type comparison succeeds, we need to check
// that the skolemized regions do not "leak".
match
leak_check
(
self
.infcx
,
&
skol_map
,
snapshot
)
{
Ok
(())
=>
{
}
Err
((
skol_br
,
tainted_region
))
=>
{
if
self
.a_is_expected
{
debug!
(
"Not as polymorphic!"
);
return
Err
(
TypeError
::
RegionsInsufficientlyPolymorphic
(
skol_br
,
tainted_region
));
}
else
{
debug!
(
"Overly polymorphic!"
);
return
Err
(
TypeError
::
RegionsOverlyPolymorphic
(
skol_br
,
tainted_region
));
}
}
}
self
.infcx
.leak_check
(
!
self
.a_is_expected
,
&
skol_map
,
snapshot
)
?
;
debug!
(
"higher_ranked_sub: OK result={:?}"
,
result
);
debug!
(
"higher_ranked_sub: OK result={:?}"
,
result
);
Ok
(
ty
::
Binder
(
result
))
});
...
...
@@ -371,7 +349,7 @@ fn fold_regions_in<'tcx, T, F>(tcx: &TyCtxt<'tcx>,
})
}
impl
<
'a
,
'tcx
>
InferCtxt
Ext
for
InferCtxt
<
'a
,
'tcx
>
{
impl
<
'a
,
'tcx
>
InferCtxt
<
'a
,
'tcx
>
{
fn
tainted_regions
(
&
self
,
snapshot
:
&
CombinedSnapshot
,
r
:
ty
::
Region
)
->
Vec
<
ty
::
Region
>
{
self
.region_vars
.tainted
(
&
snapshot
.region_vars_snapshot
,
r
)
}
...
...
@@ -452,12 +430,11 @@ fn region_vars_confined_to_snapshot(&self,
region_vars
}
}
pub
fn
skolemize_late_bound_regions
<
'a
,
'tcx
,
T
>
(
infcx
:
&
InferCtxt
<
'a
,
'tcx
>
,
binder
:
&
ty
::
Binder
<
T
>
,
snapshot
:
&
CombinedSnapshot
)
->
(
T
,
SkolemizationMap
)
pub
fn
skolemize_late_bound_regions
<
T
>
(
&
self
,
binder
:
&
ty
::
Binder
<
T
>
,
snapshot
:
&
CombinedSnapshot
)
->
(
T
,
SkolemizationMap
)
where
T
:
TypeFoldable
<
'tcx
>
{
/*!
...
...
@@ -468,8 +445,8 @@ pub fn skolemize_late_bound_regions<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
* details.
*/
let
(
result
,
map
)
=
infcx
.tcx
.replace_late_bound_regions
(
binder
,
|
br
|
{
infcx
.region_vars
.new_skolemized
(
br
,
&
snapshot
.region_vars_snapshot
)
let
(
result
,
map
)
=
self
.tcx
.replace_late_bound_regions
(
binder
,
|
br
|
{
self
.region_vars
.new_skolemized
(
br
,
&
snapshot
.region_vars_snapshot
)
});
debug!
(
"skolemize_bound_regions(binder={:?}, result={:?}, map={:?})"
,
...
...
@@ -480,10 +457,11 @@ pub fn skolemize_late_bound_regions<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
(
result
,
map
)
}
pub
fn
leak_check
<
'a
,
'tcx
>
(
infcx
:
&
InferCtxt
<
'a
,
'tcx
>
,
skol_map
:
&
SkolemizationMap
,
snapshot
:
&
CombinedSnapshot
)
->
Result
<
(),(
ty
::
BoundRegion
,
ty
::
Region
)
>
pub
fn
leak_check
(
&
self
,
overly_polymorphic
:
bool
,
skol_map
:
&
SkolemizationMap
,
snapshot
:
&
CombinedSnapshot
)
->
RelateResult
<
'tcx
,
()
>
{
/*!
* Searches the region constriants created since `snapshot` was started
...
...
@@ -496,9 +474,9 @@ pub fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
debug!
(
"leak_check: skol_map={:?}"
,
skol_map
);
let
new_vars
=
infcx
.region_vars_confined_to_snapshot
(
snapshot
);
let
new_vars
=
self
.region_vars_confined_to_snapshot
(
snapshot
);
for
(
&
skol_br
,
&
skol
)
in
skol_map
{
let
tainted
=
infcx
.tainted_regions
(
snapshot
,
skol
);
let
tainted
=
self
.tainted_regions
(
snapshot
,
skol
);
for
&
tainted_region
in
&
tainted
{
// Each skolemized should only be relatable to itself
// or new variables:
...
...
@@ -516,8 +494,15 @@ pub fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
skol_br
,
tainted_region
);
// A is not as polymorphic as B:
return
Err
((
skol_br
,
tainted_region
));
if
overly_polymorphic
{
debug!
(
"Overly polymorphic!"
);
return
Err
(
TypeError
::
RegionsOverlyPolymorphic
(
skol_br
,
tainted_region
));
}
else
{
debug!
(
"Not as polymorphic!"
);
return
Err
(
TypeError
::
RegionsInsufficientlyPolymorphic
(
skol_br
,
tainted_region
));
}
}
}
Ok
(())
...
...
@@ -551,14 +536,13 @@ pub fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
/// replace `'0` with a late-bound region `'a`. The depth is matched
/// to the depth of the predicate, in this case 1, so that the final
/// predicate is `for<'a> &'a int : Clone`.
pub
fn
plug_leaks
<
'a
,
'tcx
,
T
>
(
infcx
:
&
InferCtxt
<
'a
,
'tcx
>
,
skol_map
:
SkolemizationMap
,
snapshot
:
&
CombinedSnapshot
,
value
:
&
T
)
->
T
pub
fn
plug_leaks
<
T
>
(
&
self
,
skol_map
:
SkolemizationMap
,
snapshot
:
&
CombinedSnapshot
,
value
:
&
T
)
->
T
where
T
:
TypeFoldable
<
'tcx
>
{
debug_assert!
(
leak_check
(
infcx
,
&
skol_map
,
snapshot
)
.is_ok
());
debug_assert!
(
self
.leak_check
(
false
,
&
skol_map
,
snapshot
)
.is_ok
());
debug!
(
"plug_leaks(skol_map={:?}, value={:?})"
,
skol_map
,
...
...
@@ -572,7 +556,7 @@ pub fn plug_leaks<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
skol_map
.into_iter
()
.flat_map
(|(
skol_br
,
skol
)|
{
infcx
.tainted_regions
(
snapshot
,
skol
)
self
.tainted_regions
(
snapshot
,
skol
)
.into_iter
()
.map
(
move
|
tainted_region
|
(
tainted_region
,
skol_br
))
})
...
...
@@ -583,14 +567,14 @@ pub fn plug_leaks<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
// Remove any instantiated type variables from `value`; those can hide
// references to regions from the `fold_regions` code below.
let
value
=
infcx
.resolve_type_vars_if_possible
(
value
);
let
value
=
self
.resolve_type_vars_if_possible
(
value
);
// Map any skolemization byproducts back to a late-bound
// region. Put that late-bound region at whatever the outermost
// binder is that we encountered in `value`. The caller is
// responsible for ensuring that (a) `value` contains at least one
// binder and (b) that binder is the one we want to use.
let
result
=
infcx
.tcx
.fold_regions
(
&
value
,
&
mut
false
,
|
r
,
current_depth
|
{
let
result
=
self
.tcx
.fold_regions
(
&
value
,
&
mut
false
,
|
r
,
current_depth
|
{
match
inv_skol_map
.get
(
&
r
)
{
None
=>
r
,
Some
(
br
)
=>
{
...
...
@@ -612,3 +596,4 @@ pub fn plug_leaks<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
result
}
}
src/librustc/infer/lattice.rs
浏览文件 @
f8ea24ed
...
...
@@ -29,7 +29,6 @@
//! over a `LatticeValue`, which is a value defined with respect to
//! a lattice.
use
super
::
combine
;
use
super
::
InferCtxt
;
use
ty
::
TyVar
;
...
...
@@ -78,7 +77,7 @@ pub fn super_lattice_tys<'a,'tcx,L:LatticeDir<'a,'tcx>>(this: &mut L,
}
_
=>
{
combine
::
super_combine_tys
(
this
.infcx
(),
this
,
a
,
b
)
infcx
.super_combine_tys
(
this
,
a
,
b
)
}
}
}
src/librustc/infer/mod.rs
浏览文件 @
f8ea24ed
...
...
@@ -366,19 +366,21 @@ pub enum FixupError {
UnresolvedTy
(
TyVid
)
}
pub
fn
fixup_err_to_string
(
f
:
FixupError
)
->
String
{
use
self
::
FixupError
::
*
;
match
f
{
UnresolvedIntTy
(
_
)
=>
{
"cannot determine the type of this integer; add a suffix to
\
specify the type explicitly"
.to_string
()
}
UnresolvedFloatTy
(
_
)
=>
{
"cannot determine the type of this number; add a suffix to specify
\
the type explicitly"
.to_string
()
}
UnresolvedTy
(
_
)
=>
"unconstrained type"
.to_string
(),
impl
fmt
::
Display
for
FixupError
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
use
self
::
FixupError
::
*
;
match
*
self
{
UnresolvedIntTy
(
_
)
=>
{
write!
(
f
,
"cannot determine the type of this integer;
\
add a suffix to specify the type explicitly"
)
}
UnresolvedFloatTy
(
_
)
=>
{
write!
(
f
,
"cannot determine the type of this number;
\
add a suffix to specify the type explicitly"
)
}
UnresolvedTy
(
_
)
=>
write!
(
f
,
"unconstrained type"
)
}
}
}
...
...
@@ -414,103 +416,19 @@ pub fn normalizing(tcx: &'a TyCtxt<'tcx>,
}
}
pub
fn
mk_subty
<
'a
,
'tcx
>
(
cx
:
&
InferCtxt
<
'a
,
'tcx
>
,
a_is_expected
:
bool
,
origin
:
TypeOrigin
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
InferResult
<
'tcx
,
()
>
{
debug!
(
"mk_subty({:?} <: {:?})"
,
a
,
b
);
cx
.sub_types
(
a_is_expected
,
origin
,
a
,
b
)
}
pub
fn
can_mk_subty
<
'a
,
'tcx
>
(
cx
:
&
InferCtxt
<
'a
,
'tcx
>
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
UnitResult
<
'tcx
>
{
debug!
(
"can_mk_subty({:?} <: {:?})"
,
a
,
b
);
cx
.probe
(|
_
|
{
let
trace
=
TypeTrace
{
origin
:
TypeOrigin
::
Misc
(
codemap
::
DUMMY_SP
),
values
:
Types
(
expected_found
(
true
,
a
,
b
))
};
cx
.sub
(
true
,
trace
,
&
a
,
&
b
)
.map
(|
_
|
())
})
}
pub
fn
can_mk_eqty
<
'a
,
'tcx
>
(
cx
:
&
InferCtxt
<
'a
,
'tcx
>
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
UnitResult
<
'tcx
>
{
cx
.can_equate
(
&
a
,
&
b
)
}
pub
fn
mk_subr
<
'a
,
'tcx
>
(
cx
:
&
InferCtxt
<
'a
,
'tcx
>
,
origin
:
SubregionOrigin
<
'tcx
>
,
a
:
ty
::
Region
,
b
:
ty
::
Region
)
{
debug!
(
"mk_subr({:?} <: {:?})"
,
a
,
b
);
let
snapshot
=
cx
.region_vars
.start_snapshot
();
cx
.region_vars
.make_subregion
(
origin
,
a
,
b
);
cx
.region_vars
.commit
(
snapshot
);
}
pub
fn
mk_eqty
<
'a
,
'tcx
>
(
cx
:
&
InferCtxt
<
'a
,
'tcx
>
,
a_is_expected
:
bool
,
origin
:
TypeOrigin
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
InferResult
<
'tcx
,
()
>
{
debug!
(
"mk_eqty({:?} <: {:?})"
,
a
,
b
);
cx
.eq_types
(
a_is_expected
,
origin
,
a
,
b
)
}
pub
fn
mk_eq_trait_refs
<
'a
,
'tcx
>
(
cx
:
&
InferCtxt
<
'a
,
'tcx
>
,
a_is_expected
:
bool
,
origin
:
TypeOrigin
,
a
:
ty
::
TraitRef
<
'tcx
>
,
b
:
ty
::
TraitRef
<
'tcx
>
)
->
InferResult
<
'tcx
,
()
>
{
debug!
(
"mk_eq_trait_refs({:?} = {:?})"
,
a
,
b
);
cx
.eq_trait_refs
(
a_is_expected
,
origin
,
a
,
b
)
}
pub
fn
mk_sub_poly_trait_refs
<
'a
,
'tcx
>
(
cx
:
&
InferCtxt
<
'a
,
'tcx
>
,
a_is_expected
:
bool
,
origin
:
TypeOrigin
,
a
:
ty
::
PolyTraitRef
<
'tcx
>
,
b
:
ty
::
PolyTraitRef
<
'tcx
>
)
->
InferResult
<
'tcx
,
()
>
{
debug!
(
"mk_sub_poly_trait_refs({:?} <: {:?})"
,
a
,
b
);
cx
.sub_poly_trait_refs
(
a_is_expected
,
origin
,
a
,
b
)
}
pub
fn
mk_eq_impl_headers
<
'a
,
'tcx
>
(
cx
:
&
InferCtxt
<
'a
,
'tcx
>
,
a_is_expected
:
bool
,
origin
:
TypeOrigin
,
a
:
&
ty
::
ImplHeader
<
'tcx
>
,
b
:
&
ty
::
ImplHeader
<
'tcx
>
)
->
InferResult
<
'tcx
,
()
>
{
debug!
(
"mk_eq_impl_header({:?} = {:?})"
,
a
,
b
);
match
(
a
.trait_ref
,
b
.trait_ref
)
{
(
Some
(
a_ref
),
Some
(
b_ref
))
=>
mk_eq_trait_refs
(
cx
,
a_is_expected
,
origin
,
a_ref
,
b_ref
),
(
None
,
None
)
=>
mk_eqty
(
cx
,
a_is_expected
,
origin
,
a
.self_ty
,
b
.self_ty
),
_
=>
bug!
(
"mk_eq_impl_headers given mismatched impl kinds"
),
impl
<
T
>
ExpectedFound
<
T
>
{
fn
new
(
a_is_expected
:
bool
,
a
:
T
,
b
:
T
)
->
Self
{
if
a_is_expected
{
ExpectedFound
{
expected
:
a
,
found
:
b
}
}
else
{
ExpectedFound
{
expected
:
b
,
found
:
a
}
}
}
}
fn
expected_found
<
T
>
(
a_is_expected
:
bool
,
a
:
T
,
b
:
T
)
->
ExpectedFound
<
T
>
{
if
a_is_expected
{
ExpectedFound
{
expected
:
a
,
found
:
b
}
}
else
{
ExpectedFound
{
expected
:
b
,
found
:
a
}
impl
<
'tcx
,
T
>
InferOk
<
'tcx
,
T
>
{
fn
unit
(
self
)
->
InferOk
<
'tcx
,
()
>
{
InferOk
{
value
:
(),
obligations
:
self
.obligations
}
}
}
...
...
@@ -551,18 +469,19 @@ pub fn normalize_associated_type<T>(&self, value: &T) -> T
fulfill_cx
.register_predicate_obligation
(
&
infcx
,
obligation
);
}
drain_fulfillment_cx_or_panic
(
DUMMY_SP
,
&
infcx
,
&
mut
fulfill_cx
,
&
result
)
infcx
.drain_fulfillment_cx_or_panic
(
DUMMY_SP
,
&
mut
fulfill_cx
,
&
result
)
}
}
pub
fn
drain_fulfillment_cx_or_panic
<
'a
,
'tcx
,
T
>
(
span
:
Span
,
infcx
:
&
InferCtxt
<
'a
,
'tcx
>
,
fulfill_cx
:
&
mut
traits
::
FulfillmentContext
<
'tcx
>
,
result
:
&
T
)
->
T
impl
<
'a
,
'tcx
>
InferCtxt
<
'a
,
'tcx
>
{
pub
fn
drain_fulfillment_cx_or_panic
<
T
>
(
&
self
,
span
:
Span
,
fulfill_cx
:
&
mut
traits
::
FulfillmentContext
<
'tcx
>
,
result
:
&
T
)
->
T
where
T
:
TypeFoldable
<
'tcx
>
{
match
drain_fulfillment_cx
(
infcx
,
fulfill_cx
,
result
)
{
match
self
.drain_fulfillment_cx
(
fulfill_cx
,
result
)
{
Ok
(
v
)
=>
v
,
Err
(
errors
)
=>
{
span_bug!
(
...
...
@@ -580,10 +499,10 @@ pub fn drain_fulfillment_cx_or_panic<'a,'tcx,T>(span: Span,
/// 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
:
&
InferCtxt
<
'a
,
'tcx
>
,
fulfill_cx
:
&
mut
traits
::
FulfillmentContext
<
'tcx
>
,
result
:
&
T
)
->
Result
<
T
,
Vec
<
traits
::
FulfillmentError
<
'tcx
>>>
pub
fn
drain_fulfillment_cx
<
T
>
(
&
self
,
fulfill_cx
:
&
mut
traits
::
FulfillmentContext
<
'tcx
>
,
result
:
&
T
)
->
Result
<
T
,
Vec
<
traits
::
FulfillmentError
<
'tcx
>>>
where
T
:
TypeFoldable
<
'tcx
>
{
debug!
(
"drain_fulfillment_cx(result={:?})"
,
...
...
@@ -592,24 +511,12 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
// 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
);
}
}
let
result
=
infcx
.resolve_type_vars_if_possible
(
result
);
Ok
(
infcx
.tcx
.erase_regions
(
&
result
))
}
fulfill_cx
.select_all_or_error
(
self
)
?
;
impl
<
'tcx
,
T
>
InferOk
<
'tcx
,
T
>
{
fn
unit
(
self
)
->
InferOk
<
'tcx
,
()
>
{
InferOk
{
value
:
(),
obligations
:
self
.obligations
}
}
let
result
=
self
.resolve_type_vars_if_possible
(
result
);
Ok
(
self
.tcx
.erase_regions
(
&
result
))
}
impl
<
'a
,
'tcx
>
InferCtxt
<
'a
,
'tcx
>
{
pub
fn
projection_mode
(
&
self
)
->
ProjectionMode
{
self
.projection_mode
}
...
...
@@ -896,6 +803,18 @@ pub fn sub_types(&self,
})
}
pub
fn
can_sub_types
(
&
self
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
UnitResult
<
'tcx
>
{
self
.probe
(|
_
|
{
let
origin
=
TypeOrigin
::
Misc
(
codemap
::
DUMMY_SP
);
let
trace
=
TypeTrace
::
types
(
origin
,
true
,
a
,
b
);
self
.sub
(
true
,
trace
,
&
a
,
&
b
)
.map
(|
_
|
())
})
}
pub
fn
eq_types
(
&
self
,
a_is_expected
:
bool
,
origin
:
TypeOrigin
,
...
...
@@ -916,18 +835,31 @@ pub fn eq_trait_refs(&self,
b
:
ty
::
TraitRef
<
'tcx
>
)
->
InferResult
<
'tcx
,
()
>
{
debug!
(
"eq_trait_refs({:?} <: {:?})"
,
a
,
b
);
debug!
(
"eq_trait_refs({:?} = {:?})"
,
a
,
b
);
self
.commit_if_ok
(|
_
|
{
let
trace
=
TypeTrace
{
origin
:
origin
,
values
:
TraitRefs
(
expected_found
(
a_is_expected
,
a
.clone
(),
b
.clone
()
))
values
:
TraitRefs
(
ExpectedFound
::
new
(
a_is_expected
,
a
,
b
))
};
self
.equate
(
a_is_expected
,
trace
,
&
a
,
&
b
)
.map
(|
ok
|
ok
.unit
())
})
}
pub
fn
eq_impl_headers
(
&
self
,
a_is_expected
:
bool
,
origin
:
TypeOrigin
,
a
:
&
ty
::
ImplHeader
<
'tcx
>
,
b
:
&
ty
::
ImplHeader
<
'tcx
>
)
->
InferResult
<
'tcx
,
()
>
{
debug!
(
"eq_impl_header({:?} = {:?})"
,
a
,
b
);
match
(
a
.trait_ref
,
b
.trait_ref
)
{
(
Some
(
a_ref
),
Some
(
b_ref
))
=>
self
.eq_trait_refs
(
a_is_expected
,
origin
,
a_ref
,
b_ref
),
(
None
,
None
)
=>
self
.eq_types
(
a_is_expected
,
origin
,
a
.self_ty
,
b
.self_ty
),
_
=>
bug!
(
"mk_eq_impl_headers given mismatched impl kinds"
),
}
}
pub
fn
sub_poly_trait_refs
(
&
self
,
a_is_expected
:
bool
,
origin
:
TypeOrigin
,
...
...
@@ -935,52 +867,22 @@ pub fn sub_poly_trait_refs(&self,
b
:
ty
::
PolyTraitRef
<
'tcx
>
)
->
InferResult
<
'tcx
,
()
>
{
debug!
(
"sub_poly_trait_refs({:?} <: {:?})"
,
a
,
b
);
debug!
(
"sub_poly_trait_refs({:?} <: {:?})"
,
a
,
b
);
self
.commit_if_ok
(|
_
|
{
let
trace
=
TypeTrace
{
origin
:
origin
,
values
:
PolyTraitRefs
(
expected_found
(
a_is_expected
,
a
.clone
(),
b
.clone
()
))
values
:
PolyTraitRefs
(
ExpectedFound
::
new
(
a_is_expected
,
a
,
b
))
};
self
.sub
(
a_is_expected
,
trace
,
&
a
,
&
b
)
.map
(|
ok
|
ok
.unit
())
})
}
pub
fn
skolemize_late_bound_regions
<
T
>
(
&
self
,
value
:
&
ty
::
Binder
<
T
>
,
snapshot
:
&
CombinedSnapshot
)
->
(
T
,
SkolemizationMap
)
where
T
:
TypeFoldable
<
'tcx
>
{
/*! See `higher_ranked::skolemize_late_bound_regions` */
higher_ranked
::
skolemize_late_bound_regions
(
self
,
value
,
snapshot
)
}
pub
fn
leak_check
(
&
self
,
skol_map
:
&
SkolemizationMap
,
snapshot
:
&
CombinedSnapshot
)
->
UnitResult
<
'tcx
>
{
/*! See `higher_ranked::leak_check` */
match
higher_ranked
::
leak_check
(
self
,
skol_map
,
snapshot
)
{
Ok
(())
=>
Ok
(()),
Err
((
br
,
r
))
=>
Err
(
TypeError
::
RegionsInsufficientlyPolymorphic
(
br
,
r
))
}
}
pub
fn
plug_leaks
<
T
>
(
&
self
,
skol_map
:
SkolemizationMap
,
snapshot
:
&
CombinedSnapshot
,
value
:
&
T
)
->
T
where
T
:
TypeFoldable
<
'tcx
>
{
/*! See `higher_ranked::plug_leaks` */
higher_ranked
::
plug_leaks
(
self
,
skol_map
,
snapshot
,
value
)
pub
fn
sub_regions
(
&
self
,
origin
:
SubregionOrigin
<
'tcx
>
,
a
:
ty
::
Region
,
b
:
ty
::
Region
)
{
debug!
(
"sub_regions({:?} <: {:?})"
,
a
,
b
);
self
.region_vars
.make_subregion
(
origin
,
a
,
b
);
}
pub
fn
equality_predicate
(
&
self
,
...
...
@@ -992,8 +894,8 @@ pub fn equality_predicate(&self,
let
(
ty
::
EquatePredicate
(
a
,
b
),
skol_map
)
=
self
.skolemize_late_bound_regions
(
predicate
,
snapshot
);
let
origin
=
TypeOrigin
::
EquatePredicate
(
span
);
let
eqty_ok
=
mk_eqty
(
self
,
false
,
origin
,
a
,
b
)
?
;
self
.leak_check
(
&
skol_map
,
snapshot
)
.map
(|
_
|
eqty_ok
.unit
())
let
eqty_ok
=
self
.eq_types
(
false
,
origin
,
a
,
b
)
?
;
self
.leak_check
(
false
,
&
skol_map
,
snapshot
)
.map
(|
_
|
eqty_ok
.unit
())
})
}
...
...
@@ -1006,8 +908,8 @@ pub fn region_outlives_predicate(&self,
let
(
ty
::
OutlivesPredicate
(
r_a
,
r_b
),
skol_map
)
=
self
.skolemize_late_bound_regions
(
predicate
,
snapshot
);
let
origin
=
RelateRegionParamBound
(
span
);
let
()
=
mk_subr
(
self
,
origin
,
r_b
,
r_a
);
// `b : a` ==> `a <= b`
self
.leak_check
(
&
skol_map
,
snapshot
)
self
.sub_regions
(
origin
,
r_b
,
r_a
);
// `b : a` ==> `a <= b`
self
.leak_check
(
false
,
&
skol_map
,
snapshot
)
})
}
...
...
@@ -1509,12 +1411,7 @@ pub fn can_equate<'b,T>(&'b self, a: &T, b: &T) -> UnitResult<'tcx>
// anyhow. We should make this typetrace stuff more
// generic so we don't have to do anything quite this
// terrible.
let
e
=
self
.tcx.types.err
;
let
trace
=
TypeTrace
{
origin
:
TypeOrigin
::
Misc
(
codemap
::
DUMMY_SP
),
values
:
Types
(
expected_found
(
true
,
e
,
e
))
};
self
.equate
(
true
,
trace
,
a
,
b
)
self
.equate
(
true
,
TypeTrace
::
dummy
(
self
.tcx
),
a
,
b
)
})
.map
(|
_
|
())
}
...
...
@@ -1638,7 +1535,7 @@ pub fn types(origin: TypeOrigin,
->
TypeTrace
<
'tcx
>
{
TypeTrace
{
origin
:
origin
,
values
:
Types
(
expected_found
(
a_is_expected
,
a
,
b
))
values
:
Types
(
ExpectedFound
::
new
(
a_is_expected
,
a
,
b
))
}
}
...
...
src/librustc/infer/sub.rs
浏览文件 @
f8ea24ed
...
...
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
super
::
combine
::
{
self
,
CombineFields
}
;
use
super
::
combine
::
CombineFields
;
use
super
::
higher_ranked
::
HigherRankedRelations
;
use
super
::
SubregionOrigin
;
use
super
::
type_variable
::{
SubtypeOf
,
SupertypeOf
};
...
...
@@ -96,7 +96,7 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
}
_
=>
{
combine
::
super_combine_tys
(
self
.fields.infcx
,
self
,
a
,
b
)
?
;
self
.fields.infcx
.super_combine_tys
(
self
,
a
,
b
)
?
;
Ok
(
a
)
}
}
...
...
src/librustc/middle/astconv_util.rs
浏览文件 @
f8ea24ed
...
...
@@ -20,59 +20,59 @@
use
syntax
::
codemap
::
Span
;
use
hir
as
ast
;
pub
fn
prohibit_type_params
(
tcx
:
&
TyCtxt
,
segments
:
&
[
ast
::
PathSegment
])
{
impl
<
'tcx
>
TyCtxt
<
'tcx
>
{
pub
fn
prohibit_type_params
(
&
self
,
segments
:
&
[
ast
::
PathSegment
])
{
for
segment
in
segments
{
for
typ
in
segment
.parameters
.types
()
{
span_err!
(
tcx
.sess
,
typ
.span
,
E0109
,
span_err!
(
self
.sess
,
typ
.span
,
E0109
,
"type parameters are not allowed on this type"
);
break
;
}
for
lifetime
in
segment
.parameters
.lifetimes
()
{
span_err!
(
tcx
.sess
,
lifetime
.span
,
E0110
,
span_err!
(
self
.sess
,
lifetime
.span
,
E0110
,
"lifetime parameters are not allowed on this type"
);
break
;
}
for
binding
in
segment
.parameters
.bindings
()
{
prohibit_projection
(
tcx
,
binding
.span
);
self
.prohibit_projection
(
binding
.span
);
break
;
}
}
}
pub
fn
prohibit_projection
(
tcx
:
&
TyCtxt
,
span
:
Span
)
pub
fn
prohibit_projection
(
&
self
,
span
:
Span
)
{
span_err!
(
tcx
.sess
,
span
,
E0229
,
span_err!
(
self
.sess
,
span
,
E0229
,
"associated type bindings are not allowed here"
);
}
pub
fn
prim_ty_to_ty
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
segments
:
&
[
ast
::
PathSegment
],
nty
:
ast
::
PrimTy
)
->
Ty
<
'tcx
>
{
prohibit_type_params
(
tcx
,
segments
);
pub
fn
prim_ty_to_ty
(
&
self
,
segments
:
&
[
ast
::
PathSegment
],
nty
:
ast
::
PrimTy
)
->
Ty
<
'tcx
>
{
self
.prohibit_type_params
(
segments
);
match
nty
{
ast
::
TyBool
=>
tcx
.types.bool
,
ast
::
TyChar
=>
tcx
.types.char
,
ast
::
TyInt
(
it
)
=>
tcx
.mk_mach_int
(
it
),
ast
::
TyUint
(
uit
)
=>
tcx
.mk_mach_uint
(
uit
),
ast
::
TyFloat
(
ft
)
=>
tcx
.mk_mach_float
(
ft
),
ast
::
TyStr
=>
tcx
.mk_str
()
ast
::
TyBool
=>
self
.types.bool
,
ast
::
TyChar
=>
self
.types.char
,
ast
::
TyInt
(
it
)
=>
self
.mk_mach_int
(
it
),
ast
::
TyUint
(
uit
)
=>
self
.mk_mach_uint
(
uit
),
ast
::
TyFloat
(
ft
)
=>
self
.mk_mach_float
(
ft
),
ast
::
TyStr
=>
self
.mk_str
()
}
}
/// If a type in the AST is a primitive type, return the ty::Ty corresponding
/// to it.
pub
fn
ast_ty_to_prim_ty
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
ast_ty
:
&
ast
::
Ty
)
->
Option
<
Ty
<
'tcx
>>
{
pub
fn
ast_ty_to_prim_ty
(
&
self
,
ast_ty
:
&
ast
::
Ty
)
->
Option
<
Ty
<
'tcx
>>
{
if
let
ast
::
TyPath
(
None
,
ref
path
)
=
ast_ty
.node
{
let
def
=
match
tcx
.def_map
.borrow
()
.get
(
&
ast_ty
.id
)
{
let
def
=
match
self
.def_map
.borrow
()
.get
(
&
ast_ty
.id
)
{
None
=>
{
span_bug!
(
ast_ty
.span
,
"unbound path {:?}"
,
path
)
}
Some
(
d
)
=>
d
.full_def
()
};
if
let
Def
::
PrimTy
(
nty
)
=
def
{
Some
(
prim_ty_to_ty
(
tcx
,
&
path
.segments
,
nty
))
Some
(
self
.prim_ty_to_ty
(
&
path
.segments
,
nty
))
}
else
{
None
}
...
...
@@ -80,3 +80,4 @@ pub fn ast_ty_to_prim_ty<'tcx>(tcx: &TyCtxt<'tcx>, ast_ty: &ast::Ty)
None
}
}
}
src/librustc/middle/free_region.rs
浏览文件 @
f8ea24ed
...
...
@@ -48,9 +48,8 @@ pub fn relate_free_regions_from_implied_bounds<'tcx>(&mut self,
}
}
pub
fn
relate_free_regions_from_predicates
<
'tcx
>
(
&
mut
self
,
_
tcx
:
&
TyCtxt
<
'tcx
>
,
predicates
:
&
[
ty
::
Predicate
<
'tcx
>
])
{
pub
fn
relate_free_regions_from_predicates
(
&
mut
self
,
predicates
:
&
[
ty
::
Predicate
])
{
debug!
(
"relate_free_regions_from_predicates(predicates={:?})"
,
predicates
);
for
predicate
in
predicates
{
match
*
predicate
{
...
...
src/librustc/middle/stability.rs
浏览文件 @
f8ea24ed
...
...
@@ -625,9 +625,9 @@ fn maybe_do_stability_check(tcx: &TyCtxt, id: DefId, span: Span,
return
;
}
let
(
stability
,
deprecation
)
=
if
is_staged_api
(
tcx
,
id
)
{
(
lookup_stability
(
tcx
,
id
),
None
)
(
tcx
.lookup_stability
(
id
),
None
)
}
else
{
(
None
,
lookup_deprecation
(
tcx
,
id
))
(
None
,
tcx
.lookup_deprecation
(
id
))
};
debug!
(
"maybe_do_stability_check:
\
inspecting id={:?} span={:?} of stability={:?}"
,
id
,
span
,
stability
);
...
...
@@ -651,45 +651,47 @@ fn is_staged_api(tcx: &TyCtxt, id: DefId) -> bool {
}
}
impl
<
'tcx
>
TyCtxt
<
'tcx
>
{
/// Lookup the stability for a node, loading external crate
/// metadata as necessary.
pub
fn
lookup_stability
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
id
:
DefId
)
->
Option
<&
'tcx
Stability
>
{
if
let
Some
(
st
)
=
tcx
.stability
.borrow
()
.stab_map
.get
(
&
id
)
{
pub
fn
lookup_stability
(
&
self
,
id
:
DefId
)
->
Option
<&
'tcx
Stability
>
{
if
let
Some
(
st
)
=
self
.stability
.borrow
()
.stab_map
.get
(
&
id
)
{
return
*
st
;
}
let
st
=
lookup_stability_uncached
(
tcx
,
id
);
tcx
.stability
.borrow_mut
()
.stab_map
.insert
(
id
,
st
);
let
st
=
self
.lookup_stability_uncached
(
id
);
self
.stability
.borrow_mut
()
.stab_map
.insert
(
id
,
st
);
st
}
pub
fn
lookup_deprecation
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
id
:
DefId
)
->
Option
<
Deprecation
>
{
if
let
Some
(
depr
)
=
tcx
.stability
.borrow
()
.depr_map
.get
(
&
id
)
{
pub
fn
lookup_deprecation
(
&
self
,
id
:
DefId
)
->
Option
<
Deprecation
>
{
if
let
Some
(
depr
)
=
self
.stability
.borrow
()
.depr_map
.get
(
&
id
)
{
return
depr
.clone
();
}
let
depr
=
lookup_deprecation_uncached
(
tcx
,
id
);
tcx
.stability
.borrow_mut
()
.depr_map
.insert
(
id
,
depr
.clone
());
let
depr
=
self
.lookup_deprecation_uncached
(
id
);
self
.stability
.borrow_mut
()
.depr_map
.insert
(
id
,
depr
.clone
());
depr
}
fn
lookup_stability_uncached
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
id
:
DefId
)
->
Option
<&
'tcx
Stability
>
{
fn
lookup_stability_uncached
(
&
self
,
id
:
DefId
)
->
Option
<&
'tcx
Stability
>
{
debug!
(
"lookup(id={:?})"
,
id
);
if
id
.is_local
()
{
None
// The stability cache is filled partially lazily
}
else
{
tcx
.sess.cstore
.stability
(
id
)
.map
(|
st
|
tcx
.intern_stability
(
st
))
self
.sess.cstore
.stability
(
id
)
.map
(|
st
|
self
.intern_stability
(
st
))
}
}
fn
lookup_deprecation_uncached
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
id
:
DefId
)
->
Option
<
Deprecation
>
{
fn
lookup_deprecation_uncached
(
&
self
,
id
:
DefId
)
->
Option
<
Deprecation
>
{
debug!
(
"lookup(id={:?})"
,
id
);
if
id
.is_local
()
{
None
// The stability cache is filled partially lazily
}
else
{
tcx
.sess.cstore
.deprecation
(
id
)
self
.sess.cstore
.deprecation
(
id
)
}
}
}
/// Given the list of enabled features that were not language features (i.e. that
/// were expected to be library features), and the list of features used from
...
...
src/librustc/traits/coherence.rs
浏览文件 @
f8ea24ed
...
...
@@ -16,7 +16,7 @@
use
hir
::
def_id
::
DefId
;
use
ty
::
subst
::
TypeSpace
;
use
ty
::{
self
,
Ty
,
TyCtxt
};
use
infer
::{
self
,
InferCtxt
,
TypeOrigin
};
use
infer
::{
InferCtxt
,
TypeOrigin
};
use
syntax
::
codemap
::
DUMMY_SP
;
#[derive(Copy,
Clone)]
...
...
@@ -57,11 +57,10 @@ fn overlap<'cx, 'tcx>(selcx: &mut SelectionContext<'cx, 'tcx>,
debug!
(
"overlap: b_impl_header={:?}"
,
b_impl_header
);
// Do `a` and `b` unify? If not, no overlap.
if
let
Err
(
_
)
=
infer
::
mk_eq_impl_headers
(
selcx
.infcx
(),
true
,
TypeOrigin
::
Misc
(
DUMMY_SP
),
&
a_impl_header
,
&
b_impl_header
)
{
if
let
Err
(
_
)
=
selcx
.infcx
()
.eq_impl_headers
(
true
,
TypeOrigin
::
Misc
(
DUMMY_SP
),
&
a_impl_header
,
&
b_impl_header
)
{
return
None
;
}
...
...
src/librustc/traits/error_reporting.rs
浏览文件 @
f8ea24ed
此差异已折叠。
点击以展开。
src/librustc/traits/fulfill.rs
浏览文件 @
f8ea24ed
...
...
@@ -21,16 +21,13 @@
use
super
::
CodeAmbiguity
;
use
super
::
CodeProjectionError
;
use
super
::
CodeSelectionError
;
use
super
::
is_object_safe
;
use
super
::
FulfillmentError
;
use
super
::
FulfillmentErrorCode
;
use
super
::
ObligationCause
;
use
super
::
PredicateObligation
;
use
super
::
project
;
use
super
::
report_overflow_error_cycle
;
use
super
::
select
::
SelectionContext
;
use
super
::
Unimplemented
;
use
super
::
util
::
predicate_for_builtin_bound
;
pub
struct
GlobalFulfilledPredicates
<
'tcx
>
{
set
:
FnvHashSet
<
ty
::
PolyTraitPredicate
<
'tcx
>>
,
...
...
@@ -163,7 +160,7 @@ pub fn register_builtin_bound<'a>(&mut self,
builtin_bound
:
ty
::
BuiltinBound
,
cause
:
ObligationCause
<
'tcx
>
)
{
match
predicate_for_builtin_bound
(
infcx
.tcx
,
cause
,
builtin_bound
,
0
,
ty
)
{
match
infcx
.tcx
.predicate_for_builtin_bound
(
cause
,
builtin_bound
,
0
,
ty
)
{
Ok
(
predicate
)
=>
{
self
.register_predicate_obligation
(
infcx
,
predicate
);
}
...
...
@@ -449,7 +446,7 @@ fn process_child_obligations<'a,'tcx>(
debug!
(
"process_child_obligations: coinductive match"
);
None
}
else
{
report_overflow_error_cycle
(
selcx
.infcx
(),
&
cycle
);
selcx
.infcx
()
.report_overflow_error_cycle
(
&
cycle
);
}
}
else
{
// Not a cycle. Just ignore this obligation then,
...
...
@@ -677,7 +674,7 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
}
ty
::
Predicate
::
ObjectSafe
(
trait_def_id
)
=>
{
if
!
is_object_safe
(
selcx
.tcx
(),
trait_def_id
)
{
if
!
selcx
.tcx
()
.is_object_safe
(
trait_def_id
)
{
Err
(
CodeSelectionError
(
Unimplemented
))
}
else
{
Ok
(
Some
(
Vec
::
new
()))
...
...
src/librustc/traits/mod.rs
浏览文件 @
f8ea24ed
...
...
@@ -19,46 +19,31 @@
use
middle
::
free_region
::
FreeRegionMap
;
use
ty
::
subst
;
use
ty
::{
self
,
Ty
,
TypeFoldable
};
use
infer
::
{
fixup_err_to_string
,
InferCtxt
}
;
use
infer
::
InferCtxt
;
use
std
::
rc
::
Rc
;
use
syntax
::
ast
;
use
syntax
::
codemap
::{
Span
,
DUMMY_SP
};
pub
use
self
::
error_reporting
::
TraitErrorKey
;
pub
use
self
::
error_reporting
::
recursive_type_with_infinite_size_error
;
pub
use
self
::
error_reporting
::
report_fulfillment_errors
;
pub
use
self
::
error_reporting
::
report_fulfillment_errors_as_warnings
;
pub
use
self
::
error_reporting
::
report_overflow_error
;
pub
use
self
::
error_reporting
::
report_overflow_error_cycle
;
pub
use
self
::
error_reporting
::
report_selection_error
;
pub
use
self
::
error_reporting
::
report_object_safety_error
;
pub
use
self
::
coherence
::
orphan_check
;
pub
use
self
::
coherence
::
overlapping_impls
;
pub
use
self
::
coherence
::
OrphanCheckErr
;
pub
use
self
::
fulfill
::{
FulfillmentContext
,
GlobalFulfilledPredicates
,
RegionObligation
};
pub
use
self
::
project
::{
MismatchedProjectionTypes
,
ProjectionMode
};
pub
use
self
::
project
::{
normalize
,
Normalized
};
pub
use
self
::
object_safety
::
is_object_safe
;
pub
use
self
::
object_safety
::
astconv_object_safety_violations
;
pub
use
self
::
object_safety
::
object_safety_violations
;
pub
use
self
::
object_safety
::
ObjectSafetyViolation
;
pub
use
self
::
object_safety
::
MethodViolationCode
;
pub
use
self
::
object_safety
::
is_vtable_safe_method
;
pub
use
self
::
select
::{
EvaluationCache
,
SelectionContext
,
SelectionCache
};
pub
use
self
::
select
::{
MethodMatchResult
,
MethodMatched
,
MethodAmbiguous
,
MethodDidNotMatch
};
pub
use
self
::
select
::{
MethodMatchedData
};
// intentionally don't export variants
pub
use
self
::
specialize
::{
Overlap
,
specialization_graph
,
specializes
,
translate_substs
};
pub
use
self
::
util
::
elaborate_predicates
;
pub
use
self
::
util
::
get_vtable_index_of_object_method
;
pub
use
self
::
util
::
trait_ref_for_builtin_bound
;
pub
use
self
::
util
::
predicate_for_trait_def
;
pub
use
self
::
util
::
supertraits
;
pub
use
self
::
util
::
Supertraits
;
pub
use
self
::
util
::
supertrait_def_ids
;
pub
use
self
::
util
::
SupertraitDefIds
;
pub
use
self
::
util
::
transitive_bounds
;
pub
use
self
::
util
::
upcast
;
mod
coherence
;
mod
error_reporting
;
...
...
@@ -343,7 +328,7 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
let
cause
=
ObligationCause
::
misc
(
span
,
ast
::
DUMMY_NODE_ID
);
let
obligation
=
util
::
predicate_for_builtin_bound
(
infcx
.tcx
,
cause
,
bound
,
0
,
ty
);
infcx
.tcx
.predicate_for_builtin_bound
(
cause
,
bound
,
0
,
ty
);
let
obligation
=
match
obligation
{
Ok
(
o
)
=>
o
,
Err
(
..
)
=>
return
false
...
...
@@ -444,7 +429,7 @@ pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvi
&
infcx
.parameter_environment.caller_bounds
)
{
Ok
(
predicates
)
=>
predicates
,
Err
(
errors
)
=>
{
report_fulfillment_errors
(
&
infcx
,
&
errors
);
infcx
.report_fulfillment_errors
(
&
errors
);
return
infcx
.parameter_environment
;
// an unnormalized env is better than nothing
}
};
...
...
@@ -464,8 +449,7 @@ pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvi
// represents a legitimate failure due to some kind of
// unconstrained variable, and it seems better not to ICE,
// all things considered.
let
err_msg
=
fixup_err_to_string
(
fixup_err
);
tcx
.sess
.span_err
(
span
,
&
err_msg
);
tcx
.sess
.span_err
(
span
,
&
fixup_err
.to_string
());
return
infcx
.parameter_environment
;
// an unnormalized env is better than nothing
}
};
...
...
src/librustc/traits/object_safety.rs
浏览文件 @
f8ea24ed
...
...
@@ -53,15 +53,13 @@ pub enum MethodViolationCode {
Generic
,
}
pub
fn
is_object_safe
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
trait_def_id
:
DefId
)
->
bool
{
impl
<
'tcx
>
TyCtxt
<
'tcx
>
{
pub
fn
is_object_safe
(
&
self
,
trait_def_id
:
DefId
)
->
bool
{
// Because we query yes/no results frequently, we keep a cache:
let
def
=
tcx
.lookup_trait_def
(
trait_def_id
);
let
def
=
self
.lookup_trait_def
(
trait_def_id
);
let
result
=
def
.object_safety
()
.unwrap_or_else
(||
{
let
result
=
object_safety_violations
(
tcx
,
trait_def_id
)
.is_empty
();
let
result
=
self
.object_safety_violations
(
trait_def_id
)
.is_empty
();
// Record just a yes/no result in the cache; this is what is
// queried most frequently. Note that this may overwrite a
...
...
@@ -80,43 +78,40 @@ pub fn is_object_safe<'tcx>(tcx: &TyCtxt<'tcx>,
/// astconv - currently, Self in supertraits. This is needed
/// because `object_safety_violations` can't be used during
/// type collection.
pub
fn
astconv_object_safety_violations
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
trait_def_id
:
DefId
)
->
Vec
<
ObjectSafetyViolation
<
'tcx
>>
pub
fn
astconv_object_safety_violations
(
&
self
,
trait_def_id
:
DefId
)
->
Vec
<
ObjectSafetyViolation
<
'tcx
>>
{
let
mut
violations
=
vec!
[];
if
s
upertraits_reference_self
(
tcx
,
trait_def_id
)
{
if
s
elf
.supertraits_reference_self
(
trait_def_id
)
{
violations
.push
(
ObjectSafetyViolation
::
SupertraitSelf
);
}
debug!
(
"
object_safety_violations_for_trait
(trait_def_id={:?}) = {:?}"
,
debug!
(
"
astconv_object_safety_violations
(trait_def_id={:?}) = {:?}"
,
trait_def_id
,
violations
);
violations
}
pub
fn
object_safety_violations
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
trait_def_id
:
DefId
)
->
Vec
<
ObjectSafetyViolation
<
'tcx
>>
pub
fn
object_safety_violations
(
&
self
,
trait_def_id
:
DefId
)
->
Vec
<
ObjectSafetyViolation
<
'tcx
>>
{
traits
::
supertrait_def_ids
(
tcx
,
trait_def_id
)
.flat_map
(|
def_id
|
object_safety_violations_for_trait
(
tcx
,
def_id
))
traits
::
supertrait_def_ids
(
self
,
trait_def_id
)
.flat_map
(|
def_id
|
self
.object_safety_violations_for_trait
(
def_id
))
.collect
()
}
fn
object_safety_violations_for_trait
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
trait_def_id
:
DefId
)
->
Vec
<
ObjectSafetyViolation
<
'tcx
>>
fn
object_safety_violations_for_trait
(
&
self
,
trait_def_id
:
DefId
)
->
Vec
<
ObjectSafetyViolation
<
'tcx
>>
{
// Check methods for violations.
let
mut
violations
:
Vec
<
_
>
=
tcx
.trait_items
(
trait_def_id
)
.iter
()
self
.trait_items
(
trait_def_id
)
.iter
()
.filter_map
(|
item
|
{
match
*
item
{
ty
::
MethodTraitItem
(
ref
m
)
=>
{
object_safety_violation_for_method
(
tcx
,
trait_def_id
,
&
m
)
self
.object_safety_violation_for_method
(
trait_def_id
,
&
m
)
.map
(|
code
|
ObjectSafetyViolation
::
Method
(
m
.clone
(),
code
))
}
_
=>
None
,
...
...
@@ -125,10 +120,10 @@ fn object_safety_violations_for_trait<'tcx>(tcx: &TyCtxt<'tcx>,
.collect
();
// Check the trait itself.
if
trait_has_sized_self
(
tcx
,
trait_def_id
)
{
if
self
.trait_has_sized_self
(
trait_def_id
)
{
violations
.push
(
ObjectSafetyViolation
::
SizedSelf
);
}
if
s
upertraits_reference_self
(
tcx
,
trait_def_id
)
{
if
s
elf
.supertraits_reference_self
(
trait_def_id
)
{
violations
.push
(
ObjectSafetyViolation
::
SupertraitSelf
);
}
...
...
@@ -139,18 +134,15 @@ fn object_safety_violations_for_trait<'tcx>(tcx: &TyCtxt<'tcx>,
violations
}
pub
fn
supertraits_reference_self
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
trait_def_id
:
DefId
)
->
bool
{
let
trait_def
=
tcx
.lookup_trait_def
(
trait_def_id
);
fn
supertraits_reference_self
(
&
self
,
trait_def_id
:
DefId
)
->
bool
{
let
trait_def
=
self
.lookup_trait_def
(
trait_def_id
);
let
trait_ref
=
trait_def
.trait_ref
.clone
();
let
trait_ref
=
trait_ref
.to_poly_trait_ref
();
let
predicates
=
tcx
.lookup_super_predicates
(
trait_def_id
);
let
predicates
=
self
.lookup_super_predicates
(
trait_def_id
);
predicates
.predicates
.into_iter
()
.map
(|
predicate
|
predicate
.subst_supertrait
(
tcx
,
&
trait_ref
))
.map
(|
predicate
|
predicate
.subst_supertrait
(
self
,
&
trait_ref
))
.any
(|
predicate
|
{
match
predicate
{
ty
::
Predicate
::
Trait
(
ref
data
)
=>
{
...
...
@@ -174,30 +166,27 @@ pub fn supertraits_reference_self<'tcx>(tcx: &TyCtxt<'tcx>,
})
}
fn
trait_has_sized_self
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
trait_def_id
:
DefId
)
->
bool
{
let
trait_def
=
tcx
.lookup_trait_def
(
trait_def_id
);
let
trait_predicates
=
tcx
.lookup_predicates
(
trait_def_id
);
generics_require_sized_self
(
tcx
,
&
trait_def
.generics
,
&
trait_predicates
)
fn
trait_has_sized_self
(
&
self
,
trait_def_id
:
DefId
)
->
bool
{
let
trait_def
=
self
.lookup_trait_def
(
trait_def_id
);
let
trait_predicates
=
self
.lookup_predicates
(
trait_def_id
);
self
.generics_require_sized_self
(
&
trait_def
.generics
,
&
trait_predicates
)
}
fn
generics_require_sized_self
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
generics
:
&
ty
::
Generics
<
'tcx
>
,
predicates
:
&
ty
::
GenericPredicates
<
'tcx
>
)
->
bool
fn
generics_require_sized_self
(
&
self
,
generics
:
&
ty
::
Generics
<
'tcx
>
,
predicates
:
&
ty
::
GenericPredicates
<
'tcx
>
)
->
bool
{
let
sized_def_id
=
match
tcx
.lang_items
.sized_trait
()
{
let
sized_def_id
=
match
self
.lang_items
.sized_trait
()
{
Some
(
def_id
)
=>
def_id
,
None
=>
{
return
false
;
/* No Sized trait, can't require it! */
}
};
// Search for a predicate like `Self : Sized` amongst the trait bounds.
let
free_substs
=
tcx
.construct_free_substs
(
generics
,
tcx
.region_maps
.node_extent
(
ast
::
DUMMY_NODE_ID
));
let
predicates
=
predicates
.instantiate
(
tcx
,
&
free_substs
)
.predicates
.into_vec
();
elaborate_predicates
(
tcx
,
predicates
)
let
free_substs
=
self
.construct_free_substs
(
generics
,
self
.region_maps
.node_extent
(
ast
::
DUMMY_NODE_ID
));
let
predicates
=
predicates
.instantiate
(
self
,
&
free_substs
)
.predicates
.into_vec
();
elaborate_predicates
(
self
,
predicates
)
.any
(|
predicate
|
{
match
predicate
{
ty
::
Predicate
::
Trait
(
ref
trait_pred
)
if
trait_pred
.def_id
()
==
sized_def_id
=>
{
...
...
@@ -219,40 +208,40 @@ fn generics_require_sized_self<'tcx>(tcx: &TyCtxt<'tcx>,
}
/// Returns `Some(_)` if this method makes the containing trait not object safe.
fn
object_safety_violation_for_method
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
trait_def_id
:
DefId
,
method
:
&
ty
::
Method
<
'tcx
>
)
->
Option
<
MethodViolationCode
>
fn
object_safety_violation_for_method
(
&
self
,
trait_def_id
:
DefId
,
method
:
&
ty
::
Method
<
'tcx
>
)
->
Option
<
MethodViolationCode
>
{
// Any method that has a `Self : Sized` requisite is otherwise
// exempt from the regulations.
if
generics_require_sized_self
(
tcx
,
&
method
.generics
,
&
method
.predicates
)
{
if
self
.generics_require_sized_self
(
&
method
.generics
,
&
method
.predicates
)
{
return
None
;
}
virtual_call_violation_for_method
(
tcx
,
trait_def_id
,
method
)
self
.virtual_call_violation_for_method
(
trait_def_id
,
method
)
}
/// We say a method is *vtable safe* if it can be invoked on a trait
/// object. Note that object-safe traits can have some
/// non-vtable-safe methods, so long as they require `Self:Sized` or
/// otherwise ensure that they cannot be used when `Self=Trait`.
pub
fn
is_vtable_safe_method
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
trait_def_id
:
DefId
,
method
:
&
ty
::
Method
<
'tcx
>
)
->
bool
pub
fn
is_vtable_safe_method
(
&
self
,
trait_def_id
:
DefId
,
method
:
&
ty
::
Method
<
'tcx
>
)
->
bool
{
virtual_call_violation_for_method
(
tcx
,
trait_def_id
,
method
)
.is_none
()
self
.virtual_call_violation_for_method
(
trait_def_id
,
method
)
.is_none
()
}
/// Returns `Some(_)` if this method cannot be called on a trait
/// object; this does not necessarily imply that the enclosing trait
/// is not object safe, because the method might have a where clause
/// `Self:Sized`.
fn
virtual_call_violation_for_method
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
trait_def_id
:
DefId
,
method
:
&
ty
::
Method
<
'tcx
>
)
->
Option
<
MethodViolationCode
>
fn
virtual_call_violation_for_method
(
&
self
,
trait_def_id
:
DefId
,
method
:
&
ty
::
Method
<
'tcx
>
)
->
Option
<
MethodViolationCode
>
{
// The method's first parameter must be something that derefs (or
// autorefs) to `&self`. For now, we only accept `self`, `&self`
...
...
@@ -272,12 +261,12 @@ fn virtual_call_violation_for_method<'tcx>(tcx: &TyCtxt<'tcx>,
// arguments or return type apart from the receiver.
let
ref
sig
=
method
.fty.sig
;
for
&
input_ty
in
&
sig
.0
.inputs
[
1
..
]
{
if
contains_illegal_self_type_reference
(
tcx
,
trait_def_id
,
input_ty
)
{
if
self
.contains_illegal_self_type_reference
(
trait_def_id
,
input_ty
)
{
return
Some
(
MethodViolationCode
::
ReferencesSelf
);
}
}
if
let
ty
::
FnConverging
(
result_type
)
=
sig
.0
.output
{
if
contains_illegal_self_type_reference
(
tcx
,
trait_def_id
,
result_type
)
{
if
self
.contains_illegal_self_type_reference
(
trait_def_id
,
result_type
)
{
return
Some
(
MethodViolationCode
::
ReferencesSelf
);
}
}
...
...
@@ -290,10 +279,10 @@ fn virtual_call_violation_for_method<'tcx>(tcx: &TyCtxt<'tcx>,
None
}
fn
contains_illegal_self_type_reference
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
trait_def_id
:
DefId
,
ty
:
Ty
<
'tcx
>
)
->
bool
fn
contains_illegal_self_type_reference
(
&
self
,
trait_def_id
:
DefId
,
ty
:
Ty
<
'tcx
>
)
->
bool
{
// This is somewhat subtle. In general, we want to forbid
// references to `Self` in the argument and return types,
...
...
@@ -351,9 +340,9 @@ fn contains_illegal_self_type_reference<'tcx>(tcx: &TyCtxt<'tcx>,
// Compute supertraits of current trait lazily.
if
supertraits
.is_none
()
{
let
trait_def
=
tcx
.lookup_trait_def
(
trait_def_id
);
let
trait_def
=
self
.lookup_trait_def
(
trait_def_id
);
let
trait_ref
=
ty
::
Binder
(
trait_def
.trait_ref
.clone
());
supertraits
=
Some
(
traits
::
supertraits
(
tcx
,
trait_ref
)
.collect
());
supertraits
=
Some
(
traits
::
supertraits
(
self
,
trait_ref
)
.collect
());
}
// Determine whether the trait reference `Foo as
...
...
@@ -381,3 +370,4 @@ fn contains_illegal_self_type_reference<'tcx>(tcx: &TyCtxt<'tcx>,
error
}
}
src/librustc/traits/project.rs
浏览文件 @
f8ea24ed
...
...
@@ -11,7 +11,6 @@
//! Code for projecting associated types out of trait references.
use
super
::
elaborate_predicates
;
use
super
::
report_overflow_error
;
use
super
::
specialization_graph
;
use
super
::
translate_substs
;
use
super
::
Obligation
;
...
...
@@ -188,7 +187,7 @@ pub fn poly_project_and_unify_type<'cx,'tcx>(
let
skol_obligation
=
obligation
.with
(
skol_predicate
);
match
project_and_unify_type
(
selcx
,
&
skol_obligation
)
{
Ok
(
result
)
=>
{
match
infcx
.leak_check
(
&
skol_map
,
snapshot
)
{
match
infcx
.leak_check
(
false
,
&
skol_map
,
snapshot
)
{
Ok
(())
=>
Ok
(
infcx
.plug_leaks
(
skol_map
,
snapshot
,
&
result
)),
Err
(
e
)
=>
Err
(
MismatchedProjectionTypes
{
err
:
e
}),
}
...
...
@@ -231,7 +230,7 @@ fn project_and_unify_type<'cx,'tcx>(
let
infcx
=
selcx
.infcx
();
let
origin
=
TypeOrigin
::
RelateOutputImplTypes
(
obligation
.cause.span
);
match
inf
er
::
mk_eqty
(
infcx
,
true
,
origin
,
normalized_ty
,
obligation
.predicate.ty
)
{
match
inf
cx
.eq_types
(
true
,
origin
,
normalized_ty
,
obligation
.predicate.ty
)
{
Ok
(
InferOk
{
obligations
:
inferred_obligations
,
..
})
=>
{
// FIXME(#32730) propagate obligations
assert
!
(
inferred_obligations
.is_empty
());
...
...
@@ -262,11 +261,10 @@ fn consider_unification_despite_ambiguity<'cx,'tcx>(selcx: &mut SelectionContext
let
closure_typer
=
selcx
.closure_typer
();
let
closure_type
=
closure_typer
.closure_type
(
closure_def_id
,
substs
);
let
ty
::
Binder
((
_
,
ret_type
))
=
util
::
closure_trait_ref_and_return_type
(
infcx
.tcx
,
def_id
,
self_ty
,
&
closure_type
.sig
,
util
::
TupleArgumentsFlag
::
No
);
infcx
.tcx
.closure_trait_ref_and_return_type
(
def_id
,
self_ty
,
&
closure_type
.sig
,
util
::
TupleArgumentsFlag
::
No
);
// We don't have to normalize the return type here - this is only
// reached for TyClosure: Fn inputs where the closure kind is
// still unknown, which should only occur in typeck where the
...
...
@@ -281,7 +279,7 @@ fn consider_unification_despite_ambiguity<'cx,'tcx>(selcx: &mut SelectionContext
ret_type
);
let
origin
=
TypeOrigin
::
RelateOutputImplTypes
(
obligation
.cause.span
);
let
obligation_ty
=
obligation
.predicate.ty
;
match
inf
er
::
mk_eqty
(
infcx
,
true
,
origin
,
obligation_ty
,
ret_type
)
{
match
inf
cx
.eq_types
(
true
,
origin
,
obligation_ty
,
ret_type
)
{
Ok
(
InferOk
{
obligations
,
..
})
=>
{
// FIXME(#32730) propagate obligations
assert
!
(
obligations
.is_empty
());
...
...
@@ -578,7 +576,7 @@ fn project_type<'cx,'tcx>(
let
recursion_limit
=
selcx
.tcx
()
.sess.recursion_limit
.get
();
if
obligation
.recursion_depth
>=
recursion_limit
{
debug!
(
"project: overflow!"
);
report_overflow_error
(
selcx
.infcx
(),
&
obligation
,
true
);
selcx
.infcx
()
.report_overflow_error
(
&
obligation
,
true
);
}
let
obligation_trait_ref
=
...
...
@@ -1053,11 +1051,10 @@ fn confirm_callable_candidate<'cx,'tcx>(
// Note: we unwrap the binder here but re-create it below (1)
let
ty
::
Binder
((
trait_ref
,
ret_type
))
=
util
::
closure_trait_ref_and_return_type
(
tcx
,
fn_once_def_id
,
obligation
.predicate.trait_ref
.self_ty
(),
fn_sig
,
flag
);
tcx
.closure_trait_ref_and_return_type
(
fn_once_def_id
,
obligation
.predicate.trait_ref
.self_ty
(),
fn_sig
,
flag
);
let
predicate
=
ty
::
Binder
(
ty
::
ProjectionPredicate
{
// (1) recreate binder here
projection_ty
:
ty
::
ProjectionTy
{
...
...
src/librustc/traits/select.rs
浏览文件 @
f8ea24ed
...
...
@@ -20,7 +20,6 @@
use
super
::
project
;
use
super
::
project
::{
normalize_with_depth
,
Normalized
};
use
super
::{
PredicateObligation
,
TraitObligation
,
ObligationCause
};
use
super
::
report_overflow_error
;
use
super
::{
ObligationCauseCode
,
BuiltinDerivedObligation
,
ImplDerivedObligation
};
use
super
::{
SelectionError
,
Unimplemented
,
OutputTypeParameterMismatch
};
use
super
::{
ObjectCastObligation
,
Obligation
};
...
...
@@ -32,7 +31,6 @@
VtableFnPointer
,
VtableObject
,
VtableDefaultImpl
};
use
super
::{
VtableImplData
,
VtableObjectData
,
VtableBuiltinData
,
VtableClosureData
,
VtableDefaultImplData
};
use
super
::
object_safety
;
use
super
::
util
;
use
hir
::
def_id
::
DefId
;
...
...
@@ -455,7 +453,7 @@ fn evaluate_predicate_recursively<'o>(&mut self,
}
ty
::
Predicate
::
ObjectSafe
(
trait_def_id
)
=>
{
if
object_safety
::
is_object_safe
(
self
.tcx
(),
trait_def_id
)
{
if
self
.tcx
()
.is_object_safe
(
trait_def_id
)
{
EvaluatedToOk
}
else
{
EvaluatedToErr
...
...
@@ -683,7 +681,7 @@ fn candidate_from_obligation<'o>(&mut self,
// not update) the cache.
let
recursion_limit
=
self
.infcx.tcx.sess.recursion_limit
.get
();
if
stack
.obligation.recursion_depth
>=
recursion_limit
{
report_overflow_error
(
self
.infcx
(),
&
stack
.obligation
,
true
);
self
.infcx
()
.report_overflow_error
(
&
stack
.obligation
,
true
);
}
// Check the cache. Note that we skolemize the trait-ref
...
...
@@ -1155,7 +1153,7 @@ fn match_projection(&mut self,
Err
(
_
)
=>
{
return
false
;
}
}
self
.infcx
.leak_check
(
skol_map
,
snapshot
)
.is_ok
()
self
.infcx
.leak_check
(
false
,
skol_map
,
snapshot
)
.is_ok
()
}
/// Given an obligation like `<SomeTrait for T>`, search the obligations that the caller
...
...
@@ -1397,7 +1395,7 @@ fn assemble_candidates_from_object_ty(&mut self,
// these cases wind up being considered ambiguous due to a
// (spurious) ambiguity introduced here.
let
predicate_trait_ref
=
obligation
.predicate
.to_poly_trait_ref
();
if
!
object_safety
::
is_object_safe
(
self
.tcx
(),
predicate_trait_ref
.def_id
())
{
if
!
self
.tcx
()
.is_object_safe
(
predicate_trait_ref
.def_id
())
{
return
;
}
...
...
@@ -1855,7 +1853,7 @@ fn collect_predicates_for_types(&mut self,
recursion_depth
,
&
skol_ty
);
let
skol_obligation
=
util
::
predicate_for_trait_def
(
self
.tcx
(),
self
.tcx
()
.predicate_for_trait_def
(
cause
.clone
(),
trait_def_id
,
recursion_depth
,
...
...
@@ -2226,7 +2224,7 @@ fn confirm_object_candidate(&mut self,
// entries, so that we can compute the offset for the selected
// trait.
vtable_base
=
nonmatching
.map
(|
t
|
util
::
count_own_vtable_entries
(
self
.tcx
(),
t
))
nonmatching
.map
(|
t
|
self
.tcx
()
.count_own_vtable_entries
(
t
))
.sum
();
}
...
...
@@ -2248,11 +2246,10 @@ fn confirm_fn_pointer_candidate(&mut self,
let
self_ty
=
self
.infcx
.shallow_resolve
(
*
obligation
.self_ty
()
.skip_binder
());
let
sig
=
self_ty
.fn_sig
();
let
trait_ref
=
util
::
closure_trait_ref_and_return_type
(
self
.tcx
(),
obligation
.predicate
.def_id
(),
self_ty
,
sig
,
util
::
TupleArgumentsFlag
::
Yes
)
self
.tcx
()
.closure_trait_ref_and_return_type
(
obligation
.predicate
.def_id
(),
self_ty
,
sig
,
util
::
TupleArgumentsFlag
::
Yes
)
.map_bound
(|(
trait_ref
,
_
)|
trait_ref
);
self
.confirm_poly_trait_refs
(
obligation
.cause
.clone
(),
...
...
@@ -2396,7 +2393,7 @@ fn confirm_builtin_unsize_candidate(&mut self,
// })
// .chain(Some(data.principal_def_id()));
if
let
Some
(
did
)
=
object_dids
.find
(|
did
|
{
!
object_safety
::
is_object_safe
(
tcx
,
*
did
)
!
tcx
.is_object_safe
(
*
did
)
})
{
return
Err
(
TraitNotObjectSafe
(
did
))
}
...
...
@@ -2422,7 +2419,7 @@ fn confirm_builtin_unsize_candidate(&mut self,
// object type is Foo+Send, this would create an obligation
// for the Send check.)
for
bound
in
&
builtin_bounds
{
if
let
Ok
(
tr
)
=
util
::
trait_ref_for_builtin_bound
(
tcx
,
bound
,
source
)
{
if
let
Ok
(
tr
)
=
tcx
.trait_ref_for_builtin_bound
(
bound
,
source
)
{
push
(
tr
.to_predicate
());
}
else
{
return
Err
(
Unimplemented
);
...
...
@@ -2511,7 +2508,7 @@ fn confirm_builtin_unsize_candidate(&mut self,
assert
!
(
obligations
.is_empty
());
// Construct the nested Field<T>: Unsize<Field<U>> predicate.
nested
.push
(
util
::
predicate_for_trait_def
(
tcx
,
nested
.push
(
tcx
.predicate_for_trait_def
(
obligation
.cause
.clone
(),
obligation
.predicate
.def_id
(),
obligation
.recursion_depth
+
1
,
...
...
@@ -2605,7 +2602,7 @@ fn match_impl(&mut self,
// FIXME(#32730) propagate obligations
assert
!
(
obligations
.is_empty
());
if
let
Err
(
e
)
=
self
.infcx
.leak_check
(
&
skol_map
,
snapshot
)
{
if
let
Err
(
e
)
=
self
.infcx
.leak_check
(
false
,
&
skol_map
,
snapshot
)
{
debug!
(
"match_impl: failed leak check due to `{}`"
,
e
);
return
Err
(());
}
...
...
@@ -2710,11 +2707,10 @@ fn closure_trait_ref_unnormalized(&mut self,
{
let
closure_type
=
self
.infcx
.closure_type
(
closure_def_id
,
substs
);
let
ty
::
Binder
((
trait_ref
,
_
))
=
util
::
closure_trait_ref_and_return_type
(
self
.tcx
(),
obligation
.predicate
.def_id
(),
obligation
.predicate
.0
.self_ty
(),
// (1)
&
closure_type
.sig
,
util
::
TupleArgumentsFlag
::
No
);
self
.tcx
()
.closure_trait_ref_and_return_type
(
obligation
.predicate
.def_id
(),
obligation
.predicate
.0
.self_ty
(),
// (1)
&
closure_type
.sig
,
util
::
TupleArgumentsFlag
::
No
);
// (1) Feels icky to skip the binder here, but OTOH we know
// that the self-type is an unboxed closure type and hence is
// in fact unparameterized (or at least does not reference any
...
...
src/librustc/traits/specialize/mod.rs
浏览文件 @
f8ea24ed
...
...
@@ -21,7 +21,7 @@
use
super
::
util
::{
fresh_type_vars_for_impl
,
impl_trait_ref_and_oblig
};
use
hir
::
def_id
::
DefId
;
use
infer
::{
self
,
InferCtxt
,
TypeOrigin
};
use
infer
::{
InferCtxt
,
TypeOrigin
};
use
middle
::
region
;
use
ty
::
subst
::{
Subst
,
Substs
};
use
traits
::{
self
,
ProjectionMode
,
ObligationCause
,
Normalized
};
...
...
@@ -177,11 +177,10 @@ fn fulfill_implication<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
&
target_substs
);
// do the impls unify? If not, no specialization.
if
let
Err
(
_
)
=
infer
::
mk_eq_trait_refs
(
&
infcx
,
true
,
TypeOrigin
::
Misc
(
DUMMY_SP
),
source_trait_ref
,
target_trait_ref
)
{
if
let
Err
(
_
)
=
infcx
.eq_trait_refs
(
true
,
TypeOrigin
::
Misc
(
DUMMY_SP
),
source_trait_ref
,
target_trait_ref
)
{
debug!
(
"fulfill_implication: {:?} does not unify with {:?}"
,
source_trait_ref
,
target_trait_ref
);
...
...
@@ -196,7 +195,7 @@ fn fulfill_implication<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
fulfill_cx
.register_predicate_obligation
(
&
infcx
,
oblig
);
}
if
let
Err
(
errors
)
=
inf
er
::
drain_fulfillment_cx
(
&
infcx
,
&
mut
fulfill_cx
,
&
())
{
if
let
Err
(
errors
)
=
inf
cx
.drain_fulfillment_cx
(
&
mut
fulfill_cx
,
&
())
{
// no dice!
debug!
(
"fulfill_implication: for impls on {:?} and {:?}, could not fulfill: {:?} given
\
{:?}"
,
...
...
src/librustc/traits/util.rs
浏览文件 @
f8ea24ed
...
...
@@ -378,41 +378,40 @@ pub fn predicates_for_generics<'tcx>(cause: ObligationCause<'tcx>,
})
.collect
()
}
pub
fn
trait_ref_for_builtin_bound
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
pub
fn
predicate_for_trait_ref
<
'tcx
>
(
cause
:
ObligationCause
<
'tcx
>
,
trait_ref
:
ty
::
TraitRef
<
'tcx
>
,
recursion_depth
:
usize
)
->
PredicateObligation
<
'tcx
>
{
Obligation
{
cause
:
cause
,
recursion_depth
:
recursion_depth
,
predicate
:
trait_ref
.to_predicate
(),
}
}
impl
<
'tcx
>
TyCtxt
<
'tcx
>
{
pub
fn
trait_ref_for_builtin_bound
(
&
self
,
builtin_bound
:
ty
::
BuiltinBound
,
param_ty
:
Ty
<
'tcx
>
)
->
Result
<
ty
::
TraitRef
<
'tcx
>
,
ErrorReported
>
{
match
tcx
.lang_items
.from_builtin_kind
(
builtin_bound
)
{
match
self
.lang_items
.from_builtin_kind
(
builtin_bound
)
{
Ok
(
def_id
)
=>
{
Ok
(
ty
::
TraitRef
{
def_id
:
def_id
,
substs
:
tcx
.mk_substs
(
Substs
::
empty
()
.with_self_ty
(
param_ty
))
substs
:
self
.mk_substs
(
Substs
::
empty
()
.with_self_ty
(
param_ty
))
})
}
Err
(
e
)
=>
{
tcx
.sess
.err
(
&
e
);
self
.sess
.err
(
&
e
);
Err
(
ErrorReported
)
}
}
}
pub
fn
predicate_for_trait_ref
<
'tcx
>
(
cause
:
ObligationCause
<
'tcx
>
,
trait_ref
:
ty
::
TraitRef
<
'tcx
>
,
recursion_depth
:
usize
)
->
PredicateObligation
<
'tcx
>
{
Obligation
{
cause
:
cause
,
recursion_depth
:
recursion_depth
,
predicate
:
trait_ref
.to_predicate
(),
}
}
pub
fn
predicate_for_trait_def
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
pub
fn
predicate_for_trait_def
(
&
self
,
cause
:
ObligationCause
<
'tcx
>
,
trait_def_id
:
DefId
,
recursion_depth
:
usize
,
...
...
@@ -422,36 +421,35 @@ pub fn predicate_for_trait_def<'tcx>(
{
let
trait_ref
=
ty
::
TraitRef
{
def_id
:
trait_def_id
,
substs
:
tcx
.mk_substs
(
Substs
::
new_trait
(
ty_params
,
vec!
[],
param_ty
))
substs
:
self
.mk_substs
(
Substs
::
new_trait
(
ty_params
,
vec!
[],
param_ty
))
};
predicate_for_trait_ref
(
cause
,
trait_ref
,
recursion_depth
)
}
pub
fn
predicate_for_builtin_bound
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
pub
fn
predicate_for_builtin_bound
(
&
self
,
cause
:
ObligationCause
<
'tcx
>
,
builtin_bound
:
ty
::
BuiltinBound
,
recursion_depth
:
usize
,
param_ty
:
Ty
<
'tcx
>
)
->
Result
<
PredicateObligation
<
'tcx
>
,
ErrorReported
>
{
let
trait_ref
=
trait_ref_for_builtin_bound
(
tcx
,
builtin_bound
,
param_ty
)
?
;
let
trait_ref
=
self
.trait_ref_for_builtin_bound
(
builtin_bound
,
param_ty
)
?
;
Ok
(
predicate_for_trait_ref
(
cause
,
trait_ref
,
recursion_depth
))
}
/// Cast a trait reference into a reference to one of its super
/// traits; returns `None` if `target_trait_def_id` is not a
/// supertrait.
pub
fn
upcast
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
source_trait_ref
:
ty
::
PolyTraitRef
<
'tcx
>
,
target_trait_def_id
:
DefId
)
->
Vec
<
ty
::
PolyTraitRef
<
'tcx
>>
pub
fn
upcast
_choices
(
&
self
,
source_trait_ref
:
ty
::
PolyTraitRef
<
'tcx
>
,
target_trait_def_id
:
DefId
)
->
Vec
<
ty
::
PolyTraitRef
<
'tcx
>>
{
if
source_trait_ref
.def_id
()
==
target_trait_def_id
{
return
vec!
[
source_trait_ref
];
// shorcut the most common case
}
supertraits
(
tcx
,
source_trait_ref
)
supertraits
(
self
,
source_trait_ref
)
.filter
(|
r
|
r
.def_id
()
==
target_trait_def_id
)
.collect
()
}
...
...
@@ -459,13 +457,11 @@ pub fn upcast<'tcx>(tcx: &TyCtxt<'tcx>,
/// Given a trait `trait_ref`, returns the number of vtable entries
/// that come from `trait_ref`, excluding its supertraits. Used in
/// computing the vtable base for an upcast trait of a trait object.
pub
fn
count_own_vtable_entries
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
trait_ref
:
ty
::
PolyTraitRef
<
'tcx
>
)
->
usize
{
pub
fn
count_own_vtable_entries
(
&
self
,
trait_ref
:
ty
::
PolyTraitRef
<
'tcx
>
)
->
usize
{
let
mut
entries
=
0
;
// Count number of methods and add them to the total offset.
// Skip over associated types and constants.
for
trait_item
in
&
tcx
.trait_items
(
trait_ref
.def_id
())[
..
]
{
for
trait_item
in
&
self
.trait_items
(
trait_ref
.def_id
())[
..
]
{
if
let
ty
::
MethodTraitItem
(
_
)
=
*
trait_item
{
entries
+=
1
;
}
...
...
@@ -476,14 +472,14 @@ pub fn count_own_vtable_entries<'tcx>(tcx: &TyCtxt<'tcx>,
/// Given an upcast trait object described by `object`, returns the
/// index of the method `method_def_id` (which should be part of
/// `object.upcast_trait_ref`) within the vtable for `object`.
pub
fn
get_vtable_index_of_object_method
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
object
:
&
super
::
VtableObjectData
<
'tcx
>
,
method_def_id
:
DefId
)
->
usize
{
pub
fn
get_vtable_index_of_object_method
(
&
self
,
object
:
&
super
::
VtableObjectData
<
'tcx
>
,
method_def_id
:
DefId
)
->
usize
{
// Count number of methods preceding the one we are selecting and
// add them to the total offset.
// Skip over associated types and constants.
let
mut
entries
=
object
.vtable_base
;
for
trait_item
in
&
tcx
.trait_items
(
object
.upcast_trait_ref
.def_id
())[
..
]
{
for
trait_item
in
&
self
.trait_items
(
object
.upcast_trait_ref
.def_id
())[
..
]
{
if
trait_item
.def_id
()
==
method_def_id
{
// The item with the ID we were given really ought to be a method.
assert
!
(
match
*
trait_item
{
...
...
@@ -502,10 +498,7 @@ pub fn get_vtable_index_of_object_method<'tcx>(tcx: &TyCtxt<'tcx>,
method_def_id
);
}
pub
enum
TupleArgumentsFlag
{
Yes
,
No
}
pub
fn
closure_trait_ref_and_return_type
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
pub
fn
closure_trait_ref_and_return_type
(
&
self
,
fn_trait_def_id
:
DefId
,
self_ty
:
Ty
<
'tcx
>
,
sig
:
&
ty
::
PolyFnSig
<
'tcx
>
,
...
...
@@ -514,12 +507,15 @@ pub fn closure_trait_ref_and_return_type<'tcx>(
{
let
arguments_tuple
=
match
tuple_arguments
{
TupleArgumentsFlag
::
No
=>
sig
.0
.inputs
[
0
],
TupleArgumentsFlag
::
Yes
=>
tcx
.mk_tup
(
sig
.0
.inputs
.to_vec
()),
TupleArgumentsFlag
::
Yes
=>
self
.mk_tup
(
sig
.0
.inputs
.to_vec
()),
};
let
trait_substs
=
Substs
::
new_trait
(
vec!
[
arguments_tuple
],
vec!
[],
self_ty
);
let
trait_ref
=
ty
::
TraitRef
{
def_id
:
fn_trait_def_id
,
substs
:
tcx
.mk_substs
(
trait_substs
),
substs
:
self
.mk_substs
(
trait_substs
),
};
ty
::
Binder
((
trait_ref
,
sig
.0
.output
.unwrap_or
(
tcx
.mk_nil
())))
ty
::
Binder
((
trait_ref
,
sig
.0
.output
.unwrap_or
(
self
.mk_nil
())))
}
}
pub
enum
TupleArgumentsFlag
{
Yes
,
No
}
src/librustc/ty/layout.rs
浏览文件 @
f8ea24ed
...
...
@@ -12,7 +12,7 @@
pub
use
self
::
Layout
::
*
;
pub
use
self
::
Primitive
::
*
;
use
infer
::
{
InferCtxt
,
drain_fulfillment_cx_or_panic
}
;
use
infer
::
InferCtxt
;
use
session
::
Session
;
use
traits
;
use
ty
::{
self
,
Ty
,
TyCtxt
,
TypeFoldable
};
...
...
@@ -754,7 +754,7 @@ fn normalize_associated_type<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
fulfill_cx
.register_predicate_obligation
(
infcx
,
obligation
);
}
drain_fulfillment_cx_or_panic
(
DUMMY_SP
,
infcx
,
&
mut
fulfill_cx
,
&
result
)
infcx
.drain_fulfillment_cx_or_panic
(
DUMMY_SP
,
&
mut
fulfill_cx
,
&
result
)
}
impl
Layout
{
...
...
src/librustc/ty/outlives.rs
浏览文件 @
f8ea24ed
...
...
@@ -55,20 +55,18 @@ pub enum Component<'tcx> {
EscapingProjection
(
Vec
<
Component
<
'tcx
>>
),
}
impl
<
'a
,
'tcx
>
InferCtxt
<
'a
,
'tcx
>
{
/// Returns all the things that must outlive `'a` for the condition
/// `ty0: 'a` to hold.
pub
fn
components
<
'a
,
'tcx
>
(
infcx
:
&
InferCtxt
<
'a
,
'tcx
>
,
ty0
:
Ty
<
'tcx
>
)
pub
fn
outlives_components
(
&
self
,
ty0
:
Ty
<
'tcx
>
)
->
Vec
<
Component
<
'tcx
>>
{
let
mut
components
=
vec!
[];
compute_components
(
infcx
,
ty0
,
&
mut
components
);
self
.compute_components
(
ty0
,
&
mut
components
);
debug!
(
"components({:?}) = {:?}"
,
ty0
,
components
);
components
}
fn
compute_components
<
'a
,
'tcx
>
(
infcx
:
&
InferCtxt
<
'a
,
'tcx
>
,
ty
:
Ty
<
'tcx
>
,
out
:
&
mut
Vec
<
Component
<
'tcx
>>
)
{
fn
compute_components
(
&
self
,
ty
:
Ty
<
'tcx
>
,
out
:
&
mut
Vec
<
Component
<
'tcx
>>
)
{
// Descend through the types, looking for the various "base"
// components and collecting them into `out`. This is not written
// with `collect()` because of the need to sometimes skip subtrees
...
...
@@ -114,7 +112,7 @@ fn compute_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
// taking into consideration UFCS and so forth.
for
&
upvar_ty
in
&
substs
.upvar_tys
{
compute_components
(
infcx
,
upvar_ty
,
out
);
self
.compute_components
(
upvar_ty
,
out
);
}
}
...
...
@@ -145,7 +143,7 @@ fn compute_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
// fallback case: hard code
// OutlivesProjectionComponents. Continue walking
// through and constrain Pi.
let
subcomponents
=
capture_components
(
infcx
,
ty
);
let
subcomponents
=
self
.capture_components
(
ty
);
out
.push
(
Component
::
EscapingProjection
(
subcomponents
));
}
}
...
...
@@ -154,11 +152,11 @@ fn compute_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
// and proceed with resolved version. If we cannot resolve it,
// then record the unresolved variable as a component.
ty
::
TyInfer
(
_
)
=>
{
let
ty
=
infcx
.resolve_type_vars_if_possible
(
&
ty
);
let
ty
=
self
.resolve_type_vars_if_possible
(
&
ty
);
if
let
ty
::
TyInfer
(
infer_ty
)
=
ty
.sty
{
out
.push
(
Component
::
UnresolvedInferenceVariable
(
infer_ty
));
}
else
{
compute_components
(
infcx
,
ty
,
out
);
self
.compute_components
(
ty
,
out
);
}
}
...
...
@@ -194,22 +192,21 @@ fn compute_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
push_region_constraints
(
out
,
ty
.regions
());
for
subty
in
ty
.walk_shallow
()
{
compute_components
(
infcx
,
subty
,
out
);
self
.compute_components
(
subty
,
out
);
}
}
}
}
fn
capture_components
<
'a
,
'tcx
>
(
infcx
:
&
InferCtxt
<
'a
,
'tcx
>
,
ty
:
Ty
<
'tcx
>
)
->
Vec
<
Component
<
'tcx
>>
{
fn
capture_components
(
&
self
,
ty
:
Ty
<
'tcx
>
)
->
Vec
<
Component
<
'tcx
>>
{
let
mut
temp
=
vec!
[];
push_region_constraints
(
&
mut
temp
,
ty
.regions
());
for
subty
in
ty
.walk_shallow
()
{
compute_components
(
infcx
,
subty
,
&
mut
temp
);
self
.compute_components
(
subty
,
&
mut
temp
);
}
temp
}
}
fn
push_region_constraints
<
'tcx
>
(
out
:
&
mut
Vec
<
Component
<
'tcx
>>
,
regions
:
Vec
<
ty
::
Region
>
)
{
for
r
in
regions
{
...
...
src/librustc/ty/sty.rs
浏览文件 @
f8ea24ed
...
...
@@ -14,7 +14,6 @@
use
hir
::
def_id
::
DefId
;
use
middle
::
region
;
use
ty
::
subst
::{
self
,
Substs
};
use
traits
;
use
ty
::{
self
,
AdtDef
,
ToPredicate
,
TypeFlags
,
Ty
,
TyCtxt
,
TyS
,
TypeFoldable
};
use
util
::
common
::
ErrorReported
;
...
...
@@ -633,7 +632,7 @@ pub struct DebruijnIndex {
/// to be used. These also support explicit bounds: both the internally-stored
/// *scope*, which the region is assumed to outlive, as well as other
/// relations stored in the `FreeRegionMap`. Note that these relations
/// aren't checked when you `make_subregion` (or `
mk_eqty
`), only by
/// aren't checked when you `make_subregion` (or `
eq_types
`), only by
/// `resolve_regions_and_report_errors`.
///
/// When working with higher-ranked types, some region relations aren't
...
...
@@ -778,7 +777,7 @@ pub fn to_predicates<'tcx>(&self,
tcx
:
&
TyCtxt
<
'tcx
>
,
self_ty
:
Ty
<
'tcx
>
)
->
Vec
<
ty
::
Predicate
<
'tcx
>>
{
self
.iter
()
.filter_map
(|
builtin_bound
|
match
t
raits
::
trait_ref_for_builtin_bound
(
tcx
,
builtin_bound
,
self_ty
)
{
match
t
cx
.trait_ref_for_builtin_bound
(
builtin_bound
,
self_ty
)
{
Ok
(
trait_ref
)
=>
Some
(
trait_ref
.to_predicate
()),
Err
(
ErrorReported
)
=>
{
None
}
}
...
...
src/librustc/ty/wf.rs
浏览文件 @
f8ea24ed
...
...
@@ -10,7 +10,7 @@
use
hir
::
def_id
::
DefId
;
use
infer
::
InferCtxt
;
use
ty
::
outlives
::
{
self
,
Component
}
;
use
ty
::
outlives
::
Component
;
use
ty
::
subst
::
Substs
;
use
traits
;
use
ty
::{
self
,
ToPredicate
,
Ty
,
TyCtxt
,
TypeFoldable
};
...
...
@@ -182,7 +182,7 @@ pub fn implied_bounds<'a,'tcx>(
match
infcx
.tcx
.no_late_bound_regions
(
data
)
{
None
=>
vec!
[],
Some
(
ty
::
OutlivesPredicate
(
ty_a
,
r_b
))
=>
{
let
components
=
outlives
::
components
(
infcx
,
ty_a
);
let
components
=
infcx
.outlives_components
(
ty_a
);
implied_bounds_from_components
(
r_b
,
components
)
}
},
...
...
@@ -288,9 +288,7 @@ fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<
rfc1592
:
bool
)
{
if
!
subty
.has_escaping_regions
()
{
let
cause
=
self
.cause
(
cause
);
match
traits
::
trait_ref_for_builtin_bound
(
self
.infcx.tcx
,
ty
::
BoundSized
,
subty
)
{
match
self
.infcx.tcx
.trait_ref_for_builtin_bound
(
ty
::
BoundSized
,
subty
)
{
Ok
(
trait_ref
)
=>
{
let
predicate
=
trait_ref
.to_predicate
();
let
predicate
=
if
rfc1592
{
...
...
src/librustc_const_eval/eval.rs
浏览文件 @
f8ea24ed
...
...
@@ -26,7 +26,6 @@
use
rustc
::
ty
::{
self
,
Ty
,
TyCtxt
,
subst
};
use
rustc
::
ty
::
util
::
IntTypeExt
;
use
rustc
::
traits
::
ProjectionMode
;
use
rustc
::
middle
::
astconv_util
::
ast_ty_to_prim_ty
;
use
rustc
::
util
::
nodemap
::
NodeMap
;
use
rustc
::
lint
;
...
...
@@ -100,7 +99,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
None
=>
None
,
Some
(
ast_map
::
NodeItem
(
it
))
=>
match
it
.node
{
hir
::
ItemConst
(
ref
ty
,
ref
const_expr
)
=>
{
Some
((
&
const_expr
,
ast_ty_to_prim_ty
(
tcx
,
ty
)))
Some
((
&
const_expr
,
tcx
.ast_ty_to_prim_ty
(
ty
)))
}
_
=>
None
},
...
...
@@ -126,7 +125,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
},
Some
(
ast_map
::
NodeImplItem
(
ii
))
=>
match
ii
.node
{
hir
::
ImplItemKind
::
Const
(
ref
ty
,
ref
expr
)
=>
{
Some
((
&
expr
,
ast_ty_to_prim_ty
(
tcx
,
ty
)))
Some
((
&
expr
,
tcx
.ast_ty_to_prim_ty
(
ty
)))
}
_
=>
None
},
...
...
@@ -144,7 +143,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
let
expr_ty
=
match
tcx
.sess.cstore
.maybe_get_item_ast
(
tcx
,
def_id
)
{
cstore
::
FoundAst
::
Found
(
&
InlinedItem
::
Item
(
ref
item
))
=>
match
item
.node
{
hir
::
ItemConst
(
ref
ty
,
ref
const_expr
)
=>
{
Some
((
&**
const_expr
,
ast_ty_to_prim_ty
(
tcx
,
ty
)))
Some
((
&**
const_expr
,
tcx
.ast_ty_to_prim_ty
(
ty
)))
},
_
=>
None
},
...
...
@@ -165,7 +164,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
},
cstore
::
FoundAst
::
Found
(
&
InlinedItem
::
ImplItem
(
_
,
ref
ii
))
=>
match
ii
.node
{
hir
::
ImplItemKind
::
Const
(
ref
ty
,
ref
expr
)
=>
{
Some
((
&**
expr
,
ast_ty_to_prim_ty
(
tcx
,
ty
)))
Some
((
&**
expr
,
tcx
.ast_ty_to_prim_ty
(
ty
)))
},
_
=>
None
},
...
...
@@ -679,7 +678,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &TyCtxt<'tcx>,
}
}
hir
::
ExprCast
(
ref
base
,
ref
target_ty
)
=>
{
let
ety
=
ast_ty_to_prim_ty
(
tcx
,
&
target_ty
)
.or_else
(||
ety
)
let
ety
=
tcx
.ast_ty_to_prim_ty
(
&
target_ty
)
.or
(
ety
)
.unwrap_or_else
(||
{
tcx
.sess
.span_fatal
(
target_ty
.span
,
"target type not found for const cast"
)
...
...
@@ -1041,7 +1040,7 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
Some
(
ic
)
=>
lookup_const_by_id
(
tcx
,
ic
.def_id
,
None
),
None
=>
match
ti
.node
{
hir
::
ConstTraitItem
(
ref
ty
,
Some
(
ref
expr
))
=>
{
Some
((
&*
expr
,
ast_ty_to_prim_ty
(
tcx
,
ty
)))
Some
((
&*
expr
,
tcx
.ast_ty_to_prim_ty
(
ty
)))
},
_
=>
None
,
},
...
...
src/librustc_driver/test.rs
浏览文件 @
f8ea24ed
...
...
@@ -242,17 +242,14 @@ fn search(this: &Env, it: &hir::Item, idx: usize, names: &[String]) -> Option<as
}
pub
fn
make_subtype
(
&
self
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
bool
{
match
infer
::
mk_subty
(
self
.infcx
,
true
,
TypeOrigin
::
Misc
(
DUMMY_SP
),
a
,
b
)
{
match
self
.infcx
.sub_types
(
true
,
TypeOrigin
::
Misc
(
DUMMY_SP
),
a
,
b
)
{
Ok
(
_
)
=>
true
,
Err
(
ref
e
)
=>
panic!
(
"Encountered error: {}"
,
e
),
}
}
pub
fn
is_subtype
(
&
self
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
bool
{
match
infer
::
can_mk_subty
(
self
.infcx
,
a
,
b
)
{
Ok
(
_
)
=>
true
,
Err
(
_
)
=>
false
,
}
self
.infcx
.can_sub_types
(
a
,
b
)
.is_ok
()
}
pub
fn
assert_subtype
(
&
self
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
{
...
...
src/librustc_metadata/encoder.rs
浏览文件 @
f8ea24ed
...
...
@@ -25,7 +25,6 @@
use
rustc
::
hir
::
def
;
use
rustc
::
hir
::
def_id
::{
CRATE_DEF_INDEX
,
DefId
};
use
middle
::
dependency_format
::
Linkage
;
use
middle
::
stability
;
use
rustc
::
ty
::
subst
;
use
rustc
::
traits
::
specialization_graph
;
use
rustc
::
ty
::{
self
,
Ty
,
TyCtxt
};
...
...
@@ -283,8 +282,8 @@ fn encode_enum_variant_info<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
encode_attributes
(
rbml_w
,
&
attrs
);
encode_repr_attrs
(
rbml_w
,
ecx
,
&
attrs
);
let
stab
=
stability
::
lookup_stability
(
ecx
.tcx
,
vid
);
let
depr
=
stability
::
lookup_deprecation
(
ecx
.tcx
,
vid
);
let
stab
=
ecx
.tcx
.lookup_stability
(
vid
);
let
depr
=
ecx
.tcx
.lookup_deprecation
(
vid
);
encode_stability
(
rbml_w
,
stab
);
encode_deprecation
(
rbml_w
,
depr
);
...
...
@@ -376,8 +375,8 @@ fn encode_info_for_mod(ecx: &EncodeContext,
encode_visibility
(
rbml_w
,
vis
);
let
stab
=
stability
::
lookup_stability
(
ecx
.tcx
,
ecx
.tcx.map
.local_def_id
(
id
));
let
depr
=
stability
::
lookup_deprecation
(
ecx
.tcx
,
ecx
.tcx.map
.local_def_id
(
id
));
let
stab
=
ecx
.tcx
.lookup_stability
(
ecx
.tcx.map
.local_def_id
(
id
));
let
depr
=
ecx
.tcx
.lookup_deprecation
(
ecx
.tcx.map
.local_def_id
(
id
));
encode_stability
(
rbml_w
,
stab
);
encode_deprecation
(
rbml_w
,
depr
);
...
...
@@ -484,8 +483,8 @@ fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
encode_bounds_and_type_for_item
(
rbml_w
,
ecx
,
index
,
id
);
encode_def_id_and_key
(
ecx
,
rbml_w
,
field
.did
);
let
stab
=
stability
::
lookup_stability
(
ecx
.tcx
,
field
.did
);
let
depr
=
stability
::
lookup_deprecation
(
ecx
.tcx
,
field
.did
);
let
stab
=
ecx
.tcx
.lookup_stability
(
field
.did
);
let
depr
=
ecx
.tcx
.lookup_deprecation
(
field
.did
);
encode_stability
(
rbml_w
,
stab
);
encode_deprecation
(
rbml_w
,
depr
);
...
...
@@ -517,8 +516,8 @@ fn encode_info_for_struct_ctor<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
encode_symbol
(
ecx
,
rbml_w
,
ctor_id
);
}
let
stab
=
stability
::
lookup_stability
(
ecx
.tcx
,
ecx
.tcx.map
.local_def_id
(
ctor_id
));
let
depr
=
stability
::
lookup_deprecation
(
ecx
.tcx
,
ecx
.tcx.map
.local_def_id
(
ctor_id
));
let
stab
=
ecx
.tcx
.lookup_stability
(
ecx
.tcx.map
.local_def_id
(
ctor_id
));
let
depr
=
ecx
.tcx
.lookup_deprecation
(
ecx
.tcx.map
.local_def_id
(
ctor_id
));
encode_stability
(
rbml_w
,
stab
);
encode_deprecation
(
rbml_w
,
depr
);
...
...
@@ -646,8 +645,8 @@ fn encode_info_for_associated_const<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
encode_bounds_and_type_for_item
(
rbml_w
,
ecx
,
index
,
ecx
.local_id
(
associated_const
.def_id
));
let
stab
=
stability
::
lookup_stability
(
ecx
.tcx
,
associated_const
.def_id
);
let
depr
=
stability
::
lookup_deprecation
(
ecx
.tcx
,
associated_const
.def_id
);
let
stab
=
ecx
.tcx
.lookup_stability
(
associated_const
.def_id
);
let
depr
=
ecx
.tcx
.lookup_deprecation
(
associated_const
.def_id
);
encode_stability
(
rbml_w
,
stab
);
encode_deprecation
(
rbml_w
,
depr
);
...
...
@@ -681,8 +680,8 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
encode_parent_item
(
rbml_w
,
ecx
.tcx.map
.local_def_id
(
parent_id
));
encode_item_sort
(
rbml_w
,
'r'
);
let
stab
=
stability
::
lookup_stability
(
ecx
.tcx
,
m
.def_id
);
let
depr
=
stability
::
lookup_deprecation
(
ecx
.tcx
,
m
.def_id
);
let
stab
=
ecx
.tcx
.lookup_stability
(
m
.def_id
);
let
depr
=
ecx
.tcx
.lookup_deprecation
(
m
.def_id
);
encode_stability
(
rbml_w
,
stab
);
encode_deprecation
(
rbml_w
,
depr
);
...
...
@@ -736,8 +735,8 @@ fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
encode_parent_item
(
rbml_w
,
ecx
.tcx.map
.local_def_id
(
parent_id
));
encode_item_sort
(
rbml_w
,
't'
);
let
stab
=
stability
::
lookup_stability
(
ecx
.tcx
,
associated_type
.def_id
);
let
depr
=
stability
::
lookup_deprecation
(
ecx
.tcx
,
associated_type
.def_id
);
let
stab
=
ecx
.tcx
.lookup_stability
(
associated_type
.def_id
);
let
depr
=
ecx
.tcx
.lookup_deprecation
(
associated_type
.def_id
);
encode_stability
(
rbml_w
,
stab
);
encode_deprecation
(
rbml_w
,
depr
);
...
...
@@ -872,8 +871,8 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
let
vis
=
&
item
.vis
;
let
def_id
=
ecx
.tcx.map
.local_def_id
(
item
.id
);
let
stab
=
stability
::
lookup_stability
(
tcx
,
ecx
.tcx.map
.local_def_id
(
item
.id
));
let
depr
=
stability
::
lookup_deprecation
(
tcx
,
ecx
.tcx.map
.local_def_id
(
item
.id
));
let
stab
=
tcx
.lookup_stability
(
ecx
.tcx.map
.local_def_id
(
item
.id
));
let
depr
=
tcx
.lookup_deprecation
(
ecx
.tcx.map
.local_def_id
(
item
.id
));
match
item
.node
{
hir
::
ItemStatic
(
_
,
m
,
_
)
=>
{
...
...
@@ -1231,8 +1230,8 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
encode_parent_item
(
rbml_w
,
def_id
);
let
stab
=
stability
::
lookup_stability
(
tcx
,
item_def_id
.def_id
());
let
depr
=
stability
::
lookup_deprecation
(
tcx
,
item_def_id
.def_id
());
let
stab
=
tcx
.lookup_stability
(
item_def_id
.def_id
());
let
depr
=
tcx
.lookup_deprecation
(
item_def_id
.def_id
());
encode_stability
(
rbml_w
,
stab
);
encode_deprecation
(
rbml_w
,
depr
);
...
...
@@ -1358,8 +1357,8 @@ fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
encode_symbol
(
ecx
,
rbml_w
,
nitem
.id
);
}
encode_attributes
(
rbml_w
,
&
nitem
.attrs
);
let
stab
=
stability
::
lookup_stability
(
ecx
.tcx
,
ecx
.tcx.map
.local_def_id
(
nitem
.id
));
let
depr
=
stability
::
lookup_deprecation
(
ecx
.tcx
,
ecx
.tcx.map
.local_def_id
(
nitem
.id
));
let
stab
=
ecx
.tcx
.lookup_stability
(
ecx
.tcx.map
.local_def_id
(
nitem
.id
));
let
depr
=
ecx
.tcx
.lookup_deprecation
(
ecx
.tcx.map
.local_def_id
(
nitem
.id
));
encode_stability
(
rbml_w
,
stab
);
encode_deprecation
(
rbml_w
,
depr
);
encode_method_argument_names
(
rbml_w
,
&
fndecl
);
...
...
@@ -1372,8 +1371,8 @@ fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
}
encode_bounds_and_type_for_item
(
rbml_w
,
ecx
,
index
,
nitem
.id
);
encode_attributes
(
rbml_w
,
&
nitem
.attrs
);
let
stab
=
stability
::
lookup_stability
(
ecx
.tcx
,
ecx
.tcx.map
.local_def_id
(
nitem
.id
));
let
depr
=
stability
::
lookup_deprecation
(
ecx
.tcx
,
ecx
.tcx.map
.local_def_id
(
nitem
.id
));
let
stab
=
ecx
.tcx
.lookup_stability
(
ecx
.tcx.map
.local_def_id
(
nitem
.id
));
let
depr
=
ecx
.tcx
.lookup_deprecation
(
ecx
.tcx.map
.local_def_id
(
nitem
.id
));
encode_stability
(
rbml_w
,
stab
);
encode_deprecation
(
rbml_w
,
depr
);
encode_symbol
(
ecx
,
rbml_w
,
nitem
.id
);
...
...
src/librustc_mir/mir_map.rs
浏览文件 @
f8ea24ed
...
...
@@ -202,10 +202,10 @@ fn visit_fn(&mut self,
}
}
fn
closure_self_ty
<
'
a
,
'
tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
closure_expr_id
:
ast
::
NodeId
,
body_id
:
ast
::
NodeId
)
->
Ty
<
'tcx
>
{
fn
closure_self_ty
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
closure_expr_id
:
ast
::
NodeId
,
body_id
:
ast
::
NodeId
)
->
Ty
<
'tcx
>
{
let
closure_ty
=
tcx
.node_id_to_type
(
closure_expr_id
);
// We're just hard-coding the idea that the signature will be
...
...
src/librustc_mir/transform/qualify_consts.rs
浏览文件 @
f8ea24ed
...
...
@@ -1023,11 +1023,11 @@ fn run_pass(&mut self, tcx: &TyCtxt<'tcx>, map: &mut MirMap<'tcx>) {
let
mut
fulfillment_cx
=
traits
::
FulfillmentContext
::
new
();
fulfillment_cx
.register_builtin_bound
(
&
infcx
,
ty
,
ty
::
BoundSync
,
cause
);
if
let
Err
(
err
)
=
fulfillment_cx
.select_all_or_error
(
&
infcx
)
{
traits
::
report_fulfillment_errors
(
&
infcx
,
&
err
);
infcx
.report_fulfillment_errors
(
&
err
);
}
if
let
Err
(
ref
errors
)
=
fulfillment_cx
.select_rfc1592_obligations
(
&
infcx
)
{
traits
::
report_fulfillment_errors_as_warnings
(
&
infcx
,
errors
,
id
);
if
let
Err
(
errors
)
=
fulfillment_cx
.select_rfc1592_obligations
(
&
infcx
)
{
infcx
.report_fulfillment_errors_as_warnings
(
&
errors
,
id
);
}
}
}
...
...
src/librustc_mir/transform/type_check.rs
浏览文件 @
f8ea24ed
...
...
@@ -237,7 +237,7 @@ fn sanitize_projection(&mut self,
let
fty
=
self
.sanitize_type
(
lvalue
,
fty
);
match
self
.field_ty
(
lvalue
,
base
,
field
)
{
Ok
(
ty
)
=>
{
if
let
Err
(
terr
)
=
self
.cx
.
mk_eqty
(
span
,
ty
,
fty
)
{
if
let
Err
(
terr
)
=
self
.cx
.
eq_types
(
span
,
ty
,
fty
)
{
span_mirbug!
(
self
,
lvalue
,
"bad field access ({:?}: {:?}): {:?}"
,
ty
,
fty
,
terr
);
...
...
@@ -333,20 +333,18 @@ fn new(infcx: &'a InferCtxt<'a, 'tcx>) -> Self {
}
}
fn
mk_subty
(
&
self
,
span
:
Span
,
sup
:
Ty
<
'tcx
>
,
sub
:
Ty
<
'tcx
>
)
->
infer
::
UnitResult
<
'tcx
>
fn
sub_types
(
&
self
,
span
:
Span
,
sup
:
Ty
<
'tcx
>
,
sub
:
Ty
<
'tcx
>
)
->
infer
::
UnitResult
<
'tcx
>
{
infer
::
mk_subty
(
self
.infcx
,
false
,
infer
::
TypeOrigin
::
Misc
(
span
),
sup
,
sub
)
self
.infcx
.sub_types
(
false
,
infer
::
TypeOrigin
::
Misc
(
span
),
sup
,
sub
)
// FIXME(#32730) propagate obligations
.map
(|
InferOk
{
obligations
,
..
}|
assert
!
(
obligations
.is_empty
()))
}
fn
mk_eqty
(
&
self
,
span
:
Span
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
fn
eq_types
(
&
self
,
span
:
Span
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
infer
::
UnitResult
<
'tcx
>
{
infer
::
mk_eqty
(
self
.infcx
,
false
,
infer
::
TypeOrigin
::
Misc
(
span
),
a
,
b
)
self
.infcx
.eq_types
(
false
,
infer
::
TypeOrigin
::
Misc
(
span
),
a
,
b
)
// FIXME(#32730) propagate obligations
.map
(|
InferOk
{
obligations
,
..
}|
assert
!
(
obligations
.is_empty
()))
}
...
...
@@ -363,7 +361,7 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>) {
let
lv_ty
=
mir
.lvalue_ty
(
tcx
,
lv
)
.to_ty
(
tcx
);
let
rv_ty
=
mir
.rvalue_ty
(
tcx
,
rv
);
if
let
Some
(
rv_ty
)
=
rv_ty
{
if
let
Err
(
terr
)
=
self
.
mk_subty
(
self
.last_span
,
rv_ty
,
lv_ty
)
{
if
let
Err
(
terr
)
=
self
.
sub_types
(
self
.last_span
,
rv_ty
,
lv_ty
)
{
span_mirbug!
(
self
,
stmt
,
"bad assignment ({:?} = {:?}): {:?}"
,
lv_ty
,
rv_ty
,
terr
);
}
...
...
@@ -399,7 +397,7 @@ fn check_terminator(&self,
}
TerminatorKind
::
SwitchInt
{
ref
discr
,
switch_ty
,
..
}
=>
{
let
discr_ty
=
mir
.lvalue_ty
(
tcx
,
discr
)
.to_ty
(
tcx
);
if
let
Err
(
terr
)
=
self
.
mk_subty
(
self
.last_span
,
discr_ty
,
switch_ty
)
{
if
let
Err
(
terr
)
=
self
.
sub_types
(
self
.last_span
,
discr_ty
,
switch_ty
)
{
span_mirbug!
(
self
,
term
,
"bad SwitchInt ({:?} on {:?}): {:?}"
,
switch_ty
,
discr_ty
,
terr
);
}
...
...
@@ -456,7 +454,7 @@ fn check_call_dest(&self,
}
(
&
Some
((
ref
dest
,
_
)),
ty
::
FnConverging
(
ty
))
=>
{
let
dest_ty
=
mir
.lvalue_ty
(
tcx
,
dest
)
.to_ty
(
tcx
);
if
let
Err
(
terr
)
=
self
.
mk_subty
(
self
.last_span
,
ty
,
dest_ty
)
{
if
let
Err
(
terr
)
=
self
.
sub_types
(
self
.last_span
,
ty
,
dest_ty
)
{
span_mirbug!
(
self
,
term
,
"call dest mismatch ({:?} <- {:?}): {:?}"
,
dest_ty
,
ty
,
terr
);
...
...
@@ -482,7 +480,7 @@ fn check_call_inputs(&self,
}
for
(
n
,
(
fn_arg
,
op_arg
))
in
sig
.inputs
.iter
()
.zip
(
args
)
.enumerate
()
{
let
op_arg_ty
=
mir
.operand_ty
(
self
.tcx
(),
op_arg
);
if
let
Err
(
terr
)
=
self
.
mk_subty
(
self
.last_span
,
op_arg_ty
,
fn_arg
)
{
if
let
Err
(
terr
)
=
self
.
sub_types
(
self
.last_span
,
op_arg_ty
,
fn_arg
)
{
span_mirbug!
(
self
,
term
,
"bad arg #{:?} ({:?} <- {:?}): {:?}"
,
n
,
fn_arg
,
op_arg_ty
,
terr
);
}
...
...
@@ -537,7 +535,7 @@ fn check_box_free_inputs(&self,
}
};
if
let
Err
(
terr
)
=
self
.
mk_subty
(
self
.last_span
,
arg_ty
,
pointee_ty
)
{
if
let
Err
(
terr
)
=
self
.
sub_types
(
self
.last_span
,
arg_ty
,
pointee_ty
)
{
span_mirbug!
(
self
,
term
,
"bad box_free arg ({:?} <- {:?}): {:?}"
,
pointee_ty
,
arg_ty
,
terr
);
}
...
...
src/librustc_trans/callee.rs
浏览文件 @
f8ea24ed
...
...
@@ -202,8 +202,7 @@ pub fn trait_method<'a>(ccx: &CrateContext<'a, 'tcx>,
}
traits
::
VtableObject
(
ref
data
)
=>
{
Callee
{
data
:
Virtual
(
traits
::
get_vtable_index_of_object_method
(
tcx
,
data
,
def_id
)),
data
:
Virtual
(
tcx
.get_vtable_index_of_object_method
(
data
,
def_id
)),
ty
:
def_ty
(
tcx
,
def_id
,
substs
)
}
}
...
...
src/librustc_trans/common.rs
浏览文件 @
f8ea24ed
...
...
@@ -19,7 +19,7 @@
use
rustc
::
cfg
;
use
rustc
::
hir
::
def
::
Def
;
use
rustc
::
hir
::
def_id
::
DefId
;
use
rustc
::
infer
::
{
self
,
InferCtxt
}
;
use
rustc
::
infer
::
InferCtxt
;
use
rustc
::
util
::
common
::
MemoizationMap
;
use
middle
::
lang_items
::
LangItem
;
use
rustc
::
ty
::
subst
::
Substs
;
...
...
@@ -1107,9 +1107,7 @@ pub fn fulfill_obligation<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
let
vtable
=
selection
.map
(|
predicate
|
{
fulfill_cx
.register_predicate_obligation
(
&
infcx
,
predicate
);
});
let
vtable
=
infer
::
drain_fulfillment_cx_or_panic
(
span
,
&
infcx
,
&
mut
fulfill_cx
,
&
vtable
);
let
vtable
=
infcx
.drain_fulfillment_cx_or_panic
(
span
,
&
mut
fulfill_cx
,
&
vtable
);
info!
(
"Cache miss: {:?} => {:?}"
,
trait_ref
,
vtable
);
...
...
@@ -1142,7 +1140,7 @@ pub fn normalize_and_test_predicates<'tcx>(tcx: &TyCtxt<'tcx>,
fulfill_cx
.register_predicate_obligation
(
&
infcx
,
obligation
);
}
inf
er
::
drain_fulfillment_cx
(
&
infcx
,
&
mut
fulfill_cx
,
&
())
.is_ok
()
inf
cx
.drain_fulfillment_cx
(
&
mut
fulfill_cx
,
&
())
.is_ok
()
}
pub
fn
langcall
(
bcx
:
Block
,
...
...
src/librustc_trans/meth.rs
浏览文件 @
f8ea24ed
...
...
@@ -256,7 +256,7 @@ pub fn get_vtable_methods<'tcx>(tcx: &TyCtxt<'tcx>,
let
name
=
trait_method_type
.name
;
// Some methods cannot be called on an object; skip those.
if
!
t
raits
::
is_vtable_safe_method
(
tcx
,
trt_id
,
&
trait_method_type
)
{
if
!
t
cx
.is_vtable_safe_method
(
trt_id
,
&
trait_method_type
)
{
debug!
(
"get_vtable_methods: not vtable safe"
);
return
None
;
}
...
...
src/librustc_typeck/astconv.rs
浏览文件 @
f8ea24ed
...
...
@@ -48,7 +48,6 @@
//! case but `&a` in the second. Basically, defaults that appear inside
//! an rptr (`&r.T`) use the region `r` that appears in the rptr.
use
middle
::
astconv_util
::{
prim_ty_to_ty
,
prohibit_type_params
,
prohibit_projection
};
use
middle
::
const_val
::
ConstVal
;
use
rustc_const_eval
::{
eval_const_expr_partial
,
ConstEvalErr
};
use
rustc_const_eval
::
EvalHint
::
UncheckedExprHint
;
...
...
@@ -338,7 +337,7 @@ pub fn ast_path_substs_for_ty<'tcx>(
}
};
assoc_bindings
.first
()
.map
(|
b
|
prohibit_projection
(
this
.tcx
(),
b
.span
));
assoc_bindings
.first
()
.map
(|
b
|
this
.tcx
()
.prohibit_projection
(
b
.span
));
create_substs_for_ast_path
(
this
,
span
,
...
...
@@ -825,7 +824,7 @@ fn ast_path_to_mono_trait_ref<'a,'tcx>(this: &AstConv<'tcx>,
trait_def_id
,
self_ty
,
trait_segment
);
assoc_bindings
.first
()
.map
(|
b
|
prohibit_projection
(
this
.tcx
(),
b
.span
));
assoc_bindings
.first
()
.map
(|
b
|
this
.tcx
()
.prohibit_projection
(
b
.span
));
ty
::
TraitRef
::
new
(
trait_def_id
,
substs
)
}
...
...
@@ -1141,10 +1140,10 @@ fn make_object_type<'tcx>(this: &AstConv<'tcx>,
// most importantly, that the supertraits don't contain Self,
// to avoid ICE-s.
let
object_safety_violations
=
t
raits
::
astconv_object_safety_violations
(
tcx
,
principal
.def_id
());
t
cx
.astconv_object_safety_violations
(
principal
.def_id
());
if
!
object_safety_violations
.is_empty
()
{
t
raits
::
report_object_safety_error
(
tcx
,
span
,
principal
.def_id
(),
None
,
object_safety_violations
)
t
cx
.
report_object_safety_error
(
span
,
principal
.def_id
(),
None
,
object_safety_violations
)
.unwrap
()
.emit
();
return
tcx
.types.err
;
}
...
...
@@ -1281,7 +1280,7 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
debug!
(
"associated_path_def_to_ty: {:?}::{}"
,
ty
,
assoc_name
);
prohibit_type_params
(
tcx
,
slice
::
ref_slice
(
item_segment
));
tcx
.prohibit_type_params
(
slice
::
ref_slice
(
item_segment
));
// Find the type of the associated item, and the trait where the associated
// item is declared.
...
...
@@ -1383,7 +1382,7 @@ fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>,
{
let
tcx
=
this
.tcx
();
prohibit_type_params
(
tcx
,
slice
::
ref_slice
(
item_segment
));
tcx
.prohibit_type_params
(
slice
::
ref_slice
(
item_segment
));
let
self_ty
=
if
let
Some
(
ty
)
=
opt_self_ty
{
ty
...
...
@@ -1472,7 +1471,7 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
base_segments
.last
()
.unwrap
(),
&
mut
projection_bounds
);
prohibit_type_params
(
tcx
,
base_segments
.split_last
()
.unwrap
()
.1
);
tcx
.prohibit_type_params
(
base_segments
.split_last
()
.unwrap
()
.1
);
trait_ref_to_object_type
(
this
,
rscope
,
span
,
...
...
@@ -1481,7 +1480,7 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
&
[])
}
Def
::
Enum
(
did
)
|
Def
::
TyAlias
(
did
)
|
Def
::
Struct
(
did
)
=>
{
prohibit_type_params
(
tcx
,
base_segments
.split_last
()
.unwrap
()
.1
);
tcx
.prohibit_type_params
(
base_segments
.split_last
()
.unwrap
()
.1
);
ast_path_to_ty
(
this
,
rscope
,
span
,
...
...
@@ -1490,12 +1489,12 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
base_segments
.last
()
.unwrap
())
}
Def
::
TyParam
(
space
,
index
,
_
,
name
)
=>
{
prohibit_type_params
(
tcx
,
base_segments
);
tcx
.prohibit_type_params
(
base_segments
);
tcx
.mk_param
(
space
,
index
,
name
)
}
Def
::
SelfTy
(
_
,
Some
((
_
,
self_ty_id
)))
=>
{
// Self in impl (we know the concrete type).
prohibit_type_params
(
tcx
,
base_segments
);
tcx
.prohibit_type_params
(
base_segments
);
if
let
Some
(
&
ty
)
=
tcx
.ast_ty_to_ty_cache
.borrow
()
.get
(
&
self_ty_id
)
{
if
let
Some
(
free_substs
)
=
this
.get_free_substs
()
{
ty
.subst
(
tcx
,
free_substs
)
...
...
@@ -1508,11 +1507,11 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
}
Def
::
SelfTy
(
Some
(
_
),
None
)
=>
{
// Self in trait.
prohibit_type_params
(
tcx
,
base_segments
);
tcx
.prohibit_type_params
(
base_segments
);
tcx
.mk_self_type
()
}
Def
::
AssociatedTy
(
trait_did
,
_
)
=>
{
prohibit_type_params
(
tcx
,
&
base_segments
[
..
base_segments
.len
()
-
2
]);
tcx
.prohibit_type_params
(
&
base_segments
[
..
base_segments
.len
()
-
2
]);
qpath_to_ty
(
this
,
rscope
,
span
,
...
...
@@ -1536,7 +1535,7 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
opt_self_ty
.expect
(
"missing T in <T>::a::b::c"
)
}
Def
::
PrimTy
(
prim_ty
)
=>
{
prim_ty_to_ty
(
tcx
,
base_segments
,
prim_ty
)
tcx
.prim_ty_to_ty
(
base_segments
,
prim_ty
)
}
Def
::
Err
=>
{
this
.set_tainted_by_errors
();
...
...
@@ -2259,7 +2258,7 @@ pub fn predicates(&self,
let
mut
vec
=
Vec
::
new
();
for
builtin_bound
in
&
self
.builtin_bounds
{
match
t
raits
::
trait_ref_for_builtin_bound
(
tcx
,
builtin_bound
,
param_ty
)
{
match
t
cx
.trait_ref_for_builtin_bound
(
builtin_bound
,
param_ty
)
{
Ok
(
trait_ref
)
=>
{
vec
.push
(
trait_ref
.to_predicate
());
}
Err
(
ErrorReported
)
=>
{
}
}
...
...
src/librustc_typeck/check/coercion.rs
浏览文件 @
f8ea24ed
...
...
@@ -64,7 +64,6 @@
use
rustc
::
infer
::{
Coercion
,
InferOk
,
TypeOrigin
,
TypeTrace
};
use
rustc
::
traits
::{
self
,
ObligationCause
};
use
rustc
::
traits
::{
predicate_for_trait_def
,
report_selection_error
};
use
rustc
::
ty
::
adjustment
::{
AutoAdjustment
,
AutoDerefRef
,
AdjustDerefRef
};
use
rustc
::
ty
::
adjustment
::{
AutoPtr
,
AutoUnsafe
,
AdjustReifyFnPointer
};
use
rustc
::
ty
::
adjustment
::{
AdjustUnsafeFnPointer
,
AdjustMutToConstPointer
};
...
...
@@ -446,12 +445,11 @@ fn coerce_unsized(&self,
// Create an obligation for `Source: CoerceUnsized<Target>`.
let
cause
=
ObligationCause
::
misc
(
self
.origin
.span
(),
self
.fcx.body_id
);
queue
.push_back
(
predicate_for_trait_def
(
self
.tcx
(),
cause
,
coerce_unsized_did
,
0
,
source
,
vec!
[
target
]));
queue
.push_back
(
self
.tcx
()
.predicate_for_trait_def
(
cause
,
coerce_unsized_did
,
0
,
source
,
vec!
[
target
]));
// Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid
// emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where
...
...
@@ -477,7 +475,7 @@ fn coerce_unsized(&self,
// Object safety violations or miscellaneous.
Err
(
err
)
=>
{
report_selection_error
(
self
.fcx
.infcx
(),
&
obligation
,
&
err
,
None
);
self
.fcx
.infcx
()
.report_selection_error
(
&
obligation
,
&
err
,
None
);
// Treat this like an obligation and follow through
// with the unsizing - the lack of a coercion should
// be silent, as it causes a type mismatch later.
...
...
src/librustc_typeck/check/compare_method.rs
浏览文件 @
f8ea24ed
...
...
@@ -325,9 +325,9 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
debug!
(
"compare_impl_method: trait_fty={:?}"
,
trait_fty
);
inf
er
::
mk_subty
(
&
infcx
,
false
,
origin
,
impl_fty
,
trait_fty
)
?
;
inf
cx
.sub_types
(
false
,
origin
,
impl_fty
,
trait_fty
)
?
;
infcx
.leak_check
(
&
skol_map
,
snapshot
)
infcx
.leak_check
(
false
,
&
skol_map
,
snapshot
)
});
match
err
{
...
...
@@ -347,7 +347,7 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
// Check that all obligations are satisfied by the implementation's
// version.
match
fulfillment_cx
.select_all_or_error
(
&
infcx
)
{
Err
(
ref
errors
)
=>
{
traits
::
report_fulfillment_errors
(
&
infcx
,
errors
)
}
Err
(
ref
errors
)
=>
{
infcx
.report_fulfillment_errors
(
errors
)
}
Ok
(
_
)
=>
{}
}
...
...
@@ -361,8 +361,7 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
// anyway, so it shouldn't be needed there either. Anyway, we can
// always add more relations later (it's backwards compat).
let
mut
free_regions
=
FreeRegionMap
::
new
();
free_regions
.relate_free_regions_from_predicates
(
tcx
,
&
infcx
.parameter_environment.caller_bounds
);
free_regions
.relate_free_regions_from_predicates
(
&
infcx
.parameter_environment.caller_bounds
);
infcx
.resolve_regions_and_report_errors
(
&
free_regions
,
impl_m_body_id
);
...
...
@@ -474,7 +473,7 @@ pub fn compare_const_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
debug!
(
"compare_const_impl: trait_ty={:?}"
,
trait_ty
);
inf
er
::
mk_subty
(
&
infcx
,
false
,
origin
,
impl_ty
,
trait_ty
)
inf
cx
.sub_types
(
false
,
origin
,
impl_ty
,
trait_ty
)
});
match
err
{
...
...
src/librustc_typeck/check/dropck.rs
浏览文件 @
f8ea24ed
...
...
@@ -96,7 +96,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
infcx
.fresh_substs_for_generics
(
drop_impl_span
,
drop_impl_generics
);
let
fresh_impl_self_ty
=
drop_impl_ty
.subst
(
tcx
,
&
fresh_impl_substs
);
if
let
Err
(
_
)
=
inf
er
::
mk_eqty
(
&
infcx
,
true
,
infer
::
TypeOrigin
::
Misc
(
drop_impl_span
),
if
let
Err
(
_
)
=
inf
cx
.eq_types
(
true
,
infer
::
TypeOrigin
::
Misc
(
drop_impl_span
),
named_type
,
fresh_impl_self_ty
)
{
let
item_span
=
tcx
.map
.span
(
self_type_node_id
);
struct_span_err!
(
tcx
.sess
,
drop_impl_span
,
E0366
,
...
...
@@ -110,13 +110,12 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
if
let
Err
(
ref
errors
)
=
fulfillment_cx
.select_all_or_error
(
&
infcx
)
{
// this could be reached when we get lazy normalization
traits
::
report_fulfillment_errors
(
&
infcx
,
errors
);
infcx
.report_fulfillment_errors
(
errors
);
return
Err
(());
}
if
let
Err
(
ref
errors
)
=
fulfillment_cx
.select_rfc1592_obligations
(
&
infcx
)
{
traits
::
report_fulfillment_errors_as_warnings
(
&
infcx
,
errors
,
drop_impl_node_id
);
infcx
.report_fulfillment_errors_as_warnings
(
errors
,
drop_impl_node_id
);
}
let
free_regions
=
FreeRegionMap
::
new
();
...
...
src/librustc_typeck/check/method/confirm.rs
浏览文件 @
f8ea24ed
...
...
@@ -19,7 +19,7 @@
use
rustc
::
ty
::
adjustment
::{
AdjustDerefRef
,
AutoDerefRef
,
AutoPtr
};
use
rustc
::
ty
::
fold
::
TypeFoldable
;
use
rustc
::
infer
;
use
rustc
::
infer
::{
InferCtxt
,
TypeOrigin
};
use
rustc
::
infer
::{
InferCtxt
,
InferOk
,
TypeOrigin
};
use
syntax
::
codemap
::
Span
;
use
rustc
::
hir
;
...
...
@@ -369,8 +369,12 @@ fn unify_receivers(&mut self,
self_ty
:
Ty
<
'tcx
>
,
method_self_ty
:
Ty
<
'tcx
>
)
{
match
self
.fcx
.mk_subty
(
false
,
TypeOrigin
::
Misc
(
self
.span
),
self_ty
,
method_self_ty
)
{
Ok
(
_
)
=>
{}
match
self
.fcx
.infcx
()
.sub_types
(
false
,
TypeOrigin
::
Misc
(
self
.span
),
self_ty
,
method_self_ty
)
{
Ok
(
InferOk
{
obligations
,
..
})
=>
{
// FIXME(#32730) propagate obligations
assert
!
(
obligations
.is_empty
());
}
Err
(
_
)
=>
{
span_bug!
(
self
.span
,
...
...
@@ -636,9 +640,8 @@ fn upcast(&mut self,
target_trait_def_id
:
DefId
)
->
ty
::
PolyTraitRef
<
'tcx
>
{
let
upcast_trait_refs
=
traits
::
upcast
(
self
.tcx
(),
source_trait_ref
.clone
(),
target_trait_def_id
);
let
upcast_trait_refs
=
self
.tcx
()
.upcast_choices
(
source_trait_ref
.clone
(),
target_trait_def_id
);
// must be exactly one trait ref or we'd get an ambig error etc
if
upcast_trait_refs
.len
()
!=
1
{
...
...
src/librustc_typeck/check/mod.rs
浏览文件 @
f8ea24ed
...
...
@@ -84,14 +84,13 @@
use
check
::
_
match
::
PatCtxt
;
use
dep_graph
::
DepNode
;
use
fmt_macros
::{
Parser
,
Piece
,
Position
};
use
middle
::
astconv_util
::
prohibit_type_params
;
use
middle
::
cstore
::
LOCAL_CRATE
;
use
hir
::
def
::{
self
,
Def
};
use
hir
::
def_id
::
DefId
;
use
rustc
::
infer
::{
self
,
InferCtxt
,
InferOk
,
TypeOrigin
,
TypeTrace
,
type_variable
};
use
hir
::
pat_util
::{
self
,
pat_id_map
};
use
rustc
::
ty
::
subst
::{
self
,
Subst
,
Substs
,
VecPerParamSpace
,
ParamSpace
};
use
rustc
::
traits
::{
self
,
report_fulfillment_errors
,
ProjectionMode
};
use
rustc
::
traits
::{
self
,
ProjectionMode
};
use
rustc
::
ty
::{
GenericPredicates
,
TypeScheme
};
use
rustc
::
ty
::{
ParamTy
,
ParameterEnvironment
};
use
rustc
::
ty
::{
LvaluePreference
,
NoPreference
,
PreferMutLvalue
};
...
...
@@ -1158,7 +1157,7 @@ pub fn check_representable(tcx: &TyCtxt,
match
rty
.is_representable
(
tcx
,
sp
)
{
Representability
::
SelfRecursive
=>
{
let
item_def_id
=
tcx
.map
.local_def_id
(
item_id
);
t
raits
::
recursive_type_with_infinite_size_error
(
tcx
,
item_def_id
)
.emit
();
t
cx
.recursive_type_with_infinite_size_error
(
item_def_id
)
.emit
();
return
false
}
Representability
::
Representable
|
Representability
::
ContainsRecursive
=>
(),
...
...
@@ -1803,35 +1802,6 @@ pub fn opt_node_ty_substs<F>(&self,
}
}
pub
fn
mk_subty
(
&
self
,
a_is_expected
:
bool
,
origin
:
TypeOrigin
,
sub
:
Ty
<
'tcx
>
,
sup
:
Ty
<
'tcx
>
)
->
Result
<
(),
TypeError
<
'tcx
>>
{
infer
::
mk_subty
(
self
.infcx
(),
a_is_expected
,
origin
,
sub
,
sup
)
// FIXME(#32730) propagate obligations
.map
(|
InferOk
{
obligations
,
..
}|
assert
!
(
obligations
.is_empty
()))
}
pub
fn
mk_eqty
(
&
self
,
a_is_expected
:
bool
,
origin
:
TypeOrigin
,
sub
:
Ty
<
'tcx
>
,
sup
:
Ty
<
'tcx
>
)
->
Result
<
(),
TypeError
<
'tcx
>>
{
infer
::
mk_eqty
(
self
.infcx
(),
a_is_expected
,
origin
,
sub
,
sup
)
// FIXME(#32730) propagate obligations
.map
(|
InferOk
{
obligations
,
..
}|
assert
!
(
obligations
.is_empty
()))
}
pub
fn
mk_subr
(
&
self
,
origin
:
infer
::
SubregionOrigin
<
'tcx
>
,
sub
:
ty
::
Region
,
sup
:
ty
::
Region
)
{
infer
::
mk_subr
(
self
.infcx
(),
origin
,
sub
,
sup
)
}
pub
fn
type_error_message
<
M
>
(
&
self
,
sp
:
Span
,
mk_msg
:
M
,
...
...
@@ -2119,9 +2089,9 @@ fn new_select_all_obligations_and_apply_defaults(&self) {
Neither
=>
{
if
let
Some
(
default
)
=
default_map
.get
(
ty
)
{
let
default
=
default
.clone
();
match
infer
::
mk_eqty
(
self
.infcx
(),
false
,
TypeOrigin
::
Misc
(
default
.origin_span
),
ty
,
default
.ty
)
{
match
self
.infcx
()
.eq_types
(
false
,
TypeOrigin
::
Misc
(
default
.origin_span
),
ty
,
default
.ty
)
{
Ok
(
InferOk
{
obligations
,
..
})
=>
{
// FIXME(#32730) propagate obligations
assert
!
(
obligations
.is_empty
())
...
...
@@ -2215,9 +2185,9 @@ fn find_conflicting_default(&self,
Neither
=>
{
if
let
Some
(
default
)
=
default_map
.get
(
ty
)
{
let
default
=
default
.clone
();
match
infer
::
mk_eqty
(
self
.infcx
(),
false
,
TypeOrigin
::
Misc
(
default
.origin_span
),
ty
,
default
.ty
)
{
match
self
.infcx
()
.eq_types
(
false
,
TypeOrigin
::
Misc
(
default
.origin_span
),
ty
,
default
.ty
)
{
// FIXME(#32730) propagate obligations
Ok
(
InferOk
{
obligations
,
..
})
=>
assert
!
(
obligations
.is_empty
()),
Err
(
_
)
=>
{
...
...
@@ -2239,18 +2209,17 @@ fn select_all_obligations_or_error(&self) {
// upvar inference should have ensured that all deferred call
// resolutions are handled by now.
assert
!
(
self
.inh.deferred_call_resolutions
.borrow
()
.is_empty
());
let
infcx
=
self
.infcx
();
self
.select_all_obligations_and_apply_defaults
();
let
mut
fulfillment_cx
=
self
.inh.fulfillment_cx
.borrow_mut
();
match
fulfillment_cx
.select_all_or_error
(
infcx
)
{
match
fulfillment_cx
.select_all_or_error
(
self
.infcx
()
)
{
Ok
(())
=>
{
}
Err
(
errors
)
=>
{
report_fulfillment_errors
(
infcx
,
&
errors
);
}
Err
(
errors
)
=>
{
self
.infcx
()
.report_fulfillment_errors
(
&
errors
);
}
}
if
let
Err
(
ref
errors
)
=
fulfillment_cx
.select_rfc1592_obligations
(
infcx
)
{
traits
::
report_fulfillment_errors_as_warnings
(
infcx
,
errors
,
self
.body_id
);
if
let
Err
(
ref
errors
)
=
fulfillment_cx
.select_rfc1592_obligations
(
self
.infcx
()
)
{
self
.infcx
()
.report_fulfillment_errors_as_warnings
(
errors
,
self
.body_id
);
}
}
...
...
@@ -2262,7 +2231,7 @@ fn select_obligations_where_possible(&self) {
.select_where_possible
(
self
.infcx
())
{
Ok
(())
=>
{
}
Err
(
errors
)
=>
{
report_fulfillment_errors
(
self
.infcx
(),
&
errors
);
}
Err
(
errors
)
=>
{
self
.infcx
()
.report_fulfillment_errors
(
&
errors
);
}
}
}
...
...
@@ -3570,16 +3539,18 @@ fn check_expr_with_expectation_and_lvalue_pref(&self,
hir
::
ExprRet
(
ref
expr_opt
)
=>
{
match
self
.ret_ty
{
ty
::
FnConverging
(
result_type
)
=>
{
match
*
expr_opt
{
None
=>
if
let
Err
(
_
)
=
self
.mk_eqty
(
false
,
TypeOrigin
::
Misc
(
expr
.span
),
result_type
,
self
.tcx
()
.mk_nil
())
{
span_err!
(
tcx
.sess
,
expr
.span
,
E0069
,
"`return;` in a function whose return type is
\
not `()`"
);
},
Some
(
ref
e
)
=>
{
self
.check_expr_coercable_to_type
(
&
e
,
result_type
);
if
let
Some
(
ref
e
)
=
*
expr_opt
{
self
.check_expr_coercable_to_type
(
&
e
,
result_type
);
}
else
{
let
eq_result
=
self
.infcx
()
.eq_types
(
false
,
TypeOrigin
::
Misc
(
expr
.span
),
result_type
,
self
.tcx
()
.mk_nil
())
// FIXME(#32730) propagate obligations
.map
(|
InferOk
{
obligations
,
..
}|
assert
!
(
obligations
.is_empty
()));
if
eq_result
.is_err
()
{
span_err!
(
tcx
.sess
,
expr
.span
,
E0069
,
"`return;` in a function whose return type is not `()`"
);
}
}
}
...
...
@@ -4370,7 +4341,7 @@ pub fn instantiate_path(&self,
segment
,
&
mut
substs
);
}
else
{
prohibit_type_params
(
self
.tcx
(),
slice
::
ref_slice
(
segment
));
self
.tcx
()
.prohibit_type_params
(
slice
::
ref_slice
(
segment
));
}
}
if
let
Some
(
self_ty
)
=
opt_self_ty
{
...
...
@@ -4423,11 +4394,17 @@ pub fn instantiate_path(&self,
impl_scheme
.generics.regions
.len
(
subst
::
TypeSpace
));
let
impl_ty
=
self
.instantiate_type_scheme
(
span
,
&
substs
,
&
impl_scheme
.ty
);
if
self
.mk_subty
(
false
,
TypeOrigin
::
Misc
(
span
),
self_ty
,
impl_ty
)
.is_err
()
{
span_bug!
(
span
,
"instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?"
,
self_ty
,
impl_ty
);
match
self
.infcx
()
.sub_types
(
false
,
TypeOrigin
::
Misc
(
span
),
self_ty
,
impl_ty
)
{
Ok
(
InferOk
{
obligations
,
..
})
=>
{
// FIXME(#32730) propagate obligations
assert
!
(
obligations
.is_empty
());
}
Err
(
_
)
=>
{
span_bug!
(
span
,
"instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?"
,
self_ty
,
impl_ty
);
}
}
}
...
...
src/librustc_typeck/check/regionck.rs
浏览文件 @
f8ea24ed
...
...
@@ -131,8 +131,7 @@ pub fn regionck_item(&self,
wf_tys
:
&
[
Ty
<
'tcx
>
])
{
debug!
(
"regionck_item(item.id={:?}, wf_tys={:?}"
,
item_id
,
wf_tys
);
let
mut
rcx
=
Rcx
::
new
(
self
,
RepeatingScope
(
item_id
),
item_id
,
Subject
(
item_id
));
let
tcx
=
self
.tcx
();
rcx
.free_region_map
.relate_free_regions_from_predicates
(
tcx
,
rcx
.free_region_map
.relate_free_regions_from_predicates
(
&
self
.infcx
()
.parameter_environment.caller_bounds
);
rcx
.relate_free_regions
(
wf_tys
,
item_id
,
span
);
rcx
.visit_region_obligations
(
item_id
);
...
...
@@ -152,8 +151,7 @@ pub fn regionck_fn(&self,
rcx
.visit_fn_body
(
fn_id
,
decl
,
blk
,
fn_span
);
}
let
tcx
=
self
.tcx
();
rcx
.free_region_map
.relate_free_regions_from_predicates
(
tcx
,
rcx
.free_region_map
.relate_free_regions_from_predicates
(
&
self
.infcx
()
.parameter_environment.caller_bounds
);
rcx
.resolve_regions_and_report_errors
();
...
...
@@ -844,7 +842,7 @@ fn walk_cast<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
/*From:*/
(
&
ty
::
TyRef
(
from_r
,
ref
from_mt
),
/*To: */
&
ty
::
TyRef
(
to_r
,
ref
to_mt
))
=>
{
// Target cannot outlive source, naturally.
rcx
.fcx
.
mk_subr
(
infer
::
Reborrow
(
cast_expr
.span
),
*
to_r
,
*
from_r
);
rcx
.fcx
.
infcx
()
.sub_regions
(
infer
::
Reborrow
(
cast_expr
.span
),
*
to_r
,
*
from_r
);
walk_cast
(
rcx
,
cast_expr
,
from_mt
.ty
,
to_mt
.ty
);
}
...
...
@@ -1038,8 +1036,8 @@ pub fn mk_subregion_due_to_dereference(rcx: &mut Rcx,
deref_span
:
Span
,
minimum_lifetime
:
ty
::
Region
,
maximum_lifetime
:
ty
::
Region
)
{
rcx
.fcx
.
mk_subr
(
infer
::
DerefPointer
(
deref_span
),
minimum_lifetime
,
maximum_lifetime
)
rcx
.fcx
.
infcx
()
.sub_regions
(
infer
::
DerefPointer
(
deref_span
),
minimum_lifetime
,
maximum_lifetime
)
}
fn
check_safety_of_rvalue_destructor_if_necessary
<
'a
,
'tcx
>
(
rcx
:
&
mut
Rcx
<
'a
,
'tcx
>
,
...
...
@@ -1081,8 +1079,8 @@ fn constrain_index<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
if
let
ty
::
TyRef
(
r_ptr
,
mt
)
=
indexed_ty
.sty
{
match
mt
.ty.sty
{
ty
::
TySlice
(
_
)
|
ty
::
TyStr
=>
{
rcx
.fcx
.
mk_subr
(
infer
::
IndexSlice
(
index_expr
.span
),
r_index_expr
,
*
r_ptr
);
rcx
.fcx
.
infcx
()
.sub_regions
(
infer
::
IndexSlice
(
index_expr
.span
),
r_index_expr
,
*
r_ptr
);
}
_
=>
{}
}
...
...
@@ -1410,7 +1408,7 @@ fn link_reborrowed_region<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
debug!
(
"link_reborrowed_region: {:?} <= {:?}"
,
borrow_region
,
ref_region
);
rcx
.fcx
.
mk_subr
(
cause
,
*
borrow_region
,
ref_region
);
rcx
.fcx
.
infcx
()
.sub_regions
(
cause
,
*
borrow_region
,
ref_region
);
// If we end up needing to recurse and establish a region link
// with `ref_cmt`, calculate what borrow kind we will end up
...
...
@@ -1492,7 +1490,7 @@ pub fn substs_wf_in_scope<'a,'tcx>(rcx: &mut Rcx<'a,'tcx>,
let
origin
=
infer
::
ParameterInScope
(
origin
,
expr_span
);
for
&
region
in
&
substs
.regions
{
rcx
.fcx
.
mk_subr
(
origin
.clone
(),
expr_region
,
region
);
rcx
.fcx
.
infcx
()
.sub_regions
(
origin
.clone
(),
expr_region
,
region
);
}
for
&
ty
in
&
substs
.types
{
...
...
@@ -1518,7 +1516,7 @@ pub fn type_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
assert
!
(
!
ty
.has_escaping_regions
());
let
components
=
ty
::
outlives
::
components
(
rcx
.infcx
(),
ty
);
let
components
=
rcx
.infcx
()
.outlives_components
(
ty
);
components_must_outlive
(
rcx
,
origin
,
components
,
region
);
}
...
...
@@ -1531,7 +1529,7 @@ fn components_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
let
origin
=
origin
.clone
();
match
component
{
ty
::
outlives
::
Component
::
Region
(
region1
)
=>
{
rcx
.fcx
.
mk_subr
(
origin
,
region
,
region1
);
rcx
.fcx
.
infcx
()
.sub_regions
(
origin
,
region
,
region1
);
}
ty
::
outlives
::
Component
::
Param
(
param_ty
)
=>
{
param_ty_must_outlive
(
rcx
,
origin
,
region
,
param_ty
);
...
...
@@ -1629,7 +1627,7 @@ fn projection_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
}
for
&
r
in
&
projection_ty
.trait_ref.substs.regions
{
rcx
.fcx
.
mk_subr
(
origin
.clone
(),
region
,
r
);
rcx
.fcx
.
infcx
()
.sub_regions
(
origin
.clone
(),
region
,
r
);
}
return
;
...
...
@@ -1650,7 +1648,7 @@ fn projection_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
.any
(|
r
|
env_bounds
.contains
(
r
))
{
debug!
(
"projection_must_outlive: unique declared bound appears in trait ref"
);
rcx
.fcx
.
mk_subr
(
origin
.clone
(),
region
,
unique_bound
);
rcx
.fcx
.
infcx
()
.sub_regions
(
origin
.clone
(),
region
,
unique_bound
);
return
;
}
}
...
...
@@ -1840,7 +1838,7 @@ fn declared_projection_bounds_from_trait<'a,'tcx>(rcx: &Rcx<'a, 'tcx>,
outlives
);
// check whether this predicate applies to our current projection
match
inf
er
::
mk_eqty
(
infcx
,
false
,
TypeOrigin
::
Misc
(
span
),
ty
,
outlives
.0
)
{
match
inf
cx
.eq_types
(
false
,
TypeOrigin
::
Misc
(
span
),
ty
,
outlives
.0
)
{
Ok
(
InferOk
{
obligations
,
..
})
=>
{
// FIXME(#32730) propagate obligations
assert
!
(
obligations
.is_empty
());
...
...
src/librustc_typeck/check/writeback.rs
浏览文件 @
f8ea24ed
...
...
@@ -440,28 +440,24 @@ fn report_error(&self, e: infer::FixupError) {
match
self
.reason
{
ResolvingExpr
(
span
)
=>
{
span_err!
(
self
.tcx.sess
,
span
,
E0101
,
"cannot determine a type for this expression: {}"
,
infer
::
fixup_err_to_string
(
e
));
"cannot determine a type for this expression: {}"
,
e
);
}
ResolvingLocal
(
span
)
=>
{
span_err!
(
self
.tcx.sess
,
span
,
E0102
,
"cannot determine a type for this local variable: {}"
,
infer
::
fixup_err_to_string
(
e
));
"cannot determine a type for this local variable: {}"
,
e
);
}
ResolvingPattern
(
span
)
=>
{
span_err!
(
self
.tcx.sess
,
span
,
E0103
,
"cannot determine a type for this pattern binding: {}"
,
infer
::
fixup_err_to_string
(
e
));
"cannot determine a type for this pattern binding: {}"
,
e
);
}
ResolvingUpvar
(
upvar_id
)
=>
{
let
span
=
self
.reason
.span
(
self
.tcx
);
span_err!
(
self
.tcx.sess
,
span
,
E0104
,
"cannot resolve lifetime for captured variable `{}`: {}"
,
self
.tcx
.local_var_name_str
(
upvar_id
.var_id
)
.to_string
(),
infer
::
fixup_err_to_string
(
e
));
self
.tcx
.local_var_name_str
(
upvar_id
.var_id
),
e
);
}
ResolvingClosure
(
_
)
=>
{
...
...
src/librustc_typeck/coherence/mod.rs
浏览文件 @
f8ea24ed
...
...
@@ -46,11 +46,28 @@
mod
overlap
;
mod
unsafety
;
struct
CoherenceChecker
<
'a
,
'tcx
:
'a
>
{
crate_context
:
&
'a
CrateCtxt
<
'a
,
'tcx
>
,
inference_context
:
InferCtxt
<
'a
,
'tcx
>
,
inherent_impls
:
RefCell
<
DefIdMap
<
Rc
<
RefCell
<
Vec
<
DefId
>>>>>
,
}
struct
CoherenceCheckVisitor
<
'a
,
'tcx
:
'a
>
{
cc
:
&
'a
CoherenceChecker
<
'a
,
'tcx
>
}
impl
<
'a
,
'tcx
,
'v
>
intravisit
::
Visitor
<
'v
>
for
CoherenceCheckVisitor
<
'a
,
'tcx
>
{
fn
visit_item
(
&
mut
self
,
item
:
&
Item
)
{
if
let
ItemImpl
(
..
)
=
item
.node
{
self
.cc
.check_implementation
(
item
)
}
}
}
impl
<
'a
,
'tcx
>
CoherenceChecker
<
'a
,
'tcx
>
{
// Returns the def ID of the base type, if there is one.
fn
get_base_type_def_id
<
'a
,
'tcx
>
(
inference_context
:
&
InferCtxt
<
'a
,
'tcx
>
,
span
:
Span
,
ty
:
Ty
<
'tcx
>
)
->
Option
<
DefId
>
{
fn
get_base_type_def_id
(
&
self
,
span
:
Span
,
ty
:
Ty
<
'tcx
>
)
->
Option
<
DefId
>
{
match
ty
.sty
{
TyEnum
(
def
,
_
)
|
TyStruct
(
def
,
_
)
=>
{
...
...
@@ -62,7 +79,7 @@ fn get_base_type_def_id<'a, 'tcx>(inference_context: &InferCtxt<'a, 'tcx>,
}
TyBox
(
_
)
=>
{
inference_context
.tcx.lang_items
.owned_box
()
self
.
inference_context.tcx.lang_items
.owned_box
()
}
TyBool
|
TyChar
|
TyInt
(
..
)
|
TyUint
(
..
)
|
TyFloat
(
..
)
|
...
...
@@ -83,25 +100,6 @@ fn get_base_type_def_id<'a, 'tcx>(inference_context: &InferCtxt<'a, 'tcx>,
}
}
struct
CoherenceChecker
<
'a
,
'tcx
:
'a
>
{
crate_context
:
&
'a
CrateCtxt
<
'a
,
'tcx
>
,
inference_context
:
InferCtxt
<
'a
,
'tcx
>
,
inherent_impls
:
RefCell
<
DefIdMap
<
Rc
<
RefCell
<
Vec
<
DefId
>>>>>
,
}
struct
CoherenceCheckVisitor
<
'a
,
'tcx
:
'a
>
{
cc
:
&
'a
CoherenceChecker
<
'a
,
'tcx
>
}
impl
<
'a
,
'tcx
,
'v
>
intravisit
::
Visitor
<
'v
>
for
CoherenceCheckVisitor
<
'a
,
'tcx
>
{
fn
visit_item
(
&
mut
self
,
item
:
&
Item
)
{
if
let
ItemImpl
(
..
)
=
item
.node
{
self
.cc
.check_implementation
(
item
)
}
}
}
impl
<
'a
,
'tcx
>
CoherenceChecker
<
'a
,
'tcx
>
{
fn
check
(
&
self
)
{
// Check implementations and traits. This populates the tables
// containing the inherent methods and extension methods. It also
...
...
@@ -167,9 +165,8 @@ fn check_implementation(&self, item: &Item) {
// Add the implementation to the mapping from implementation to base
// type def ID, if there is a base type for this implementation and
// the implementation does not have any associated traits.
if
let
Some
(
base_type_def_id
)
=
get_base_type_def_id
(
&
self
.inference_context
,
item
.span
,
self_type
.ty
)
{
self
.add_inherent_impl
(
base_type_def_id
,
impl_did
);
if
let
Some
(
base_def_id
)
=
self
.get_base_type_def_id
(
item
.span
,
self_type
.ty
)
{
self
.add_inherent_impl
(
base_def_id
,
impl_did
);
}
}
...
...
@@ -394,7 +391,7 @@ fn check_implementations_of_coerce_unsized(&self) {
(
&
ty
::
TyBox
(
a
),
&
ty
::
TyBox
(
b
))
=>
(
a
,
b
,
unsize_trait
,
None
),
(
&
ty
::
TyRef
(
r_a
,
mt_a
),
&
ty
::
TyRef
(
r_b
,
mt_b
))
=>
{
inf
er
::
mk_subr
(
&
infcx
,
infer
::
RelateObjectBound
(
span
),
*
r_b
,
*
r_a
);
inf
cx
.sub_regions
(
infer
::
RelateObjectBound
(
span
),
*
r_b
,
*
r_a
);
check_mutbl
(
mt_a
,
mt_b
,
&
|
ty
|
tcx
.mk_imm_ref
(
r_b
,
ty
))
}
...
...
@@ -466,19 +463,19 @@ fn check_implementations_of_coerce_unsized(&self) {
// Register an obligation for `A: Trait<B>`.
let
cause
=
traits
::
ObligationCause
::
misc
(
span
,
impl_node_id
);
let
predicate
=
t
raits
::
predicate_for_trait_def
(
tcx
,
cause
,
trait_def_id
,
0
,
source
,
vec!
[
target
]);
let
predicate
=
t
cx
.predicate_for_trait_def
(
cause
,
trait_def_id
,
0
,
source
,
vec!
[
target
]);
fulfill_cx
.register_predicate_obligation
(
&
infcx
,
predicate
);
// Check that all transitive obligations are satisfied.
if
let
Err
(
errors
)
=
fulfill_cx
.select_all_or_error
(
&
infcx
)
{
traits
::
report_fulfillment_errors
(
&
infcx
,
&
errors
);
infcx
.report_fulfillment_errors
(
&
errors
);
}
// Finally, resolve all regions.
let
mut
free_regions
=
FreeRegionMap
::
new
();
free_regions
.relate_free_regions_from_predicates
(
tcx
,
&
infcx
.parameter_environment
.caller_bounds
);
free_regions
.relate_free_regions_from_predicates
(
&
infcx
.parameter_environment
.caller_bounds
);
infcx
.resolve_regions_and_report_errors
(
&
free_regions
,
impl_node_id
);
if
let
Some
(
kind
)
=
kind
{
...
...
src/librustc_typeck/coherence/overlap.rs
浏览文件 @
f8ea24ed
...
...
@@ -174,7 +174,7 @@ 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
!
traits
::
is_object_safe
(
self
.tcx
,
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
...
...
src/librustc_typeck/lib.rs
浏览文件 @
f8ea24ed
...
...
@@ -201,10 +201,10 @@ fn require_same_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
->
bool
{
let
err
=
if
let
Some
(
infcx
)
=
maybe_infcx
{
inf
er
::
mk_eqty
(
infcx
,
false
,
TypeOrigin
::
Misc
(
span
),
t1
,
t2
)
.err
()
inf
cx
.eq_types
(
false
,
TypeOrigin
::
Misc
(
span
),
t1
,
t2
)
.err
()
}
else
{
let
infcx
=
InferCtxt
::
new
(
ccx
.tcx
,
&
ccx
.tcx.tables
,
None
,
ProjectionMode
::
AnyFinal
);
inf
er
::
mk_eqty
(
&
infcx
,
false
,
TypeOrigin
::
Misc
(
span
),
t1
,
t2
)
.err
()
inf
cx
.eq_types
(
false
,
TypeOrigin
::
Misc
(
span
),
t1
,
t2
)
.err
()
};
if
let
Some
(
ref
terr
)
=
err
{
...
...
src/librustdoc/clean/inline.rs
浏览文件 @
f8ea24ed
...
...
@@ -22,7 +22,6 @@
use
rustc
::
hir
::
print
as
pprust
;
use
rustc
::
ty
::{
self
,
TyCtxt
};
use
rustc
::
ty
::
subst
;
use
rustc
::
middle
::
stability
;
use
rustc_const_eval
::
lookup_const_by_id
;
...
...
@@ -124,8 +123,8 @@ fn try_inline_def(cx: &DocContext, tcx: &TyCtxt,
attrs
:
load_attrs
(
cx
,
tcx
,
did
),
inner
:
inner
,
visibility
:
Some
(
clean
::
Public
),
stability
:
stability
::
lookup_stability
(
tcx
,
did
)
.clean
(
cx
),
deprecation
:
stability
::
lookup_deprecation
(
tcx
,
did
)
.clean
(
cx
),
stability
:
tcx
.lookup_stability
(
did
)
.clean
(
cx
),
deprecation
:
tcx
.lookup_deprecation
(
did
)
.clean
(
cx
),
def_id
:
did
,
});
Some
(
ret
)
...
...
@@ -305,8 +304,8 @@ pub fn build_impl(cx: &DocContext,
name
:
None
,
attrs
:
attrs
,
visibility
:
Some
(
clean
::
Inherited
),
stability
:
stability
::
lookup_stability
(
tcx
,
did
)
.clean
(
cx
),
deprecation
:
stability
::
lookup_deprecation
(
tcx
,
did
)
.clean
(
cx
),
stability
:
tcx
.lookup_stability
(
did
)
.clean
(
cx
),
deprecation
:
tcx
.lookup_deprecation
(
did
)
.clean
(
cx
),
def_id
:
did
,
});
}
...
...
@@ -347,8 +346,8 @@ pub fn build_impl(cx: &DocContext,
source
:
clean
::
Span
::
empty
(),
attrs
:
vec!
[],
visibility
:
None
,
stability
:
stability
::
lookup_stability
(
tcx
,
did
)
.clean
(
cx
),
deprecation
:
stability
::
lookup_deprecation
(
tcx
,
did
)
.clean
(
cx
),
stability
:
tcx
.lookup_stability
(
did
)
.clean
(
cx
),
deprecation
:
tcx
.lookup_deprecation
(
did
)
.clean
(
cx
),
def_id
:
did
})
}
...
...
@@ -396,8 +395,8 @@ pub fn build_impl(cx: &DocContext,
source
:
clean
::
Span
::
empty
(),
attrs
:
vec!
[],
visibility
:
None
,
stability
:
stability
::
lookup_stability
(
tcx
,
did
)
.clean
(
cx
),
deprecation
:
stability
::
lookup_deprecation
(
tcx
,
did
)
.clean
(
cx
),
stability
:
tcx
.lookup_stability
(
did
)
.clean
(
cx
),
deprecation
:
tcx
.lookup_deprecation
(
did
)
.clean
(
cx
),
def_id
:
did
})
}
...
...
@@ -436,8 +435,8 @@ pub fn build_impl(cx: &DocContext,
name
:
None
,
attrs
:
attrs
,
visibility
:
Some
(
clean
::
Inherited
),
stability
:
stability
::
lookup_stability
(
tcx
,
did
)
.clean
(
cx
),
deprecation
:
stability
::
lookup_deprecation
(
tcx
,
did
)
.clean
(
cx
),
stability
:
tcx
.lookup_stability
(
did
)
.clean
(
cx
),
deprecation
:
tcx
.lookup_deprecation
(
did
)
.clean
(
cx
),
def_id
:
did
,
});
}
...
...
src/librustdoc/clean/mod.rs
浏览文件 @
f8ea24ed
...
...
@@ -64,11 +64,11 @@
// extract the stability index for a node from tcx, if possible
fn
get_stability
(
cx
:
&
DocContext
,
def_id
:
DefId
)
->
Option
<
Stability
>
{
cx
.tcx_opt
()
.and_then
(|
tcx
|
stability
::
lookup_stability
(
tcx
,
def_id
))
.clean
(
cx
)
cx
.tcx_opt
()
.and_then
(|
tcx
|
tcx
.lookup_stability
(
def_id
))
.clean
(
cx
)
}
fn
get_deprecation
(
cx
:
&
DocContext
,
def_id
:
DefId
)
->
Option
<
Deprecation
>
{
cx
.tcx_opt
()
.and_then
(|
tcx
|
stability
::
lookup_deprecation
(
tcx
,
def_id
))
.clean
(
cx
)
cx
.tcx_opt
()
.and_then
(|
tcx
|
tcx
.lookup_deprecation
(
def_id
))
.clean
(
cx
)
}
pub
trait
Clean
<
T
>
{
...
...
@@ -2878,8 +2878,8 @@ fn clean(&self, cx: &DocContext) -> Item {
inner
:
AssociatedTypeItem
(
bounds
,
self
.ty
.clean
(
cx
)),
visibility
:
self
.vis
.clean
(
cx
),
def_id
:
self
.def_id
,
stability
:
stability
::
lookup_stability
(
cx
.tcx
(),
self
.def_id
)
.clean
(
cx
),
deprecation
:
stability
::
lookup_deprecation
(
cx
.tcx
(),
self
.def_id
)
.clean
(
cx
),
stability
:
cx
.tcx
()
.lookup_stability
(
self
.def_id
)
.clean
(
cx
),
deprecation
:
cx
.tcx
()
.lookup_deprecation
(
self
.def_id
)
.clean
(
cx
),
}
}
}
...
...
src/librustdoc/visit_ast.rs
浏览文件 @
f8ea24ed
...
...
@@ -22,7 +22,6 @@
use
rustc
::
hir
::
map
as
hir_map
;
use
rustc
::
hir
::
def
::
Def
;
use
rustc
::
middle
::
stability
;
use
rustc
::
middle
::
privacy
::
AccessLevel
;
use
rustc
::
hir
;
...
...
@@ -64,7 +63,7 @@ pub fn new(cx: &'a core::DocContext<'a, 'tcx>) -> RustdocVisitor<'a, 'tcx> {
fn
stability
(
&
self
,
id
:
ast
::
NodeId
)
->
Option
<
attr
::
Stability
>
{
self
.cx
.tcx_opt
()
.and_then
(|
tcx
|
{
self
.cx.map
.opt_local_def_id
(
id
)
.and_then
(|
def_id
|
stability
::
lookup_stability
(
tcx
,
def_id
))
.and_then
(|
def_id
|
tcx
.lookup_stability
(
def_id
))
.cloned
()
})
}
...
...
@@ -72,7 +71,7 @@ fn stability(&self, id: ast::NodeId) -> Option<attr::Stability> {
fn
deprecation
(
&
self
,
id
:
ast
::
NodeId
)
->
Option
<
attr
::
Deprecation
>
{
self
.cx
.tcx_opt
()
.and_then
(|
tcx
|
{
self
.cx.map
.opt_local_def_id
(
id
)
.and_then
(|
def_id
|
stability
::
lookup_deprecation
(
tcx
,
def_id
))
.and_then
(|
def_id
|
tcx
.lookup_deprecation
(
def_id
))
})
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录