Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
eb6ea5d4
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
eb6ea5d4
编写于
12月 01, 2014
作者:
N
Niko Matsakis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Cleanup type resolution to use type folding infrastructure and not
have such a silly over-engineered interface.
上级
3efc9d2c
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
155 addition
and
426 deletion
+155
-426
src/librustc/middle/infer/coercion.rs
src/librustc/middle/infer/coercion.rs
+2
-14
src/librustc/middle/infer/mod.rs
src/librustc/middle/infer/mod.rs
+34
-34
src/librustc/middle/infer/resolve.rs
src/librustc/middle/infer/resolve.rs
+71
-251
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/_match.rs
+18
-23
src/librustc_typeck/check/demand.rs
src/librustc_typeck/check/demand.rs
+1
-8
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/regionck.rs
+1
-7
src/librustc_typeck/check/writeback.rs
src/librustc_typeck/check/writeback.rs
+6
-23
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/coherence/mod.rs
+22
-66
未找到文件。
src/librustc/middle/infer/coercion.rs
浏览文件 @
eb6ea5d4
...
...
@@ -60,10 +60,9 @@
//! sort of a minor point so I've opted to leave it for later---after all
//! we may want to adjust precisely when coercions occur.
use
super
::{
CoerceResult
,
resolve_type
,
Coercion
};
use
super
::{
CoerceResult
,
Coercion
};
use
super
::
combine
::{
CombineFields
,
Combine
};
use
super
::
sub
::
Sub
;
use
super
::
resolve
::
try_resolve_tvar_shallow
;
use
middle
::
subst
;
use
middle
::
ty
::{
AutoPtr
,
AutoDerefRef
,
AdjustDerefRef
,
AutoUnsize
,
AutoUnsafe
};
...
...
@@ -197,18 +196,7 @@ pub fn subtype(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
pub
fn
unpack_actual_value
<
T
,
F
>
(
&
self
,
a
:
Ty
<
'tcx
>
,
f
:
F
)
->
T
where
F
:
FnOnce
(
&
ty
::
sty
<
'tcx
>
)
->
T
,
{
match
resolve_type
(
self
.get_ref
()
.infcx
,
None
,
a
,
try_resolve_tvar_shallow
)
{
Ok
(
t
)
=>
{
f
(
&
t
.sty
)
}
Err
(
e
)
=>
{
self
.get_ref
()
.infcx.tcx.sess
.span_bug
(
self
.get_ref
()
.trace.origin
.span
(),
format!
(
"failed to resolve even without
\
any force options: {}"
,
e
)
.as_slice
());
}
}
f
(
&
self
.get_ref
()
.infcx
.shallow_resolve
(
a
)
.sty
)
}
// ~T -> &T or &mut T -> &T (including where T = [U] or str)
...
...
src/librustc/middle/infer/mod.rs
浏览文件 @
eb6ea5d4
...
...
@@ -19,13 +19,6 @@
pub
use
self
::
ValuePairs
::
*
;
pub
use
self
::
fixup_err
::
*
;
pub
use
middle
::
ty
::
IntVarValue
;
pub
use
self
::
resolve
::
resolve_and_force_all_but_regions
;
pub
use
self
::
resolve
::{
force_all
,
not_regions
};
pub
use
self
::
resolve
::{
force_ivar
};
pub
use
self
::
resolve
::{
force_tvar
,
force_rvar
};
pub
use
self
::
resolve
::{
resolve_ivar
,
resolve_all
};
pub
use
self
::
resolve
::{
resolve_nested_tvar
};
pub
use
self
::
resolve
::{
resolve_rvar
};
pub
use
self
::
skolemize
::
TypeSkolemizer
;
use
middle
::
subst
;
...
...
@@ -47,7 +40,6 @@
use
self
::
coercion
::
Coerce
;
use
self
::
combine
::{
Combine
,
CombineFields
};
use
self
::
region_inference
::{
RegionVarBindings
,
RegionSnapshot
};
use
self
::
resolve
::{
resolver
};
use
self
::
equate
::
Equate
;
use
self
::
sub
::
Sub
;
use
self
::
lub
::
Lub
;
...
...
@@ -453,22 +445,6 @@ pub fn mk_coercety<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
})
}
// See comment on the type `resolve_state` below
pub
fn
resolve_type
<
'a
,
'tcx
>
(
cx
:
&
InferCtxt
<
'a
,
'tcx
>
,
span
:
Option
<
Span
>
,
a
:
Ty
<
'tcx
>
,
modes
:
uint
)
->
fres
<
Ty
<
'tcx
>>
{
let
mut
resolver
=
resolver
(
cx
,
modes
,
span
);
cx
.commit_unconditionally
(||
resolver
.resolve_type_chk
(
a
))
}
pub
fn
resolve_region
(
cx
:
&
InferCtxt
,
r
:
ty
::
Region
,
modes
:
uint
)
->
fres
<
ty
::
Region
>
{
let
mut
resolver
=
resolver
(
cx
,
modes
,
None
);
resolver
.resolve_region_chk
(
r
)
}
trait
then
<
'tcx
>
{
fn
then
<
T
,
F
>
(
&
self
,
f
:
F
)
->
Result
<
T
,
ty
::
type_err
<
'tcx
>>
where
T
:
Clone
,
...
...
@@ -835,20 +811,21 @@ pub fn trait_ref_to_string(&self, t: &Rc<ty::TraitRef<'tcx>>) -> String {
trait_ref_to_string
(
self
.tcx
,
&
t
)
}
pub
fn
contains_unbound_type_variables
(
&
self
,
typ
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
match
resolve_type
(
self
,
None
,
typ
,
resolve_nested_tvar
|
resolve_ivar
)
{
Ok
(
new_type
)
=>
new_type
,
Err
(
_
)
=>
typ
}
}
pub
fn
shallow_resolve
(
&
self
,
typ
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
match
typ
.sty
{
ty
::
ty_infer
(
ty
::
TyVar
(
v
))
=>
{
// Not entirely obvious: if `typ` is a type variable,
// it can be resolved to an int/float variable, which
// can then be recursively resolved, hence the
// recursion. Note though that we prevent type
// variables from unifying to other type variables
// directly (though they may be embedded
// structurally), and we prevent cycles in any case,
// so this recursion should always be of very limited
// depth.
self
.type_variables
.borrow
()
.probe
(
v
)
.map
(|
t
|
self
.shallow_resolve
(
t
))
.unwrap_or
(
typ
)
}
...
...
@@ -869,10 +846,33 @@ pub fn shallow_resolve(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
}
pub
fn
resolve_type_vars_if_possible
<
T
:
TypeFoldable
<
'tcx
>>
(
&
self
,
value
:
&
T
)
->
T
{
let
mut
r
=
resolve
::
DeepTypeResolver
::
new
(
self
);
/*!
* Where possible, replaces type/int/float variables in
* `value` with their final value. Note that region variables
* are unaffected. If a type variable has not been unified, it
* is left as is. This is an idempotent operation that does
* not affect inference state in any way and so you can do it
* at will.
*/
let
mut
r
=
resolve
::
OpportunisticTypeResolver
::
new
(
self
);
value
.fold_with
(
&
mut
r
)
}
pub
fn
fully_resolve
<
T
:
TypeFoldable
<
'tcx
>>
(
&
self
,
value
:
&
T
)
->
fres
<
T
>
{
/*!
* Attempts to resolve all type/region variables in
* `value`. Region inference must have been run already (e.g.,
* by calling `resolve_regions_and_report_errors`). If some
* variable was never unified, an `Err` results.
*
* This method is idempotent, but it not typically not invoked
* except during the writeback phase.
*/
resolve
::
fully_resolve
(
self
,
value
)
}
// [Note-Type-error-reporting]
// An invariant is that anytime the expected or actual type is ty_err (the special
// error type, meaning that an error occurred when typechecking this expression),
...
...
src/librustc/middle/infer/resolve.rs
浏览文件 @
eb6ea5d4
...
...
@@ -8,288 +8,108 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Resolution is the process of removing type variables and replacing
// them with their inferred values. Unfortunately our inference has
// become fairly complex and so there are a number of options to
// control *just how much* you want to resolve and how you want to do
// it.
//
// # Controlling the scope of resolution
//
// The options resolve_* determine what kinds of variables get
// resolved. Generally resolution starts with a top-level type
// variable; we will always resolve this. However, once we have
// resolved that variable, we may end up with a type that still
// contains type variables. For example, if we resolve `<T0>` we may
// end up with something like `[<T1>]`. If the option
// `resolve_nested_tvar` is passed, we will then go and recursively
// resolve `<T1>`.
//
// The options `resolve_rvar` controls whether we resolve region
// variables. The options `resolve_fvar` and `resolve_ivar` control
// whether we resolve floating point and integral variables,
// respectively.
//
// # What do if things are unconstrained
//
// Sometimes we will encounter a variable that has no constraints, and
// therefore cannot sensibly be mapped to any particular result. By
// default, we will leave such variables as is (so you will get back a
// variable in your result). The options force_* will cause the
// resolution to fail in this case instead, except for the case of
// integral variables, which resolve to `int` if forced.
//
// # resolve_all and force_all
//
// The options are a bit set, so you can use the *_all to resolve or
// force all kinds of variables (including those we may add in the
// future). If you want to resolve everything but one type, you are
// probably better off writing `resolve_all - resolve_ivar`.
#![allow(non_upper_case_globals)]
use
super
::{
fixup_err
,
fres
,
InferCtxt
};
use
super
::{
unresolved_int_ty
,
unresolved_float_ty
,
unresolved_ty
};
use
middle
::
ty
::{
FloatVar
,
FloatVid
,
IntVar
,
IntVid
,
RegionVid
,
TyVar
,
TyVid
};
use
middle
::
ty
::{
IntType
,
UintType
};
use
super
::{
InferCtxt
,
fixup_err
,
fres
,
unresolved_ty
,
unresolved_int_ty
,
unresolved_float_ty
};
use
middle
::
ty
::{
mod
,
Ty
};
use
middle
::
ty_fold
;
use
syntax
::
codemap
::
Span
;
use
util
::
ppaux
::{
Repr
,
ty_to_string
};
use
middle
::
ty_fold
::{
mod
,
TypeFoldable
};
use
util
::
ppaux
::
Repr
;
pub
const
resolve_nested_tvar
:
uint
=
0b0000000001
;
pub
const
resolve_rvar
:
uint
=
0b0000000010
;
pub
const
resolve_ivar
:
uint
=
0b0000000100
;
pub
const
resolve_fvar
:
uint
=
0b0000001000
;
pub
const
resolve_all
:
uint
=
0b0000001111
;
pub
const
force_tvar
:
uint
=
0b0000100000
;
pub
const
force_rvar
:
uint
=
0b0001000000
;
pub
const
force_ivar
:
uint
=
0b0010000000
;
pub
const
force_fvar
:
uint
=
0b0100000000
;
pub
const
force_all
:
uint
=
0b0111100000
;
pub
const
not_regions
:
uint
=
!
(
force_rvar
|
resolve_rvar
);
pub
const
try_resolve_tvar_shallow
:
uint
=
0
;
pub
const
resolve_and_force_all_but_regions
:
uint
=
(
resolve_all
|
force_all
)
&
not_regions
;
///////////////////////////////////////////////////////////////////////////
// OPPORTUNISTIC TYPE RESOLVER
pub
struct
ResolveState
<
'a
,
'tcx
:
'a
>
{
/// The opportunistic type resolver can be used at any time. It simply replaces
/// type variables that have been unified with the things they have
/// been unified with (similar to `shallow_resolve`, but deep). This is
/// useful for printing messages etc but also required at various
/// points for correctness.
pub
struct
OpportunisticTypeResolver
<
'a
,
'tcx
:
'a
>
{
infcx
:
&
'a
InferCtxt
<
'a
,
'tcx
>
,
modes
:
uint
,
err
:
Option
<
fixup_err
>
,
type_depth
:
uint
,
}
pub
fn
resolver
<
'a
,
'tcx
>
(
infcx
:
&
'a
InferCtxt
<
'a
,
'tcx
>
,
modes
:
uint
,
_
:
Option
<
Span
>
)
->
ResolveState
<
'a
,
'tcx
>
{
ResolveState
{
infcx
:
infcx
,
modes
:
modes
,
err
:
None
,
type_depth
:
0
,
impl
<
'a
,
'tcx
>
OpportunisticTypeResolver
<
'a
,
'tcx
>
{
pub
fn
new
(
infcx
:
&
'a
InferCtxt
<
'a
,
'tcx
>
)
->
OpportunisticTypeResolver
<
'a
,
'tcx
>
{
OpportunisticTypeResolver
{
infcx
:
infcx
}
}
}
impl
<
'a
,
'tcx
>
ty_fold
::
TypeFolder
<
'tcx
>
for
ResolveState
<
'a
,
'tcx
>
{
impl
<
'a
,
'tcx
>
ty_fold
::
TypeFolder
<
'tcx
>
for
OpportunisticTypeResolver
<
'a
,
'tcx
>
{
fn
tcx
(
&
self
)
->
&
ty
::
ctxt
<
'tcx
>
{
self
.infcx.tcx
}
fn
fold_ty
(
&
mut
self
,
t
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
self
.resolve_type
(
t
)
}
fn
fold_region
(
&
mut
self
,
r
:
ty
::
Region
)
->
ty
::
Region
{
self
.resolve_region
(
r
)
}
}
impl
<
'a
,
'tcx
>
ResolveState
<
'a
,
'tcx
>
{
pub
fn
should
(
&
mut
self
,
mode
:
uint
)
->
bool
{
(
self
.modes
&
mode
)
==
mode
}
pub
fn
resolve_type_chk
(
&
mut
self
,
typ
:
Ty
<
'tcx
>
)
->
fres
<
Ty
<
'tcx
>>
{
self
.err
=
None
;
debug!
(
"Resolving {} (modes={:x})"
,
ty_to_string
(
self
.infcx.tcx
,
typ
),
self
.modes
);
// n.b. This is a hokey mess because the current fold doesn't
// allow us to pass back errors in any useful way.
let
rty
=
self
.resolve_type
(
typ
);
match
self
.err
{
None
=>
{
debug!
(
"Resolved {} to {} (modes={:x})"
,
ty_to_string
(
self
.infcx.tcx
,
typ
),
ty_to_string
(
self
.infcx.tcx
,
rty
),
self
.modes
);
return
Ok
(
rty
);
}
Some
(
e
)
=>
{
return
Err
(
e
);
}
}
}
pub
fn
resolve_region_chk
(
&
mut
self
,
orig
:
ty
::
Region
)
->
fres
<
ty
::
Region
>
{
self
.err
=
None
;
let
resolved
=
self
.resolve_region
(
orig
);
match
self
.err
{
None
=>
Ok
(
resolved
),
Some
(
e
)
=>
Err
(
e
)
}
}
pub
fn
resolve_type
(
&
mut
self
,
typ
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
debug!
(
"resolve_type({})"
,
typ
.repr
(
self
.infcx.tcx
));
if
!
ty
::
type_needs_infer
(
typ
)
{
return
typ
;
}
if
self
.type_depth
>
0
&&
!
self
.should
(
resolve_nested_tvar
)
{
return
typ
;
}
match
typ
.sty
{
ty
::
ty_infer
(
TyVar
(
vid
))
=>
{
self
.resolve_ty_var
(
vid
)
}
ty
::
ty_infer
(
IntVar
(
vid
))
=>
{
self
.resolve_int_var
(
vid
)
}
ty
::
ty_infer
(
FloatVar
(
vid
))
=>
{
self
.resolve_float_var
(
vid
)
}
_
=>
{
if
self
.modes
&
resolve_all
==
0
{
// if we are only resolving top-level type
// variables, and this is not a top-level type
// variable, then shortcircuit for efficiency
typ
}
else
{
self
.type_depth
+=
1
;
let
result
=
ty_fold
::
super_fold_ty
(
self
,
typ
);
self
.type_depth
-=
1
;
result
}
}
}
}
pub
fn
resolve_region
(
&
mut
self
,
orig
:
ty
::
Region
)
->
ty
::
Region
{
debug!
(
"Resolve_region({})"
,
orig
.repr
(
self
.infcx.tcx
));
match
orig
{
ty
::
ReInfer
(
ty
::
ReVar
(
rid
))
=>
self
.resolve_region_var
(
rid
),
_
=>
orig
}
}
pub
fn
resolve_region_var
(
&
mut
self
,
rid
:
RegionVid
)
->
ty
::
Region
{
if
!
self
.should
(
resolve_rvar
)
{
return
ty
::
ReInfer
(
ty
::
ReVar
(
rid
));
}
self
.infcx.region_vars
.resolve_var
(
rid
)
}
pub
fn
resolve_ty_var
(
&
mut
self
,
vid
:
TyVid
)
->
Ty
<
'tcx
>
{
let
tcx
=
self
.infcx.tcx
;
let
tv
=
self
.infcx.type_variables
.borrow
();
match
tv
.probe
(
vid
)
{
Some
(
t
)
=>
{
self
.resolve_type
(
t
)
}
None
=>
{
if
self
.should
(
force_tvar
)
{
self
.err
=
Some
(
unresolved_ty
(
vid
));
}
ty
::
mk_var
(
tcx
,
vid
)
}
}
}
pub
fn
resolve_int_var
(
&
mut
self
,
vid
:
IntVid
)
->
Ty
<
'tcx
>
{
if
!
self
.should
(
resolve_ivar
)
{
return
ty
::
mk_int_var
(
self
.infcx.tcx
,
vid
);
}
let
tcx
=
self
.infcx.tcx
;
let
table
=
&
self
.infcx.int_unification_table
;
let
node
=
table
.borrow_mut
()
.get
(
tcx
,
vid
);
match
node
.value
{
Some
(
IntType
(
t
))
=>
ty
::
mk_mach_int
(
t
),
Some
(
UintType
(
t
))
=>
ty
::
mk_mach_uint
(
t
),
None
=>
{
if
self
.should
(
force_ivar
)
{
// As a last resort, emit an error.
self
.err
=
Some
(
unresolved_int_ty
(
vid
));
}
ty
::
mk_int_var
(
self
.infcx.tcx
,
vid
)
}
}
}
pub
fn
resolve_float_var
(
&
mut
self
,
vid
:
FloatVid
)
->
Ty
<
'tcx
>
{
if
!
self
.should
(
resolve_fvar
)
{
return
ty
::
mk_float_var
(
self
.infcx.tcx
,
vid
);
}
let
tcx
=
self
.infcx.tcx
;
let
table
=
&
self
.infcx.float_unification_table
;
let
node
=
table
.borrow_mut
()
.get
(
tcx
,
vid
);
match
node
.value
{
Some
(
t
)
=>
ty
::
mk_mach_float
(
t
),
None
=>
{
if
self
.should
(
force_fvar
)
{
// As a last resort, emit an error.
self
.err
=
Some
(
unresolved_float_ty
(
vid
));
}
ty
::
mk_float_var
(
self
.infcx.tcx
,
vid
)
}
if
!
ty
::
type_has_ty_infer
(
t
)
{
t
// micro-optimize -- if there is nothing in this type that this fold affects...
}
else
{
let
t0
=
self
.infcx
.shallow_resolve
(
t
);
ty_fold
::
super_fold_ty
(
self
,
t0
)
}
}
}
///////////////////////////////////////////////////////////////////////////
/// DEEP TYPE RESOLVER
///
/// This kind of resolver can be used at any time. It simply replaces
/// type variables that have been unified with the things they have
/// been unified with (similar to `shallow_resolve`, but deep). This is
/// useful for printing messages etc but also required at various
/// points for correctness.
pub
struct
DeepTypeResolver
<
'a
,
'tcx
:
'a
>
{
infcx
:
&
'a
InferCtxt
<
'a
,
'tcx
>
,
// FULL TYPE RESOLUTION
/// Full type resolution replaces all type and region variables with
/// their concrete results. If any variable cannot be replaced (never unified, etc)
/// then an `Err` result is returned.
pub
fn
fully_resolve
<
'a
,
'tcx
,
T
>
(
infcx
:
&
InferCtxt
<
'a
,
'tcx
>
,
value
:
&
T
)
->
fres
<
T
>
where
T
:
TypeFoldable
<
'tcx
>
{
let
mut
full_resolver
=
FullTypeResolver
{
infcx
:
infcx
,
err
:
None
};
let
result
=
value
.fold_with
(
&
mut
full_resolver
);
match
full_resolver
.err
{
None
=>
Ok
(
result
),
Some
(
e
)
=>
Err
(
e
),
}
}
impl
<
'a
,
'tcx
>
DeepTypeResolver
<
'a
,
'tcx
>
{
pub
fn
new
(
infcx
:
&
'a
InferCtxt
<
'a
,
'tcx
>
)
->
DeepTypeResolver
<
'a
,
'tcx
>
{
DeepTypeResolver
{
infcx
:
infcx
}
}
// N.B. This type is not public because the protocol around checking the
// `err` field is not enforcable otherwise.
struct
FullTypeResolver
<
'a
,
'tcx
:
'a
>
{
infcx
:
&
'a
InferCtxt
<
'a
,
'tcx
>
,
err
:
Option
<
fixup_err
>
,
}
impl
<
'a
,
'tcx
>
ty_fold
::
TypeFolder
<
'tcx
>
for
Deep
TypeResolver
<
'a
,
'tcx
>
{
impl
<
'a
,
'tcx
>
ty_fold
::
TypeFolder
<
'tcx
>
for
Full
TypeResolver
<
'a
,
'tcx
>
{
fn
tcx
(
&
self
)
->
&
ty
::
ctxt
<
'tcx
>
{
self
.infcx.tcx
}
fn
fold_ty
(
&
mut
self
,
t
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
if
!
ty
::
type_
has_ty
_infer
(
t
)
{
if
!
ty
::
type_
needs
_infer
(
t
)
{
t
// micro-optimize -- if there is nothing in this type that this fold affects...
}
else
{
let
t0
=
self
.infcx
.shallow_resolve
(
t
);
ty_fold
::
super_fold_ty
(
self
,
t0
)
let
t
=
self
.infcx
.shallow_resolve
(
t
);
match
t
.sty
{
ty
::
ty_infer
(
ty
::
TyVar
(
vid
))
=>
{
self
.err
=
Some
(
unresolved_ty
(
vid
));
ty
::
mk_err
()
}
ty
::
ty_infer
(
ty
::
IntVar
(
vid
))
=>
{
self
.err
=
Some
(
unresolved_int_ty
(
vid
));
ty
::
mk_err
()
}
ty
::
ty_infer
(
ty
::
FloatVar
(
vid
))
=>
{
self
.err
=
Some
(
unresolved_float_ty
(
vid
));
ty
::
mk_err
()
}
ty
::
ty_infer
(
_
)
=>
{
self
.infcx.tcx.sess
.bug
(
format!
(
"Unexpected type in full type resolver: {}"
,
t
.repr
(
self
.infcx.tcx
))[]);
}
_
=>
{
ty_fold
::
super_fold_ty
(
self
,
t
)
}
}
}
}
}
fn
fold_region
(
&
mut
self
,
r
:
ty
::
Region
)
->
ty
::
Region
{
match
r
{
ty
::
ReInfer
(
ty
::
ReVar
(
rid
))
=>
self
.infcx.region_vars
.resolve_var
(
rid
),
_
=>
r
,
}
}
}
src/librustc_typeck/check/_match.rs
浏览文件 @
eb6ea5d4
...
...
@@ -9,7 +9,7 @@
// except according to those terms.
use
middle
::
def
;
use
middle
::
infer
::{
mod
,
resolve
}
;
use
middle
::
infer
;
use
middle
::
pat_util
::{
PatIdMap
,
pat_id_map
,
pat_is_binding
,
pat_is_const
};
use
middle
::
subst
::{
Subst
,
Substs
};
use
middle
::
ty
::{
mod
,
Ty
};
...
...
@@ -143,11 +143,8 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
ast
::
PatRegion
(
ref
inner
)
=>
{
let
inner_ty
=
fcx
.infcx
()
.next_ty_var
();
let
mutbl
=
infer
::
resolve_type
(
fcx
.infcx
(),
Some
(
pat
.span
),
expected
,
resolve
::
try_resolve_tvar_shallow
)
.ok
()
.and_then
(|
t
|
ty
::
deref
(
t
,
true
))
let
mutbl
=
ty
::
deref
(
fcx
.infcx
()
.shallow_resolve
(
expected
),
true
)
.map_or
(
ast
::
MutImmutable
,
|
mt
|
mt
.mutbl
);
let
mt
=
ty
::
mt
{
ty
:
inner_ty
,
mutbl
:
mutbl
};
...
...
@@ -214,23 +211,21 @@ pub fn check_dereferencable<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
inner
:
&
ast
::
Pat
)
->
bool
{
let
fcx
=
pcx
.fcx
;
let
tcx
=
pcx
.fcx.ccx.tcx
;
match
infer
::
resolve_type
(
fcx
.infcx
(),
Some
(
span
),
expected
,
resolve
::
try_resolve_tvar_shallow
)
{
Ok
(
t
)
if
pat_is_binding
(
&
tcx
.def_map
,
inner
)
=>
{
ty
::
deref
(
t
,
true
)
.map_or
(
true
,
|
mt
|
match
mt
.ty.sty
{
ty
::
ty_trait
(
_
)
=>
{
// This is "x = SomeTrait" being reduced from
// "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
span_err!
(
tcx
.sess
,
span
,
E0033
,
"type `{}` cannot be dereferenced"
,
fcx
.infcx
()
.ty_to_string
(
t
));
false
}
_
=>
true
})
}
_
=>
true
if
pat_is_binding
(
&
tcx
.def_map
,
inner
)
{
let
expected
=
fcx
.infcx
()
.shallow_resolve
(
expected
);
ty
::
deref
(
expected
,
true
)
.map_or
(
true
,
|
mt
|
match
mt
.ty.sty
{
ty
::
ty_trait
(
_
)
=>
{
// This is "x = SomeTrait" being reduced from
// "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
span_err!
(
tcx
.sess
,
span
,
E0033
,
"type `{}` cannot be dereferenced"
,
fcx
.infcx
()
.ty_to_string
(
expected
));
false
}
_
=>
true
})
}
else
{
true
}
}
...
...
src/librustc_typeck/check/demand.rs
浏览文件 @
eb6ea5d4
...
...
@@ -12,8 +12,6 @@
use
check
::
FnCtxt
;
use
middle
::
ty
::{
mod
,
Ty
};
use
middle
::
infer
;
use
middle
::
infer
::
resolve_type
;
use
middle
::
infer
::
resolve
::
try_resolve_tvar_shallow
;
use
std
::
result
::
Result
::{
Err
,
Ok
};
use
syntax
::
ast
;
...
...
@@ -63,12 +61,7 @@ pub fn coerce<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
debug!
(
"demand::coerce(expected = {}, expr_ty = {})"
,
expected
.repr
(
fcx
.ccx.tcx
),
expr_ty
.repr
(
fcx
.ccx.tcx
));
let
expected
=
if
ty
::
type_needs_infer
(
expected
)
{
resolve_type
(
fcx
.infcx
(),
None
,
expected
,
try_resolve_tvar_shallow
)
.unwrap_or
(
expected
)
}
else
{
expected
};
let
expected
=
fcx
.infcx
()
.resolve_type_vars_if_possible
(
&
expected
);
match
fcx
.mk_assignty
(
expr
,
expr_ty
,
expected
)
{
Ok
(())
=>
{
/* ok */
}
Err
(
ref
err
)
=>
{
...
...
src/librustc_typeck/check/regionck.rs
浏览文件 @
eb6ea5d4
...
...
@@ -124,8 +124,6 @@
use
middle
::
traits
;
use
middle
::
ty
::{
ReScope
};
use
middle
::
ty
::{
mod
,
Ty
,
MethodCall
};
use
middle
::
infer
::
resolve_and_force_all_but_regions
;
use
middle
::
infer
::
resolve_type
;
use
middle
::
infer
;
use
middle
::
pat_util
;
use
util
::
nodemap
::{
DefIdMap
,
NodeMap
,
FnvHashMap
};
...
...
@@ -307,11 +305,7 @@ pub fn set_repeating_scope(&mut self, scope: ast::NodeId) -> ast::NodeId {
/// of b will be `&<R0>.int` and then `*b` will require that `<R0>` be bigger than the let and
/// the `*b` expression, so we will effectively resolve `<R0>` to be the block B.
pub
fn
resolve_type
(
&
self
,
unresolved_ty
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
match
resolve_type
(
self
.fcx
.infcx
(),
None
,
unresolved_ty
,
resolve_and_force_all_but_regions
)
{
Ok
(
t
)
=>
t
,
Err
(
_
)
=>
ty
::
mk_err
()
}
self
.fcx
.infcx
()
.resolve_type_vars_if_possible
(
&
unresolved_ty
)
}
/// Try to resolve the type for the given node.
...
...
src/librustc_typeck/check/writeback.rs
浏览文件 @
eb6ea5d4
...
...
@@ -19,8 +19,6 @@
use
middle
::
pat_util
;
use
middle
::
ty
::{
mod
,
Ty
,
MethodCall
,
MethodCallee
};
use
middle
::
ty_fold
::{
TypeFolder
,
TypeFoldable
};
use
middle
::
infer
::{
force_all
,
resolve_all
,
resolve_region
};
use
middle
::
infer
::
resolve_type
;
use
middle
::
infer
;
use
write_substs_to_tcx
;
use
write_ty_to_tcx
;
...
...
@@ -337,8 +335,8 @@ fn visit_method_map_entry(&self,
}
}
fn
resolve
<
T
:
ResolveIn
<
'tcx
>>
(
&
self
,
t
:
&
T
,
reason
:
ResolveReason
)
->
T
{
t
.
resolve_in
(
&
mut
Resolver
::
new
(
self
.fcx
,
reason
))
fn
resolve
<
T
:
TypeFoldable
<
'tcx
>>
(
&
self
,
t
:
&
T
,
reason
:
ResolveReason
)
->
T
{
t
.
fold_with
(
&
mut
Resolver
::
new
(
self
.fcx
,
reason
))
}
}
...
...
@@ -375,19 +373,6 @@ fn span(&self, tcx: &ty::ctxt) -> Span {
}
}
///////////////////////////////////////////////////////////////////////////
// Convenience methods for resolving different kinds of things.
trait
ResolveIn
<
'tcx
>
{
fn
resolve_in
<
'a
>
(
&
self
,
resolver
:
&
mut
Resolver
<
'a
,
'tcx
>
)
->
Self
;
}
impl
<
'tcx
,
T
:
TypeFoldable
<
'tcx
>>
ResolveIn
<
'tcx
>
for
T
{
fn
resolve_in
<
'a
>
(
&
self
,
resolver
:
&
mut
Resolver
<
'a
,
'tcx
>
)
->
T
{
self
.fold_with
(
resolver
)
}
}
///////////////////////////////////////////////////////////////////////////
// The Resolver. This is the type folding engine that detects
// unresolved types and so forth.
...
...
@@ -465,13 +450,11 @@ fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> {
}
fn
fold_ty
(
&
mut
self
,
t
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
if
!
ty
::
type_needs_infer
(
t
)
{
return
t
;
}
match
resolve_type
(
self
.infcx
,
None
,
t
,
resolve_all
|
force_all
)
{
match
self
.infcx
.fully_resolve
(
&
t
)
{
Ok
(
t
)
=>
t
,
Err
(
e
)
=>
{
debug!
(
"Resolver::fold_ty: input type `{}` not fully resolvable"
,
t
.repr
(
self
.tcx
));
self
.report_error
(
e
);
ty
::
mk_err
()
}
...
...
@@ -479,7 +462,7 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
}
fn
fold_region
(
&
mut
self
,
r
:
ty
::
Region
)
->
ty
::
Region
{
match
resolve_region
(
self
.infcx
,
r
,
resolve_all
|
force_all
)
{
match
self
.infcx
.fully_resolve
(
&
r
)
{
Ok
(
r
)
=>
r
,
Err
(
e
)
=>
{
self
.report_error
(
e
);
...
...
src/librustc_typeck/coherence/mod.rs
浏览文件 @
eb6ea5d4
...
...
@@ -26,12 +26,13 @@
use
middle
::
ty
::{
ty_rptr
,
ty_struct
,
ty_trait
,
ty_tup
};
use
middle
::
ty
::{
ty_str
,
ty_vec
,
ty_float
,
ty_infer
,
ty_int
,
ty_open
};
use
middle
::
ty
::{
ty_uint
,
ty_unboxed_closure
,
ty_uniq
,
ty_bare_fn
};
use
middle
::
ty
::{
type_is_ty_var
};
use
middle
::
ty
::{
ty_closure
};
use
middle
::
subst
::
Subst
;
use
middle
::
ty
;
use
CrateCtxt
;
use
middle
::
infer
::
combine
::
Combine
;
use
middle
::
infer
::
InferCtxt
;
use
middle
::
infer
::{
new_infer_ctxt
,
resolve_ivar
,
resolve_type
};
use
middle
::
infer
::{
new_infer_ctxt
};
use
std
::
collections
::{
HashSet
};
use
std
::
cell
::
RefCell
;
use
std
::
rc
::
Rc
;
...
...
@@ -52,80 +53,35 @@
mod
overlap
;
mod
unsafety
;
fn
get_base_type
<
'a
,
'tcx
>
(
inference_context
:
&
InferCtxt
<
'a
,
'tcx
>
,
span
:
Span
,
original_type
:
Ty
<
'tcx
>
)
->
Option
<
Ty
<
'tcx
>>
{
let
resolved_type
=
match
resolve_type
(
inference_context
,
Some
(
span
),
original_type
,
resolve_ivar
)
{
Ok
(
resulting_type
)
if
!
type_is_ty_var
(
resulting_type
)
=>
resulting_type
,
_
=>
{
inference_context
.tcx.sess
.span_fatal
(
span
,
"the type of this value must be known in order
\
to determine the base type"
);
}
};
match
resolved_type
.sty
{
ty_enum
(
..
)
|
ty_struct
(
..
)
|
ty_unboxed_closure
(
..
)
=>
{
debug!
(
"(getting base type) found base type"
);
Some
(
resolved_type
)
// 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
>
{
match
ty
.sty
{
ty_enum
(
def_id
,
_
)
|
ty_struct
(
def_id
,
_
)
=>
{
Some
(
def_id
)
}
_
if
ty
::
type_is_trait
(
resolved_type
)
=>
{
debug!
(
"(getting base type) found base type (trait)"
);
Some
(
resolved_type
)
ty_trait
(
ref
t
)
=>
{
Some
(
t
.principal.def_id
)
}
ty_bool
|
ty_char
|
ty_int
(
..
)
|
ty_uint
(
..
)
|
ty_float
(
..
)
|
ty_str
(
..
)
|
ty_vec
(
..
)
|
ty_bare_fn
(
..
)
|
ty_closure
(
..
)
|
ty_tup
(
..
)
|
ty_
infer
(
..
)
|
ty_
param
(
..
)
|
ty_err
|
ty_open
(
..
)
|
ty_uniq
(
_
)
|
ty_param
(
..
)
|
ty_err
|
ty_open
(
..
)
|
ty_uniq
(
_
)
|
ty_ptr
(
_
)
|
ty_rptr
(
_
,
_
)
=>
{
debug!
(
"(getting base type) no base type; found {}"
,
original_type
.sty
);
None
}
ty_trait
(
..
)
=>
panic!
(
"should have been caught"
)
}
}
// 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
,
original_type
:
Ty
<
'tcx
>
)
->
Option
<
DefId
>
{
match
get_base_type
(
inference_context
,
span
,
original_type
)
{
None
=>
None
,
Some
(
base_type
)
=>
{
match
base_type
.sty
{
ty_enum
(
def_id
,
_
)
|
ty_struct
(
def_id
,
_
)
|
ty_unboxed_closure
(
def_id
,
_
,
_
)
=>
{
Some
(
def_id
)
}
ty_ptr
(
ty
::
mt
{
ty
,
..
})
|
ty_rptr
(
_
,
ty
::
mt
{
ty
,
..
})
|
ty_uniq
(
ty
)
=>
{
match
ty
.sty
{
ty_trait
(
box
ty
::
TyTrait
{
ref
principal
,
..
})
=>
{
Some
(
principal
.def_id
)
}
_
=>
{
panic!
(
"get_base_type() returned a type that wasn't an
\
enum, struct, or trait"
);
}
}
}
ty_trait
(
box
ty
::
TyTrait
{
ref
principal
,
..
})
=>
{
Some
(
principal
.def_id
)
}
_
=>
{
panic!
(
"get_base_type() returned a type that wasn't an
\
enum, struct, or trait"
);
}
}
ty_infer
(
..
)
|
ty_unboxed_closure
(
..
)
=>
{
// `ty` comes from a user declaration so we should only expect types
// that the user can type
inference_context
.tcx.sess
.span_bug
(
span
,
format!
(
"coherence encountered unexpected type searching for base type: {}"
,
ty
.repr
(
inference_context
.tcx
))[]);
}
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录