Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
8403b82d
R
Rust
项目概览
int
/
Rust
12 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
8403b82d
编写于
3月 22, 2015
作者:
N
Niko Matsakis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Port over type inference to using the new type relation stuff
上级
e301d7ca
变更
19
展开全部
隐藏空白更改
内联
并排
Showing
19 changed file
with
1140 addition
and
955 deletion
+1140
-955
src/librustc/lib.rs
src/librustc/lib.rs
+1
-0
src/librustc/middle/infer/bivariate.rs
src/librustc/middle/infer/bivariate.rs
+43
-50
src/librustc/middle/infer/combine.rs
src/librustc/middle/infer/combine.rs
+104
-600
src/librustc/middle/infer/equate.rs
src/librustc/middle/infer/equate.rs
+41
-38
src/librustc/middle/infer/glb.rs
src/librustc/middle/infer/glb.rs
+47
-35
src/librustc/middle/infer/higher_ranked/mod.rs
src/librustc/middle/infer/higher_ranked/mod.rs
+66
-63
src/librustc/middle/infer/lattice.rs
src/librustc/middle/infer/lattice.rs
+15
-31
src/librustc/middle/infer/lub.rs
src/librustc/middle/infer/lub.rs
+48
-35
src/librustc/middle/infer/mod.rs
src/librustc/middle/infer/mod.rs
+39
-30
src/librustc/middle/infer/region_inference/mod.rs
src/librustc/middle/infer/region_inference/mod.rs
+5
-5
src/librustc/middle/infer/sub.rs
src/librustc/middle/infer/sub.rs
+42
-46
src/librustc/middle/traits/project.rs
src/librustc/middle/traits/project.rs
+1
-0
src/librustc/middle/ty_fold.rs
src/librustc/middle/ty_fold.rs
+14
-4
src/librustc/middle/ty_relate/mod.rs
src/librustc/middle/ty_relate/mod.rs
+655
-0
src/librustc/util/ppaux.rs
src/librustc/util/ppaux.rs
+6
-0
src/librustc_driver/test.rs
src/librustc_driver/test.rs
+9
-9
src/librustc_typeck/check/coercion.rs
src/librustc_typeck/check/coercion.rs
+4
-4
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/coherence/mod.rs
+0
-1
src/test/compile-fail/dst-bad-coerce1.rs
src/test/compile-fail/dst-bad-coerce1.rs
+0
-4
未找到文件。
src/librustc/lib.rs
浏览文件 @
8403b82d
...
...
@@ -122,6 +122,7 @@ pub mod middle {
pub
mod
traits
;
pub
mod
ty
;
pub
mod
ty_fold
;
pub
mod
ty_relate
;
pub
mod
ty_walk
;
pub
mod
weak_lang_items
;
}
...
...
src/librustc/middle/infer/bivariate.rs
浏览文件 @
8403b82d
...
...
@@ -25,66 +25,54 @@
//! In particular, it might be enough to say (A,B) are bivariant for
//! all (A,B).
use
middle
::
ty
::
BuiltinBounds
;
use
super
::
combine
::{
self
,
CombineFields
};
use
super
::
type_variable
::{
BiTo
};
use
middle
::
ty
::{
self
,
Ty
};
use
middle
::
ty
::
TyVar
;
use
middle
::
infer
::
combine
::
*
;
use
middle
::
infer
::
CombineResult
;
use
middle
::
infer
::
type_variable
::
BiTo
;
use
util
::
ppaux
::
Repr
;
use
middle
::
ty_relate
::{
Relate
,
RelateResult
,
TypeRelation
};
use
util
::
ppaux
::{
Repr
};
pub
struct
Bivariate
<
'
f
,
'tcx
:
'f
>
{
fields
:
CombineFields
<
'
f
,
'tcx
>
pub
struct
Bivariate
<
'
a
,
'tcx
:
'a
>
{
fields
:
CombineFields
<
'
a
,
'tcx
>
}
#[allow(non_snake_case)]
pub
fn
Bivariate
<
'f
,
'tcx
>
(
cf
:
CombineFields
<
'f
,
'tcx
>
)
->
Bivariate
<
'f
,
'tcx
>
{
Bivariate
{
fields
:
cf
}
impl
<
'a
,
'tcx
>
Bivariate
<
'a
,
'tcx
>
{
pub
fn
new
(
fields
:
CombineFields
<
'a
,
'tcx
>
)
->
Bivariate
<
'a
,
'tcx
>
{
Bivariate
{
fields
:
fields
}
}
}
impl
<
'f
,
'tcx
>
Combine
<
'tcx
>
for
Bivariate
<
'f
,
'tcx
>
{
fn
tag
(
&
self
)
->
String
{
"Bivariate"
.to_string
()
}
fn
fields
<
'a
>
(
&
'a
self
)
->
&
'a
CombineFields
<
'a
,
'tcx
>
{
&
self
.fields
}
impl
<
'a
,
'tcx
>
TypeRelation
<
'a
,
'tcx
>
for
Bivariate
<
'a
,
'tcx
>
{
fn
tag
(
&
self
)
->
&
'static
str
{
"Bivariate"
}
fn
tys_with_variance
(
&
self
,
v
:
ty
::
Variance
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
CombineResult
<
'tcx
,
Ty
<
'tcx
>>
{
match
v
{
ty
::
Invariant
=>
self
.equate
()
.tys
(
a
,
b
),
ty
::
Covariant
=>
self
.tys
(
a
,
b
),
ty
::
Contravariant
=>
self
.tys
(
a
,
b
),
ty
::
Bivariant
=>
self
.tys
(
a
,
b
),
}
}
fn
tcx
(
&
self
)
->
&
'a
ty
::
ctxt
<
'tcx
>
{
self
.fields
.tcx
()
}
fn
regions_with_variance
(
&
self
,
v
:
ty
::
Variance
,
a
:
ty
::
Region
,
b
:
ty
::
Region
)
->
CombineResult
<
'tcx
,
ty
::
Region
>
{
match
v
{
ty
::
Invariant
=>
self
.equate
()
.regions
(
a
,
b
),
ty
::
Covariant
=>
self
.regions
(
a
,
b
),
ty
::
Contravariant
=>
self
.regions
(
a
,
b
),
ty
::
Bivariant
=>
self
.regions
(
a
,
b
),
}
}
fn
a_is_expected
(
&
self
)
->
bool
{
self
.fields.a_is_expected
}
fn
regions
(
&
self
,
a
:
ty
::
Region
,
_
:
ty
::
Region
)
->
CombineResult
<
'tcx
,
ty
::
Region
>
{
Ok
(
a
)
}
fn
builtin_bounds
(
&
self
,
a
:
BuiltinBounds
,
b
:
BuiltinBounds
)
->
CombineResult
<
'tcx
,
BuiltinBounds
>
fn
relate_with_variance
<
T
:
Relate
<
'a
,
'tcx
>>
(
&
mut
self
,
variance
:
ty
::
Variance
,
a
:
&
T
,
b
:
&
T
)
->
RelateResult
<
'tcx
,
T
>
{
if
a
!=
b
{
Err
(
ty
::
terr_builtin_bounds
(
expected_found
(
self
,
a
,
b
)))
}
else
{
Ok
(
a
)
match
variance
{
// If we have Foo<A> and Foo is invariant w/r/t A,
// and we want to assert that
//
// Foo<A> <: Foo<B> ||
// Foo<B> <: Foo<A>
//
// then still A must equal B.
ty
::
Invariant
=>
self
.relate
(
a
,
b
),
ty
::
Covariant
=>
self
.relate
(
a
,
b
),
ty
::
Bivariant
=>
self
.relate
(
a
,
b
),
ty
::
Contravariant
=>
self
.relate
(
a
,
b
),
}
}
fn
tys
(
&
self
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
Combin
eResult
<
'tcx
,
Ty
<
'tcx
>>
{
fn
tys
(
&
mut
self
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
Relat
eResult
<
'tcx
,
Ty
<
'tcx
>>
{
debug!
(
"{}.tys({}, {})"
,
self
.tag
(),
a
.repr
(
self
.fields.infcx.tcx
),
b
.repr
(
self
.fields.infcx.tcx
));
if
a
==
b
{
return
Ok
(
a
);
}
...
...
@@ -109,17 +97,22 @@ fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CombineResult<'tcx, Ty<'tcx>> {
}
_
=>
{
super_tys
(
self
,
a
,
b
)
combine
::
super_combine_tys
(
self
.fields.infcx
,
self
,
a
,
b
)
}
}
}
fn
binders
<
T
>
(
&
self
,
a
:
&
ty
::
Binder
<
T
>
,
b
:
&
ty
::
Binder
<
T
>
)
->
CombineResult
<
'tcx
,
ty
::
Binder
<
T
>>
where
T
:
Combineable
<
'tcx
>
fn
regions
(
&
mut
self
,
a
:
ty
::
Region
,
_
:
ty
::
Region
)
->
RelateResult
<
'tcx
,
ty
::
Region
>
{
Ok
(
a
)
}
fn
binders
<
T
>
(
&
mut
self
,
a
:
&
ty
::
Binder
<
T
>
,
b
:
&
ty
::
Binder
<
T
>
)
->
RelateResult
<
'tcx
,
ty
::
Binder
<
T
>>
where
T
:
Relate
<
'a
,
'tcx
>
{
let
a1
=
ty
::
erase_late_bound_regions
(
self
.tcx
(),
a
);
let
b1
=
ty
::
erase_late_bound_regions
(
self
.tcx
(),
b
);
let
c
=
try!
(
Combineable
::
combine
(
self
,
&
a1
,
&
b1
));
let
c
=
try!
(
self
.relate
(
&
a1
,
&
b1
));
Ok
(
ty
::
Binder
(
c
))
}
}
src/librustc/middle/infer/combine.rs
浏览文件 @
8403b82d
此差异已折叠。
点击以展开。
src/librustc/middle/infer/equate.rs
浏览文件 @
8403b82d
...
...
@@ -8,51 +8,43 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
super
::
combine
::{
self
,
CombineFields
};
use
super
::
higher_ranked
::
HigherRankedRelations
;
use
super
::{
Subtype
};
use
super
::
type_variable
::{
EqTo
};
use
middle
::
ty
::{
self
,
Ty
};
use
middle
::
ty
::
TyVar
;
use
middle
::
infer
::
combine
::
*
;
use
middle
::
infer
::
CombineResult
;
use
middle
::
infer
::
Subtype
;
use
middle
::
infer
::
type_variable
::
EqTo
;
use
util
::
ppaux
::
Repr
;
use
middle
::
ty_relate
::{
Relate
,
RelateResult
,
TypeRelation
};
use
util
::
ppaux
::{
Repr
};
pub
struct
Equate
<
'
f
,
'tcx
:
'f
>
{
fields
:
CombineFields
<
'
f
,
'tcx
>
pub
struct
Equate
<
'
a
,
'tcx
:
'a
>
{
fields
:
CombineFields
<
'
a
,
'tcx
>
}
#[allow(non_snake_case)]
pub
fn
Equate
<
'f
,
'tcx
>
(
cf
:
CombineFields
<
'f
,
'tcx
>
)
->
Equate
<
'f
,
'tcx
>
{
Equate
{
fields
:
cf
}
impl
<
'a
,
'tcx
>
Equate
<
'a
,
'tcx
>
{
pub
fn
new
(
fields
:
CombineFields
<
'a
,
'tcx
>
)
->
Equate
<
'a
,
'tcx
>
{
Equate
{
fields
:
fields
}
}
}
impl
<
'f
,
'tcx
>
Combine
<
'tcx
>
for
Equate
<
'f
,
'tcx
>
{
fn
tag
(
&
self
)
->
String
{
"Equate"
.to_string
()
}
fn
fields
<
'a
>
(
&
'a
self
)
->
&
'a
CombineFields
<
'a
,
'tcx
>
{
&
self
.fields
}
impl
<
'a
,
'tcx
>
TypeRelation
<
'a
,
'tcx
>
for
Equate
<
'a
,
'tcx
>
{
fn
tag
(
&
self
)
->
&
'static
str
{
"Equate"
}
fn
tys_with_variance
(
&
self
,
_
:
ty
::
Variance
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
CombineResult
<
'tcx
,
Ty
<
'tcx
>>
{
// Once we're equating, it doesn't matter what the variance is.
self
.tys
(
a
,
b
)
}
fn
tcx
(
&
self
)
->
&
'a
ty
::
ctxt
<
'tcx
>
{
self
.fields
.tcx
()
}
fn
regions_with_variance
(
&
self
,
_
:
ty
::
Variance
,
a
:
ty
::
Region
,
b
:
ty
::
Region
)
->
CombineResult
<
'tcx
,
ty
::
Region
>
{
// Once we're equating, it doesn't matter what the variance is.
self
.regions
(
a
,
b
)
}
fn
a_is_expected
(
&
self
)
->
bool
{
self
.fields.a_is_expected
}
fn
re
gions
(
&
self
,
a
:
ty
::
Region
,
b
:
ty
::
Region
)
->
CombineResult
<
'tcx
,
ty
::
Region
>
{
debug!
(
"{}.regions({}, {})"
,
self
.tag
()
,
a
.repr
(
self
.fields.infcx.tcx
),
b
.repr
(
self
.fields.infcx.tcx
));
self
.infcx
()
.region_vars
.make_eqregion
(
Subtype
(
self
.trace
()),
a
,
b
);
Ok
(
a
)
fn
re
late_with_variance
<
T
:
Relate
<
'a
,
'tcx
>>
(
&
mut
self
,
_
:
ty
::
Variance
,
a
:
&
T
,
b
:
&
T
)
->
RelateResult
<
'tcx
,
T
>
{
self
.relate
(
a
,
b
)
}
fn
tys
(
&
self
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
Combin
eResult
<
'tcx
,
Ty
<
'tcx
>>
{
fn
tys
(
&
mut
self
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
Relat
eResult
<
'tcx
,
Ty
<
'tcx
>>
{
debug!
(
"{}.tys({}, {})"
,
self
.tag
(),
a
.repr
(
self
.fields.infcx.tcx
),
b
.repr
(
self
.fields.infcx.tcx
));
if
a
==
b
{
return
Ok
(
a
);
}
...
...
@@ -77,15 +69,26 @@ fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CombineResult<'tcx, Ty<'tcx>> {
}
_
=>
{
super_tys
(
self
,
a
,
b
)
combine
::
super_combine_tys
(
self
.fields.infcx
,
self
,
a
,
b
)
}
}
}
fn
binders
<
T
>
(
&
self
,
a
:
&
ty
::
Binder
<
T
>
,
b
:
&
ty
::
Binder
<
T
>
)
->
CombineResult
<
'tcx
,
ty
::
Binder
<
T
>>
where
T
:
Combineable
<
'tcx
>
fn
regions
(
&
mut
self
,
a
:
ty
::
Region
,
b
:
ty
::
Region
)
->
RelateResult
<
'tcx
,
ty
::
Region
>
{
debug!
(
"{}.regions({}, {})"
,
self
.tag
(),
a
.repr
(
self
.fields.infcx.tcx
),
b
.repr
(
self
.fields.infcx.tcx
));
let
origin
=
Subtype
(
self
.fields.trace
.clone
());
self
.fields.infcx.region_vars
.make_eqregion
(
origin
,
a
,
b
);
Ok
(
a
)
}
fn
binders
<
T
>
(
&
mut
self
,
a
:
&
ty
::
Binder
<
T
>
,
b
:
&
ty
::
Binder
<
T
>
)
->
RelateResult
<
'tcx
,
ty
::
Binder
<
T
>>
where
T
:
Relate
<
'a
,
'tcx
>
{
try!
(
self
.
sub
()
.binders
(
a
,
b
));
self
.
sub
()
.binders
(
b
,
a
)
try!
(
self
.
fields
.higher_ranked_sub
(
a
,
b
));
self
.
fields
.higher_ranked_sub
(
b
,
a
)
}
}
src/librustc/middle/infer/glb.rs
浏览文件 @
8403b82d
...
...
@@ -8,67 +8,79 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
super
::
combine
::
*
;
use
super
::
lattice
::
*
;
use
super
::
combine
::
CombineFields
;
use
super
::
higher_ranked
::
HigherRankedRelations
;
use
super
::
CombineResult
;
use
super
::
InferCtxt
;
use
super
::
lattice
::{
self
,
LatticeDir
};
use
super
::
Subtype
;
use
middle
::
ty
::{
self
,
Ty
};
use
middle
::
ty_relate
::{
Relate
,
RelateResult
,
TypeRelation
};
use
util
::
ppaux
::
Repr
;
/// "Greatest lower bound" (common subtype)
pub
struct
Glb
<
'
f
,
'tcx
:
'f
>
{
fields
:
CombineFields
<
'
f
,
'tcx
>
pub
struct
Glb
<
'
a
,
'tcx
:
'a
>
{
fields
:
CombineFields
<
'
a
,
'tcx
>
}
#[allow(non_snake_case)]
pub
fn
Glb
<
'f
,
'tcx
>
(
cf
:
CombineFields
<
'f
,
'tcx
>
)
->
Glb
<
'f
,
'tcx
>
{
Glb
{
fields
:
cf
}
impl
<
'a
,
'tcx
>
Glb
<
'a
,
'tcx
>
{
pub
fn
new
(
fields
:
CombineFields
<
'a
,
'tcx
>
)
->
Glb
<
'a
,
'tcx
>
{
Glb
{
fields
:
fields
}
}
}
impl
<
'f
,
'tcx
>
Combine
<
'tcx
>
for
Glb
<
'f
,
'tcx
>
{
fn
tag
(
&
self
)
->
String
{
"Glb"
.to_string
()
}
fn
fields
<
'a
>
(
&
'a
self
)
->
&
'a
CombineFields
<
'a
,
'tcx
>
{
&
self
.fields
}
impl
<
'a
,
'tcx
>
TypeRelation
<
'a
,
'tcx
>
for
Glb
<
'a
,
'tcx
>
{
fn
tag
(
&
self
)
->
&
'static
str
{
"Glb"
}
fn
tcx
(
&
self
)
->
&
'a
ty
::
ctxt
<
'tcx
>
{
self
.fields
.tcx
()
}
fn
a_is_expected
(
&
self
)
->
bool
{
self
.fields.a_is_expected
}
fn
tys_with_variance
(
&
self
,
v
:
ty
::
Variance
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
CombineResult
<
'tcx
,
Ty
<
'tcx
>>
fn
relate_with_variance
<
T
:
Relate
<
'a
,
'tcx
>>
(
&
mut
self
,
variance
:
ty
::
Variance
,
a
:
&
T
,
b
:
&
T
)
->
RelateResult
<
'tcx
,
T
>
{
match
v
{
ty
::
Invariant
=>
self
.
equate
()
.tys
(
a
,
b
),
ty
::
Covariant
=>
self
.
tys
(
a
,
b
),
ty
::
Bivariant
=>
self
.
bivariate
()
.tys
(
a
,
b
),
ty
::
Contravariant
=>
self
.
lub
()
.tys
(
a
,
b
),
match
v
ariance
{
ty
::
Invariant
=>
self
.
fields
.equate
()
.relate
(
a
,
b
),
ty
::
Covariant
=>
self
.
relate
(
a
,
b
),
ty
::
Bivariant
=>
self
.
fields
.bivariate
()
.relate
(
a
,
b
),
ty
::
Contravariant
=>
self
.
fields
.lub
()
.relate
(
a
,
b
),
}
}
fn
regions_with_variance
(
&
self
,
v
:
ty
::
Variance
,
a
:
ty
::
Region
,
b
:
ty
::
Region
)
->
CombineResult
<
'tcx
,
ty
::
Region
>
{
match
v
{
ty
::
Invariant
=>
self
.equate
()
.regions
(
a
,
b
),
ty
::
Covariant
=>
self
.regions
(
a
,
b
),
ty
::
Bivariant
=>
self
.bivariate
()
.regions
(
a
,
b
),
ty
::
Contravariant
=>
self
.lub
()
.regions
(
a
,
b
),
}
fn
tys
(
&
mut
self
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
RelateResult
<
'tcx
,
Ty
<
'tcx
>>
{
lattice
::
super_lattice_tys
(
self
,
a
,
b
)
}
fn
regions
(
&
self
,
a
:
ty
::
Region
,
b
:
ty
::
Region
)
->
Combin
eResult
<
'tcx
,
ty
::
Region
>
{
fn
regions
(
&
mut
self
,
a
:
ty
::
Region
,
b
:
ty
::
Region
)
->
Relat
eResult
<
'tcx
,
ty
::
Region
>
{
debug!
(
"{}.regions({}, {})"
,
self
.tag
(),
a
.repr
(
self
.fields.infcx.tcx
),
b
.repr
(
self
.fields.infcx.tcx
));
Ok
(
self
.fields.infcx.region_vars
.glb_regions
(
Subtype
(
self
.trace
()),
a
,
b
))
let
origin
=
Subtype
(
self
.fields.trace
.clone
());
Ok
(
self
.fields.infcx.region_vars
.glb_regions
(
origin
,
a
,
b
))
}
fn
tys
(
&
self
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
CombineResult
<
'tcx
,
Ty
<
'tcx
>>
{
super_lattice_tys
(
self
,
a
,
b
)
fn
binders
<
T
>
(
&
mut
self
,
a
:
&
ty
::
Binder
<
T
>
,
b
:
&
ty
::
Binder
<
T
>
)
->
RelateResult
<
'tcx
,
ty
::
Binder
<
T
>>
where
T
:
Relate
<
'a
,
'tcx
>
{
self
.fields
.higher_ranked_glb
(
a
,
b
)
}
}
fn
binders
<
T
>
(
&
self
,
a
:
&
ty
::
Binder
<
T
>
,
b
:
&
ty
::
Binder
<
T
>
)
->
CombineResult
<
'tcx
,
ty
::
Binder
<
T
>>
where
T
:
Combineable
<
'tcx
>
{
self
.higher_ranked_glb
(
a
,
b
)
impl
<
'a
,
'tcx
>
LatticeDir
<
'a
,
'tcx
>
for
Glb
<
'a
,
'tcx
>
{
fn
infcx
(
&
self
)
->
&
'a
InferCtxt
<
'a
,
'tcx
>
{
self
.fields.infcx
}
fn
relate_bound
(
&
self
,
v
:
Ty
<
'tcx
>
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
RelateResult
<
'tcx
,
()
>
{
let
mut
sub
=
self
.fields
.sub
();
try!
(
sub
.relate
(
&
v
,
&
a
));
try!
(
sub
.relate
(
&
v
,
&
b
));
Ok
(())
}
}
src/librustc/middle/infer/higher_ranked/mod.rs
浏览文件 @
8403b82d
...
...
@@ -11,25 +11,26 @@
//! Helper routines for higher-ranked things. See the `doc` module at
//! the end of the file for details.
use
super
::{
CombinedSnapshot
,
CombineResult
,
InferCtxt
,
HigherRankedType
,
SkolemizationMap
};
use
super
::
combine
::
{
Combine
,
Combineable
}
;
use
super
::{
CombinedSnapshot
,
InferCtxt
,
HigherRankedType
,
SkolemizationMap
};
use
super
::
combine
::
CombineFields
;
use
middle
::
subst
;
use
middle
::
ty
::{
self
,
Binder
};
use
middle
::
ty_fold
::{
self
,
TypeFoldable
};
use
middle
::
ty_relate
::{
Relate
,
RelateResult
,
TypeRelation
};
use
syntax
::
codemap
::
Span
;
use
util
::
nodemap
::{
FnvHashMap
,
FnvHashSet
};
use
util
::
ppaux
::
Repr
;
pub
trait
HigherRankedRelations
<
'tcx
>
{
fn
higher_ranked_sub
<
T
>
(
&
self
,
a
:
&
Binder
<
T
>
,
b
:
&
Binder
<
T
>
)
->
Combin
eResult
<
'tcx
,
Binder
<
T
>>
where
T
:
Combineable
<
'tcx
>
;
pub
trait
HigherRankedRelations
<
'
a
,
'
tcx
>
{
fn
higher_ranked_sub
<
T
>
(
&
self
,
a
:
&
Binder
<
T
>
,
b
:
&
Binder
<
T
>
)
->
Relat
eResult
<
'tcx
,
Binder
<
T
>>
where
T
:
Relate
<
'a
,
'tcx
>
;
fn
higher_ranked_lub
<
T
>
(
&
self
,
a
:
&
Binder
<
T
>
,
b
:
&
Binder
<
T
>
)
->
Combin
eResult
<
'tcx
,
Binder
<
T
>>
where
T
:
Combineable
<
'tcx
>
;
fn
higher_ranked_lub
<
T
>
(
&
self
,
a
:
&
Binder
<
T
>
,
b
:
&
Binder
<
T
>
)
->
Relat
eResult
<
'tcx
,
Binder
<
T
>>
where
T
:
Relate
<
'a
,
'tcx
>
;
fn
higher_ranked_glb
<
T
>
(
&
self
,
a
:
&
Binder
<
T
>
,
b
:
&
Binder
<
T
>
)
->
Combin
eResult
<
'tcx
,
Binder
<
T
>>
where
T
:
Combineable
<
'tcx
>
;
fn
higher_ranked_glb
<
T
>
(
&
self
,
a
:
&
Binder
<
T
>
,
b
:
&
Binder
<
T
>
)
->
Relat
eResult
<
'tcx
,
Binder
<
T
>>
where
T
:
Relate
<
'a
,
'tcx
>
;
}
trait
InferCtxtExt
{
...
...
@@ -40,15 +41,15 @@ fn region_vars_confined_to_snapshot(&self,
->
Vec
<
ty
::
RegionVid
>
;
}
impl
<
'tcx
,
C
>
HigherRankedRelations
<
'tcx
>
for
C
where
C
:
Combine
<
'tcx
>
{
impl
<
'a
,
'tcx
>
HigherRankedRelations
<
'a
,
'tcx
>
for
CombineFields
<
'a
,
'tcx
>
{
fn
higher_ranked_sub
<
T
>
(
&
self
,
a
:
&
Binder
<
T
>
,
b
:
&
Binder
<
T
>
)
->
Combin
eResult
<
'tcx
,
Binder
<
T
>>
where
T
:
Combineable
<
'tcx
>
->
Relat
eResult
<
'tcx
,
Binder
<
T
>>
where
T
:
Relate
<
'a
,
'tcx
>
{
let
tcx
=
self
.infcx.tcx
;
debug!
(
"higher_ranked_sub(a={}, b={})"
,
a
.repr
(
self
.tcx
()),
b
.repr
(
self
.tcx
()
));
a
.repr
(
tcx
),
b
.repr
(
tcx
));
// Rather than checking the subtype relationship between `a` and `b`
// as-is, we need to do some extra work here in order to make sure
...
...
@@ -60,32 +61,32 @@ fn higher_ranked_sub<T>(&self, a: &Binder<T>, b: &Binder<T>)
// Start a snapshot so we can examine "all bindings that were
// created as part of this type comparison".
return
self
.infcx
()
.commit_if_ok
(|
snapshot
|
{
return
self
.infcx
.commit_if_ok
(|
snapshot
|
{
// First, we instantiate each bound region in the subtype with a fresh
// region variable.
let
(
a_prime
,
_
)
=
self
.infcx
()
.replace_late_bound_regions_with_fresh_var
(
self
.trace
()
.origin
.span
(),
self
.infcx
.replace_late_bound_regions_with_fresh_var
(
self
.trace.origin
.span
(),
HigherRankedType
,
a
);
// Second, we instantiate each bound region in the supertype with a
// fresh concrete region.
let
(
b_prime
,
skol_map
)
=
self
.infcx
()
.skolemize_late_bound_regions
(
b
,
snapshot
);
self
.infcx
.skolemize_late_bound_regions
(
b
,
snapshot
);
debug!
(
"a_prime={}"
,
a_prime
.repr
(
self
.tcx
()
));
debug!
(
"b_prime={}"
,
b_prime
.repr
(
self
.tcx
()
));
debug!
(
"a_prime={}"
,
a_prime
.repr
(
tcx
));
debug!
(
"b_prime={}"
,
b_prime
.repr
(
tcx
));
// Compare types now that bound regions have been replaced.
let
result
=
try!
(
Combineable
::
combine
(
self
,
&
a_prime
,
&
b_prime
));
let
result
=
try!
(
self
.sub
()
.relate
(
&
a_prime
,
&
b_prime
));
// Presuming type comparison succeeds, we need to check
// that the skolemized regions do not "leak".
match
leak_check
(
self
.infcx
()
,
&
skol_map
,
snapshot
)
{
match
leak_check
(
self
.infcx
,
&
skol_map
,
snapshot
)
{
Ok
(())
=>
{
}
Err
((
skol_br
,
tainted_region
))
=>
{
if
self
.a_is_expected
()
{
if
self
.a_is_expected
{
debug!
(
"Not as polymorphic!"
);
return
Err
(
ty
::
terr_regions_insufficiently_polymorphic
(
skol_br
,
tainted_region
));
...
...
@@ -98,42 +99,42 @@ fn higher_ranked_sub<T>(&self, a: &Binder<T>, b: &Binder<T>)
}
debug!
(
"higher_ranked_sub: OK result={}"
,
result
.repr
(
self
.tcx
()
));
result
.repr
(
tcx
));
Ok
(
ty
::
Binder
(
result
))
});
}
fn
higher_ranked_lub
<
T
>
(
&
self
,
a
:
&
Binder
<
T
>
,
b
:
&
Binder
<
T
>
)
->
Combin
eResult
<
'tcx
,
Binder
<
T
>>
where
T
:
Combineable
<
'tcx
>
fn
higher_ranked_lub
<
T
>
(
&
self
,
a
:
&
Binder
<
T
>
,
b
:
&
Binder
<
T
>
)
->
Relat
eResult
<
'tcx
,
Binder
<
T
>>
where
T
:
Relate
<
'a
,
'tcx
>
{
// Start a snapshot so we can examine "all bindings that were
// created as part of this type comparison".
return
self
.infcx
()
.commit_if_ok
(|
snapshot
|
{
return
self
.infcx
.commit_if_ok
(|
snapshot
|
{
// Instantiate each bound region with a fresh region variable.
let
span
=
self
.trace
()
.origin
.span
();
let
span
=
self
.trace.origin
.span
();
let
(
a_with_fresh
,
a_map
)
=
self
.infcx
()
.replace_late_bound_regions_with_fresh_var
(
self
.infcx
.replace_late_bound_regions_with_fresh_var
(
span
,
HigherRankedType
,
a
);
let
(
b_with_fresh
,
_
)
=
self
.infcx
()
.replace_late_bound_regions_with_fresh_var
(
self
.infcx
.replace_late_bound_regions_with_fresh_var
(
span
,
HigherRankedType
,
b
);
// Collect constraints.
let
result0
=
try!
(
Combineable
::
combine
(
self
,
&
a_with_fresh
,
&
b_with_fresh
));
try!
(
self
.lub
()
.relate
(
&
a_with_fresh
,
&
b_with_fresh
));
let
result0
=
self
.infcx
()
.resolve_type_vars_if_possible
(
&
result0
);
self
.infcx
.resolve_type_vars_if_possible
(
&
result0
);
debug!
(
"lub result0 = {}"
,
result0
.repr
(
self
.tcx
()));
// Generalize the regions appearing in result0 if possible
let
new_vars
=
self
.infcx
()
.region_vars_confined_to_snapshot
(
snapshot
);
let
span
=
self
.trace
()
.origin
.span
();
let
new_vars
=
self
.infcx
.region_vars_confined_to_snapshot
(
snapshot
);
let
span
=
self
.trace.origin
.span
();
let
result1
=
fold_regions_in
(
self
.tcx
(),
&
result0
,
|
r
,
debruijn
|
generalize_region
(
self
.infcx
()
,
span
,
snapshot
,
debruijn
,
|
r
,
debruijn
|
generalize_region
(
self
.infcx
,
span
,
snapshot
,
debruijn
,
&
new_vars
,
&
a_map
,
r
));
debug!
(
"lub({},{}) = {}"
,
...
...
@@ -194,40 +195,40 @@ fn generalize_region(infcx: &InferCtxt,
}
}
fn
higher_ranked_glb
<
T
>
(
&
self
,
a
:
&
Binder
<
T
>
,
b
:
&
Binder
<
T
>
)
->
Combin
eResult
<
'tcx
,
Binder
<
T
>>
where
T
:
Combineable
<
'tcx
>
fn
higher_ranked_glb
<
T
>
(
&
self
,
a
:
&
Binder
<
T
>
,
b
:
&
Binder
<
T
>
)
->
Relat
eResult
<
'tcx
,
Binder
<
T
>>
where
T
:
Relate
<
'a
,
'tcx
>
{
debug!
(
"
{}.
higher_ranked_glb({}, {})"
,
self
.tag
(),
a
.repr
(
self
.tcx
()),
b
.repr
(
self
.tcx
()));
debug!
(
"higher_ranked_glb({}, {})"
,
a
.repr
(
self
.tcx
()),
b
.repr
(
self
.tcx
()));
// Make a snapshot so we can examine "all bindings that were
// created as part of this type comparison".
return
self
.infcx
()
.commit_if_ok
(|
snapshot
|
{
return
self
.infcx
.commit_if_ok
(|
snapshot
|
{
// Instantiate each bound region with a fresh region variable.
let
(
a_with_fresh
,
a_map
)
=
self
.infcx
()
.replace_late_bound_regions_with_fresh_var
(
self
.trace
()
.origin
.span
(),
HigherRankedType
,
a
);
self
.infcx
.replace_late_bound_regions_with_fresh_var
(
self
.trace.origin
.span
(),
HigherRankedType
,
a
);
let
(
b_with_fresh
,
b_map
)
=
self
.infcx
()
.replace_late_bound_regions_with_fresh_var
(
self
.trace
()
.origin
.span
(),
HigherRankedType
,
b
);
self
.infcx
.replace_late_bound_regions_with_fresh_var
(
self
.trace.origin
.span
(),
HigherRankedType
,
b
);
let
a_vars
=
var_ids
(
self
,
&
a_map
);
let
b_vars
=
var_ids
(
self
,
&
b_map
);
// Collect constraints.
let
result0
=
try!
(
Combineable
::
combine
(
self
,
&
a_with_fresh
,
&
b_with_fresh
));
try!
(
self
.glb
()
.relate
(
&
a_with_fresh
,
&
b_with_fresh
));
let
result0
=
self
.infcx
()
.resolve_type_vars_if_possible
(
&
result0
);
self
.infcx
.resolve_type_vars_if_possible
(
&
result0
);
debug!
(
"glb result0 = {}"
,
result0
.repr
(
self
.tcx
()));
// Generalize the regions appearing in result0 if possible
let
new_vars
=
self
.infcx
()
.region_vars_confined_to_snapshot
(
snapshot
);
let
span
=
self
.trace
()
.origin
.span
();
let
new_vars
=
self
.infcx
.region_vars_confined_to_snapshot
(
snapshot
);
let
span
=
self
.trace.origin
.span
();
let
result1
=
fold_regions_in
(
self
.tcx
(),
&
result0
,
|
r
,
debruijn
|
generalize_region
(
self
.infcx
()
,
span
,
snapshot
,
debruijn
,
|
r
,
debruijn
|
generalize_region
(
self
.infcx
,
span
,
snapshot
,
debruijn
,
&
new_vars
,
&
a_map
,
&
a_vars
,
&
b_vars
,
r
));
...
...
@@ -332,17 +333,19 @@ fn fresh_bound_variable(infcx: &InferCtxt, debruijn: ty::DebruijnIndex) -> ty::R
}
}
fn
var_ids
<
'tcx
,
T
:
Combine
<
'tcx
>>
(
combiner
:
&
T
,
map
:
&
FnvHashMap
<
ty
::
BoundRegion
,
ty
::
Region
>
)
->
Vec
<
ty
::
RegionVid
>
{
map
.iter
()
.map
(|(
_
,
r
)|
match
*
r
{
ty
::
ReInfer
(
ty
::
ReVar
(
r
))
=>
{
r
}
r
=>
{
combiner
.infcx
()
.tcx.sess
.span_bug
(
combiner
.trace
()
.origin
.span
(),
&
format!
(
"found non-region-vid: {:?}"
,
r
));
}
})
.collect
()
fn
var_ids
<
'a
,
'tcx
>
(
fields
:
&
CombineFields
<
'a
,
'tcx
>
,
map
:
&
FnvHashMap
<
ty
::
BoundRegion
,
ty
::
Region
>
)
->
Vec
<
ty
::
RegionVid
>
{
map
.iter
()
.map
(|(
_
,
r
)|
match
*
r
{
ty
::
ReInfer
(
ty
::
ReVar
(
r
))
=>
{
r
}
r
=>
{
fields
.tcx
()
.sess
.span_bug
(
fields
.trace.origin
.span
(),
&
format!
(
"found non-region-vid: {:?}"
,
r
));
}
})
.collect
()
}
fn
is_var_in_set
(
new_vars
:
&
[
ty
::
RegionVid
],
r
:
ty
::
Region
)
->
bool
{
...
...
@@ -356,8 +359,8 @@ fn fold_regions_in<'tcx, T, F>(tcx: &ty::ctxt<'tcx>,
unbound_value
:
&
T
,
mut
fldr
:
F
)
->
T
where
T
:
Combine
able
<
'tcx
>
,
F
:
FnMut
(
ty
::
Region
,
ty
::
DebruijnIndex
)
->
ty
::
Region
,
where
T
:
TypeFold
able
<
'tcx
>
,
F
:
FnMut
(
ty
::
Region
,
ty
::
DebruijnIndex
)
->
ty
::
Region
,
{
unbound_value
.fold_with
(
&
mut
ty_fold
::
RegionFolder
::
new
(
tcx
,
&
mut
|
region
,
current_depth
|
{
// we should only be encountering "escaping" late-bound regions here,
...
...
src/librustc/middle/infer/lattice.rs
浏览文件 @
8403b82d
...
...
@@ -29,48 +29,32 @@
//! over a `LatticeValue`, which is a value defined with respect to
//! a lattice.
use
super
::
*
;
use
super
::
combine
::
*
;
use
super
::
glb
::
Glb
;
use
super
::
lub
::
Lub
;
use
super
::
combine
;
use
super
::
InferCtxt
;
use
middle
::
ty
::
TyVar
;
use
middle
::
ty
::{
self
,
Ty
};
use
middle
::
ty_relate
::{
RelateResult
,
TypeRelation
};
use
util
::
ppaux
::
Repr
;
pub
trait
LatticeDir
<
'tcx
>
{
pub
trait
LatticeDir
<
'f
,
'tcx
>
:
TypeRelation
<
'f
,
'tcx
>
{
fn
infcx
(
&
self
)
->
&
'f
InferCtxt
<
'f
,
'tcx
>
;
// Relates the type `v` to `a` and `b` such that `v` represents
// the LUB/GLB of `a` and `b` as appropriate.
fn
relate_bound
(
&
self
,
v
:
Ty
<
'tcx
>
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
CombineResult
<
'tcx
,
()
>
;
}
impl
<
'a
,
'tcx
>
LatticeDir
<
'tcx
>
for
Lub
<
'a
,
'tcx
>
{
fn
relate_bound
(
&
self
,
v
:
Ty
<
'tcx
>
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
CombineResult
<
'tcx
,
()
>
{
let
sub
=
self
.sub
();
try!
(
sub
.tys
(
a
,
v
));
try!
(
sub
.tys
(
b
,
v
));
Ok
(())
}
}
impl
<
'a
,
'tcx
>
LatticeDir
<
'tcx
>
for
Glb
<
'a
,
'tcx
>
{
fn
relate_bound
(
&
self
,
v
:
Ty
<
'tcx
>
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
CombineResult
<
'tcx
,
()
>
{
let
sub
=
self
.sub
();
try!
(
sub
.tys
(
v
,
a
));
try!
(
sub
.tys
(
v
,
b
));
Ok
(())
}
fn
relate_bound
(
&
self
,
v
:
Ty
<
'tcx
>
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
RelateResult
<
'tcx
,
()
>
;
}
pub
fn
super_lattice_tys
<
'tcx
,
L
:
LatticeDir
<
'tcx
>+
Combine
<
'tcx
>>
(
this
:
&
L
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
CombineResult
<
'tcx
,
Ty
<
'tcx
>>
pub
fn
super_lattice_tys
<
'a
,
'tcx
,
L
:
LatticeDir
<
'a
,
'tcx
>>
(
this
:
&
mut
L
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
RelateResult
<
'tcx
,
Ty
<
'tcx
>>
where
'tcx
:
'a
{
debug!
(
"{}.lattice_tys({}, {})"
,
this
.tag
(),
a
.repr
(
this
.
infcx
()
.tcx
),
b
.repr
(
this
.
infcx
()
.tcx
));
a
.repr
(
this
.
tcx
()
),
b
.repr
(
this
.
tcx
()
));
if
a
==
b
{
return
Ok
(
a
);
...
...
@@ -95,7 +79,7 @@ pub fn super_lattice_tys<'tcx, L:LatticeDir<'tcx>+Combine<'tcx>>(this: &L,
}
_
=>
{
super_tys
(
this
,
a
,
b
)
combine
::
super_combine_tys
(
this
.infcx
(),
this
,
a
,
b
)
}
}
}
src/librustc/middle/infer/lub.rs
浏览文件 @
8403b82d
...
...
@@ -8,67 +8,80 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
super
::
combine
::
*
;
use
super
::
combine
::
CombineFields
;
use
super
::
higher_ranked
::
HigherRankedRelations
;
use
super
::
lattice
::
*
;
use
super
::
CombineResult
;
use
super
::
InferCtxt
;
use
super
::
lattice
::{
self
,
LatticeDir
}
;
use
super
::
Subtype
;
use
middle
::
ty
::{
self
,
Ty
};
use
middle
::
ty_relate
::{
Relate
,
RelateResult
,
TypeRelation
};
use
util
::
ppaux
::
Repr
;
/// "Least upper bound" (common supertype)
pub
struct
Lub
<
'
f
,
'tcx
:
'f
>
{
fields
:
CombineFields
<
'
f
,
'tcx
>
pub
struct
Lub
<
'
a
,
'tcx
:
'a
>
{
fields
:
CombineFields
<
'
a
,
'tcx
>
}
#[allow(non_snake_case)]
pub
fn
Lub
<
'f
,
'tcx
>
(
cf
:
CombineFields
<
'f
,
'tcx
>
)
->
Lub
<
'f
,
'tcx
>
{
Lub
{
fields
:
cf
}
impl
<
'a
,
'tcx
>
Lub
<
'a
,
'tcx
>
{
pub
fn
new
(
fields
:
CombineFields
<
'a
,
'tcx
>
)
->
Lub
<
'a
,
'tcx
>
{
Lub
{
fields
:
fields
}
}
}
impl
<
'f
,
'tcx
>
Combine
<
'tcx
>
for
Lub
<
'f
,
'tcx
>
{
fn
tag
(
&
self
)
->
String
{
"Lub"
.to_string
()
}
fn
fields
<
'a
>
(
&
'a
self
)
->
&
'a
CombineFields
<
'a
,
'tcx
>
{
&
self
.fields
}
impl
<
'a
,
'tcx
>
TypeRelation
<
'a
,
'tcx
>
for
Lub
<
'a
,
'tcx
>
{
fn
tag
(
&
self
)
->
&
'static
str
{
"Lub"
}
fn
tcx
(
&
self
)
->
&
'a
ty
::
ctxt
<
'tcx
>
{
self
.fields
.tcx
()
}
fn
a_is_expected
(
&
self
)
->
bool
{
self
.fields.a_is_expected
}
fn
tys_with_variance
(
&
self
,
v
:
ty
::
Variance
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
CombineResult
<
'tcx
,
Ty
<
'tcx
>>
fn
relate_with_variance
<
T
:
Relate
<
'a
,
'tcx
>>
(
&
mut
self
,
variance
:
ty
::
Variance
,
a
:
&
T
,
b
:
&
T
)
->
RelateResult
<
'tcx
,
T
>
{
match
v
{
ty
::
Invariant
=>
self
.
equate
()
.tys
(
a
,
b
),
ty
::
Covariant
=>
self
.
tys
(
a
,
b
),
ty
::
Bivariant
=>
self
.
bivariate
()
.tys
(
a
,
b
),
ty
::
Contravariant
=>
self
.
glb
()
.tys
(
a
,
b
),
match
v
ariance
{
ty
::
Invariant
=>
self
.
fields
.equate
()
.relate
(
a
,
b
),
ty
::
Covariant
=>
self
.
relate
(
a
,
b
),
ty
::
Bivariant
=>
self
.
fields
.bivariate
()
.relate
(
a
,
b
),
ty
::
Contravariant
=>
self
.
fields
.glb
()
.relate
(
a
,
b
),
}
}
fn
regions_with_variance
(
&
self
,
v
:
ty
::
Variance
,
a
:
ty
::
Region
,
b
:
ty
::
Region
)
->
CombineResult
<
'tcx
,
ty
::
Region
>
{
match
v
{
ty
::
Invariant
=>
self
.equate
()
.regions
(
a
,
b
),
ty
::
Covariant
=>
self
.regions
(
a
,
b
),
ty
::
Bivariant
=>
self
.bivariate
()
.regions
(
a
,
b
),
ty
::
Contravariant
=>
self
.glb
()
.regions
(
a
,
b
),
}
fn
tys
(
&
mut
self
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
RelateResult
<
'tcx
,
Ty
<
'tcx
>>
{
lattice
::
super_lattice_tys
(
self
,
a
,
b
)
}
fn
regions
(
&
self
,
a
:
ty
::
Region
,
b
:
ty
::
Region
)
->
Combin
eResult
<
'tcx
,
ty
::
Region
>
{
fn
regions
(
&
mut
self
,
a
:
ty
::
Region
,
b
:
ty
::
Region
)
->
Relat
eResult
<
'tcx
,
ty
::
Region
>
{
debug!
(
"{}.regions({}, {})"
,
self
.tag
(),
a
.repr
(
self
.tcx
()),
b
.repr
(
self
.tcx
()));
Ok
(
self
.infcx
()
.region_vars
.lub_regions
(
Subtype
(
self
.trace
()),
a
,
b
))
let
origin
=
Subtype
(
self
.fields.trace
.clone
());
Ok
(
self
.fields.infcx.region_vars
.lub_regions
(
origin
,
a
,
b
))
}
fn
tys
(
&
self
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
CombineResult
<
'tcx
,
Ty
<
'tcx
>>
{
super_lattice_tys
(
self
,
a
,
b
)
fn
binders
<
T
>
(
&
mut
self
,
a
:
&
ty
::
Binder
<
T
>
,
b
:
&
ty
::
Binder
<
T
>
)
->
RelateResult
<
'tcx
,
ty
::
Binder
<
T
>>
where
T
:
Relate
<
'a
,
'tcx
>
{
self
.fields
.higher_ranked_lub
(
a
,
b
)
}
}
fn
binders
<
T
>
(
&
self
,
a
:
&
ty
::
Binder
<
T
>
,
b
:
&
ty
::
Binder
<
T
>
)
->
CombineResult
<
'tcx
,
ty
::
Binder
<
T
>>
where
T
:
Combineable
<
'tcx
>
{
self
.higher_ranked_lub
(
a
,
b
)
impl
<
'a
,
'tcx
>
LatticeDir
<
'a
,
'tcx
>
for
Lub
<
'a
,
'tcx
>
{
fn
infcx
(
&
self
)
->
&
'a
InferCtxt
<
'a
,
'tcx
>
{
self
.fields.infcx
}
fn
relate_bound
(
&
self
,
v
:
Ty
<
'tcx
>
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
RelateResult
<
'tcx
,
()
>
{
let
mut
sub
=
self
.fields
.sub
();
try!
(
sub
.relate
(
&
a
,
&
v
));
try!
(
sub
.relate
(
&
b
,
&
v
));
Ok
(())
}
}
src/librustc/middle/infer/mod.rs
浏览文件 @
8403b82d
...
...
@@ -28,7 +28,8 @@
use
middle
::
ty
::
replace_late_bound_regions
;
use
middle
::
ty
::{
self
,
Ty
};
use
middle
::
ty_fold
::{
TypeFolder
,
TypeFoldable
};
use
std
::
cell
::
RefCell
;
use
middle
::
ty_relate
::{
Relate
,
RelateResult
,
TypeRelation
};
use
std
::
cell
::{
RefCell
};
use
std
::
fmt
;
use
std
::
rc
::
Rc
;
use
syntax
::
ast
;
...
...
@@ -38,11 +39,8 @@
use
util
::
ppaux
::
ty_to_string
;
use
util
::
ppaux
::{
Repr
,
UserString
};
use
self
::
combine
::
{
Combine
,
Combineable
,
CombineFields
}
;
use
self
::
combine
::
CombineFields
;
use
self
::
region_inference
::{
RegionVarBindings
,
RegionSnapshot
};
use
self
::
equate
::
Equate
;
use
self
::
sub
::
Sub
;
use
self
::
lub
::
Lub
;
use
self
::
unify
::{
ToType
,
UnificationTable
};
use
self
::
error_reporting
::
ErrorReporting
;
...
...
@@ -62,9 +60,7 @@
pub
mod
unify
;
pub
type
Bound
<
T
>
=
Option
<
T
>
;
pub
type
CombineResult
<
'tcx
,
T
>
=
Result
<
T
,
ty
::
type_err
<
'tcx
>>
;
// "combine result"
pub
type
UnitResult
<
'tcx
>
=
CombineResult
<
'tcx
,
()
>
;
// "unify result"
pub
type
UnitResult
<
'tcx
>
=
RelateResult
<
'tcx
,
()
>
;
// "unify result"
pub
type
fres
<
T
>
=
Result
<
T
,
fixup_err
>
;
// "fixup result"
pub
struct
InferCtxt
<
'a
,
'tcx
:
'a
>
{
...
...
@@ -343,7 +339,7 @@ pub fn common_supertype<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
values
:
Types
(
expected_found
(
a_is_expected
,
a
,
b
))
};
let
result
=
cx
.commit_if_ok
(|
_
|
cx
.lub
(
a_is_expected
,
trace
.clone
())
.
tys
(
a
,
b
));
let
result
=
cx
.commit_if_ok
(|
_
|
cx
.lub
(
a_is_expected
,
trace
.clone
())
.
relate
(
&
a
,
&
b
));
match
result
{
Ok
(
t
)
=>
t
,
Err
(
ref
err
)
=>
{
...
...
@@ -374,11 +370,12 @@ pub fn can_mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
origin
:
Misc
(
codemap
::
DUMMY_SP
),
values
:
Types
(
expected_found
(
true
,
a
,
b
))
};
cx
.sub
(
true
,
trace
)
.
tys
(
a
,
b
)
.map
(|
_
|
())
cx
.sub
(
true
,
trace
)
.
relate
(
&
a
,
&
b
)
.map
(|
_
|
())
})
}
pub
fn
can_mk_eqty
<
'a
,
'tcx
>
(
cx
:
&
InferCtxt
<
'a
,
'tcx
>
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
UnitResult
<
'tcx
>
pub
fn
can_mk_eqty
<
'a
,
'tcx
>
(
cx
:
&
InferCtxt
<
'a
,
'tcx
>
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
UnitResult
<
'tcx
>
{
cx
.can_equate
(
&
a
,
&
b
)
}
...
...
@@ -473,26 +470,39 @@ pub fn type_is_unconstrained_numeric(&'a self, ty: Ty) -> UnconstrainedNumeric {
}
}
fn
combine_fields
<
'b
>
(
&
'b
self
,
a_is_expected
:
bool
,
trace
:
TypeTrace
<
'tcx
>
)
->
CombineFields
<
'b
,
'tcx
>
{
fn
combine_fields
(
&
'a
self
,
a_is_expected
:
bool
,
trace
:
TypeTrace
<
'tcx
>
)
->
CombineFields
<
'a
,
'tcx
>
{
CombineFields
{
infcx
:
self
,
a_is_expected
:
a_is_expected
,
trace
:
trace
}
}
fn
equate
<
'b
>
(
&
'b
self
,
a_is_expected
:
bool
,
trace
:
TypeTrace
<
'tcx
>
)
->
Equate
<
'b
,
'tcx
>
{
Equate
(
self
.combine_fields
(
a_is_expected
,
trace
))
// public so that it can be used from the rustc_driver unit tests
pub
fn
equate
(
&
'a
self
,
a_is_expected
:
bool
,
trace
:
TypeTrace
<
'tcx
>
)
->
equate
::
Equate
<
'a
,
'tcx
>
{
self
.combine_fields
(
a_is_expected
,
trace
)
.equate
()
}
fn
sub
<
'b
>
(
&
'b
self
,
a_is_expected
:
bool
,
trace
:
TypeTrace
<
'tcx
>
)
->
Sub
<
'b
,
'tcx
>
{
Sub
(
self
.combine_fields
(
a_is_expected
,
trace
))
// public so that it can be used from the rustc_driver unit tests
pub
fn
sub
(
&
'a
self
,
a_is_expected
:
bool
,
trace
:
TypeTrace
<
'tcx
>
)
->
sub
::
Sub
<
'a
,
'tcx
>
{
self
.combine_fields
(
a_is_expected
,
trace
)
.sub
()
}
fn
lub
<
'b
>
(
&
'b
self
,
a_is_expected
:
bool
,
trace
:
TypeTrace
<
'tcx
>
)
->
Lub
<
'b
,
'tcx
>
{
Lub
(
self
.combine_fields
(
a_is_expected
,
trace
))
// public so that it can be used from the rustc_driver unit tests
pub
fn
lub
(
&
'a
self
,
a_is_expected
:
bool
,
trace
:
TypeTrace
<
'tcx
>
)
->
lub
::
Lub
<
'a
,
'tcx
>
{
self
.combine_fields
(
a_is_expected
,
trace
)
.lub
()
}
// public so that it can be used from the rustc_driver unit tests
pub
fn
glb
(
&
'a
self
,
a_is_expected
:
bool
,
trace
:
TypeTrace
<
'tcx
>
)
->
glb
::
Glb
<
'a
,
'tcx
>
{
self
.combine_fields
(
a_is_expected
,
trace
)
.glb
()
}
fn
start_snapshot
(
&
self
)
->
CombinedSnapshot
{
...
...
@@ -631,7 +641,7 @@ pub fn sub_types(&self,
debug!
(
"sub_types({} <: {})"
,
a
.repr
(
self
.tcx
),
b
.repr
(
self
.tcx
));
self
.commit_if_ok
(|
_
|
{
let
trace
=
TypeTrace
::
types
(
origin
,
a_is_expected
,
a
,
b
);
self
.sub
(
a_is_expected
,
trace
)
.
tys
(
a
,
b
)
.map
(|
_
|
())
self
.sub
(
a_is_expected
,
trace
)
.
relate
(
&
a
,
&
b
)
.map
(|
_
|
())
})
}
...
...
@@ -644,7 +654,7 @@ pub fn eq_types(&self,
{
self
.commit_if_ok
(|
_
|
{
let
trace
=
TypeTrace
::
types
(
origin
,
a_is_expected
,
a
,
b
);
self
.equate
(
a_is_expected
,
trace
)
.
tys
(
a
,
b
)
.map
(|
_
|
())
self
.equate
(
a_is_expected
,
trace
)
.
relate
(
&
a
,
&
b
)
.map
(|
_
|
())
})
}
...
...
@@ -663,7 +673,7 @@ pub fn sub_trait_refs(&self,
origin
:
origin
,
values
:
TraitRefs
(
expected_found
(
a_is_expected
,
a
.clone
(),
b
.clone
()))
};
self
.sub
(
a_is_expected
,
trace
)
.
trait_refs
(
&*
a
,
&*
b
)
.map
(|
_
|
())
self
.sub
(
a_is_expected
,
trace
)
.
relate
(
&*
a
,
&*
b
)
.map
(|
_
|
())
})
}
...
...
@@ -682,7 +692,7 @@ pub fn sub_poly_trait_refs(&self,
origin
:
origin
,
values
:
PolyTraitRefs
(
expected_found
(
a_is_expected
,
a
.clone
(),
b
.clone
()))
};
self
.sub
(
a_is_expected
,
trace
)
.
binders
(
&
a
,
&
b
)
.map
(|
_
|
())
self
.sub
(
a_is_expected
,
trace
)
.
relate
(
&
a
,
&
b
)
.map
(|
_
|
())
})
}
...
...
@@ -1045,8 +1055,8 @@ pub fn verify_generic_bound(&self,
self
.region_vars
.verify_generic_bound
(
origin
,
kind
,
a
,
bs
);
}
pub
fn
can_equate
<
T
>
(
&
self
,
a
:
&
T
,
b
:
&
T
)
->
UnitResult
<
'tcx
>
where
T
:
Combineable
<
'tcx
>
+
Repr
<
'tcx
>
pub
fn
can_equate
<
'b
,
T
>
(
&
'b
self
,
a
:
&
T
,
b
:
&
T
)
->
UnitResult
<
'tcx
>
where
T
:
Relate
<
'b
,
'tcx
>
+
Repr
<
'tcx
>
{
debug!
(
"can_equate({}, {})"
,
a
.repr
(
self
.tcx
),
b
.repr
(
self
.tcx
));
self
.probe
(|
_
|
{
...
...
@@ -1057,8 +1067,7 @@ pub fn can_equate<T>(&self, a: &T, b: &T) -> UnitResult<'tcx>
let
e
=
self
.tcx.types.err
;
let
trace
=
TypeTrace
{
origin
:
Misc
(
codemap
::
DUMMY_SP
),
values
:
Types
(
expected_found
(
true
,
e
,
e
))
};
let
eq
=
self
.equate
(
true
,
trace
);
Combineable
::
combine
(
&
eq
,
a
,
b
)
self
.equate
(
true
,
trace
)
.relate
(
a
,
b
)
})
.map
(|
_
|
())
}
}
...
...
src/librustc/middle/infer/region_inference/mod.rs
浏览文件 @
8403b82d
...
...
@@ -18,7 +18,6 @@
pub
use
self
::
VarValue
::
*
;
use
self
::
Classification
::
*
;
use
super
::
CombineResult
;
use
super
::{
RegionVariableOrigin
,
SubregionOrigin
,
TypeTrace
,
MiscVariable
};
use
middle
::
region
;
...
...
@@ -26,6 +25,7 @@
use
middle
::
ty
::{
BoundRegion
,
FreeRegion
,
Region
,
RegionVid
};
use
middle
::
ty
::{
ReEmpty
,
ReStatic
,
ReInfer
,
ReFree
,
ReEarlyBound
};
use
middle
::
ty
::{
ReLateBound
,
ReScope
,
ReVar
,
ReSkolemized
,
BrFresh
};
use
middle
::
ty_relate
::
RelateResult
;
use
middle
::
graph
;
use
middle
::
graph
::{
Direction
,
NodeIndex
};
use
util
::
common
::
indenter
;
...
...
@@ -825,7 +825,7 @@ fn helper(this: &RegionVarBindings,
fn
glb_concrete_regions
(
&
self
,
a
:
Region
,
b
:
Region
)
->
Combin
eResult
<
'tcx
,
Region
>
->
Relat
eResult
<
'tcx
,
Region
>
{
debug!
(
"glb_concrete_regions({:?}, {:?})"
,
a
,
b
);
match
(
a
,
b
)
{
...
...
@@ -901,7 +901,7 @@ fn glb_concrete_regions(&self,
fn
glb_free_regions
(
&
self
,
a
:
&
FreeRegion
,
b
:
&
FreeRegion
)
->
Combin
eResult
<
'tcx
,
ty
::
Region
>
->
Relat
eResult
<
'tcx
,
ty
::
Region
>
{
return
match
a
.cmp
(
b
)
{
Less
=>
helper
(
self
,
a
,
b
),
...
...
@@ -911,7 +911,7 @@ fn glb_free_regions(&self,
fn
helper
<
'a
,
'tcx
>
(
this
:
&
RegionVarBindings
<
'a
,
'tcx
>
,
a
:
&
FreeRegion
,
b
:
&
FreeRegion
)
->
Combin
eResult
<
'tcx
,
ty
::
Region
>
b
:
&
FreeRegion
)
->
Relat
eResult
<
'tcx
,
ty
::
Region
>
{
if
this
.tcx.region_maps
.sub_free_region
(
*
a
,
*
b
)
{
Ok
(
ty
::
ReFree
(
*
a
))
...
...
@@ -930,7 +930,7 @@ fn intersect_scopes(&self,
region_b
:
ty
::
Region
,
scope_a
:
region
::
CodeExtent
,
scope_b
:
region
::
CodeExtent
)
->
Combin
eResult
<
'tcx
,
Region
>
->
Relat
eResult
<
'tcx
,
Region
>
{
// We want to generate the intersection of two
// scopes or two free regions. So, if one of
...
...
src/librustc/middle/infer/sub.rs
浏览文件 @
8403b82d
...
...
@@ -8,64 +8,49 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
super
::
combine
::
*
;
use
super
::
CombineResult
;
use
super
::
combine
::{
self
,
CombineFields
};
use
super
::
higher_ranked
::
HigherRankedRelations
;
use
super
::
Subtype
;
use
super
::
type_variable
::{
SubtypeOf
,
SupertypeOf
};
use
middle
::
ty
::{
self
,
Ty
};
use
middle
::
ty
::
TyVar
;
use
util
::
ppaux
::
Repr
;
use
middle
::
ty_relate
::{
Relate
,
RelateResult
,
TypeRelation
};
use
util
::
ppaux
::{
Repr
};
/// "Greatest lower bound" (common subtype)
pub
struct
Sub
<
'
f
,
'tcx
:
'f
>
{
fields
:
CombineFields
<
'
f
,
'tcx
>
pub
struct
Sub
<
'
a
,
'tcx
:
'a
>
{
fields
:
CombineFields
<
'
a
,
'tcx
>
}
#[allow(non_snake_case)]
pub
fn
Sub
<
'f
,
'tcx
>
(
cf
:
CombineFields
<
'f
,
'tcx
>
)
->
Sub
<
'f
,
'tcx
>
{
Sub
{
fields
:
cf
}
impl
<
'a
,
'tcx
>
Sub
<
'a
,
'tcx
>
{
pub
fn
new
(
f
:
CombineFields
<
'a
,
'tcx
>
)
->
Sub
<
'a
,
'tcx
>
{
Sub
{
fields
:
f
}
}
}
impl
<
'f
,
'tcx
>
Combine
<
'tcx
>
for
Sub
<
'f
,
'tcx
>
{
fn
tag
(
&
self
)
->
String
{
"Sub"
.to_string
()
}
fn
fields
<
'a
>
(
&
'a
self
)
->
&
'a
CombineFields
<
'a
,
'tcx
>
{
&
self
.fields
}
fn
tys_with_variance
(
&
self
,
v
:
ty
::
Variance
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
CombineResult
<
'tcx
,
Ty
<
'tcx
>>
{
match
v
{
ty
::
Invariant
=>
self
.equate
()
.tys
(
a
,
b
),
ty
::
Covariant
=>
self
.tys
(
a
,
b
),
ty
::
Bivariant
=>
self
.bivariate
()
.tys
(
a
,
b
),
ty
::
Contravariant
=>
Sub
(
self
.fields
.switch_expected
())
.tys
(
b
,
a
),
}
}
impl
<
'a
,
'tcx
>
TypeRelation
<
'a
,
'tcx
>
for
Sub
<
'a
,
'tcx
>
{
fn
tag
(
&
self
)
->
&
'static
str
{
"Sub"
}
fn
tcx
(
&
self
)
->
&
'a
ty
::
ctxt
<
'tcx
>
{
self
.fields.infcx.tcx
}
fn
a_is_expected
(
&
self
)
->
bool
{
self
.fields.a_is_expected
}
fn
regions_with_variance
(
&
self
,
v
:
ty
::
Variance
,
a
:
ty
::
Region
,
b
:
ty
::
Region
)
->
CombineResult
<
'tcx
,
ty
::
Region
>
fn
relate_with_variance
<
T
:
Relate
<
'a
,
'tcx
>>
(
&
mut
self
,
variance
:
ty
::
Variance
,
a
:
&
T
,
b
:
&
T
)
->
RelateResult
<
'tcx
,
T
>
{
match
v
{
ty
::
Invariant
=>
self
.
equate
()
.regions
(
a
,
b
),
ty
::
Covariant
=>
self
.re
gions
(
a
,
b
),
ty
::
Bivariant
=>
self
.
bivariate
()
.regions
(
a
,
b
),
ty
::
Contravariant
=>
Sub
(
self
.fields
.switch_expected
())
.regions
(
b
,
a
),
match
v
ariance
{
ty
::
Invariant
=>
self
.
fields
.equate
()
.relate
(
a
,
b
),
ty
::
Covariant
=>
self
.re
late
(
a
,
b
),
ty
::
Bivariant
=>
self
.
fields
.bivariate
()
.relate
(
a
,
b
),
ty
::
Contravariant
=>
self
.fields
.switch_expected
()
.sub
()
.relate
(
b
,
a
),
}
}
fn
regions
(
&
self
,
a
:
ty
::
Region
,
b
:
ty
::
Region
)
->
CombineResult
<
'tcx
,
ty
::
Region
>
{
debug!
(
"{}.regions({}, {})"
,
self
.tag
(),
a
.repr
(
self
.tcx
()),
b
.repr
(
self
.tcx
()));
self
.infcx
()
.region_vars
.make_subregion
(
Subtype
(
self
.trace
()),
a
,
b
);
Ok
(
a
)
}
fn
tys
(
&
mut
self
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
RelateResult
<
'tcx
,
Ty
<
'tcx
>>
{
debug!
(
"{}.tys({}, {})"
,
self
.tag
(),
a
.repr
(
self
.tcx
()),
b
.repr
(
self
.tcx
()));
fn
tys
(
&
self
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
CombineResult
<
'tcx
,
Ty
<
'tcx
>>
{
debug!
(
"{}.tys({}, {})"
,
self
.tag
(),
a
.repr
(
self
.tcx
()),
b
.repr
(
self
.tcx
()));
if
a
==
b
{
return
Ok
(
a
);
}
let
infcx
=
self
.fields.infcx
;
...
...
@@ -80,8 +65,8 @@ fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CombineResult<'tcx, Ty<'tcx>> {
}
(
&
ty
::
ty_infer
(
TyVar
(
a_id
)),
_
)
=>
{
try!
(
self
.fields
.switch_expected
()
.instantiate
(
b
,
SupertypeOf
,
a_id
));
.switch_expected
()
.instantiate
(
b
,
SupertypeOf
,
a_id
));
Ok
(
a
)
}
(
_
,
&
ty
::
ty_infer
(
TyVar
(
b_id
)))
=>
{
...
...
@@ -94,14 +79,25 @@ fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CombineResult<'tcx, Ty<'tcx>> {
}
_
=>
{
super_tys
(
self
,
a
,
b
)
combine
::
super_combine_tys
(
self
.fields.infcx
,
self
,
a
,
b
)
}
}
}
fn
binders
<
T
>
(
&
self
,
a
:
&
ty
::
Binder
<
T
>
,
b
:
&
ty
::
Binder
<
T
>
)
->
CombineResult
<
'tcx
,
ty
::
Binder
<
T
>>
where
T
:
Combineable
<
'tcx
>
fn
regions
(
&
mut
self
,
a
:
ty
::
Region
,
b
:
ty
::
Region
)
->
RelateResult
<
'tcx
,
ty
::
Region
>
{
debug!
(
"{}.regions({}, {})"
,
self
.tag
(),
a
.repr
(
self
.tcx
()),
b
.repr
(
self
.tcx
()));
let
origin
=
Subtype
(
self
.fields.trace
.clone
());
self
.fields.infcx.region_vars
.make_subregion
(
origin
,
a
,
b
);
Ok
(
a
)
}
fn
binders
<
T
>
(
&
mut
self
,
a
:
&
ty
::
Binder
<
T
>
,
b
:
&
ty
::
Binder
<
T
>
)
->
RelateResult
<
'tcx
,
ty
::
Binder
<
T
>>
where
T
:
Relate
<
'a
,
'tcx
>
{
self
.higher_ranked_sub
(
a
,
b
)
self
.
fields
.
higher_ranked_sub
(
a
,
b
)
}
}
src/librustc/middle/traits/project.rs
浏览文件 @
8403b82d
...
...
@@ -291,6 +291,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
}
}
#[derive(Clone)]
pub
struct
Normalized
<
'tcx
,
T
>
{
pub
value
:
T
,
pub
obligations
:
Vec
<
PredicateObligation
<
'tcx
>>
,
...
...
src/librustc/middle/ty_fold.rs
浏览文件 @
8403b82d
...
...
@@ -39,6 +39,8 @@
use
middle
::
ty
::{
self
,
Ty
};
use
middle
::
traits
;
use
std
::
rc
::
Rc
;
use
syntax
::
abi
;
use
syntax
::
ast
;
use
syntax
::
owned_slice
::
OwnedSlice
;
use
util
::
ppaux
::
Repr
;
...
...
@@ -47,7 +49,7 @@
/// The TypeFoldable trait is implemented for every type that can be folded.
/// Basically, every type that has a corresponding method in TypeFolder.
pub
trait
TypeFoldable
<
'tcx
>
{
pub
trait
TypeFoldable
<
'tcx
>
:
Repr
<
'tcx
>
+
Clone
{
fn
fold_with
<
F
:
TypeFolder
<
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
Self
;
}
...
...
@@ -149,12 +151,20 @@ fn fold_item_substs(&mut self, i: ty::ItemSubsts<'tcx>) -> ty::ItemSubsts<'tcx>
// can easily refactor the folding into the TypeFolder trait as
// needed.
impl
<
'tcx
>
TypeFoldable
<
'tcx
>
for
()
{
fn
fold_with
<
F
:
TypeFolder
<
'tcx
>>
(
&
self
,
_
:
&
mut
F
)
->
()
{
()
macro_rules!
CopyImpls
{
(
$
(
$ty:ty
),
+
)
=>
{
$
(
impl
<
'tcx
>
TypeFoldable
<
'tcx
>
for
$ty
{
fn
fold_with
<
F
:
TypeFolder
<
'tcx
>>
(
&
self
,
_
:
&
mut
F
)
->
$ty
{
*
self
}
}
)
+
}
}
CopyImpls!
{
(),
ast
::
Unsafety
,
abi
::
Abi
}
impl
<
'tcx
,
T
:
TypeFoldable
<
'tcx
>
,
U
:
TypeFoldable
<
'tcx
>>
TypeFoldable
<
'tcx
>
for
(
T
,
U
)
{
fn
fold_with
<
F
:
TypeFolder
<
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
(
T
,
U
)
{
(
self
.0
.fold_with
(
folder
),
self
.1
.fold_with
(
folder
))
...
...
src/librustc/middle/ty_relate/mod.rs
0 → 100644
浏览文件 @
8403b82d
此差异已折叠。
点击以展开。
src/librustc/util/ppaux.rs
浏览文件 @
8403b82d
...
...
@@ -1532,3 +1532,9 @@ fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
}
}
}
impl
<
'tcx
>
Repr
<
'tcx
>
for
ast
::
Unsafety
{
fn
repr
(
&
self
,
_
:
&
ctxt
<
'tcx
>
)
->
String
{
format!
(
"{:?}"
,
*
self
)
}
}
src/librustc_driver/test.rs
浏览文件 @
8403b82d
...
...
@@ -22,7 +22,7 @@
use
rustc_typeck
::
middle
::
subst
;
use
rustc_typeck
::
middle
::
subst
::
Subst
;
use
rustc_typeck
::
middle
::
ty
::{
self
,
Ty
};
use
rustc_typeck
::
middle
::
infer
::
combine
::
Combine
;
use
rustc_typeck
::
middle
::
ty_relate
::
TypeRelation
;
use
rustc_typeck
::
middle
::
infer
;
use
rustc_typeck
::
middle
::
infer
::
lub
::
Lub
;
use
rustc_typeck
::
middle
::
infer
::
glb
::
Glb
;
...
...
@@ -350,21 +350,21 @@ pub fn dummy_type_trace(&self) -> infer::TypeTrace<'tcx> {
pub
fn
sub
(
&
self
)
->
Sub
<
'a
,
'tcx
>
{
let
trace
=
self
.dummy_type_trace
();
Sub
(
self
.infcx
.combine_fields
(
true
,
trace
)
)
self
.infcx
.sub
(
true
,
trace
)
}
pub
fn
lub
(
&
self
)
->
Lub
<
'a
,
'tcx
>
{
let
trace
=
self
.dummy_type_trace
();
Lub
(
self
.infcx
.combine_fields
(
true
,
trace
)
)
self
.infcx
.lub
(
true
,
trace
)
}
pub
fn
glb
(
&
self
)
->
Glb
<
'a
,
'tcx
>
{
let
trace
=
self
.dummy_type_trace
();
Glb
(
self
.infcx
.combine_fields
(
true
,
trace
)
)
self
.infcx
.glb
(
true
,
trace
)
}
pub
fn
make_lub_ty
(
&
self
,
t1
:
Ty
<
'tcx
>
,
t2
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
match
self
.lub
()
.
tys
(
t1
,
t2
)
{
match
self
.lub
()
.
relate
(
&
t1
,
&
t2
)
{
Ok
(
t
)
=>
t
,
Err
(
ref
e
)
=>
panic!
(
"unexpected error computing LUB: {}"
,
ty
::
type_err_to_str
(
self
.infcx.tcx
,
e
))
...
...
@@ -374,7 +374,7 @@ pub fn make_lub_ty(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) -> Ty<'tcx> {
/// Checks that `t1 <: t2` is true (this may register additional
/// region checks).
pub
fn
check_sub
(
&
self
,
t1
:
Ty
<
'tcx
>
,
t2
:
Ty
<
'tcx
>
)
{
match
self
.sub
()
.
tys
(
t1
,
t2
)
{
match
self
.sub
()
.
relate
(
&
t1
,
&
t2
)
{
Ok
(
_
)
=>
{
}
Err
(
ref
e
)
=>
{
panic!
(
"unexpected error computing sub({},{}): {}"
,
...
...
@@ -388,7 +388,7 @@ pub fn check_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
/// Checks that `t1 <: t2` is false (this may register additional
/// region checks).
pub
fn
check_not_sub
(
&
self
,
t1
:
Ty
<
'tcx
>
,
t2
:
Ty
<
'tcx
>
)
{
match
self
.sub
()
.
tys
(
t1
,
t2
)
{
match
self
.sub
()
.
relate
(
&
t1
,
&
t2
)
{
Err
(
_
)
=>
{
}
Ok
(
_
)
=>
{
panic!
(
"unexpected success computing sub({},{})"
,
...
...
@@ -400,7 +400,7 @@ pub fn check_not_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
/// Checks that `LUB(t1,t2) == t_lub`
pub
fn
check_lub
(
&
self
,
t1
:
Ty
<
'tcx
>
,
t2
:
Ty
<
'tcx
>
,
t_lub
:
Ty
<
'tcx
>
)
{
match
self
.lub
()
.
tys
(
t1
,
t2
)
{
match
self
.lub
()
.
relate
(
&
t1
,
&
t2
)
{
Ok
(
t
)
=>
{
self
.assert_eq
(
t
,
t_lub
);
}
...
...
@@ -417,7 +417,7 @@ pub fn check_glb(&self, t1: Ty<'tcx>, t2: Ty<'tcx>, t_glb: Ty<'tcx>) {
self
.ty_to_string
(
t1
),
self
.ty_to_string
(
t2
),
self
.ty_to_string
(
t_glb
));
match
self
.glb
()
.
tys
(
t1
,
t2
)
{
match
self
.glb
()
.
relate
(
&
t1
,
&
t2
)
{
Err
(
e
)
=>
{
panic!
(
"unexpected error computing LUB: {:?}"
,
e
)
}
...
...
src/librustc_typeck/check/coercion.rs
浏览文件 @
8403b82d
...
...
@@ -62,11 +62,11 @@
use
check
::{
autoderef
,
FnCtxt
,
NoPreference
,
PreferMutLvalue
,
UnresolvedTypeAction
};
use
middle
::
infer
::{
self
,
CombineResult
,
Coercion
};
use
middle
::
infer
::
combine
::
Combine
;
use
middle
::
infer
::{
self
,
Coercion
};
use
middle
::
subst
;
use
middle
::
ty
::{
AutoPtr
,
AutoDerefRef
,
AdjustDerefRef
,
AutoUnsize
,
AutoUnsafe
};
use
middle
::
ty
::{
self
,
mt
,
Ty
};
use
middle
::
ty_relate
::
RelateResult
;
use
util
::
common
::
indent
;
use
util
::
ppaux
;
use
util
::
ppaux
::
Repr
;
...
...
@@ -78,7 +78,7 @@ struct Coerce<'a, 'tcx: 'a> {
origin
:
infer
::
TypeOrigin
,
}
type
CoerceResult
<
'tcx
>
=
Combin
eResult
<
'tcx
,
Option
<
ty
::
AutoAdjustment
<
'tcx
>>>
;
type
CoerceResult
<
'tcx
>
=
Relat
eResult
<
'tcx
,
Option
<
ty
::
AutoAdjustment
<
'tcx
>>>
;
impl
<
'f
,
'tcx
>
Coerce
<
'f
,
'tcx
>
{
fn
tcx
(
&
self
)
->
&
ty
::
ctxt
<
'tcx
>
{
...
...
@@ -536,7 +536,7 @@ pub fn mk_assignty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
expr
:
&
ast
::
Expr
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
Combin
eResult
<
'tcx
,
()
>
{
->
Relat
eResult
<
'tcx
,
()
>
{
debug!
(
"mk_assignty({} -> {})"
,
a
.repr
(
fcx
.tcx
()),
b
.repr
(
fcx
.tcx
()));
let
adjustment
=
try!
(
indent
(||
{
fcx
.infcx
()
.commit_if_ok
(|
_
|
{
...
...
src/librustc_typeck/coherence/mod.rs
浏览文件 @
8403b82d
...
...
@@ -30,7 +30,6 @@
use
middle
::
ty
::
ty_projection
;
use
middle
::
ty
;
use
CrateCtxt
;
use
middle
::
infer
::
combine
::
Combine
;
use
middle
::
infer
::
InferCtxt
;
use
middle
::
infer
::
new_infer_ctxt
;
use
std
::
collections
::
HashSet
;
...
...
src/test/compile-fail/dst-bad-coerce1.rs
浏览文件 @
8403b82d
...
...
@@ -23,10 +23,6 @@ pub fn main() {
let
f2
:
&
Fat
<
[
isize
;
3
]
>
=
&
f1
;
let
f3
:
&
Fat
<
[
usize
]
>
=
f2
;
//~^ ERROR mismatched types
//~| expected `&Fat<[usize]>`
//~| found `&Fat<[isize; 3]>`
//~| expected usize
//~| found isize
// With a trait.
let
f1
=
Fat
{
ptr
:
Foo
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录