Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
6feb1dfd
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,发现更多精彩内容 >>
提交
6feb1dfd
编写于
6月 08, 2011
作者:
P
Patrick Walton
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc: Don't eagerly resolve type variables after unification
上级
537d4ac6
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
59 addition
and
40 deletion
+59
-40
src/comp/middle/ty.rs
src/comp/middle/ty.rs
+19
-0
src/comp/middle/typeck.rs
src/comp/middle/typeck.rs
+40
-40
未找到文件。
src/comp/middle/ty.rs
浏览文件 @
6feb1dfd
...
...
@@ -2126,6 +2126,25 @@ fn folder(ty_ctxt tcx, @var_bindings vb, t typ) -> t {
ret
fold_ty
(
tcx
,
bind
folder
(
tcx
,
vb
,
_
),
typ
);
}
// If the given type is a variable, returns the structure of that type.
fn
resolve_type_structure
(
&
ty_ctxt
tcx
,
&@
var_bindings
vb
,
t
typ
)
->
fixup_result
{
alt
(
struct
(
tcx
,
typ
))
{
case
(
ty_var
(
?
vid
))
{
if
((
vid
as
uint
)
>=
ufind
::
set_count
(
vb
.sets
))
{
ret
fix_err
(
vid
);
}
auto
root_id
=
ufind
::
find
(
vb
.sets
,
vid
as
uint
);
alt
(
smallintmap
::
find
[
t
](
vb
.types
,
root_id
))
{
case
(
none
[
t
])
{
ret
fix_err
(
vid
);
}
case
(
some
[
t
](
?
rt
))
{
ret
fix_ok
(
rt
);
}
}
}
case
(
_
)
{
ret
fix_ok
(
typ
);
}
}
}
fn
unify_step
(
&@
ctxt
cx
,
&
t
expected
,
&
t
actual
)
->
result
{
// TODO: rewrite this using tuple pattern matching when available, to
// avoid all this rightward drift and spikiness.
...
...
src/comp/middle/typeck.rs
浏览文件 @
6feb1dfd
...
...
@@ -21,7 +21,6 @@
import
middle
::
ty
::
node_type_table
;
import
middle
::
ty
::
pat_ty
;
import
middle
::
ty
::
path_to_str
;
import
middle
::
ty
::
struct
;
import
middle
::
ty
::
ty_param_substs_opt_and_ty
;
import
middle
::
ty
::
ty_to_str
;
import
middle
::
ty
::
type_is_integral
;
...
...
@@ -195,6 +194,19 @@ fn ast_mode_to_mode(ast::mode mode) -> ty::mode {
ret
ty_mode
;
}
// Returns the one-level-deep structure of the given type.
fn
structure_of
(
&@
fn_ctxt
fcx
,
&
span
sp
,
ty
::
t
typ
)
->
ty
::
sty
{
auto
r
=
ty
::
unify
::
resolve_type_structure
(
fcx
.ccx.tcx
,
fcx
.var_bindings
,
typ
);
alt
(
r
)
{
case
(
fix_ok
(
?
typ_s
))
{
ret
ty
::
struct
(
fcx
.ccx.tcx
,
typ_s
);
}
case
(
fix_err
(
_
))
{
fcx
.ccx.tcx.sess
.span_err
(
sp
,
"the type of this value must be "
+
"known in this context"
);
}
}
}
// Parses the programmer's textual representation of a type into our internal
// notion of a type. `getter` is a function that returns the type
// corresponding to a definition ID:
...
...
@@ -810,20 +822,11 @@ fn collect_item_types(&ty::ctxt tcx, &@ast::crate crate) {
// Type unification
// TODO: rename to just "unify"
mod
unify
{
fn
simple
(
&@
fn_ctxt
fcx
,
&
ty
::
t
expected
,
&
ty
::
t
actual
)
->
ty
::
unify
::
result
{
auto
result
=
ty
::
unify
::
unify
(
expected
,
actual
,
fcx
.var_bindings
,
fcx
.ccx.tcx
);
// FIXME: Shouldn't be necessary, but is until we remove pushdown.
alt
(
result
)
{
case
(
ures_ok
(
?
typ
))
{
ret
ures_ok
(
ty
::
unify
::
resolve_all_vars
(
fcx
.ccx.tcx
,
fcx
.var_bindings
,
typ
));
}
case
(
_
)
{
ret
result
;
}
}
ret
ty
::
unify
::
unify
(
expected
,
actual
,
fcx
.var_bindings
,
fcx
.ccx.tcx
);
}
}
...
...
@@ -833,10 +836,10 @@ fn simple(&@fn_ctxt fcx, &ty::t expected, &ty::t actual)
NO_AUTODEREF
;
}
fn
strip_boxes
(
&
ty
::
ctxt
tcx
,
&
ty
::
t
t
)
->
ty
::
t
{
fn
strip_boxes
(
&
@
fn_ctxt
fcx
,
&
span
sp
,
&
ty
::
t
t
)
->
ty
::
t
{
auto
t1
=
t
;
while
(
true
)
{
alt
(
struct
(
tcx
,
t1
))
{
alt
(
struct
ure_of
(
fcx
,
sp
,
t1
))
{
case
(
ty
::
ty_box
(
?
inner
))
{
t1
=
inner
.ty
;
}
case
(
_
)
{
ret
t1
;
}
}
...
...
@@ -854,11 +857,11 @@ fn add_boxes(&@crate_ctxt ccx, uint n, &ty::t t) -> ty::t {
}
fn
count_boxes
(
&
ty
::
ctxt
tcx
,
&
ty
::
t
t
)
->
uint
{
fn
count_boxes
(
&
@
fn_ctxt
fcx
,
&
span
sp
,
&
ty
::
t
t
)
->
uint
{
auto
n
=
0u
;
auto
t1
=
t
;
while
(
true
)
{
alt
(
struct
(
tcx
,
t1
))
{
alt
(
struct
ure_of
(
fcx
,
sp
,
t1
))
{
case
(
ty
::
ty_box
(
?
inner
))
{
n
+=
1u
;
t1
=
inner
.ty
;
}
case
(
_
)
{
ret
n
;
}
}
...
...
@@ -897,9 +900,9 @@ fn full(&@fn_ctxt fcx, &span sp, &ty::t expected, &ty::t actual,
auto
implicit_boxes
=
0u
;
if
(
adk
==
AUTODEREF_OK
)
{
expected_1
=
strip_boxes
(
fcx
.ccx.tcx
,
expected_1
);
actual_1
=
strip_boxes
(
fcx
.ccx.tcx
,
actual_1
);
implicit_boxes
=
count_boxes
(
fcx
.ccx.tcx
,
actual
);
expected_1
=
strip_boxes
(
fcx
,
sp
,
expected_1
);
actual_1
=
strip_boxes
(
fcx
,
sp
,
actual_1
);
implicit_boxes
=
count_boxes
(
fcx
,
sp
,
actual
);
}
let
vec
[
mutable
ty
::
t
]
ty_param_substs
=
[
mutable
];
...
...
@@ -958,7 +961,7 @@ fn variant_arg_types(&@crate_ctxt ccx, &span sp, &ast::def_id vid,
let
vec
[
ty
::
t
]
result
=
[];
auto
tpt
=
ty
::
lookup_item_type
(
ccx
.tcx
,
vid
);
alt
(
struct
(
ccx
.tcx
,
tpt
._1
))
{
alt
(
ty
::
struct
(
ccx
.tcx
,
tpt
._1
))
{
case
(
ty
::
ty_fn
(
_
,
?
ins
,
_
,
_
))
{
// N-ary variant.
for
(
ty
::
arg
arg
in
ins
)
{
...
...
@@ -1272,7 +1275,7 @@ fn check_pat(&@fn_ctxt fcx, &@ast::pat pat, ty::t expected) {
// Take the tag type params out of `expected`.
auto
expected_tps
;
alt
(
struct
(
fcx
.ccx.tcx
,
expected
))
{
alt
(
struct
ure_of
(
fcx
,
pat
.span
,
expected
))
{
case
(
ty
::
ty_tag
(
_
,
?
tps
))
{
expected_tps
=
tps
;
}
case
(
_
)
{
// FIXME: Switch expected and actual in this message? I
...
...
@@ -1405,14 +1408,12 @@ fn check_call_or_bind(&@fn_ctxt fcx, &span sp, &@ast::expr f,
// Check the function.
check_expr
(
fcx
,
f
);
// Get the function type. We need to have resolved it enough to know
// it's a ty_fn or ty_native_fn.
// Get the function type.
auto
fty
=
expr_ty
(
fcx
.ccx.tcx
,
f
);
fty
=
ty
::
unify
::
resolve_all_vars
(
fcx
.ccx.tcx
,
fcx
.var_bindings
,
fty
);
// Grab the argument types and the return type.
auto
arg_tys
;
alt
(
ty
::
struct
(
fcx
.ccx.tcx
,
fty
))
{
alt
(
structure_of
(
fcx
,
sp
,
fty
))
{
case
(
ty
::
ty_fn
(
_
,
?
arg_tys_0
,
_
,
_
))
{
arg_tys
=
arg_tys_0
;
}
...
...
@@ -1508,7 +1509,7 @@ fn check_for_or_for_each(&@fn_ctxt fcx, &@ast::decl decl,
auto
lhs_t
=
expr_ty
(
fcx
.ccx.tcx
,
lhs
);
// FIXME: Binops have a bit more subtlety than this.
auto
t
=
strip_boxes
(
fcx
.ccx.tcx
,
lhs_t
);
auto
t
=
strip_boxes
(
fcx
,
expr
.span
,
lhs_t
);
alt
(
binop
)
{
case
(
ast
::
eq
)
{
t
=
ty
::
mk_bool
(
fcx
.ccx.tcx
);
}
case
(
ast
::
lt
)
{
t
=
ty
::
mk_bool
(
fcx
.ccx.tcx
);
}
...
...
@@ -1532,7 +1533,7 @@ fn check_for_or_for_each(&@fn_ctxt fcx, &@ast::decl decl,
rec
(
ty
=
oper_t
,
mut
=
mut
));
}
case
(
ast
::
deref
)
{
alt
(
struct
(
fcx
.ccx.tcx
,
oper_t
))
{
alt
(
struct
ure_of
(
fcx
,
expr
.span
,
oper_t
))
{
case
(
ty
::
ty_box
(
?
inner
))
{
oper_t
=
inner
.ty
;
}
case
(
_
)
{
fcx
.ccx.tcx.sess
.span_err
...
...
@@ -1542,7 +1543,7 @@ fn check_for_or_for_each(&@fn_ctxt fcx, &@ast::decl decl,
}
}
}
case
(
_
)
{
oper_t
=
strip_boxes
(
fcx
.ccx.tcx
,
oper_t
);
}
case
(
_
)
{
oper_t
=
strip_boxes
(
fcx
,
expr
.span
,
oper_t
);
}
}
write
::
ty_only_fixup
(
fcx
,
a
.id
,
oper_t
);
...
...
@@ -1721,7 +1722,7 @@ fn check_for_or_for_each(&@fn_ctxt fcx, &@ast::decl decl,
auto
item_t
;
auto
lhs_t
=
expr_ty
(
fcx
.ccx.tcx
,
lhs
);
alt
(
struct
(
fcx
.ccx.tcx
,
lhs_t
))
{
alt
(
struct
ure_of
(
fcx
,
expr
.span
,
lhs_t
))
{
case
(
ty
::
ty_chan
(
?
it
))
{
item_t
=
it
;
}
case
(
_
)
{
fcx
.ccx.tcx.sess
.span_err
(
expr
.span
,
...
...
@@ -1775,8 +1776,7 @@ fn check_for_or_for_each(&@fn_ctxt fcx, &@ast::decl decl,
case
(
ast
::
expr_for
(
?
decl
,
?
seq
,
?
body
,
?
a
))
{
check_expr
(
fcx
,
seq
);
alt
(
struct
(
fcx
.ccx.tcx
,
expr_ty
(
fcx
.ccx.tcx
,
seq
)))
{
alt
(
structure_of
(
fcx
,
expr
.span
,
expr_ty
(
fcx
.ccx.tcx
,
seq
)))
{
// FIXME: I include the check_for_or_each call in
// each case because of a bug in typestate.
// The bug is fixed; once there's a new snapshot,
...
...
@@ -1877,7 +1877,7 @@ fn check_for_or_for_each(&@fn_ctxt fcx, &@ast::decl decl,
auto
rt_1
;
auto
fty
=
expr_ty
(
fcx
.ccx.tcx
,
f
);
auto
t_1
;
alt
(
struct
(
fcx
.ccx.tcx
,
fty
))
{
alt
(
struct
ure_of
(
fcx
,
expr
.span
,
fty
))
{
case
(
ty
::
ty_fn
(
?
proto
,
?
arg_tys
,
?
rt
,
?
cf
))
{
proto_1
=
proto
;
rt_1
=
rt
;
...
...
@@ -1917,7 +1917,7 @@ fn check_for_or_for_each(&@fn_ctxt fcx, &@ast::decl decl,
// Pull the return type out of the type of the function.
auto
rt_1
=
ty
::
mk_nil
(
fcx
.ccx.tcx
);
// FIXME: typestate botch
auto
fty
=
ty
::
expr_ty
(
fcx
.ccx.tcx
,
f
);
alt
(
struct
(
fcx
.ccx.tcx
,
fty
))
{
alt
(
struct
ure_of
(
fcx
,
expr
.span
,
fty
))
{
case
(
ty
::
ty_fn
(
_
,
_
,
?
rt
,
_
))
{
rt_1
=
rt
;
}
case
(
ty
::
ty_native_fn
(
_
,
_
,
?
rt
))
{
rt_1
=
rt
;
}
case
(
_
)
{
...
...
@@ -1949,7 +1949,7 @@ fn check_for_or_for_each(&@fn_ctxt fcx, &@ast::decl decl,
}
// Grab this method's type out of the current object type.
alt
(
struct
(
fcx
.ccx.tcx
,
this_obj_ty
))
{
alt
(
struct
ure_of
(
fcx
,
expr
.span
,
this_obj_ty
))
{
case
(
ty
::
ty_obj
(
?
methods
))
{
for
(
ty
::
method
method
in
methods
)
{
if
(
method
.ident
==
id
)
{
...
...
@@ -2059,7 +2059,7 @@ fn check_for_or_for_each(&@fn_ctxt fcx, &@ast::decl decl,
let
vec
[
field
]
base_fields
=
[];
alt
(
struct
(
fcx
.ccx.tcx
,
bexpr_t
))
{
alt
(
struct
ure_of
(
fcx
,
expr
.span
,
bexpr_t
))
{
case
(
ty
::
ty_rec
(
?
flds
))
{
base_fields
=
flds
;
}
case
(
_
)
{
fcx
.ccx.tcx.sess
.span_err
...
...
@@ -2093,10 +2093,10 @@ fn check_for_or_for_each(&@fn_ctxt fcx, &@ast::decl decl,
case
(
ast
::
expr_field
(
?
base
,
?
field
,
?
a
))
{
check_expr
(
fcx
,
base
);
auto
base_t
=
expr_ty
(
fcx
.ccx.tcx
,
base
);
base_t
=
strip_boxes
(
fcx
.ccx.tcx
,
base_t
);
base_t
=
strip_boxes
(
fcx
,
expr
.span
,
base_t
);
base_t
=
ty
::
unify
::
resolve_all_vars
(
fcx
.ccx.tcx
,
fcx
.var_bindings
,
base_t
);
alt
(
struct
(
fcx
.ccx.tcx
,
base_t
))
{
alt
(
struct
ure_of
(
fcx
,
expr
.span
,
base_t
))
{
case
(
ty
::
ty_tup
(
?
args
))
{
let
uint
ix
=
ty
::
field_num
(
fcx
.ccx.tcx.sess
,
expr
.span
,
field
);
...
...
@@ -2142,11 +2142,11 @@ fn check_for_or_for_each(&@fn_ctxt fcx, &@ast::decl decl,
case
(
ast
::
expr_index
(
?
base
,
?
idx
,
?
a
))
{
check_expr
(
fcx
,
base
);
auto
base_t
=
expr_ty
(
fcx
.ccx.tcx
,
base
);
base_t
=
strip_boxes
(
fcx
.ccx.tcx
,
base_t
);
base_t
=
strip_boxes
(
fcx
,
expr
.span
,
base_t
);
check_expr
(
fcx
,
idx
);
auto
idx_t
=
expr_ty
(
fcx
.ccx.tcx
,
idx
);
alt
(
struct
(
fcx
.ccx.tcx
,
base_t
))
{
alt
(
struct
ure_of
(
fcx
,
expr
.span
,
base_t
))
{
case
(
ty
::
ty_vec
(
?
mt
))
{
if
(
!
type_is_integral
(
fcx
.ccx.tcx
,
idx_t
))
{
fcx
.ccx.tcx.sess
.span_err
...
...
@@ -2184,7 +2184,7 @@ fn check_for_or_for_each(&@fn_ctxt fcx, &@ast::decl decl,
case
(
ast
::
expr_chan
(
?
x
,
?
a
))
{
check_expr
(
fcx
,
x
);
auto
port_t
=
expr_ty
(
fcx
.ccx.tcx
,
x
);
alt
(
struct
(
fcx
.ccx.tcx
,
port_t
))
{
alt
(
struct
ure_of
(
fcx
,
expr
.span
,
port_t
))
{
case
(
ty
::
ty_port
(
?
subtype
))
{
auto
ct
=
ty
::
mk_chan
(
fcx
.ccx.tcx
,
subtype
);
write
::
ty_only_fixup
(
fcx
,
a
.id
,
ct
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录