Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
664a0443
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,发现更多精彩内容 >>
提交
664a0443
编写于
12月 29, 2011
作者:
M
Marijn Haverbeke
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
More resolving and typechecking of bounded type parameters.
Extern interfaces still don't get recognized. Issue #1227
上级
40d5f288
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
211 addition
and
55 deletion
+211
-55
src/comp/metadata/csearch.rs
src/comp/metadata/csearch.rs
+1
-0
src/comp/middle/kind.rs
src/comp/middle/kind.rs
+4
-4
src/comp/middle/resolve.rs
src/comp/middle/resolve.rs
+16
-7
src/comp/middle/trans.rs
src/comp/middle/trans.rs
+4
-1
src/comp/middle/ty.rs
src/comp/middle/ty.rs
+25
-9
src/comp/middle/typeck.rs
src/comp/middle/typeck.rs
+161
-34
未找到文件。
src/comp/metadata/csearch.rs
浏览文件 @
664a0443
...
...
@@ -72,6 +72,7 @@ fn get_impls_for_mod(cstore: cstore::cstore, def: ast::def_id,
let
nm
=
decoder
::
lookup_item_name
(
cdata
,
did
.node
);
if
alt
name
{
some
(
n
)
{
n
==
nm
}
none
.
{
true
}
}
{
result
+=
[
@
{
did
:
did
,
iface_did
:
none
::
<
ast
::
def_id
>
,
// FIXME[impl]
ident
:
nm
,
methods
:
decoder
::
lookup_impl_methods
(
cdata
,
did
.node
,
did
.crate
)}];
...
...
src/comp/middle/kind.rs
浏览文件 @
664a0443
...
...
@@ -163,14 +163,14 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
alt
substs
.substs
{
some
(
ts
)
{
let
did
=
ast_util
::
def_id_of_def
(
cx
.tcx.def_map
.get
(
e
.id
));
let
kinds
=
vec
::
map
(
ty
::
lookup_item_type
(
cx
.tcx
,
did
)
.bounds
,
{|
bs
|
ty
::
param_bounds_to_kind
(
bs
)});
let
bounds
=
ty
::
lookup_item_type
(
cx
.tcx
,
did
)
.bounds
;
let
i
=
0u
;
for
ty
in
ts
{
let
kind
=
ty
::
type_kind
(
cx
.tcx
,
ty
);
if
!
ty
::
kind_lteq
(
kinds
[
i
],
kind
)
{
let
p_kind
=
ty
::
param_bounds_to_kind
(
bounds
[
i
]);
if
!
ty
::
kind_lteq
(
p_kind
,
kind
)
{
cx
.tcx.sess
.span_err
(
e
.span
,
"instantiating a "
+
kind_to_str
(
kinds
[
i
]
)
+
kind_to_str
(
p_kind
)
+
" type parameter with a "
+
kind_to_str
(
kind
)
+
" type"
);
}
...
...
src/comp/middle/resolve.rs
浏览文件 @
664a0443
...
...
@@ -1701,7 +1701,8 @@ fn check_export(e: @env, ident: str, val: @indexed_mod, vi: @view_item) {
// Impl resolution
type
method_info
=
{
did
:
def_id
,
n_tps
:
uint
,
ident
:
ast
::
ident
};
type
_
impl
=
{
did
:
def_id
,
ident
:
ast
::
ident
,
methods
:
[
@
method_info
]};
type
_
impl
=
{
did
:
def_id
,
iface_did
:
option
::
t
<
def_id
>
,
ident
:
ast
::
ident
,
methods
:
[
@
method_info
]};
type
iscopes
=
list
<@
[
@
_
impl
]
>
;
fn
resolve_impls
(
e
:
@
env
,
c
:
@
ast
::
crate
)
{
...
...
@@ -1757,14 +1758,20 @@ fn find_impls_in_view_item(e: env, vi: @ast::view_item,
}
}
fn
find_impls_in_item
(
i
:
@
ast
::
item
,
&
impls
:
[
@
_
impl
],
fn
find_impls_in_item
(
e
:
env
,
i
:
@
ast
::
item
,
&
impls
:
[
@
_
impl
],
name
:
option
::
t
<
ident
>
,
ck_exports
:
option
::
t
<
ast
::
_
mod
>
)
{
alt
i
.node
{
ast
::
item_impl
(
_
,
_
,
_
,
mthds
)
{
ast
::
item_impl
(
_
,
ifce
,
_
,
mthds
)
{
if
alt
name
{
some
(
n
)
{
n
==
i
.ident
}
_
{
true
}
}
&&
alt
ck_exports
{
some
(
m
)
{
is_exported
(
i
.ident
,
m
)
}
_
{
true
}
}
{
impls
+=
[
@
{
did
:
local_def
(
i
.id
),
iface_did
:
alt
ifce
{
some
(
@
{
node
:
ast
::
ty_path
(
_
,
id
),
_
})
{
some
(
def_id_of_def
(
e
.def_map
.get
(
id
)))
}
_
{
none
}
},
ident
:
i
.ident
,
methods
:
vec
::
map
(
mthds
,
{|
m
|
@
{
did
:
local_def
(
m
.id
),
...
...
@@ -1788,7 +1795,7 @@ fn find_impls_in_mod(e: env, m: def, &impls: [@_impl],
cached
=
if
defid
.crate
==
ast
::
local_crate
{
let
tmp
=
[];
for
i
in
option
::
get
(
e
.mod_map
.get
(
defid
.node
)
.m
)
.items
{
find_impls_in_item
(
i
,
tmp
,
name
,
none
);
find_impls_in_item
(
e
,
i
,
tmp
,
name
,
none
);
}
@
tmp
}
else
{
...
...
@@ -1816,7 +1823,7 @@ fn visit_block_with_impl_scope(e: @env, b: ast::blk, sc: iscopes,
for
st
in
b
.node.stmts
{
alt
st
.node
{
ast
::
stmt_decl
(
@
{
node
:
ast
::
decl_item
(
i
),
_
},
_
)
{
find_impls_in_item
(
i
,
impls
,
none
,
none
);
find_impls_in_item
(
*
e
,
i
,
impls
,
none
,
none
);
}
_
{}
}
...
...
@@ -1829,13 +1836,15 @@ fn visit_mod_with_impl_scope(e: @env, m: ast::_mod, s: span, sc: iscopes,
v
:
vt
<
iscopes
>
)
{
let
impls
=
[];
for
vi
in
m
.view_items
{
find_impls_in_view_item
(
*
e
,
vi
,
impls
,
sc
);
}
for
i
in
m
.items
{
find_impls_in_item
(
i
,
impls
,
none
,
none
);
}
for
i
in
m
.items
{
find_impls_in_item
(
*
e
,
i
,
impls
,
none
,
none
);
}
visit
::
visit_mod
(
m
,
s
,
vec
::
len
(
impls
)
>
0u
?
cons
(
@
impls
,
@
sc
)
:
sc
,
v
);
}
fn
resolve_impl_in_expr
(
e
:
@
env
,
x
:
@
ast
::
expr
,
sc
:
iscopes
,
v
:
vt
<
iscopes
>
)
{
alt
x
.node
{
ast
::
expr_field
(
_
,
_
,
_
)
{
e
.impl_map
.insert
(
x
.id
,
sc
);
}
ast
::
expr_field
(
_
,
_
,
_
)
|
ast
::
expr_path
(
_
)
{
e
.impl_map
.insert
(
x
.id
,
sc
);
}
_
{}
}
visit
::
visit_expr
(
x
,
sc
,
v
);
...
...
src/comp/middle/trans.rs
浏览文件 @
664a0443
...
...
@@ -2858,9 +2858,12 @@ fn trans_callee(bcx: @block_ctxt, e: @ast::expr) -> lval_maybe_callee {
// Lval means this is a record field, so not a method
if
!
expr_is_lval
(
bcx
,
e
)
{
alt
bcx_ccx
(
bcx
)
.method_map
.find
(
e
.id
)
{
some
(
did
)
{
// An impl method
some
(
typeck
::
method_static
(
did
)
)
{
// An impl method
ret
trans_method_callee
(
bcx
,
e
,
base
,
did
);
}
some
(
typeck
::
method_param
(
_
))
{
fail
"not implemented"
;
// FIXME[impl]
}
none
.
{
// An object method
let
of
=
trans_object_field
(
bcx
,
base
,
ident
);
ret
{
bcx
:
of
.bcx
,
val
:
of
.mthptr
,
kind
:
owned
,
...
...
src/comp/middle/ty.rs
浏览文件 @
664a0443
...
...
@@ -814,7 +814,7 @@ fn fold_ty(cx: ctxt, fld: fold_mode, ty_0: t) -> t {
alt
fld
{
fm_var
(
folder
)
{
ty
=
folder
(
id
);
}
_
{
/* no-op */
}
}
}
ty_param
(
id
,
did
)
{
alt
fld
{
fm_param
(
folder
)
{
ty
=
folder
(
id
,
did
);
}
_
{
/* no-op */
}
}
alt
fld
{
fm_param
(
folder
)
{
ty
=
folder
(
id
,
did
);
}
_
{}
}
}
}
...
...
@@ -1731,6 +1731,7 @@ mod unify {
export
ures_ok
;
export
ures_err
;
export
var_bindings
;
export
precise
,
in_bindings
,
bind_params
;
tag
result
{
ures_ok
(
t
);
ures_err
(
type_err
);
}
tag
union_result
{
unres_ok
;
unres_err
(
type_err
);
}
...
...
@@ -1741,7 +1742,12 @@ mod unify {
type
var_bindings
=
{
sets
:
ufind
::
ufind
,
types
:
smallintmap
::
smallintmap
<
t
>
};
type
ctxt
=
{
vb
:
option
::
t
<@
var_bindings
>
,
tcx
:
ty_ctxt
};
tag
unify_style
{
precise
;
in_bindings
(
@
var_bindings
);
bind_params
(
@
mutable
[
mutable
option
::
t
<
t
>
]);
}
type
ctxt
=
{
st
:
unify_style
,
tcx
:
ty_ctxt
};
fn
mk_var_bindings
()
->
@
var_bindings
{
ret
@
{
sets
:
ufind
::
make
(),
types
:
smallintmap
::
mk
::
<
t
>
()};
...
...
@@ -1750,7 +1756,9 @@ fn mk_var_bindings() -> @var_bindings {
// Unifies two sets.
fn
union
(
cx
:
@
ctxt
,
set_a
:
uint
,
set_b
:
uint
,
variance
:
variance
)
->
union_result
{
let
vb
=
option
::
get
(
cx
.vb
);
let
vb
=
alt
cx
.st
{
in_bindings
(
vb
)
{
vb
}
};
ufind
::
grow
(
vb
.sets
,
float
::
max
(
set_a
,
set_b
)
+
1u
);
let
root_a
=
ufind
::
find
(
vb
.sets
,
set_a
);
let
root_b
=
ufind
::
find
(
vb
.sets
,
set_b
);
...
...
@@ -1800,7 +1808,7 @@ fn record_var_binding_for_actual(
fn
record_var_binding
(
cx
:
@
ctxt
,
key
:
int
,
typ
:
t
,
variance
:
variance
)
->
result
{
let
vb
=
option
::
get
(
cx
.vb
)
;
let
vb
=
alt
cx
.st
{
in_bindings
(
vb
)
{
vb
}
}
;
ufind
::
grow
(
vb
.sets
,
(
key
as
uint
)
+
1u
);
let
root
=
ufind
::
find
(
vb
.sets
,
key
as
uint
);
let
result_type
=
typ
;
...
...
@@ -2136,7 +2144,6 @@ fn unify_step(cx: @ctxt, expected: t, actual: t,
// If the RHS is a variable type, then just do the
// appropriate binding.
ty
::
ty_var
(
actual_id
)
{
assert
option
::
is_some
(
cx
.vb
);
let
actual_n
=
actual_id
as
uint
;
alt
struct
(
cx
.tcx
,
expected
)
{
ty
::
ty_var
(
expected_id
)
{
...
...
@@ -2157,11 +2164,20 @@ fn unify_step(cx: @ctxt, expected: t, actual: t,
}
ret
ures_ok
(
mk_var
(
cx
.tcx
,
actual_id
));
}
ty
::
ty_param
(
n
,
_
)
{
alt
cx
.st
{
bind_params
(
cell
)
{
while
vec
::
len
(
*
cell
)
<
n
+
1u
{
*
cell
+=
[
mutable
none
];
}
cell
[
n
]
=
some
(
expected
);
ret
ures_ok
(
expected
);
}
_
{}
}
}
_
{
/* empty */
}
}
alt
struct
(
cx
.tcx
,
expected
)
{
ty
::
ty_var
(
expected_id
)
{
assert
option
::
is_some
(
cx
.vb
);
// Add a binding. (`actual` can't actually be a var here.)
alt
record_var_binding_for_expected
(
cx
,
expected_id
,
actual
,
...
...
@@ -2478,9 +2494,9 @@ fn unify_step(cx: @ctxt, expected: t, actual: t,
}
}
}
fn
unify
(
expected
:
t
,
actual
:
t
,
vb
:
option
::
t
<@
var_bindings
>
,
fn
unify
(
expected
:
t
,
actual
:
t
,
st
:
unify_style
,
tcx
:
ty_ctxt
)
->
result
{
let
cx
=
@
{
vb
:
vb
,
tcx
:
tcx
};
let
cx
=
@
{
st
:
st
,
tcx
:
tcx
};
ret
unify_step
(
cx
,
expected
,
actual
,
covariant
);
}
fn
dump_var_bindings
(
tcx
:
ty_ctxt
,
vb
:
@
var_bindings
)
{
...
...
@@ -2553,7 +2569,7 @@ fn resolve_type_var(tcx: ty_ctxt, sp: option::t<span>, vb: @var_bindings,
}
fn
same_type
(
cx
:
ctxt
,
a
:
t
,
b
:
t
)
->
bool
{
alt
unify
::
unify
(
a
,
b
,
non
e
,
cx
)
{
alt
unify
::
unify
(
a
,
b
,
unify
::
precis
e
,
cx
)
{
unify
::
ures_ok
(
_
)
{
true
}
_
{
false
}
}
...
...
src/comp/middle/typeck.rs
浏览文件 @
664a0443
...
...
@@ -18,9 +18,13 @@
import
option
::{
none
,
some
};
import
syntax
::
print
::
pprust
::
*
;
export
check_crate
,
method_map
;
export
check_crate
,
method_map
,
method_origin
,
method_static
,
method_param
;
type
method_map
=
hashmap
<
ast
::
node_id
,
ast
::
def_id
>
;
tag
method_origin
{
method_static
(
ast
::
def_id
);
method_param
(
uint
);
}
type
method_map
=
hashmap
<
ast
::
node_id
,
method_origin
>
;
type
ty_table
=
hashmap
<
ast
::
def_id
,
ty
::
t
>
;
...
...
@@ -798,7 +802,8 @@ fn collect_item_types(tcx: ty::ctxt, crate: @ast::crate) {
mod
unify
{
fn
unify
(
fcx
:
@
fn_ctxt
,
expected
:
ty
::
t
,
actual
:
ty
::
t
)
->
ty
::
unify
::
result
{
ret
ty
::
unify
::
unify
(
expected
,
actual
,
some
(
fcx
.var_bindings
),
ret
ty
::
unify
::
unify
(
expected
,
actual
,
ty
::
unify
::
in_bindings
(
fcx
.var_bindings
),
fcx
.ccx.tcx
);
}
}
...
...
@@ -1115,7 +1120,8 @@ fn gather_locals(ccx: @crate_ctxt,
alt
ty_opt
{
none
.
{
/* nothing to do */
}
some
(
typ
)
{
ty
::
unify
::
unify
(
ty
::
mk_var
(
tcx
,
var_id
),
typ
,
some
(
vb
),
tcx
);
ty
::
unify
::
unify
(
ty
::
mk_var
(
tcx
,
var_id
),
typ
,
ty
::
unify
::
in_bindings
(
vb
),
tcx
);
}
}
};
...
...
@@ -1465,28 +1471,75 @@ fn check_expr_with(fcx: @fn_ctxt, expr: @ast::expr, expected: ty::t) -> bool {
ret
check_expr_with_unifier
(
fcx
,
expr
,
demand
::
simple
,
expected
);
}
fn
impl_self_ty
(
tcx
:
ty
::
ctxt
,
did
:
ast
::
def_id
)
->
{
n_tps
:
uint
,
ty
:
ty
::
t
}
{
if
did
.crate
==
ast
::
local_crate
{
alt
tcx
.items
.get
(
did
.node
)
{
ast_map
::
node_item
(
@
{
node
:
ast
::
item_impl
(
ts
,
_
,
st
,
_
),
_
})
{
{
n_tps
:
vec
::
len
(
ts
),
ty
:
ast_ty_to_ty
(
tcx
,
m_check
,
st
)}
}
}
}
else
{
let
tpt
=
csearch
::
get_type
(
tcx
,
did
);
{
n_tps
:
vec
::
len
(
tpt
.bounds
),
ty
:
tpt
.ty
}
}
}
fn
lookup_method
(
fcx
:
@
fn_ctxt
,
isc
:
resolve
::
iscopes
,
name
:
ast
::
ident
,
ty
:
ty
::
t
,
sp
:
span
)
->
option
::
t
<
{
method
:
@
resolve
::
method_info
,
ids
:
[
int
]}
>
{
->
option
::
t
<
{
method_ty
:
ty
::
t
,
n_tps
:
uint
,
ids
:
[
int
],
origin
:
method_origin
}
>
{
let
tcx
=
fcx
.ccx.tcx
;
// First, see whether this is an interface-bounded parameter
alt
ty
::
struct
(
tcx
,
ty
)
{
ty
::
ty_param
(
n
,
did
)
{
for
bound
in
*
tcx
.ty_param_bounds
.get
(
did
)
{
alt
bound
{
ty
::
bound_iface
(
t
)
{
let
(
iid
,
_
tps
)
=
alt
ty
::
struct
(
tcx
,
t
)
{
ty
::
ty_iface
(
i
,
tps
)
{
(
i
,
tps
)
}
_
{
ret
none
;
}
};
alt
vec
::
find
(
*
ty
::
iface_methods
(
tcx
,
iid
),
{|
m
|
m
.ident
==
name
})
{
some
(
m
)
{
ret
some
({
method_ty
:
ty
::
mk_fn
(
tcx
,
m
.fty
),
n_tps
:
vec
::
len
(
m
.tps
),
ids
:
[],
// FIXME[impl]
origin
:
method_param
(
n
)});
}
_
{}
}
}
_
{}
}
}
ret
none
;
}
_
{}
}
fn
ty_from_did
(
tcx
:
ty
::
ctxt
,
did
:
ast
::
def_id
)
->
ty
::
t
{
if
did
.crate
==
ast
::
local_crate
{
alt
tcx
.items
.get
(
did
.node
)
{
ast_map
::
node_method
(
m
)
{
let
mt
=
ty_of_method
(
tcx
,
m_check
,
m
);
ty
::
mk_fn
(
tcx
,
mt
.fty
)
}
}
}
else
{
csearch
::
get_type
(
tcx
,
did
)
.ty
}
}
let
result
=
none
;
std
::
list
::
iter
(
isc
)
{|
impls
|
if
option
::
is_some
(
result
)
{
ret
;
}
for
@
{
did
,
methods
,
_
}
in
*
impls
{
alt
vec
::
find
(
methods
,
{|
m
|
m
.ident
==
name
})
{
some
(
m
)
{
let
(
n_tps
,
self_ty
)
=
if
did
.crate
==
ast
::
local_crate
{
alt
fcx
.ccx.tcx.items
.get
(
did
.node
)
{
ast_map
::
node_item
(
@
{
node
:
ast
::
item_impl
(
ts
,
_
,
st
,
_
),
_
})
{
(
vec
::
len
(
ts
),
ast_ty_to_ty_crate
(
fcx
.ccx
,
st
))
}
}
}
else
{
let
tpt
=
csearch
::
get_type
(
fcx
.ccx.tcx
,
did
);
(
vec
::
len
(
tpt
.bounds
),
tpt
.ty
)
};
let
{
n_tps
,
ty
:
self_ty
}
=
impl_self_ty
(
tcx
,
did
);
let
{
ids
,
ty
:
self_ty
}
=
if
n_tps
>
0u
{
bind_params_in_type
(
ast_util
::
dummy_sp
(),
fcx
.ccx.
tcx
,
bind_params_in_type
(
ast_util
::
dummy_sp
(),
tcx
,
bind
next_ty_var_id
(
fcx
),
self_ty
,
n_tps
)
}
else
{
{
ids
:
[],
ty
:
self_ty
}
};
...
...
@@ -1494,10 +1547,13 @@ fn lookup_method(fcx: @fn_ctxt, isc: resolve::iscopes,
ures_ok
(
_
)
{
if
option
::
is_some
(
result
)
{
// FIXME[impl] score specificity to resolve ambiguity?
fcx
.ccx.
tcx.sess
.span_err
(
tcx
.sess
.span_err
(
sp
,
"multiple applicable methods in scope"
);
}
else
{
result
=
some
({
method
:
m
,
ids
:
ids
});
result
=
some
({
method_ty
:
ty_from_did
(
tcx
,
m
.did
),
n_tps
:
m
.n_tps
,
ids
:
ids
,
origin
:
method_static
(
m
.did
)});
}
}
_
{}
...
...
@@ -2153,7 +2209,8 @@ fn get_node(f: spanned<field>) -> field { f.node }
}
ast
::
expr_field
(
base
,
field
,
tys
)
{
bot
|
=
check_expr
(
fcx
,
base
);
let
expr_t
=
expr_ty
(
tcx
,
base
);
let
expr_t
=
structurally_resolved_type
(
fcx
,
expr
.span
,
expr_ty
(
tcx
,
base
));
let
base_t
=
do_autoderef
(
fcx
,
expr
.span
,
expr_t
);
let
handled
=
false
,
n_tys
=
vec
::
len
(
tys
);
alt
structure_of
(
fcx
,
expr
.span
,
base_t
)
{
...
...
@@ -2191,21 +2248,13 @@ fn get_node(f: spanned<field>) -> field { f.node }
if
!
handled
{
let
iscope
=
fcx
.ccx.impl_map
.get
(
expr
.id
);
alt
lookup_method
(
fcx
,
iscope
,
field
,
expr_t
,
expr
.span
)
{
some
({
method
,
ids
})
{
let
fty
=
if
method
.did.crate
==
ast
::
local_crate
{
alt
tcx
.items
.get
(
method
.did.node
)
{
ast_map
::
node_method
(
m
)
{
let
mt
=
ty_of_method
(
tcx
,
m_check
,
m
);
ty
::
mk_fn
(
tcx
,
mt
.fty
)
}
}
}
else
{
csearch
::
get_type
(
tcx
,
method
.did
)
.ty
};
some
({
method_ty
:
fty
,
n_tps
:
method_n_tps
,
ids
,
origin
})
{
let
tvars
=
vec
::
map
(
ids
,
{|
id
|
ty
::
mk_var
(
tcx
,
id
)});
let
n_tps
=
vec
::
len
(
ids
);
if
method
.
n_tps
+
n_tps
>
0u
{
if
method
_
n_tps
+
n_tps
>
0u
{
let
b
=
bind_params_in_type
(
expr
.span
,
tcx
,
bind
next_ty_var_id
(
fcx
),
fty
,
n_tps
+
method
.
n_tps
);
n_tps
+
method
_
n_tps
);
let
_
tvars
=
vec
::
map
(
b
.ids
,
{|
id
|
ty
::
mk_var
(
tcx
,
id
)});
let
i
=
0
;
for
v
in
tvars
{
...
...
@@ -2213,9 +2262,8 @@ fn get_node(f: spanned<field>) -> field { f.node }
i
+=
1
;
}
tvars
=
_
tvars
;
fty
=
b
.ty
;
if
n_tys
>
0u
{
if
n_tys
!=
method
.
n_tps
{
if
n_tys
!=
method
_
n_tps
{
tcx
.sess
.span_fatal
(
expr
.span
,
"incorrect number of type
\
parameters given for this method"
);
...
...
@@ -2235,7 +2283,7 @@ fn get_node(f: spanned<field>) -> field { f.node }
parameters"
);
}
write
::
ty_fixup
(
fcx
,
id
,
{
substs
:
some
(
tvars
),
ty
:
fty
});
fcx
.ccx.method_map
.insert
(
id
,
method
.did
);
fcx
.ccx.method_map
.insert
(
id
,
origin
);
}
none
.
{
let
t_err
=
resolve_type_vars_if_possible
(
fcx
,
expr_t
);
...
...
@@ -2807,6 +2855,84 @@ fn check_for_main_fn(tcx: ty::ctxt, crate: @ast::crate) {
}
}
// Detect points where an interface-bounded type parameter is instantiated,
// resolve the impls for the parameters.
fn
resolve_vtables
(
tcx
:
ty
::
ctxt
,
impl_map
:
resolve
::
impl_map
,
crate
:
@
ast
::
crate
)
{
type
ccx
=
{
tcx
:
ty
::
ctxt
,
impl_map
:
resolve
::
impl_map
};
let
cx
=
{
tcx
:
tcx
,
impl_map
:
impl_map
};
fn
resolve_expr
(
ex
:
@
ast
::
expr
,
cx
:
ccx
,
v
:
visit
::
vt
<
ccx
>
)
{
alt
ex
.node
{
ast
::
expr_path
(
_
)
{
let
substs
=
ty
::
node_id_to_ty_param_substs_opt_and_ty
(
cx
.tcx
,
ex
.id
);
alt
substs
.substs
{
some
(
ts
)
{
let
did
=
ast_util
::
def_id_of_def
(
cx
.tcx.def_map
.get
(
ex
.id
));
let
item_ty
=
ty
::
lookup_item_type
(
cx
.tcx
,
did
),
i
=
0u
;
for
s_ty
in
ts
{
for
bound
in
*
item_ty
.bounds
[
i
]
{
alt
bound
{
ty
::
bound_iface
(
i_ty
)
{
let
impls
=
cx
.impl_map
.get
(
ex
.id
);
lookup_impl
(
cx
,
impls
,
ex
.span
,
s_ty
,
i_ty
);
}
_
{}
}
}
i
+=
1u
;
}
}
_
{}
}
}
_
{}
}
visit
::
visit_expr
(
ex
,
cx
,
v
);
}
fn
lookup_impl
(
cx
:
ccx
,
isc
:
resolve
::
iscopes
,
sp
:
span
,
sub_ty
:
ty
::
t
,
iface_ty
:
ty
::
t
)
{
let
iface_id
=
alt
ty
::
struct
(
cx
.tcx
,
iface_ty
)
{
ty
::
ty_iface
(
did
,
_
)
{
did
}
_
{
ret
;
}
};
let
found
=
false
;
std
::
list
::
iter
(
isc
)
{|
impls
|
if
found
{
ret
;
}
for
im
in
*
impls
{
if
im
.iface_did
==
some
(
iface_id
)
{
let
self_ty
=
impl_self_ty
(
cx
.tcx
,
im
.did
)
.ty
;
let
params
=
@
mutable
[
mutable
];
alt
ty
::
unify
::
unify
(
sub_ty
,
self_ty
,
ty
::
unify
::
bind_params
(
params
),
cx
.tcx
)
{
ures_ok
(
_
)
{
if
found
{
cx
.tcx.sess
.span_err
(
sp
,
"multiple applicable implementations in
\
scope"
);
}
else
{
found
=
true
;
}
}
_
{}
}
}
}
}
if
!
found
{
cx
.tcx.sess
.span_err
(
sp
,
"failed to find an implementation of interface "
+
ty_to_str
(
cx
.tcx
,
iface_ty
)
+
" for "
+
ty_to_str
(
cx
.tcx
,
sub_ty
));
}
}
visit
::
visit_crate
(
*
crate
,
cx
,
visit
::
mk_vt
(
@
{
visit_expr
:
resolve_expr
with
*
visit
::
default_visitor
()
}));
}
fn
check_crate
(
tcx
:
ty
::
ctxt
,
impl_map
:
resolve
::
impl_map
,
crate
:
@
ast
::
crate
)
->
method_map
{
collect
::
collect_item_types
(
tcx
,
crate
);
...
...
@@ -2821,6 +2947,7 @@ fn check_crate(tcx: ty::ctxt, impl_map: resolve::impl_map,
bind
check_native_item
(
ccx
,
_
)
with
*
visit
::
default_simple_visitor
()});
visit
::
visit_crate
(
*
crate
,
(),
visit
);
resolve_vtables
(
tcx
,
impl_map
,
crate
);
check_for_main_fn
(
tcx
,
crate
);
tcx
.sess
.abort_if_errors
();
ccx
.method_map
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录