Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
3c4baf69
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,发现更多精彩内容 >>
提交
3c4baf69
编写于
6月 04, 2012
作者:
N
Niko Matsakis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
better support for classes with polymorphic methods
上级
7213274e
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
37 addition
and
70 deletion
+37
-70
src/rustc/metadata/encoder.rs
src/rustc/metadata/encoder.rs
+1
-1
src/rustc/middle/kind.rs
src/rustc/middle/kind.rs
+7
-20
src/rustc/middle/typeck/check/method.rs
src/rustc/middle/typeck/check/method.rs
+8
-0
src/rustc/middle/typeck/collect.rs
src/rustc/middle/typeck/collect.rs
+17
-38
src/test/run-pass/borrowck-preserve-box-in-pat.rs
src/test/run-pass/borrowck-preserve-box-in-pat.rs
+0
-1
src/test/run-pass/class-impl-very-parameterized-iface.rs
src/test/run-pass/class-impl-very-parameterized-iface.rs
+4
-6
src/test/run-pass/class-poly-methods-cross-crate.rs
src/test/run-pass/class-poly-methods-cross-crate.rs
+0
-2
src/test/run-pass/class-typarams.rs
src/test/run-pass/class-typarams.rs
+0
-2
未找到文件。
src/rustc/metadata/encoder.rs
浏览文件 @
3c4baf69
...
...
@@ -664,7 +664,7 @@ fn add_to_index_(item: @item, ebml_w: ebml::writer,
ebml_w
.start_tag
(
tag_item_iface_method
);
encode_family
(
ebml_w
,
purity_fn_family
(
m
.decl.purity
));
encode_name
(
ebml_w
,
m
.ident
);
encode_type_param_bounds
(
ebml_w
,
ecx
,
tps
+
m
.tps
);
encode_type_param_bounds
(
ebml_w
,
ecx
,
m
.tps
);
encode_type
(
ecx
,
ebml_w
,
node_id_to_type
(
tcx
,
m
.id
));
encode_def_id
(
ebml_w
,
local_def
(
m
.id
));
ebml_w
.end_tag
();
...
...
src/rustc/middle/kind.rs
浏览文件 @
3c4baf69
...
...
@@ -254,29 +254,16 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
expr_field
(
base
,
_
,
_
)
{
alt
cx
.method_map
.get
(
e
.id
)
{
typeck
::
method_static
(
did
)
{
/*
If this is a class method, we want to use the
class bounds plus the method bounds -- otherwise the
indices come out wrong. So we check base's type...
*/
let
mut
bounds
=
ty
::
lookup_item_type
(
cx
.tcx
,
did
)
.bounds
;
alt
ty
::
get
(
ty
::
node_id_to_type
(
cx
.tcx
,
base
.id
))
.struct
{
ty
::
ty_class
(
parent_id
,
ts
)
{
/* ...and if it has a class type, prepend the
class bounds onto the method bounds */
/* n.b. this code is very likely sketchy --
currently, class-impl-very-parameterized-iface
fails here and is thus xfailed */
bounds
=
@
(
*
ty
::
lookup_item_type
(
cx
.tcx
,
parent_id
)
.bounds
+
*
bounds
);
}
_
{
}
}
bounds
// n.b.: When we encode class/impl methods, the bounds
// that we encode include both the class/impl bounds
// and then the method bounds themselves...
ty
::
lookup_item_type
(
cx
.tcx
,
did
)
.bounds
}
typeck
::
method_param
(
ifce_id
,
n_mth
,
_
,
_
)
|
typeck
::
method_iface
(
ifce_id
,
n_mth
)
{
// ...iface methods bounds, in contrast, include only the
// method bounds, so we must preprend the tps from the
// iface itself. This ought to be harmonized.
let
ifce_bounds
=
ty
::
lookup_item_type
(
cx
.tcx
,
ifce_id
)
.bounds
;
let
mth
=
ty
::
iface_methods
(
cx
.tcx
,
ifce_id
)[
n_mth
];
...
...
src/rustc/middle/typeck/check/method.rs
浏览文件 @
3c4baf69
...
...
@@ -18,6 +18,9 @@ enum lookup = {
impl
methods
for
lookup
{
// Entrypoint:
fn
method
()
->
option
<
method_origin
>
{
#
debug
[
"method lookup(m_name=%s, self_ty=%s)"
,
self
.m_name
,
self
.fcx.infcx
.ty_to_str
(
self
.self_ty
)];
// First, see whether this is an interface-bounded parameter
let
pass1
=
alt
ty
::
get
(
self
.self_ty
)
.struct
{
ty
::
ty_param
(
n
,
did
)
{
...
...
@@ -288,6 +291,11 @@ fn write_mty_from_fty(self_substs: ty::substs,
let
tcx
=
self
.fcx.ccx.tcx
;
#
debug
[
"write_mty_from_fty(n_tps_m=%u, fty=%s, origin=%?)"
,
n_tps_m
,
self
.fcx.infcx
.ty_to_str
(
fty
),
origin
];
// Here I will use the "c_" prefix to refer to the method's
// owner. You can read it as class, but it may also be an iface.
...
...
src/rustc/middle/typeck/collect.rs
浏览文件 @
3c4baf69
...
...
@@ -228,17 +228,15 @@ fn check_methods_against_iface(ccx: @crate_ctxt,
rp
:
ast
::
region_param
,
selfty
:
ty
::
t
,
a_ifacety
:
@
ast
::
iface_ref
,
ms
:
[
@
ast
::
method
])
{
ms
:
[
converted_
method
])
{
let
tcx
=
ccx
.tcx
;
let
i_bounds
=
ty_param_bounds
(
ccx
,
tps
);
let
my_methods
=
convert_methods
(
ccx
,
ms
,
rp
,
i_bounds
,
selfty
);
let
(
did
,
tpt
)
=
instantiate_iface_ref
(
ccx
,
a_ifacety
,
rp
);
if
did
.crate
==
ast
::
local_crate
{
ensure_iface_methods
(
ccx
,
did
.node
);
}
for
vec
::
each
(
*
ty
::
iface_methods
(
tcx
,
did
))
{|
if_m
|
alt
vec
::
find
(
m
y_method
s
,
{|
m
|
if_m
.ident
==
m
.mty.ident
})
{
alt
vec
::
find
(
ms
,
{|
m
|
if_m
.ident
==
m
.mty.ident
})
{
some
({
mty
:
m
,
id
,
span
})
{
if
m
.purity
!=
if_m
.purity
{
ccx
.tcx.sess
.span_err
(
...
...
@@ -274,12 +272,13 @@ fn convert_class_item(ccx: @crate_ctxt,
ccx
.tcx.tcache
.insert
(
local_def
(
v
.id
),
{
bounds
:
bounds
,
rp
:
rp
,
ty
:
tt
});
}
type
converted_method
=
{
mty
:
ty
::
method
,
id
:
ast
::
node_id
,
span
:
span
};
fn
convert_methods
(
ccx
:
@
crate_ctxt
,
ms
:
[
@
ast
::
method
],
rp
:
ast
::
region_param
,
i_bounds
:
@
[
ty
::
param_bounds
],
self_ty
:
ty
::
t
)
->
[{
mty
:
ty
::
method
,
id
:
ast
::
node_id
,
span
:
span
}]
{
rcvr_bounds
:
@
[
ty
::
param_bounds
],
self_ty
:
ty
::
t
)
->
[
converted_method
]
{
let
tcx
=
ccx
.tcx
;
vec
::
map
(
ms
)
{
|
m
|
...
...
@@ -289,9 +288,10 @@ fn convert_methods(ccx: @crate_ctxt,
let
fty
=
ty
::
mk_fn
(
tcx
,
mty
.fty
);
tcx
.tcache
.insert
(
local_def
(
m
.id
),
// n.b. This code is kind of sketchy (concat'ing i_bounds
// with bounds), but removing *i_bounds breaks other stuff
{
bounds
:
@
(
*
i_bounds
+
*
bounds
),
rp
:
rp
,
ty
:
fty
});
// n.b.: the type of a method is parameterized by both
// the tps on the receiver and those on the method itself
{
bounds
:
@
(
*
rcvr_bounds
+
*
bounds
),
rp
:
rp
,
ty
:
fty
});
write_ty_to_tcx
(
tcx
,
m
.id
,
fty
);
{
mty
:
mty
,
id
:
m
.id
,
span
:
m
.span
}
}
...
...
@@ -316,19 +316,10 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
{
bounds
:
i_bounds
,
rp
:
rp
,
ty
:
selfty
});
alt
ifce
{
some
(
t
)
{
check_methods_against_iface
(
ccx
,
tps
,
rp
,
selfty
,
t
,
ms
);
}
_
{
// Still have to do this to write method types
// into the table
convert_methods
(
ccx
,
ms
,
rp
,
i_bounds
,
selfty
);
}
let
cms
=
convert_methods
(
ccx
,
ms
,
rp
,
i_bounds
,
selfty
);
for
ifce
.each
{
|
t
|
check_methods_against_iface
(
ccx
,
tps
,
rp
,
selfty
,
t
,
cms
);
}
}
ast
::
item_res
(
decl
,
tps
,
_
,
dtor_id
,
ctor_id
,
rp
)
{
...
...
@@ -412,23 +403,11 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
for
fields
.each
{|
f
|
convert_class_item
(
ccx
,
rp
,
tpt
.bounds
,
f
);
}
// The selfty is just the class type
let
{
bounds
:
_
,
substs
}
=
mk_substs
(
ccx
,
tps
,
rp
);
let
{
bounds
,
substs
}
=
mk_substs
(
ccx
,
tps
,
rp
);
let
selfty
=
ty
::
mk_class
(
tcx
,
local_def
(
it
.id
),
substs
);
// Need to convert all methods so we can check internal
// references to private methods
// NDM to TJC---I think we ought to be using bounds here, not @[].
// But doing so causes errors later on.
convert_methods
(
ccx
,
methods
,
rp
,
@
[],
selfty
);
/*
Finally, check that the class really implements the ifaces
that it claims to implement.
*/
let
cms
=
convert_methods
(
ccx
,
methods
,
rp
,
bounds
,
selfty
);
for
ifaces
.each
{
|
ifce
|
check_methods_against_iface
(
ccx
,
tps
,
rp
,
selfty
,
ifce
,
methods
);
check_methods_against_iface
(
ccx
,
tps
,
rp
,
selfty
,
ifce
,
cms
);
// FIXME #2434---this is somewhat bogus, but it seems that
// the id of iface_ref is also the id of the impl, and so
...
...
src/test/run-pass/borrowck-preserve-box-in-pat.rs
浏览文件 @
3c4baf69
// xfail-test (still buggy)
// xfail-fast (compile-flags unsupported on windows)
// compile-flags:--borrowck=err
// exec-env:RUST_POISON_ON_FREE=1
...
...
src/test/run-pass/class-impl-very-parameterized-iface.rs
浏览文件 @
3c4baf69
// xfail-test
// xfail-fast
use
std
;
import
std
::
map
::
*
;
...
...
@@ -59,7 +57,7 @@ fn find(&&k:int) -> option<T> { if k <= self.meows {
}
else
{
none
}
}
fn
remove
(
&&
k
:
int
)
->
option
<
T
>
{
alt
self
.find
(
k
)
{
some
(
x
)
{
...
...
@@ -76,7 +74,7 @@ fn each(f: fn(&&int, &&T) -> bool) {
n
-=
1
;
}
}
fn
each_key
(
&&
f
:
fn
(
&&
int
)
->
bool
)
{
for
self
.each
{|
k
,
_
v
|
if
!
f
(
k
)
{
break
;
}
cont
;};
}
...
...
@@ -88,11 +86,11 @@ fn each_value(&&f: fn(&&T) -> bool) {
fn
main
()
{
let
nyan
:
cat
<
str
>
=
cat
(
0
,
2
,
"nyan"
);
uint
::
range
(
1u
,
5u
)
{|
_
i
|
nyan
.speak
();
}
for
uint
::
range
(
1u
,
5u
)
{|
_
i
|
nyan
.speak
();
}
assert
(
nyan
.find
(
1
)
==
some
(
"nyan"
));
assert
(
nyan
.find
(
10
)
==
none
);
let
spotty
:
cat
<
cat_type
>
=
cat
(
2
,
57
,
tuxedo
);
uint
::
range
(
0u
,
6u
)
{|
_
i
|
spotty
.speak
();
}
for
uint
::
range
(
0u
,
6u
)
{|
_
i
|
spotty
.speak
();
}
assert
(
spotty
.size
()
==
8u
);
assert
(
spotty
.contains_key
(
2
));
assert
(
spotty
.get
(
3
)
==
tuxedo
);
...
...
src/test/run-pass/class-poly-methods-cross-crate.rs
浏览文件 @
3c4baf69
// xfail-test
// xfail-fast
// aux-build:cci_class_6.rs
use
cci_class_6
;
...
...
src/test/run-pass/class-typarams.rs
浏览文件 @
3c4baf69
// xfail-test
// needs metadata encoding on Windows
class
cat
<
U
>
{
priv
{
let
mut
meows
:
uint
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录