Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
31f5ab3f
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,发现更多精彩内容 >>
提交
31f5ab3f
编写于
12月 14, 2014
作者:
N
Nick Cameron
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Allow `Self` in impls.
上级
cbe9fb45
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
90 addition
and
5 deletion
+90
-5
src/libsyntax/ext/base.rs
src/libsyntax/ext/base.rs
+1
-1
src/libsyntax/ext/expand.rs
src/libsyntax/ext/expand.rs
+47
-4
src/test/run-pass/self-impl.rs
src/test/run-pass/self-impl.rs
+42
-0
未找到文件。
src/libsyntax/ext/base.rs
浏览文件 @
31f5ab3f
...
...
@@ -490,7 +490,7 @@ pub fn expand_expr(&mut self, e: P<ast::Expr>) -> P<ast::Expr> {
/// Returns a `Folder` for deeply expanding all macros in a AST node.
pub
fn
expander
<
'b
>
(
&
'b
mut
self
)
->
expand
::
MacroExpander
<
'b
,
'a
>
{
expand
::
MacroExpander
{
cx
:
self
}
expand
::
MacroExpander
::
new
(
self
)
}
pub
fn
new_parser_from_tts
(
&
self
,
tts
:
&
[
ast
::
TokenTree
])
...
...
src/libsyntax/ext/expand.rs
浏览文件 @
31f5ab3f
...
...
@@ -15,6 +15,7 @@
use
ast
::{
StmtExpr
,
StmtSemi
};
use
ast
::
TokenTree
;
use
ast
;
use
ast_util
::
path_to_ident
;
use
ext
::
mtwt
;
use
ext
::
build
::
AstBuilder
;
use
attr
;
...
...
@@ -37,6 +38,30 @@ enum Either<L,R> {
Right
(
R
)
}
pub
fn
expand_type
(
t
:
P
<
ast
::
Ty
>
,
fld
:
&
mut
MacroExpander
,
impl_ty
:
Option
<
P
<
ast
::
Ty
>>
)
->
P
<
ast
::
Ty
>
{
debug!
(
"expanding type {} with impl_ty {}"
,
t
,
impl_ty
);
let
t
=
match
(
t
.node
.clone
(),
impl_ty
)
{
// Expand uses of `Self` in impls to the concrete type.
(
ast
::
Ty_
::
TyPath
(
ref
path
,
_
),
Some
(
ref
impl_ty
))
=>
{
let
path_as_ident
=
path_to_ident
(
path
);
// Note unhygenic comparison here. I think this is correct, since
// even though `Self` is almost just a type parameter, the treatment
// for this expansion is as if it were a keyword.
if
path_as_ident
.is_some
()
&&
path_as_ident
.unwrap
()
.name
==
token
::
special_idents
::
type_self
.name
{
impl_ty
.clone
()
}
else
{
t
}
}
_
=>
t
};
fold
::
noop_fold_ty
(
t
,
fld
)
}
pub
fn
expand_expr
(
e
:
P
<
ast
::
Expr
>
,
fld
:
&
mut
MacroExpander
)
->
P
<
ast
::
Expr
>
{
e
.and_then
(|
ast
::
Expr
{
id
,
node
,
span
}|
match
node
{
// expr_mac should really be expr_ext or something; it's the
...
...
@@ -1059,6 +1084,14 @@ fn expand_and_rename_fn_decl_and_block(fn_decl: P<ast::FnDecl>, block: P<ast::Bl
/// A tree-folder that performs macro expansion
pub
struct
MacroExpander
<
'a
,
'b
:
'a
>
{
pub
cx
:
&
'a
mut
ExtCtxt
<
'b
>
,
// The type of the impl currently being expanded.
current_impl_type
:
Option
<
P
<
ast
::
Ty
>>
,
}
impl
<
'a
,
'b
>
MacroExpander
<
'a
,
'b
>
{
pub
fn
new
(
cx
:
&
'a
mut
ExtCtxt
<
'b
>
)
->
MacroExpander
<
'a
,
'b
>
{
MacroExpander
{
cx
:
cx
,
current_impl_type
:
None
}
}
}
impl
<
'a
,
'b
>
Folder
for
MacroExpander
<
'a
,
'b
>
{
...
...
@@ -1071,7 +1104,14 @@ fn fold_pat(&mut self, pat: P<ast::Pat>) -> P<ast::Pat> {
}
fn
fold_item
(
&
mut
self
,
item
:
P
<
ast
::
Item
>
)
->
SmallVector
<
P
<
ast
::
Item
>>
{
expand_item
(
item
,
self
)
let
prev_type
=
self
.current_impl_type
.clone
();
if
let
ast
::
Item_
::
ItemImpl
(
_
,
_
,
_
,
ref
ty
,
_
)
=
item
.node
{
self
.current_impl_type
=
Some
(
ty
.clone
());
}
let
result
=
expand_item
(
item
,
self
);
self
.current_impl_type
=
prev_type
;
result
}
fn
fold_item_underscore
(
&
mut
self
,
item
:
ast
::
Item_
)
->
ast
::
Item_
{
...
...
@@ -1094,6 +1134,11 @@ fn fold_method(&mut self, method: P<ast::Method>) -> SmallVector<P<ast::Method>>
expand_method
(
method
,
self
)
}
fn
fold_ty
(
&
mut
self
,
t
:
P
<
ast
::
Ty
>
)
->
P
<
ast
::
Ty
>
{
let
impl_type
=
self
.current_impl_type
.clone
();
expand_type
(
t
,
self
,
impl_type
)
}
fn
new_span
(
&
mut
self
,
span
:
Span
)
->
Span
{
new_span
(
self
.cx
,
span
)
}
...
...
@@ -1138,9 +1183,7 @@ pub fn expand_crate(parse_sess: &parse::ParseSess,
user_exts
:
Vec
<
NamedSyntaxExtension
>
,
c
:
Crate
)
->
Crate
{
let
mut
cx
=
ExtCtxt
::
new
(
parse_sess
,
c
.config
.clone
(),
cfg
);
let
mut
expander
=
MacroExpander
{
cx
:
&
mut
cx
,
};
let
mut
expander
=
MacroExpander
::
new
(
&
mut
cx
);
for
ExportedMacros
{
crate_name
,
macros
}
in
imported_macros
.into_iter
()
{
let
name
=
format!
(
"<{} macros>"
,
token
::
get_ident
(
crate_name
))
...
...
src/test/run-pass/self-impl.rs
0 → 100644
浏览文件 @
31f5ab3f
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Test that we can use `Self` types in impls in the expected way.
struct
Foo
;
// Test uses on inherant impl.
impl
Foo
{
fn
foo
(
_
x
:
Self
,
_
y
:
&
Self
,
_
z
:
Box
<
Self
>
)
->
Self
{
Foo
}
}
// Test uses when implementing a trait and with a type parameter.
pub
struct
Baz
<
X
>
{
pub
f
:
X
,
}
trait
Bar
<
X
>
{
fn
bar
(
x
:
Self
,
y
:
&
Self
,
z
:
Box
<
Self
>
)
->
Self
;
}
impl
Bar
<
int
>
for
Box
<
Baz
<
int
>>
{
fn
bar
(
_
x
:
Self
,
_
y
:
&
Self
,
_
z
:
Box
<
Self
>
)
->
Self
{
box
Baz
{
f
:
42
}
}
}
fn
main
()
{
let
_
:
Foo
=
Foo
::
foo
(
Foo
,
&
Foo
,
box
Foo
);
let
_
:
Box
<
Baz
<
int
>>
=
Bar
::
bar
(
box
Baz
{
f
:
42
},
&
box
Baz
{
f
:
42
},
box
box
Baz
{
f
:
42
});
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录