Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
5d74990c
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,发现更多精彩内容 >>
提交
5d74990c
编写于
3月 10, 2018
作者:
A
Austin Bonander
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
expand macro invocations in `extern {}` blocks
上级
5ee891cf
变更
31
显示空白变更内容
内联
并排
Showing
31 changed file
with
544 addition
and
65 deletion
+544
-65
src/librustc/hir/lowering.rs
src/librustc/hir/lowering.rs
+1
-0
src/librustc/hir/map/def_collector.rs
src/librustc/hir/map/def_collector.rs
+4
-0
src/librustc_passes/ast_validation.rs
src/librustc_passes/ast_validation.rs
+17
-1
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/build_reduced_graph.rs
+6
-0
src/librustc_resolve/lib.rs
src/librustc_resolve/lib.rs
+1
-0
src/librustc_save_analysis/dump_visitor.rs
src/librustc_save_analysis/dump_visitor.rs
+1
-0
src/librustc_save_analysis/lib.rs
src/librustc_save_analysis/lib.rs
+1
-0
src/librustc_save_analysis/sig.rs
src/librustc_save_analysis/sig.rs
+1
-0
src/libsyntax/ast.rs
src/libsyntax/ast.rs
+3
-0
src/libsyntax/ext/base.rs
src/libsyntax/ext/base.rs
+28
-0
src/libsyntax/ext/expand.rs
src/libsyntax/ext/expand.rs
+58
-0
src/libsyntax/ext/placeholders.rs
src/libsyntax/ext/placeholders.rs
+11
-0
src/libsyntax/feature_gate.rs
src/libsyntax/feature_gate.rs
+11
-0
src/libsyntax/fold.rs
src/libsyntax/fold.rs
+17
-3
src/libsyntax/parse/parser.rs
src/libsyntax/parse/parser.rs
+69
-55
src/libsyntax/parse/token.rs
src/libsyntax/parse/token.rs
+2
-0
src/libsyntax/print/pprust.rs
src/libsyntax/print/pprust.rs
+9
-0
src/libsyntax/visit.rs
src/libsyntax/visit.rs
+1
-0
src/libsyntax_ext/deriving/custom.rs
src/libsyntax_ext/deriving/custom.rs
+1
-0
src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs
src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs
+5
-1
src/test/compile-fail-fulldeps/proc-macro/auxiliary/test-macros.rs
...compile-fail-fulldeps/proc-macro/auxiliary/test-macros.rs
+36
-0
src/test/compile-fail-fulldeps/proc-macro/macros-in-extern.rs
...test/compile-fail-fulldeps/proc-macro/macros-in-extern.rs
+38
-0
src/test/compile-fail/macros-in-extern.rs
src/test/compile-fail/macros-in-extern.rs
+42
-0
src/test/parse-fail/duplicate-visibility.rs
src/test/parse-fail/duplicate-visibility.rs
+1
-1
src/test/parse-fail/extern-no-fn.rs
src/test/parse-fail/extern-no-fn.rs
+2
-2
src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs
src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs
+6
-2
src/test/run-pass-fulldeps/proc-macro/auxiliary/test-macros.rs
...est/run-pass-fulldeps/proc-macro/auxiliary/test-macros.rs
+36
-0
src/test/run-pass-fulldeps/proc-macro/macros-in-extern.rs
src/test/run-pass-fulldeps/proc-macro/macros-in-extern.rs
+35
-0
src/test/run-pass/macros-in-extern.rs
src/test/run-pass/macros-in-extern.rs
+39
-0
src/test/ui/feature-gate-macros_in_extern.rs
src/test/ui/feature-gate-macros_in_extern.rs
+35
-0
src/test/ui/feature-gate-macros_in_extern.stderr
src/test/ui/feature-gate-macros_in_extern.stderr
+27
-0
未找到文件。
src/librustc/hir/lowering.rs
浏览文件 @
5d74990c
...
...
@@ -2724,6 +2724,7 @@ fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem {
hir
::
ForeignItemStatic
(
this
.lower_ty
(
t
,
ImplTraitContext
::
Disallowed
),
m
)
}
ForeignItemKind
::
Ty
=>
hir
::
ForeignItemType
,
ForeignItemKind
::
Macro
(
_
)
=>
panic!
(
"shouldn't exist here"
),
},
vis
:
this
.lower_visibility
(
&
i
.vis
,
None
),
span
:
i
.span
,
...
...
src/librustc/hir/map/def_collector.rs
浏览文件 @
5d74990c
...
...
@@ -181,6 +181,10 @@ fn visit_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId, _nested: bool) {
}
fn
visit_foreign_item
(
&
mut
self
,
foreign_item
:
&
'a
ForeignItem
)
{
if
let
ForeignItemKind
::
Macro
(
_
)
=
foreign_item
.node
{
return
self
.visit_macro_invoc
(
foreign_item
.id
,
false
);
}
let
def
=
self
.create_def
(
foreign_item
.id
,
DefPathData
::
ValueNs
(
foreign_item
.ident.name
.as_str
()),
REGULAR_SPACE
,
...
...
src/librustc_passes/ast_validation.rs
浏览文件 @
5d74990c
...
...
@@ -381,7 +381,7 @@ fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
.span_label
(
span
,
"pattern not allowed in foreign function"
)
.emit
();
});
}
ForeignItemKind
::
Static
(
..
)
|
ForeignItemKind
::
Ty
=>
{}
ForeignItemKind
::
Static
(
..
)
|
ForeignItemKind
::
Ty
|
ForeignItemKind
::
Macro
(
..
)
=>
{}
}
visit
::
walk_foreign_item
(
self
,
fi
)
...
...
@@ -460,6 +460,14 @@ fn visit_poly_trait_ref(&mut self, t: &'a PolyTraitRef, m: &'a TraitBoundModifie
self
.check_late_bound_lifetime_defs
(
&
t
.bound_generic_params
);
visit
::
walk_poly_trait_ref
(
self
,
t
,
m
);
}
fn
visit_mac
(
&
mut
self
,
mac
:
&
Spanned
<
Mac_
>
)
{
// when a new macro kind is added but the author forgets to set it up for expansion
// because that's the only part that won't cause a compiler error
self
.session
.diagnostic
()
.span_bug
(
mac
.span
,
"macro invocation missed in expansion; did you forget to override
\
the relevant `fold_*()` method in `PlaceholderExpander`?"
);
}
}
// Bans nested `impl Trait`, e.g. `impl Into<impl Debug>`.
...
...
@@ -522,6 +530,10 @@ fn visit_path_parameters(&mut self, _: Span, path_parameters: &'a PathParameters
}
}
}
fn
visit_mac
(
&
mut
self
,
_
mac
:
&
Spanned
<
Mac_
>
)
{
// covered in AstValidator
}
}
// Bans `impl Trait` in path projections like `<impl Iterator>::Item` or `Foo::Bar<impl Trait>`.
...
...
@@ -583,6 +595,10 @@ fn visit_ty(&mut self, t: &'a Ty) {
_
=>
visit
::
walk_ty
(
self
,
t
),
}
}
fn
visit_mac
(
&
mut
self
,
_
mac
:
&
Spanned
<
Mac_
>
)
{
// covered in AstValidator
}
}
pub
fn
check_crate
(
session
:
&
Session
,
krate
:
&
Crate
)
{
...
...
src/librustc_resolve/build_reduced_graph.rs
浏览文件 @
5d74990c
...
...
@@ -456,6 +456,7 @@ fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem, expansion
ForeignItemKind
::
Ty
=>
{
(
Def
::
TyForeign
(
self
.definitions
.local_def_id
(
item
.id
)),
TypeNS
)
}
ForeignItemKind
::
Macro
(
_
)
=>
unreachable!
(),
};
let
parent
=
self
.current_module
;
let
vis
=
self
.resolve_visibility
(
&
item
.vis
);
...
...
@@ -816,6 +817,11 @@ fn visit_stmt(&mut self, stmt: &'a ast::Stmt) {
}
fn
visit_foreign_item
(
&
mut
self
,
foreign_item
:
&
'a
ForeignItem
)
{
if
let
ForeignItemKind
::
Macro
(
_
)
=
foreign_item
.node
{
self
.visit_invoc
(
foreign_item
.id
);
return
;
}
self
.resolver
.build_reduced_graph_for_foreign_item
(
foreign_item
,
self
.expansion
);
visit
::
walk_foreign_item
(
self
,
foreign_item
);
}
...
...
src/librustc_resolve/lib.rs
浏览文件 @
5d74990c
...
...
@@ -863,6 +863,7 @@ fn visit_foreign_item(&mut self, foreign_item: &'tcx ForeignItem) {
}
ForeignItemKind
::
Static
(
..
)
=>
NoTypeParameters
,
ForeignItemKind
::
Ty
=>
NoTypeParameters
,
ForeignItemKind
::
Macro
(
..
)
=>
NoTypeParameters
,
};
self
.with_type_parameter_rib
(
type_parameters
,
|
this
|
{
visit
::
walk_foreign_item
(
this
,
foreign_item
);
...
...
src/librustc_save_analysis/dump_visitor.rs
浏览文件 @
5d74990c
...
...
@@ -1812,6 +1812,7 @@ fn visit_foreign_item(&mut self, item: &'l ast::ForeignItem) {
self
.dumper
.dump_def
(
&
access
,
var_data
);
}
}
ast
::
ForeignItemKind
::
Macro
(
..
)
=>
{}
}
}
}
src/librustc_save_analysis/lib.rs
浏览文件 @
5d74990c
...
...
@@ -182,6 +182,7 @@ pub fn get_extern_item_data(&self, item: &ast::ForeignItem) -> Option<Data> {
}
// FIXME(plietar): needs a new DefKind in rls-data
ast
::
ForeignItemKind
::
Ty
=>
None
,
ast
::
ForeignItemKind
::
Macro
(
..
)
=>
None
,
}
}
...
...
src/librustc_save_analysis/sig.rs
浏览文件 @
5d74990c
...
...
@@ -822,6 +822,7 @@ fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext) ->
refs
:
vec!
[],
})
}
ast
::
ForeignItemKind
::
Macro
(
..
)
=>
Err
(
"macro"
),
}
}
}
...
...
src/libsyntax/ast.rs
浏览文件 @
5d74990c
...
...
@@ -2195,6 +2195,8 @@ pub enum ForeignItemKind {
Static
(
P
<
Ty
>
,
bool
),
/// A foreign type
Ty
,
/// A macro invocation
Macro
(
Mac
),
}
impl
ForeignItemKind
{
...
...
@@ -2203,6 +2205,7 @@ pub fn descriptive_variant(&self) -> &str {
ForeignItemKind
::
Fn
(
..
)
=>
"foreign function"
,
ForeignItemKind
::
Static
(
..
)
=>
"foreign static item"
,
ForeignItemKind
::
Ty
=>
"foreign type"
,
ForeignItemKind
::
Macro
(
..
)
=>
"macro in foreign module"
,
}
}
}
...
...
src/libsyntax/ext/base.rs
浏览文件 @
5d74990c
...
...
@@ -38,6 +38,7 @@ pub enum Annotatable {
Item
(
P
<
ast
::
Item
>
),
TraitItem
(
P
<
ast
::
TraitItem
>
),
ImplItem
(
P
<
ast
::
ImplItem
>
),
ForeignItem
(
P
<
ast
::
ForeignItem
>
),
Stmt
(
P
<
ast
::
Stmt
>
),
Expr
(
P
<
ast
::
Expr
>
),
}
...
...
@@ -48,6 +49,7 @@ fn attrs(&self) -> &[Attribute] {
Annotatable
::
Item
(
ref
item
)
=>
&
item
.attrs
,
Annotatable
::
TraitItem
(
ref
trait_item
)
=>
&
trait_item
.attrs
,
Annotatable
::
ImplItem
(
ref
impl_item
)
=>
&
impl_item
.attrs
,
Annotatable
::
ForeignItem
(
ref
foreign_item
)
=>
&
foreign_item
.attrs
,
Annotatable
::
Stmt
(
ref
stmt
)
=>
stmt
.attrs
(),
Annotatable
::
Expr
(
ref
expr
)
=>
&
expr
.attrs
,
}
...
...
@@ -58,6 +60,8 @@ fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
Annotatable
::
Item
(
item
)
=>
Annotatable
::
Item
(
item
.map_attrs
(
f
)),
Annotatable
::
TraitItem
(
trait_item
)
=>
Annotatable
::
TraitItem
(
trait_item
.map_attrs
(
f
)),
Annotatable
::
ImplItem
(
impl_item
)
=>
Annotatable
::
ImplItem
(
impl_item
.map_attrs
(
f
)),
Annotatable
::
ForeignItem
(
foreign_item
)
=>
Annotatable
::
ForeignItem
(
foreign_item
.map_attrs
(
f
)),
Annotatable
::
Stmt
(
stmt
)
=>
Annotatable
::
Stmt
(
stmt
.map_attrs
(
f
)),
Annotatable
::
Expr
(
expr
)
=>
Annotatable
::
Expr
(
expr
.map_attrs
(
f
)),
}
...
...
@@ -70,6 +74,7 @@ pub fn span(&self) -> Span {
Annotatable
::
Item
(
ref
item
)
=>
item
.span
,
Annotatable
::
TraitItem
(
ref
trait_item
)
=>
trait_item
.span
,
Annotatable
::
ImplItem
(
ref
impl_item
)
=>
impl_item
.span
,
Annotatable
::
ForeignItem
(
ref
foreign_item
)
=>
foreign_item
.span
,
Annotatable
::
Stmt
(
ref
stmt
)
=>
stmt
.span
,
Annotatable
::
Expr
(
ref
expr
)
=>
expr
.span
,
}
...
...
@@ -106,6 +111,13 @@ pub fn expect_impl_item(self) -> ast::ImplItem {
}
}
pub
fn
expect_foreign_item
(
self
)
->
ast
::
ForeignItem
{
match
self
{
Annotatable
::
ForeignItem
(
i
)
=>
i
.into_inner
(),
_
=>
panic!
(
"expected foreign item"
)
}
}
pub
fn
derive_allowed
(
&
self
)
->
bool
{
match
*
self
{
Annotatable
::
Item
(
ref
item
)
=>
match
item
.node
{
...
...
@@ -317,6 +329,9 @@ fn make_trait_items(self: Box<Self>) -> Option<SmallVector<ast::TraitItem>> {
None
}
/// Create zero or more items in an `extern {}` block
fn
make_foreign_items
(
self
:
Box
<
Self
>
)
->
Option
<
SmallVector
<
ast
::
ForeignItem
>>
{
None
}
/// Create a pattern.
fn
make_pat
(
self
:
Box
<
Self
>
)
->
Option
<
P
<
ast
::
Pat
>>
{
None
...
...
@@ -365,6 +380,7 @@ pub fn $fld(v: $t) -> Box<MacResult> {
items
:
SmallVector
<
P
<
ast
::
Item
>>
,
impl_items
:
SmallVector
<
ast
::
ImplItem
>
,
trait_items
:
SmallVector
<
ast
::
TraitItem
>
,
foreign_items
:
SmallVector
<
ast
::
ForeignItem
>
,
stmts
:
SmallVector
<
ast
::
Stmt
>
,
ty
:
P
<
ast
::
Ty
>
,
}
...
...
@@ -386,6 +402,10 @@ fn make_trait_items(self: Box<Self>) -> Option<SmallVector<ast::TraitItem>> {
self
.trait_items
}
fn
make_foreign_items
(
self
:
Box
<
Self
>
)
->
Option
<
SmallVector
<
ast
::
ForeignItem
>>
{
self
.foreign_items
}
fn
make_stmts
(
self
:
Box
<
Self
>
)
->
Option
<
SmallVector
<
ast
::
Stmt
>>
{
match
self
.stmts
.as_ref
()
.map_or
(
0
,
|
s
|
s
.len
())
{
0
=>
make_stmts_default!
(
self
),
...
...
@@ -502,6 +522,14 @@ fn make_trait_items(self: Box<DummyResult>) -> Option<SmallVector<ast::TraitItem
}
}
fn
make_foreign_items
(
self
:
Box
<
Self
>
)
->
Option
<
SmallVector
<
ast
::
ForeignItem
>>
{
if
self
.expr_only
{
None
}
else
{
Some
(
SmallVector
::
new
())
}
}
fn
make_stmts
(
self
:
Box
<
DummyResult
>
)
->
Option
<
SmallVector
<
ast
::
Stmt
>>
{
Some
(
SmallVector
::
one
(
ast
::
Stmt
{
id
:
ast
::
DUMMY_NODE_ID
,
...
...
src/libsyntax/ext/expand.rs
浏览文件 @
5d74990c
...
...
@@ -133,6 +133,8 @@ impl<'a> MacResult for ::ext::tt::macro_rules::ParserAnyMacro<'a> {
"trait item"
,
.make_trait_items
,
lift
.fold_trait_item
,
lift
.visit_trait_item
;
ImplItems
:
SmallVector
<
ast
::
ImplItem
>
[
SmallVector
,
ast
::
ImplItem
],
"impl item"
,
.make_impl_items
,
lift
.fold_impl_item
,
lift
.visit_impl_item
;
ForeignItems
:
SmallVector
<
ast
::
ForeignItem
>
[
SmallVector
,
ast
::
ForeignItem
],
"foreign item"
,
.make_foreign_items
,
lift
.fold_foreign_item
,
lift
.visit_foreign_item
;
}
impl
ExpansionKind
{
...
...
@@ -149,6 +151,8 @@ fn expect_from_annotatables<I: IntoIterator<Item = Annotatable>>(self, items: I)
Expansion
::
ImplItems
(
items
.map
(
Annotatable
::
expect_impl_item
)
.collect
()),
ExpansionKind
::
TraitItems
=>
Expansion
::
TraitItems
(
items
.map
(
Annotatable
::
expect_trait_item
)
.collect
()),
ExpansionKind
::
ForeignItems
=>
Expansion
::
ForeignItems
(
items
.map
(
Annotatable
::
expect_foreign_item
)
.collect
()),
_
=>
unreachable!
(),
}
}
...
...
@@ -435,6 +439,11 @@ fn fully_configure(&mut self, item: Annotatable) -> Annotatable {
Annotatable
::
ImplItem
(
item
)
=>
{
Annotatable
::
ImplItem
(
item
.map
(|
item
|
cfg
.fold_impl_item
(
item
)
.pop
()
.unwrap
()))
}
Annotatable
::
ForeignItem
(
item
)
=>
{
Annotatable
::
ForeignItem
(
item
.map
(|
item
|
cfg
.fold_foreign_item
(
item
)
.pop
()
.unwrap
())
)
}
Annotatable
::
Stmt
(
stmt
)
=>
{
Annotatable
::
Stmt
(
stmt
.map
(|
stmt
|
cfg
.fold_stmt
(
stmt
)
.pop
()
.unwrap
()))
}
...
...
@@ -509,6 +518,7 @@ fn expand_attr_invoc(&mut self,
Annotatable
::
Item
(
item
)
=>
token
::
NtItem
(
item
),
Annotatable
::
TraitItem
(
item
)
=>
token
::
NtTraitItem
(
item
.into_inner
()),
Annotatable
::
ImplItem
(
item
)
=>
token
::
NtImplItem
(
item
.into_inner
()),
Annotatable
::
ForeignItem
(
item
)
=>
token
::
NtForeignItem
(
item
.into_inner
()),
Annotatable
::
Stmt
(
stmt
)
=>
token
::
NtStmt
(
stmt
.into_inner
()),
Annotatable
::
Expr
(
expr
)
=>
token
::
NtExpr
(
expr
),
}))
.into
();
...
...
@@ -793,6 +803,15 @@ pub fn parse_expansion(&mut self, kind: ExpansionKind, macro_legacy_warnings: bo
}
Expansion
::
ImplItems
(
items
)
}
ExpansionKind
::
ForeignItems
=>
{
let
mut
items
=
SmallVector
::
new
();
while
self
.token
!=
token
::
Eof
{
if
let
Some
(
item
)
=
self
.parse_foreign_item
()
?
{
items
.push
(
item
);
}
}
Expansion
::
ForeignItems
(
items
)
}
ExpansionKind
::
Stmts
=>
{
let
mut
stmts
=
SmallVector
::
new
();
while
self
.token
!=
token
::
Eof
&&
...
...
@@ -1166,6 +1185,44 @@ fn fold_foreign_mod(&mut self, foreign_mod: ast::ForeignMod) -> ast::ForeignMod
noop_fold_foreign_mod
(
self
.cfg
.configure_foreign_mod
(
foreign_mod
),
self
)
}
fn
fold_foreign_item
(
&
mut
self
,
foreign_item
:
ast
::
ForeignItem
)
->
SmallVector
<
ast
::
ForeignItem
>
{
let
(
attr
,
traits
,
foreign_item
)
=
self
.classify_item
(
foreign_item
);
let
explain
=
if
self
.cx.ecfg
.proc_macro_enabled
()
{
feature_gate
::
EXPLAIN_PROC_MACROS_IN_EXTERN
}
else
{
feature_gate
::
EXPLAIN_MACROS_IN_EXTERN
};
if
attr
.is_some
()
||
!
traits
.is_empty
()
{
if
!
self
.cx.ecfg
.macros_in_extern_enabled
()
{
if
let
Some
(
ref
attr
)
=
attr
{
emit_feature_err
(
&
self
.cx.parse_sess
,
"macros_in_extern"
,
attr
.span
,
GateIssue
::
Language
,
explain
);
}
}
let
item
=
Annotatable
::
ForeignItem
(
P
(
foreign_item
));
return
self
.collect_attr
(
attr
,
traits
,
item
,
ExpansionKind
::
ForeignItems
)
.make_foreign_items
();
}
if
let
ast
::
ForeignItemKind
::
Macro
(
mac
)
=
foreign_item
.node
{
self
.check_attributes
(
&
foreign_item
.attrs
);
if
!
self
.cx.ecfg
.macros_in_extern_enabled
()
{
emit_feature_err
(
&
self
.cx.parse_sess
,
"macros_in_extern"
,
foreign_item
.span
,
GateIssue
::
Language
,
explain
);
}
return
self
.collect_bang
(
mac
,
foreign_item
.span
,
ExpansionKind
::
ForeignItems
)
.make_foreign_items
();
}
noop_fold_foreign_item
(
foreign_item
,
self
)
}
fn
fold_item_kind
(
&
mut
self
,
item
:
ast
::
ItemKind
)
->
ast
::
ItemKind
{
match
item
{
ast
::
ItemKind
::
MacroDef
(
..
)
=>
item
,
...
...
@@ -1311,6 +1368,7 @@ fn enable_trace_macros = trace_macros,
fn
enable_allow_internal_unstable
=
allow_internal_unstable
,
fn
enable_custom_derive
=
custom_derive
,
fn
proc_macro_enabled
=
proc_macro
,
fn
macros_in_extern_enabled
=
macros_in_extern
,
}
}
...
...
src/libsyntax/ext/placeholders.rs
浏览文件 @
5d74990c
...
...
@@ -60,6 +60,10 @@ fn mac_placeholder() -> ast::Mac {
defaultness
:
ast
::
Defaultness
::
Final
,
tokens
:
None
,
})),
ExpansionKind
::
ForeignItems
=>
Expansion
::
ForeignItems
(
SmallVector
::
one
(
ast
::
ForeignItem
{
id
,
span
,
ident
,
vis
,
attrs
,
node
:
ast
::
ForeignItemKind
::
Macro
(
mac_placeholder
()),
})),
ExpansionKind
::
Pat
=>
Expansion
::
Pat
(
P
(
ast
::
Pat
{
id
,
span
,
node
:
ast
::
PatKind
::
Mac
(
mac_placeholder
()),
})),
...
...
@@ -132,6 +136,13 @@ fn fold_impl_item(&mut self, item: ast::ImplItem) -> SmallVector<ast::ImplItem>
}
}
fn
fold_foreign_item
(
&
mut
self
,
item
:
ast
::
ForeignItem
)
->
SmallVector
<
ast
::
ForeignItem
>
{
match
item
.node
{
ast
::
ForeignItemKind
::
Macro
(
_
)
=>
self
.remove
(
item
.id
)
.make_foreign_items
(),
_
=>
noop_fold_foreign_item
(
item
,
self
),
}
}
fn
fold_expr
(
&
mut
self
,
expr
:
P
<
ast
::
Expr
>
)
->
P
<
ast
::
Expr
>
{
match
expr
.node
{
ast
::
ExprKind
::
Mac
(
_
)
=>
self
.remove
(
expr
.id
)
.make_expr
(),
...
...
src/libsyntax/feature_gate.rs
浏览文件 @
5d74990c
...
...
@@ -447,6 +447,9 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
// Allows keywords to be escaped for use as identifiers
(
active
,
raw_identifiers
,
"1.26.0"
,
Some
(
48589
),
None
),
// Allows macro invocations in `extern {}` blocks
(
active
,
macros_in_extern
,
"1.27.0"
,
Some
(
49476
),
None
),
);
declare_features!
(
...
...
@@ -1296,6 +1299,13 @@ fn leveled_feature_err<'a>(sess: &'a ParseSess, feature: &str, span: Span, issue
pub
const
EXPLAIN_MACRO_AT_MOST_ONCE_REP
:
&
'static
str
=
"Using the `?` macro Kleene operator for
\"
at most one
\"
repetition is unstable"
;
pub
const
EXPLAIN_MACROS_IN_EXTERN
:
&
'static
str
=
"Macro invocations in `extern {}` blocks are experimental."
;
// mention proc-macros when enabled
pub
const
EXPLAIN_PROC_MACROS_IN_EXTERN
:
&
'static
str
=
"Macro and proc-macro invocations in `extern {}` blocks are experimental."
;
struct
PostExpansionVisitor
<
'a
>
{
context
:
&
'a
Context
<
'a
>
,
}
...
...
@@ -1600,6 +1610,7 @@ fn visit_foreign_item(&mut self, i: &'a ast::ForeignItem) {
gate_feature_post!
(
&
self
,
extern_types
,
i
.span
,
"extern types are experimental"
);
}
ast
::
ForeignItemKind
::
Macro
(
..
)
=>
{}
}
visit
::
walk_foreign_item
(
self
,
i
)
...
...
src/libsyntax/fold.rs
浏览文件 @
5d74990c
...
...
@@ -60,10 +60,14 @@ fn fold_use_tree(&mut self, use_tree: UseTree) -> UseTree {
noop_fold_use_tree
(
use_tree
,
self
)
}
fn
fold_foreign_item
(
&
mut
self
,
ni
:
ForeignItem
)
->
ForeignItem
{
fn
fold_foreign_item
(
&
mut
self
,
ni
:
ForeignItem
)
->
SmallVector
<
ForeignItem
>
{
noop_fold_foreign_item
(
ni
,
self
)
}
fn
fold_foreign_item_simple
(
&
mut
self
,
ni
:
ForeignItem
)
->
ForeignItem
{
noop_fold_foreign_item_simple
(
ni
,
self
)
}
fn
fold_item
(
&
mut
self
,
i
:
P
<
Item
>
)
->
SmallVector
<
P
<
Item
>>
{
noop_fold_item
(
i
,
self
)
}
...
...
@@ -414,7 +418,7 @@ pub fn noop_fold_foreign_mod<T: Folder>(ForeignMod {abi, items}: ForeignMod,
fld
:
&
mut
T
)
->
ForeignMod
{
ForeignMod
{
abi
,
items
:
items
.move_map
(|
x
|
fld
.fold_foreign_item
(
x
)),
items
:
items
.move_
flat_
map
(|
x
|
fld
.fold_foreign_item
(
x
)),
}
}
...
...
@@ -648,6 +652,10 @@ pub fn noop_fold_interpolated<T: Folder>(nt: token::Nonterminal, fld: &mut T)
token
::
NtArg
(
arg
)
=>
token
::
NtArg
(
fld
.fold_arg
(
arg
)),
token
::
NtVis
(
vis
)
=>
token
::
NtVis
(
fld
.fold_vis
(
vis
)),
token
::
NtLifetime
(
lifetime
)
=>
token
::
NtLifetime
(
fld
.fold_lifetime
(
lifetime
)),
token
::
NtForeignItem
(
ni
)
=>
token
::
NtForeignItem
(
fld
.fold_foreign_item
(
ni
)
// see reasoning above
.expect_one
(
"expected fold to produce exactly one item"
)),
}
}
...
...
@@ -1072,7 +1080,12 @@ pub fn noop_fold_item_simple<T: Folder>(Item {id, ident, attrs, node, vis, span,
}
}
pub
fn
noop_fold_foreign_item
<
T
:
Folder
>
(
ni
:
ForeignItem
,
folder
:
&
mut
T
)
->
ForeignItem
{
pub
fn
noop_fold_foreign_item
<
T
:
Folder
>
(
ni
:
ForeignItem
,
folder
:
&
mut
T
)
->
SmallVector
<
ForeignItem
>
{
SmallVector
::
one
(
folder
.fold_foreign_item_simple
(
ni
))
}
pub
fn
noop_fold_foreign_item_simple
<
T
:
Folder
>
(
ni
:
ForeignItem
,
folder
:
&
mut
T
)
->
ForeignItem
{
ForeignItem
{
id
:
folder
.new_id
(
ni
.id
),
vis
:
folder
.fold_vis
(
ni
.vis
),
...
...
@@ -1086,6 +1099,7 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: ForeignItem, folder: &mut T) -> For
ForeignItemKind
::
Static
(
folder
.fold_ty
(
t
),
m
)
}
ForeignItemKind
::
Ty
=>
ForeignItemKind
::
Ty
,
ForeignItemKind
::
Macro
(
mac
)
=>
ForeignItemKind
::
Macro
(
folder
.fold_mac
(
mac
)),
},
span
:
folder
.new_span
(
ni
.span
)
}
...
...
src/libsyntax/parse/parser.rs
浏览文件 @
5d74990c
...
...
@@ -26,7 +26,7 @@
use
ast
::{
Label
,
Lifetime
,
LifetimeDef
,
Lit
,
LitKind
,
UintTy
};
use
ast
::
Local
;
use
ast
::
MacStmtStyle
;
use
ast
::
Mac_
;
use
ast
::
{
Mac
,
Mac_
}
;
use
ast
::{
MutTy
,
Mutability
};
use
ast
::{
Pat
,
PatKind
,
PathSegment
};
use
ast
::{
PolyTraitRef
,
QSelf
};
...
...
@@ -1417,28 +1417,8 @@ fn parse_trait_item_(&mut self,
None
};
(
ident
,
TraitItemKind
::
Const
(
ty
,
default
),
ast
::
Generics
::
default
())
}
else
if
self
.token
.is_path_start
()
&&
!
self
.is_extern_non_path
()
{
}
else
if
let
Some
(
mac
)
=
self
.parse_assoc_macro_invoc
(
"trait"
,
None
,
&
mut
false
)
?
{
// trait item macro.
// code copied from parse_macro_use_or_failure... abstraction!
let
prev_span
=
self
.prev_span
;
let
lo
=
self
.span
;
let
pth
=
self
.parse_path
(
PathStyle
::
Mod
)
?
;
if
pth
.segments
.len
()
==
1
{
if
!
self
.eat
(
&
token
::
Not
)
{
return
Err
(
self
.missing_assoc_item_kind_err
(
"trait"
,
prev_span
));
}
}
else
{
self
.expect
(
&
token
::
Not
)
?
;
}
// eat a matched-delimiter token tree:
let
(
delim
,
tts
)
=
self
.expect_delimited_token_tree
()
?
;
if
delim
!=
token
::
Brace
{
self
.expect
(
&
token
::
Semi
)
?
}
let
mac
=
respan
(
lo
.to
(
self
.prev_span
),
Mac_
{
path
:
pth
,
tts
:
tts
});
(
keywords
::
Invalid
.ident
(),
ast
::
TraitItemKind
::
Macro
(
mac
),
ast
::
Generics
::
default
())
}
else
{
let
(
constness
,
unsafety
,
abi
)
=
self
.parse_fn_front_matter
()
?
;
...
...
@@ -5406,6 +5386,12 @@ fn complain_if_pub_macro_diag(&mut self, vis: &VisibilityKind, sp: Span) -> PRes
fn
missing_assoc_item_kind_err
(
&
mut
self
,
item_type
:
&
str
,
prev_span
:
Span
)
->
DiagnosticBuilder
<
'a
>
{
let
expected_kinds
=
if
item_type
==
"extern"
{
"missing `fn`, `type`, or `static`"
}
else
{
"missing `fn`, `type`, or `const`"
};
// Given this code `path(`, it seems like this is not
// setting the visibility of a macro invocation, but rather
// a mistyped method declaration.
...
...
@@ -5418,9 +5404,9 @@ fn missing_assoc_item_kind_err(&mut self, item_type: &str, prev_span: Span)
let
sp
=
prev_span
.between
(
self
.prev_span
);
let
mut
err
=
self
.diagnostic
()
.struct_span_err
(
sp
,
&
format!
(
"
missing `fn`, `type`, or `const`
for {}-item declaration"
,
item_type
));
err
.span_label
(
sp
,
"missing `fn`, `type`, or `const`"
);
&
format!
(
"
{}
for {}-item declaration"
,
expected_kinds
,
item_type
));
err
.span_label
(
sp
,
expected_kinds
);
err
}
...
...
@@ -5429,31 +5415,8 @@ fn parse_impl_method(&mut self, vis: &Visibility, at_end: &mut bool)
->
PResult
<
'a
,
(
Ident
,
Vec
<
Attribute
>
,
ast
::
Generics
,
ast
::
ImplItemKind
)
>
{
// code copied from parse_macro_use_or_failure... abstraction!
if
self
.token
.is_path_start
()
&&
!
self
.is_extern_non_path
()
{
if
let
Some
(
mac
)
=
self
.parse_assoc_macro_invoc
(
"impl"
,
Some
(
vis
),
at_end
)
?
{
// Method macro.
let
prev_span
=
self
.prev_span
;
let
lo
=
self
.span
;
let
pth
=
self
.parse_path
(
PathStyle
::
Mod
)
?
;
if
pth
.segments
.len
()
==
1
{
if
!
self
.eat
(
&
token
::
Not
)
{
return
Err
(
self
.missing_assoc_item_kind_err
(
"impl"
,
prev_span
));
}
}
else
{
self
.expect
(
&
token
::
Not
)
?
;
}
self
.complain_if_pub_macro
(
&
vis
.node
,
prev_span
);
// eat a matched-delimiter token tree:
*
at_end
=
true
;
let
(
delim
,
tts
)
=
self
.expect_delimited_token_tree
()
?
;
if
delim
!=
token
::
Brace
{
self
.expect
(
&
token
::
Semi
)
?
}
let
mac
=
respan
(
lo
.to
(
self
.prev_span
),
Mac_
{
path
:
pth
,
tts
:
tts
});
Ok
((
keywords
::
Invalid
.ident
(),
vec!
[],
ast
::
Generics
::
default
(),
ast
::
ImplItemKind
::
Macro
(
mac
)))
}
else
{
...
...
@@ -6799,7 +6762,9 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
}
/// Parse a foreign item.
fn
parse_foreign_item
(
&
mut
self
)
->
PResult
<
'a
,
Option
<
ForeignItem
>>
{
pub
fn
parse_foreign_item
(
&
mut
self
)
->
PResult
<
'a
,
Option
<
ForeignItem
>>
{
maybe_whole!
(
self
,
NtForeignItem
,
|
ni
|
Some
(
ni
));
let
attrs
=
self
.parse_outer_attributes
()
?
;
let
lo
=
self
.span
;
let
visibility
=
self
.parse_visibility
(
false
)
?
;
...
...
@@ -6825,12 +6790,26 @@ fn parse_foreign_item(&mut self) -> PResult<'a, Option<ForeignItem>> {
return
Ok
(
Some
(
self
.parse_item_foreign_type
(
visibility
,
lo
,
attrs
)
?
));
}
// FIXME #5668: this will occur for a macro invocation:
match
self
.parse_macro_use_or_failure
(
attrs
,
true
,
false
,
lo
,
visibility
)
?
{
Some
(
item
)
=>
{
return
Err
(
self
.span_fatal
(
item
.span
,
"macros cannot expand to foreign items"
));
match
self
.parse_assoc_macro_invoc
(
"extern"
,
Some
(
&
visibility
),
&
mut
false
)
?
{
Some
(
mac
)
=>
{
Ok
(
Some
(
ForeignItem
{
ident
:
keywords
::
Invalid
.ident
(),
span
:
lo
.to
(
self
.prev_span
),
id
:
ast
::
DUMMY_NODE_ID
,
attrs
,
vis
:
visibility
,
node
:
ForeignItemKind
::
Macro
(
mac
),
}
))
}
None
=>
{
if
!
attrs
.is_empty
()
{
self
.expected_item_err
(
&
attrs
);
}
Ok
(
None
)
}
None
=>
Ok
(
None
)
}
}
...
...
@@ -6894,6 +6873,41 @@ fn parse_macro_use_or_failure(
Ok
(
None
)
}
/// Parse a macro invocation inside a `trait`, `impl` or `extern` block
fn
parse_assoc_macro_invoc
(
&
mut
self
,
item_kind
:
&
str
,
vis
:
Option
<&
Visibility
>
,
at_end
:
&
mut
bool
)
->
PResult
<
'a
,
Option
<
Mac
>>
{
if
self
.token
.is_path_start
()
&&
!
self
.is_extern_non_path
()
{
let
prev_span
=
self
.prev_span
;
let
lo
=
self
.span
;
let
pth
=
self
.parse_path
(
PathStyle
::
Mod
)
?
;
if
pth
.segments
.len
()
==
1
{
if
!
self
.eat
(
&
token
::
Not
)
{
return
Err
(
self
.missing_assoc_item_kind_err
(
item_kind
,
prev_span
));
}
}
else
{
self
.expect
(
&
token
::
Not
)
?
;
}
if
let
Some
(
vis
)
=
vis
{
self
.complain_if_pub_macro
(
&
vis
.node
,
prev_span
);
}
*
at_end
=
true
;
// eat a matched-delimiter token tree:
let
(
delim
,
tts
)
=
self
.expect_delimited_token_tree
()
?
;
if
delim
!=
token
::
Brace
{
self
.expect
(
&
token
::
Semi
)
?
}
Ok
(
Some
(
respan
(
lo
.to
(
self
.prev_span
),
Mac_
{
path
:
pth
,
tts
:
tts
})))
}
else
{
Ok
(
None
)
}
}
fn
collect_tokens
<
F
,
R
>
(
&
mut
self
,
f
:
F
)
->
PResult
<
'a
,
(
R
,
TokenStream
)
>
where
F
:
FnOnce
(
&
mut
Self
)
->
PResult
<
'a
,
R
>
{
...
...
src/libsyntax/parse/token.rs
浏览文件 @
5d74990c
...
...
@@ -581,6 +581,7 @@ pub enum Nonterminal {
NtArm
(
ast
::
Arm
),
NtImplItem
(
ast
::
ImplItem
),
NtTraitItem
(
ast
::
TraitItem
),
NtForeignItem
(
ast
::
ForeignItem
),
NtGenerics
(
ast
::
Generics
),
NtWhereClause
(
ast
::
WhereClause
),
NtArg
(
ast
::
Arg
),
...
...
@@ -603,6 +604,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
NtArm
(
..
)
=>
f
.pad
(
"NtArm(..)"
),
NtImplItem
(
..
)
=>
f
.pad
(
"NtImplItem(..)"
),
NtTraitItem
(
..
)
=>
f
.pad
(
"NtTraitItem(..)"
),
NtForeignItem
(
..
)
=>
f
.pad
(
"NtForeignItem(..)"
),
NtGenerics
(
..
)
=>
f
.pad
(
"NtGenerics(..)"
),
NtWhereClause
(
..
)
=>
f
.pad
(
"NtWhereClause(..)"
),
NtArg
(
..
)
=>
f
.pad
(
"NtArg(..)"
),
...
...
src/libsyntax/print/pprust.rs
浏览文件 @
5d74990c
...
...
@@ -281,6 +281,7 @@ pub fn token_to_string(tok: &Token) -> String {
token
::
NtArg
(
ref
e
)
=>
arg_to_string
(
e
),
token
::
NtVis
(
ref
e
)
=>
vis_to_string
(
e
),
token
::
NtLifetime
(
ref
e
)
=>
lifetime_to_string
(
e
),
token
::
NtForeignItem
(
ref
ni
)
=>
foreign_item_to_string
(
ni
),
}
}
}
...
...
@@ -422,6 +423,10 @@ pub fn mac_to_string(arg: &ast::Mac) -> String {
to_string
(|
s
|
s
.print_mac
(
arg
,
::
parse
::
token
::
Paren
))
}
pub
fn
foreign_item_to_string
(
arg
:
&
ast
::
ForeignItem
)
->
String
{
to_string
(|
s
|
s
.print_foreign_item
(
arg
))
}
pub
fn
visibility_qualified
(
vis
:
&
ast
::
Visibility
,
s
:
&
str
)
->
String
{
format!
(
"{}{}"
,
to_string
(|
s
|
s
.print_visibility
(
vis
)),
s
)
}
...
...
@@ -1127,6 +1132,10 @@ pub fn print_foreign_item(&mut self,
self
.end
()
?
;
// end the head-ibox
self
.end
()
// end the outer cbox
}
ast
::
ForeignItemKind
::
Macro
(
ref
m
)
=>
{
self
.print_mac
(
m
,
token
::
Paren
)
?
;
self
.s
.word
(
";"
)
}
}
}
...
...
src/libsyntax/visit.rs
浏览文件 @
5d74990c
...
...
@@ -460,6 +460,7 @@ pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, foreign_item: &'a
}
ForeignItemKind
::
Static
(
ref
typ
,
_
)
=>
visitor
.visit_ty
(
typ
),
ForeignItemKind
::
Ty
=>
(),
ForeignItemKind
::
Macro
(
ref
mac
)
=>
visitor
.visit_mac
(
mac
),
}
walk_list!
(
visitor
,
visit_attribute
,
&
foreign_item
.attrs
);
...
...
src/libsyntax_ext/deriving/custom.rs
浏览文件 @
5d74990c
...
...
@@ -55,6 +55,7 @@ fn expand(&self,
Annotatable
::
Item
(
item
)
=>
item
,
Annotatable
::
ImplItem
(
_
)
|
Annotatable
::
TraitItem
(
_
)
|
Annotatable
::
ForeignItem
(
_
)
|
Annotatable
::
Stmt
(
_
)
|
Annotatable
::
Expr
(
_
)
=>
{
ecx
.span_err
(
span
,
"proc-macro derives may only be
\
...
...
src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs
浏览文件 @
5d74990c
...
...
@@ -93,7 +93,9 @@ fn expand_into_foo_multi(cx: &mut ExtCtxt,
}
})
}
// these are covered in proc_macro/attr-stmt-expr.rs
// covered in proc_macro/macros-in-extern.rs
Annotatable
::
ForeignItem
(
_
)
=>
unimplemented!
(),
// covered in proc_macro/attr-stmt-expr.rs
Annotatable
::
Stmt
(
_
)
|
Annotatable
::
Expr
(
_
)
=>
panic!
(
"expected item"
)
}
}
...
...
@@ -147,6 +149,8 @@ fn expand_duplicate(cx: &mut ExtCtxt,
new_it
.ident
=
copy_name
;
push
(
Annotatable
::
TraitItem
(
P
(
new_it
)));
}
// covered in proc_macro/macros-in-extern.rs
Annotatable
::
ForeignItem
(
_
)
=>
unimplemented!
(),
// covered in proc_macro/attr-stmt-expr.rs
Annotatable
::
Stmt
(
_
)
|
Annotatable
::
Expr
(
_
)
=>
panic!
(
"expected item"
)
}
...
...
src/test/compile-fail-fulldeps/proc-macro/auxiliary/test-macros.rs
0 → 100644
浏览文件 @
5d74990c
// Copyright 2018 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.
// no-prefer-dynamic
#![crate_type
=
"proc-macro"
]
#![feature(proc_macro)]
extern
crate
proc_macro
;
use
proc_macro
::
TokenStream
;
#[proc_macro_attribute]
pub
fn
nop_attr
(
_
attr
:
TokenStream
,
input
:
TokenStream
)
->
TokenStream
{
assert
!
(
_
attr
.to_string
()
.is_empty
());
input
}
#[proc_macro_attribute]
pub
fn
no_output
(
_
attr
:
TokenStream
,
_
input
:
TokenStream
)
->
TokenStream
{
assert
!
(
_
attr
.to_string
()
.is_empty
());
assert
!
(
!
_
input
.to_string
()
.is_empty
());
""
.parse
()
.unwrap
()
}
#[proc_macro]
pub
fn
emit_input
(
input
:
TokenStream
)
->
TokenStream
{
input
}
src/test/compile-fail-fulldeps/proc-macro/macros-in-extern.rs
0 → 100644
浏览文件 @
5d74990c
// Copyright 2018 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.
// aux-build:test-macros.rs
// ignore-stage1
// ignore-wasm32
#![feature(proc_macro)]
extern
crate
test_macros
;
use
test_macros
::{
nop_attr
,
no_output
,
emit_input
};
fn
main
()
{
assert_eq!
(
unsafe
{
rust_get_test_int
()
},
0
isize
);
assert_eq!
(
unsafe
{
rust_dbg_extern_identity_u32
(
0xDEADBEEF
)
},
0xDEADBEEF
);
}
#[link(name
=
"rust_test_helpers"
,
kind
=
"static"
)]
extern
{
#[no_output]
//~^ ERROR Macro and proc-macro invocations in `extern {}` blocks are experimental.
fn
some_definitely_unknown_symbol_which_should_be_removed
();
#[nop_attr]
//~^ ERROR Macro and proc-macro invocations in `extern {}` blocks are experimental.
fn
rust_get_test_int
()
->
isize
;
emit_input!
(
fn
rust_dbg_extern_identity_u32
(
arg
:
u32
)
->
u32
;);
//~^ ERROR Macro and proc-macro invocations in `extern {}` blocks are experimental.
}
src/test/compile-fail/macros-in-extern.rs
0 → 100644
浏览文件 @
5d74990c
// Copyright 2018 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.
// ignore-wasm32
#![feature(decl_macro)]
macro_rules!
returns_isize
(
(
$ident:ident
)
=>
(
fn
$ident
()
->
isize
;
)
);
macro
takes_u32_returns_u32
(
$
ident
:
ident
)
{
fn
$
ident
(
arg
:
u32
)
->
u32
;
}
macro_rules!
emits_nothing
(
()
=>
()
);
fn
main
()
{
assert_eq!
(
unsafe
{
rust_get_test_int
()
},
0
isize
);
assert_eq!
(
unsafe
{
rust_dbg_extern_identity_u32
(
0xDEADBEEF
)
},
0xDEADBEEFu32
);
}
#[link(name
=
"rust_test_helpers"
,
kind
=
"static"
)]
extern
{
returns_isize!
(
rust_get_test_int
);
//~^ ERROR Macro invocations in `extern {}` blocks are experimental.
takes_u32_returns_u32!
(
rust_dbg_extern_identity_u32
);
//~^ ERROR Macro invocations in `extern {}` blocks are experimental.
emits_nothing!
();
//~^ ERROR Macro invocations in `extern {}` blocks are experimental.
}
src/test/parse-fail/duplicate-visibility.rs
浏览文件 @
5d74990c
...
...
@@ -10,7 +10,7 @@
// compile-flags: -Z parse-only
// error-pattern:
unmatched visibility `pub`
// error-pattern:
expected one of `(`, `fn`, `static`, `type`, or `}` here
extern
{
pub
pub
fn
foo
();
}
src/test/parse-fail/extern-no-fn.rs
浏览文件 @
5d74990c
...
...
@@ -10,8 +10,8 @@
// compile-flags: -Z parse-only
extern
{
f
();
//~ ERROR expected one of `!` or `::`, found `(`
extern
{
//~ ERROR missing `fn`, `type`, or `static` for extern-item declaration
f
();
}
fn
main
()
{
...
...
src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs
浏览文件 @
5d74990c
...
...
@@ -96,7 +96,9 @@ fn expand_into_foo_multi(cx: &mut ExtCtxt,
}
})
],
// these are covered in proc_macro/attr-stmt-expr.rs
// covered in proc_macro/macros-in-extern.rs
Annotatable
::
ForeignItem
(
..
)
=>
unimplemented!
(),
// covered in proc_macro/attr-stmt-expr.rs
Annotatable
::
Stmt
(
_
)
|
Annotatable
::
Expr
(
_
)
=>
panic!
(
"expected item"
),
}
}
...
...
@@ -142,7 +144,9 @@ fn expand_duplicate(cx: &mut ExtCtxt,
new_it
.ident
=
copy_name
;
push
(
Annotatable
::
TraitItem
(
P
(
new_it
)));
}
// these are covered in proc_macro/attr-stmt-expr.rs
// covered in proc_macro/macros-in-extern.rs
Annotatable
::
ForeignItem
(
..
)
=>
unimplemented!
(),
// covered in proc_macro/attr-stmt-expr.rs
Annotatable
::
Stmt
(
_
)
|
Annotatable
::
Expr
(
_
)
=>
panic!
(
"expected item"
)
}
}
...
...
src/test/run-pass-fulldeps/proc-macro/auxiliary/test-macros.rs
0 → 100644
浏览文件 @
5d74990c
// Copyright 2018 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.
// no-prefer-dynamic
#![crate_type
=
"proc-macro"
]
#![feature(proc_macro)]
extern
crate
proc_macro
;
use
proc_macro
::
TokenStream
;
#[proc_macro_attribute]
pub
fn
nop_attr
(
_
attr
:
TokenStream
,
input
:
TokenStream
)
->
TokenStream
{
assert
!
(
_
attr
.to_string
()
.is_empty
());
input
}
#[proc_macro_attribute]
pub
fn
no_output
(
_
attr
:
TokenStream
,
_
input
:
TokenStream
)
->
TokenStream
{
assert
!
(
_
attr
.to_string
()
.is_empty
());
assert
!
(
!
_
input
.to_string
()
.is_empty
());
""
.parse
()
.unwrap
()
}
#[proc_macro]
pub
fn
emit_input
(
input
:
TokenStream
)
->
TokenStream
{
input
}
src/test/run-pass-fulldeps/proc-macro/macros-in-extern.rs
0 → 100644
浏览文件 @
5d74990c
// Copyright 2018 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.
// aux-build:test-macros.rs
// ignore-stage1
// ignore-wasm32
#![feature(proc_macro,
macros_in_extern)]
extern
crate
test_macros
;
use
test_macros
::{
nop_attr
,
no_output
,
emit_input
};
fn
main
()
{
assert_eq!
(
unsafe
{
rust_get_test_int
()
},
1
isize
);
assert_eq!
(
unsafe
{
rust_dbg_extern_identity_u32
(
0xDEADBEEF
)
},
0xDEADBEEF
);
}
#[link(name
=
"rust_test_helpers"
,
kind
=
"static"
)]
extern
{
#[no_output]
fn
some_definitely_unknown_symbol_which_should_be_removed
();
#[nop_attr]
fn
rust_get_test_int
()
->
isize
;
emit_input!
(
fn
rust_dbg_extern_identity_u32
(
arg
:
u32
)
->
u32
;);
}
src/test/run-pass/macros-in-extern.rs
0 → 100644
浏览文件 @
5d74990c
// Copyright 2018 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.
// ignore-wasm32
#![feature(decl_macro,
macros_in_extern)]
macro_rules!
returns_isize
(
(
$ident:ident
)
=>
(
fn
$ident
()
->
isize
;
)
);
macro
takes_u32_returns_u32
(
$
ident
:
ident
)
{
fn
$
ident
(
arg
:
u32
)
->
u32
;
}
macro_rules!
emits_nothing
(
()
=>
()
);
fn
main
()
{
assert_eq!
(
unsafe
{
rust_get_test_int
()
},
1
isize
);
assert_eq!
(
unsafe
{
rust_dbg_extern_identity_u32
(
0xDEADBEEF
)
},
0xDEADBEEFu32
);
}
#[link(name
=
"rust_test_helpers"
,
kind
=
"static"
)]
extern
{
returns_isize!
(
rust_get_test_int
);
takes_u32_returns_u32!
(
rust_dbg_extern_identity_u32
);
emits_nothing!
();
}
src/test/ui/feature-gate-macros_in_extern.rs
0 → 100644
浏览文件 @
5d74990c
// Copyright 2018 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.
#![feature(decl_macro)]
macro_rules!
returns_isize
(
(
$ident:ident
)
=>
(
fn
$ident
()
->
isize
;
)
);
macro
takes_u32_returns_u32
(
$
ident
:
ident
)
{
fn
$
ident
(
arg
:
u32
)
->
u32
;
}
macro_rules!
emits_nothing
(
()
=>
()
);
#[link(name
=
"rust_test_helpers"
,
kind
=
"static"
)]
extern
{
returns_isize!
(
rust_get_test_int
);
//~^ ERROR Macro invocations in `extern {}` blocks are experimental.
takes_u32_returns_u32!
(
rust_dbg_extern_identity_u32
);
//~^ ERROR Macro invocations in `extern {}` blocks are experimental.
emits_nothing!
();
//~^ ERROR Macro invocations in `extern {}` blocks are experimental.
}
src/test/ui/feature-gate-macros_in_extern.stderr
0 → 100644
浏览文件 @
5d74990c
error[E0658]: Macro invocations in `extern {}` blocks are experimental. (see issue #49476)
--> $DIR/feature-gate-macros_in_extern.rs:29:5
|
LL | returns_isize!(rust_get_test_int);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(macros_in_extern)] to the crate attributes to enable
error[E0658]: Macro invocations in `extern {}` blocks are experimental. (see issue #49476)
--> $DIR/feature-gate-macros_in_extern.rs:31:5
|
LL | takes_u32_returns_u32!(rust_dbg_extern_identity_u32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(macros_in_extern)] to the crate attributes to enable
error[E0658]: Macro invocations in `extern {}` blocks are experimental. (see issue #49476)
--> $DIR/feature-gate-macros_in_extern.rs:33:5
|
LL | emits_nothing!();
| ^^^^^^^^^^^^^^^^^
|
= help: add #![feature(macros_in_extern)] to the crate attributes to enable
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0658`.
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录