Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
54ae377e
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,发现更多精彩内容 >>
提交
54ae377e
编写于
11月 29, 2012
作者:
P
Patrick Walton
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
librustc: Implement explicit @self and ~self for objects. r=nmatsakis
上级
3afd6c3d
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
149 addition
and
27 deletion
+149
-27
src/librustc/middle/trans/meth.rs
src/librustc/middle/trans/meth.rs
+60
-15
src/librustc/middle/typeck/check/method.rs
src/librustc/middle/typeck/check/method.rs
+42
-12
src/test/run-pass/explicit-self-objects-box.rs
src/test/run-pass/explicit-self-objects-box.rs
+24
-0
src/test/run-pass/explicit-self-objects-uniq.rs
src/test/run-pass/explicit-self-objects-uniq.rs
+23
-0
未找到文件。
src/librustc/middle/trans/meth.rs
浏览文件 @
54ae377e
...
...
@@ -546,40 +546,85 @@ fn trans_trait_callee_from_llval(bcx: block,
let
mut
llself
;
debug!
(
"(translating trait callee) loading second index from pair"
);
let
llbox
=
Load
(
bcx
,
GEPi
(
bcx
,
llpair
,
[
0u
,
1u
]));
match
vstore
{
ty
::
vstore_box
|
ty
::
vstore_uniq
=>
{
llself
=
GEPi
(
bcx
,
llbox
,
[
0u
,
abi
::
box_field_body
]);
}
ty
::
vstore_slice
(
_
)
=>
{
llself
=
llbox
;
}
ty
::
vstore_fixed
(
*
)
=>
{
bcx
.tcx
()
.sess
.bug
(
~
"vstore_fixed trait"
);
}
}
// Munge `llself` appropriately for the type of `self` in the method.
let
self_mode
;
match
explicit_self
{
ast
::
sty_static
=>
{
bcx
.tcx
()
.sess
.bug
(
~
"shouldn't see static method here"
);
}
ast
::
sty_by_ref
=>
{}
// Nothing to do.
ast
::
sty_by_ref
=>
{
// We need to pass a pointer to a pointer to the payload.
match
vstore
{
ty
::
vstore_box
|
ty
::
vstore_uniq
=>
{
llself
=
GEPi
(
bcx
,
llbox
,
[
0u
,
abi
::
box_field_body
]);
}
ty
::
vstore_slice
(
_
)
=>
{
llself
=
llbox
;
}
ty
::
vstore_fixed
(
*
)
=>
{
bcx
.tcx
()
.sess
.bug
(
~
"vstore_fixed trait"
);
}
}
self_mode
=
ast
::
by_ref
;
}
ast
::
sty_value
=>
{
bcx
.tcx
()
.sess
.bug
(
~
"methods with by-value self should not be
\
called on objects"
);
}
ast
::
sty_region
(
_
)
=>
{
// As before, we need to pass a pointer to a pointer to the
// payload.
match
vstore
{
ty
::
vstore_box
|
ty
::
vstore_uniq
=>
{
llself
=
GEPi
(
bcx
,
llbox
,
[
0u
,
abi
::
box_field_body
]);
}
ty
::
vstore_slice
(
_
)
=>
{
llself
=
llbox
;
}
ty
::
vstore_fixed
(
*
)
=>
{
bcx
.tcx
()
.sess
.bug
(
~
"vstore_fixed trait"
);
}
}
let
llscratch
=
alloca
(
bcx
,
val_ty
(
llself
));
Store
(
bcx
,
llself
,
llscratch
);
llself
=
llscratch
;
self_mode
=
ast
::
by_ref
;
}
ast
::
sty_box
(
_
)
=>
{
// Bump the reference count on the box.
debug!
(
"(translating trait callee) callee type is `%s`"
,
bcx
.ty_to_str
(
callee_ty
));
bcx
=
glue
::
take_ty
(
bcx
,
llself
,
callee_ty
);
bcx
=
glue
::
take_ty
(
bcx
,
llbox
,
callee_ty
);
// Pass a pointer to the box.
match
vstore
{
ty
::
vstore_box
=>
llself
=
llbox
,
_
=>
bcx
.tcx
()
.sess
.bug
(
~
"@self receiver with non-@Trait"
)
}
let
llscratch
=
alloca
(
bcx
,
val_ty
(
llself
));
Store
(
bcx
,
llself
,
llscratch
);
llself
=
llscratch
;
self_mode
=
ast
::
by_ref
;
}
ast
::
sty_uniq
(
_
)
=>
{
// Pass the unique pointer.
match
vstore
{
ty
::
vstore_uniq
=>
llself
=
llbox
,
_
=>
bcx
.tcx
()
.sess
.bug
(
~
"~self receiver with non-~Trait"
)
}
let
llscratch
=
alloca
(
bcx
,
val_ty
(
llself
));
Store
(
bcx
,
llself
,
llscratch
);
llself
=
llscratch
;
self_mode
=
ast
::
by_ref
;
}
ast
::
sty_uniq
(
_
)
=>
{}
// Nothing to do here.
}
// Load the function from the vtable and cast it to the expected type.
...
...
@@ -594,7 +639,7 @@ fn trans_trait_callee_from_llval(bcx: block,
llfn
:
mptr
,
llself
:
llself
,
self_ty
:
ty
::
mk_opaque_box
(
bcx
.tcx
()),
self_mode
:
ast
::
by_ref
,
// XXX: is this bogosity?
self_mode
:
self_mode
,
/* XXX: Some(llbox) */
})
};
...
...
src/librustc/middle/typeck/check/method.rs
浏览文件 @
54ae377e
...
...
@@ -140,6 +140,15 @@ struct Candidate {
origin
:
method_origin
,
}
/**
* Whether the self type should be transformed according to the form of
* explicit self provided by the method.
*/
enum
TransformTypeFlag
{
DontTransformType
,
TransformType
}
impl
LookupContext
{
fn
do_lookup
(
&
self
,
self_ty
:
ty
::
t
)
->
Option
<
method_map_entry
>
{
debug!
(
"do_lookup(self_ty=%s, expr=%s, self_expr=%s)"
,
...
...
@@ -402,7 +411,10 @@ fn push_inherent_candidates_from_param(&self, rcvr_ty: ty::t,
let
(
rcvr_ty
,
rcvr_substs
)
=
self
.create_rcvr_ty_and_substs_for_method
(
method
.self_ty
,
rcvr_ty
,
move
init_substs
);
method
.self_ty
,
rcvr_ty
,
move
init_substs
,
TransformType
);
let
cand
=
Candidate
{
rcvr_ty
:
rcvr_ty
,
...
...
@@ -461,8 +473,10 @@ fn push_inherent_candidates_from_trait(&self,
let
rcvr_substs
=
{
self_ty
:
Some
(
self_ty
),
..*
substs
};
let
(
rcvr_ty
,
rcvr_substs
)
=
self
.create_rcvr_ty_and_substs_for_method
(
method
.self_ty
,
self_ty
,
move
rcvr_substs
);
self
.create_rcvr_ty_and_substs_for_method
(
method
.self_ty
,
self_ty
,
move
rcvr_substs
,
DontTransformType
);
self
.inherent_candidates
.push
(
Candidate
{
rcvr_ty
:
rcvr_ty
,
...
...
@@ -490,7 +504,10 @@ fn push_inherent_candidates_from_self(&self,
let
rcvr_substs
=
{
self_ty
:
Some
(
self_ty
),
..*
substs
};
let
(
rcvr_ty
,
rcvr_substs
)
=
self
.create_rcvr_ty_and_substs_for_method
(
method
.self_ty
,
self_ty
,
move
rcvr_substs
);
method
.self_ty
,
self_ty
,
move
rcvr_substs
,
TransformType
);
self
.inherent_candidates
.push
(
Candidate
{
rcvr_ty
:
rcvr_ty
,
...
...
@@ -542,7 +559,10 @@ fn push_candidates_from_impl(&self, candidates: &DVec<Candidate>,
let
(
impl_ty
,
impl_substs
)
=
self
.create_rcvr_ty_and_substs_for_method
(
method
.self_type
,
impl_ty
,
move
impl_substs
);
method
.self_type
,
impl_ty
,
move
impl_substs
,
TransformType
);
candidates
.push
(
Candidate
{
rcvr_ty
:
impl_ty
,
...
...
@@ -577,7 +597,8 @@ fn push_candidates_from_provided_methods(
self
.create_rcvr_ty_and_substs_for_method
(
provided_method_info
.method_info.self_type
,
self_ty
,
dummy_substs
);
dummy_substs
,
TransformType
);
candidates
.push
(
Candidate
{
rcvr_ty
:
impl_ty
,
...
...
@@ -594,8 +615,9 @@ fn push_candidates_from_provided_methods(
fn
create_rcvr_ty_and_substs_for_method
(
&
self
,
self_decl
:
ast
::
self_ty_
,
self_ty
:
ty
::
t
,
+
self_substs
:
ty
::
substs
)
->
(
ty
::
t
,
ty
::
substs
)
{
+
self_substs
:
ty
::
substs
,
transform_type
:
TransformTypeFlag
)
->
(
ty
::
t
,
ty
::
substs
)
{
// If the self type includes a region (like &self), we need to
// ensure that the receiver substitutions have a self region.
// If the receiver type does not itself contain borrowed
...
...
@@ -624,10 +646,18 @@ fn create_rcvr_ty_and_substs_for_method(&self,
}
};
let
rcvr_ty
=
transform_self_type_for_method
(
self
.tcx
(),
rcvr_substs
.self_r
,
self_ty
,
self_decl
);
let
rcvr_ty
;
match
transform_type
{
TransformType
=>
{
rcvr_ty
=
transform_self_type_for_method
(
self
.tcx
(),
rcvr_substs
.self_r
,
self_ty
,
self_decl
);
}
DontTransformType
=>
{
rcvr_ty
=
self_ty
;
}
}
(
rcvr_ty
,
rcvr_substs
)
}
...
...
src/test/run-pass/explicit-self-objects-box.rs
0 → 100644
浏览文件 @
54ae377e
trait
Foo
{
fn
f
(
@
self
);
}
struct
S
{
x
:
int
}
impl
S
:
Foo
{
fn
f
(
@
self
)
{
assert
self
.x
==
3
;
}
}
fn
main
()
{
let
x
=
@
S
{
x
:
3
};
let
y
=
x
as
@
Foo
;
y
.f
();
y
.f
();
y
.f
();
y
.f
();
}
src/test/run-pass/explicit-self-objects-uniq.rs
0 → 100644
浏览文件 @
54ae377e
trait
Foo
{
fn
f
(
~
self
);
}
struct
S
{
x
:
int
}
impl
S
:
Foo
{
fn
f
(
~
self
)
{
assert
self
.x
==
3
;
}
}
fn
main
()
{
let
x
=
~
S
{
x
:
3
};
let
y
=
x
as
~
Foo
;
y
.f
();
y
.f
();
y
.f
();
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录