diff options
Diffstat (limited to 'crates/syntax')
10 files changed, 93 insertions, 70 deletions
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs index 30d11b146..0ad75214f 100644 --- a/crates/syntax/src/ast/generated/nodes.rs +++ b/crates/syntax/src/ast/generated/nodes.rs | |||
@@ -128,7 +128,6 @@ pub struct MacroCall { | |||
128 | pub(crate) syntax: SyntaxNode, | 128 | pub(crate) syntax: SyntaxNode, |
129 | } | 129 | } |
130 | impl ast::AttrsOwner for MacroCall {} | 130 | impl ast::AttrsOwner for MacroCall {} |
131 | impl ast::NameOwner for MacroCall {} | ||
132 | impl MacroCall { | 131 | impl MacroCall { |
133 | pub fn path(&self) -> Option<Path> { support::child(&self.syntax) } | 132 | pub fn path(&self) -> Option<Path> { support::child(&self.syntax) } |
134 | pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) } | 133 | pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) } |
@@ -273,6 +272,20 @@ impl Impl { | |||
273 | pub fn assoc_item_list(&self) -> Option<AssocItemList> { support::child(&self.syntax) } | 272 | pub fn assoc_item_list(&self) -> Option<AssocItemList> { support::child(&self.syntax) } |
274 | } | 273 | } |
275 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 274 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
275 | pub struct MacroRules { | ||
276 | pub(crate) syntax: SyntaxNode, | ||
277 | } | ||
278 | impl ast::AttrsOwner for MacroRules {} | ||
279 | impl ast::NameOwner for MacroRules {} | ||
280 | impl ast::VisibilityOwner for MacroRules {} | ||
281 | impl MacroRules { | ||
282 | pub fn macro_rules_token(&self) -> Option<SyntaxToken> { | ||
283 | support::token(&self.syntax, T![macro_rules]) | ||
284 | } | ||
285 | pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) } | ||
286 | pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) } | ||
287 | } | ||
288 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
276 | pub struct Module { | 289 | pub struct Module { |
277 | pub(crate) syntax: SyntaxNode, | 290 | pub(crate) syntax: SyntaxNode, |
278 | } | 291 | } |
@@ -1318,6 +1331,7 @@ pub enum Item { | |||
1318 | Fn(Fn), | 1331 | Fn(Fn), |
1319 | Impl(Impl), | 1332 | Impl(Impl), |
1320 | MacroCall(MacroCall), | 1333 | MacroCall(MacroCall), |
1334 | MacroRules(MacroRules), | ||
1321 | Module(Module), | 1335 | Module(Module), |
1322 | Static(Static), | 1336 | Static(Static), |
1323 | Struct(Struct), | 1337 | Struct(Struct), |
@@ -1374,7 +1388,6 @@ pub enum AssocItem { | |||
1374 | TypeAlias(TypeAlias), | 1388 | TypeAlias(TypeAlias), |
1375 | } | 1389 | } |
1376 | impl ast::AttrsOwner for AssocItem {} | 1390 | impl ast::AttrsOwner for AssocItem {} |
1377 | impl ast::NameOwner for AssocItem {} | ||
1378 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 1391 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
1379 | pub enum ExternItem { | 1392 | pub enum ExternItem { |
1380 | Fn(Fn), | 1393 | Fn(Fn), |
@@ -1383,7 +1396,6 @@ pub enum ExternItem { | |||
1383 | TypeAlias(TypeAlias), | 1396 | TypeAlias(TypeAlias), |
1384 | } | 1397 | } |
1385 | impl ast::AttrsOwner for ExternItem {} | 1398 | impl ast::AttrsOwner for ExternItem {} |
1386 | impl ast::NameOwner for ExternItem {} | ||
1387 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 1399 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
1388 | pub enum GenericParam { | 1400 | pub enum GenericParam { |
1389 | ConstParam(ConstParam), | 1401 | ConstParam(ConstParam), |
@@ -1666,6 +1678,17 @@ impl AstNode for Impl { | |||
1666 | } | 1678 | } |
1667 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | 1679 | fn syntax(&self) -> &SyntaxNode { &self.syntax } |
1668 | } | 1680 | } |
1681 | impl AstNode for MacroRules { | ||
1682 | fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_RULES } | ||
1683 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
1684 | if Self::can_cast(syntax.kind()) { | ||
1685 | Some(Self { syntax }) | ||
1686 | } else { | ||
1687 | None | ||
1688 | } | ||
1689 | } | ||
1690 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
1691 | } | ||
1669 | impl AstNode for Module { | 1692 | impl AstNode for Module { |
1670 | fn can_cast(kind: SyntaxKind) -> bool { kind == MODULE } | 1693 | fn can_cast(kind: SyntaxKind) -> bool { kind == MODULE } |
1671 | fn cast(syntax: SyntaxNode) -> Option<Self> { | 1694 | fn cast(syntax: SyntaxNode) -> Option<Self> { |
@@ -3060,6 +3083,9 @@ impl From<Impl> for Item { | |||
3060 | impl From<MacroCall> for Item { | 3083 | impl From<MacroCall> for Item { |
3061 | fn from(node: MacroCall) -> Item { Item::MacroCall(node) } | 3084 | fn from(node: MacroCall) -> Item { Item::MacroCall(node) } |
3062 | } | 3085 | } |
3086 | impl From<MacroRules> for Item { | ||
3087 | fn from(node: MacroRules) -> Item { Item::MacroRules(node) } | ||
3088 | } | ||
3063 | impl From<Module> for Item { | 3089 | impl From<Module> for Item { |
3064 | fn from(node: Module) -> Item { Item::Module(node) } | 3090 | fn from(node: Module) -> Item { Item::Module(node) } |
3065 | } | 3091 | } |
@@ -3084,8 +3110,8 @@ impl From<Use> for Item { | |||
3084 | impl AstNode for Item { | 3110 | impl AstNode for Item { |
3085 | fn can_cast(kind: SyntaxKind) -> bool { | 3111 | fn can_cast(kind: SyntaxKind) -> bool { |
3086 | match kind { | 3112 | match kind { |
3087 | CONST | ENUM | EXTERN_BLOCK | EXTERN_CRATE | FN | IMPL | MACRO_CALL | MODULE | 3113 | CONST | ENUM | EXTERN_BLOCK | EXTERN_CRATE | FN | IMPL | MACRO_CALL | MACRO_RULES |
3088 | | STATIC | STRUCT | TRAIT | TYPE_ALIAS | UNION | USE => true, | 3114 | | MODULE | STATIC | STRUCT | TRAIT | TYPE_ALIAS | UNION | USE => true, |
3089 | _ => false, | 3115 | _ => false, |
3090 | } | 3116 | } |
3091 | } | 3117 | } |
@@ -3098,6 +3124,7 @@ impl AstNode for Item { | |||
3098 | FN => Item::Fn(Fn { syntax }), | 3124 | FN => Item::Fn(Fn { syntax }), |
3099 | IMPL => Item::Impl(Impl { syntax }), | 3125 | IMPL => Item::Impl(Impl { syntax }), |
3100 | MACRO_CALL => Item::MacroCall(MacroCall { syntax }), | 3126 | MACRO_CALL => Item::MacroCall(MacroCall { syntax }), |
3127 | MACRO_RULES => Item::MacroRules(MacroRules { syntax }), | ||
3101 | MODULE => Item::Module(Module { syntax }), | 3128 | MODULE => Item::Module(Module { syntax }), |
3102 | STATIC => Item::Static(Static { syntax }), | 3129 | STATIC => Item::Static(Static { syntax }), |
3103 | STRUCT => Item::Struct(Struct { syntax }), | 3130 | STRUCT => Item::Struct(Struct { syntax }), |
@@ -3118,6 +3145,7 @@ impl AstNode for Item { | |||
3118 | Item::Fn(it) => &it.syntax, | 3145 | Item::Fn(it) => &it.syntax, |
3119 | Item::Impl(it) => &it.syntax, | 3146 | Item::Impl(it) => &it.syntax, |
3120 | Item::MacroCall(it) => &it.syntax, | 3147 | Item::MacroCall(it) => &it.syntax, |
3148 | Item::MacroRules(it) => &it.syntax, | ||
3121 | Item::Module(it) => &it.syntax, | 3149 | Item::Module(it) => &it.syntax, |
3122 | Item::Static(it) => &it.syntax, | 3150 | Item::Static(it) => &it.syntax, |
3123 | Item::Struct(it) => &it.syntax, | 3151 | Item::Struct(it) => &it.syntax, |
@@ -3582,6 +3610,11 @@ impl std::fmt::Display for Impl { | |||
3582 | std::fmt::Display::fmt(self.syntax(), f) | 3610 | std::fmt::Display::fmt(self.syntax(), f) |
3583 | } | 3611 | } |
3584 | } | 3612 | } |
3613 | impl std::fmt::Display for MacroRules { | ||
3614 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
3615 | std::fmt::Display::fmt(self.syntax(), f) | ||
3616 | } | ||
3617 | } | ||
3585 | impl std::fmt::Display for Module { | 3618 | impl std::fmt::Display for Module { |
3586 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | 3619 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
3587 | std::fmt::Display::fmt(self.syntax(), f) | 3620 | std::fmt::Display::fmt(self.syntax(), f) |
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index 820af2d20..c59a29eab 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs | |||
@@ -382,21 +382,6 @@ impl ast::Visibility { | |||
382 | } | 382 | } |
383 | } | 383 | } |
384 | 384 | ||
385 | impl ast::MacroCall { | ||
386 | pub fn is_macro_rules(&self) -> Option<ast::Name> { | ||
387 | let name_ref = self.path()?.segment()?.name_ref()?; | ||
388 | if name_ref.text() == "macro_rules" { | ||
389 | self.name() | ||
390 | } else { | ||
391 | None | ||
392 | } | ||
393 | } | ||
394 | |||
395 | pub fn is_bang(&self) -> bool { | ||
396 | self.is_macro_rules().is_none() | ||
397 | } | ||
398 | } | ||
399 | |||
400 | impl ast::LifetimeParam { | 385 | impl ast::LifetimeParam { |
401 | pub fn lifetime_bounds(&self) -> impl Iterator<Item = SyntaxToken> { | 386 | pub fn lifetime_bounds(&self) -> impl Iterator<Item = SyntaxToken> { |
402 | self.syntax() | 387 | self.syntax() |
@@ -476,5 +461,5 @@ impl ast::DocCommentsOwner for ast::Static {} | |||
476 | impl ast::DocCommentsOwner for ast::Const {} | 461 | impl ast::DocCommentsOwner for ast::Const {} |
477 | impl ast::DocCommentsOwner for ast::TypeAlias {} | 462 | impl ast::DocCommentsOwner for ast::TypeAlias {} |
478 | impl ast::DocCommentsOwner for ast::Impl {} | 463 | impl ast::DocCommentsOwner for ast::Impl {} |
479 | impl ast::DocCommentsOwner for ast::MacroCall {} | 464 | impl ast::DocCommentsOwner for ast::MacroRules {} |
480 | impl ast::DocCommentsOwner for ast::Use {} | 465 | impl ast::DocCommentsOwner for ast::Use {} |
diff --git a/crates/syntax/src/display.rs b/crates/syntax/src/display.rs index 8d2c7eae4..d33bde30c 100644 --- a/crates/syntax/src/display.rs +++ b/crates/syntax/src/display.rs | |||
@@ -76,7 +76,7 @@ pub fn type_label(node: &ast::TypeAlias) -> String { | |||
76 | label.trim().to_owned() | 76 | label.trim().to_owned() |
77 | } | 77 | } |
78 | 78 | ||
79 | pub fn macro_label(node: &ast::MacroCall) -> String { | 79 | pub fn macro_label(node: &ast::MacroRules) -> String { |
80 | let name = node.name().map(|name| name.syntax().text().to_string()).unwrap_or_default(); | 80 | let name = node.name().map(|name| name.syntax().text().to_string()).unwrap_or_default(); |
81 | let vis = if node.has_atom_attr("macro_export") { "#[macro_export]\n" } else { "" }; | 81 | let vis = if node.has_atom_attr("macro_export") { "#[macro_export]\n" } else { "" }; |
82 | format!("{}macro_rules! {}", vis, name) | 82 | format!("{}macro_rules! {}", vis, name) |
diff --git a/crates/syntax/src/parsing/text_tree_sink.rs b/crates/syntax/src/parsing/text_tree_sink.rs index 49842177a..ce27c3dd9 100644 --- a/crates/syntax/src/parsing/text_tree_sink.rs +++ b/crates/syntax/src/parsing/text_tree_sink.rs | |||
@@ -147,8 +147,8 @@ fn n_attached_trivias<'a>( | |||
147 | trivias: impl Iterator<Item = (SyntaxKind, &'a str)>, | 147 | trivias: impl Iterator<Item = (SyntaxKind, &'a str)>, |
148 | ) -> usize { | 148 | ) -> usize { |
149 | match kind { | 149 | match kind { |
150 | MACRO_CALL | CONST | TYPE_ALIAS | STRUCT | ENUM | VARIANT | FN | TRAIT | MODULE | 150 | MACRO_CALL | MACRO_RULES | CONST | TYPE_ALIAS | STRUCT | ENUM | VARIANT | FN | TRAIT |
151 | | RECORD_FIELD | STATIC | USE => { | 151 | | MODULE | RECORD_FIELD | STATIC | USE => { |
152 | let mut res = 0; | 152 | let mut res = 0; |
153 | let mut trivias = trivias.enumerate().peekable(); | 153 | let mut trivias = trivias.enumerate().peekable(); |
154 | 154 | ||
diff --git a/crates/syntax/src/validation.rs b/crates/syntax/src/validation.rs index 6f45149bf..2ddaeb176 100644 --- a/crates/syntax/src/validation.rs +++ b/crates/syntax/src/validation.rs | |||
@@ -3,7 +3,9 @@ | |||
3 | mod block; | 3 | mod block; |
4 | 4 | ||
5 | use crate::{ | 5 | use crate::{ |
6 | algo, ast, match_ast, AstNode, SyntaxError, | 6 | algo, |
7 | ast::{self, VisibilityOwner}, | ||
8 | match_ast, AstNode, SyntaxError, | ||
7 | SyntaxKind::{CONST, FN, INT_NUMBER, TYPE_ALIAS}, | 9 | SyntaxKind::{CONST, FN, INT_NUMBER, TYPE_ALIAS}, |
8 | SyntaxNode, SyntaxToken, TextSize, T, | 10 | SyntaxNode, SyntaxToken, TextSize, T, |
9 | }; | 11 | }; |
@@ -99,6 +101,7 @@ pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> { | |||
99 | ast::RefType(it) => validate_trait_object_ref_ty(it, &mut errors), | 101 | ast::RefType(it) => validate_trait_object_ref_ty(it, &mut errors), |
100 | ast::PtrType(it) => validate_trait_object_ptr_ty(it, &mut errors), | 102 | ast::PtrType(it) => validate_trait_object_ptr_ty(it, &mut errors), |
101 | ast::FnPtrType(it) => validate_trait_object_fn_ptr_ret_ty(it, &mut errors), | 103 | ast::FnPtrType(it) => validate_trait_object_fn_ptr_ret_ty(it, &mut errors), |
104 | ast::MacroRules(it) => validate_macro_rules(it, &mut errors), | ||
102 | _ => (), | 105 | _ => (), |
103 | } | 106 | } |
104 | } | 107 | } |
@@ -350,3 +353,12 @@ fn validate_trait_object_ty(ty: ast::DynTraitType) -> Option<SyntaxError> { | |||
350 | } | 353 | } |
351 | None | 354 | None |
352 | } | 355 | } |
356 | |||
357 | fn validate_macro_rules(mac: ast::MacroRules, errors: &mut Vec<SyntaxError>) { | ||
358 | if let Some(vis) = mac.visibility() { | ||
359 | errors.push(SyntaxError::new( | ||
360 | "visibilities are not allowed on `macro_rules!` items", | ||
361 | vis.syntax().text_range(), | ||
362 | )); | ||
363 | } | ||
364 | } | ||
diff --git a/crates/syntax/test_data/parser/err/0002_duplicate_shebang.rast b/crates/syntax/test_data/parser/err/0002_duplicate_shebang.rast index 4cfd1bce4..9ad5b12b8 100644 --- a/crates/syntax/test_data/parser/err/0002_duplicate_shebang.rast +++ b/crates/syntax/test_data/parser/err/0002_duplicate_shebang.rast | |||
@@ -17,14 +17,17 @@ [email protected] | |||
17 | [email protected] "bin" | 17 | [email protected] "bin" |
18 | [email protected] | 18 | [email protected] |
19 | [email protected] "/" | 19 | [email protected] "/" |
20 | MACRO_CALL@32..41 | 20 | MACRO_CALL@32..35 |
21 | [email protected] | 21 | [email protected] |
22 | [email protected] | 22 | [email protected] |
23 | [email protected] | 23 | [email protected] |
24 | [email protected] "env" | 24 | [email protected] "env" |
25 | [email protected] " " | 25 | [email protected] " " |
26 | [email protected] | 26 | [email protected] |
27 | [email protected] "rusti" | 27 | [email protected] |
28 | [email protected] | ||
29 | [email protected] | ||
30 | [email protected] "rusti" | ||
28 | [email protected] "\n" | 31 | [email protected] "\n" |
29 | error 23..23: expected `[` | 32 | error 23..23: expected `[` |
30 | error 23..23: expected an item | 33 | error 23..23: expected an item |
@@ -35,5 +38,8 @@ error 31..31: expected `{`, `[`, `(` | |||
35 | error 31..31: expected SEMICOLON | 38 | error 31..31: expected SEMICOLON |
36 | error 31..31: expected an item | 39 | error 31..31: expected an item |
37 | error 35..35: expected BANG | 40 | error 35..35: expected BANG |
41 | error 35..35: expected `{`, `[`, `(` | ||
42 | error 35..35: expected SEMICOLON | ||
43 | error 41..41: expected BANG | ||
38 | error 41..41: expected `{`, `[`, `(` | 44 | error 41..41: expected `{`, `[`, `(` |
39 | error 41..41: expected SEMICOLON | 45 | error 41..41: expected SEMICOLON |
diff --git a/crates/syntax/test_data/parser/inline/ok/0062_mod_contents.rast b/crates/syntax/test_data/parser/inline/ok/0062_mod_contents.rast index de8217064..e4fb32de1 100644 --- a/crates/syntax/test_data/parser/inline/ok/0062_mod_contents.rast +++ b/crates/syntax/test_data/parser/inline/ok/0062_mod_contents.rast | |||
@@ -12,11 +12,8 @@ [email protected] | |||
12 | [email protected] "{" | 12 | [email protected] "{" |
13 | [email protected] "}" | 13 | [email protected] "}" |
14 | [email protected] "\n" | 14 | [email protected] "\n" |
15 | [email protected] | 15 | [email protected] |
16 | [email protected] | 16 | [email protected] "macro_rules" |
17 | [email protected] | ||
18 | [email protected] | ||
19 | [email protected] "macro_rules" | ||
20 | [email protected] "!" | 17 | [email protected] "!" |
21 | [email protected] " " | 18 | [email protected] " " |
22 | [email protected] | 19 | [email protected] |
diff --git a/crates/syntax/test_data/parser/inline/ok/0096_no_semi_after_block.rast b/crates/syntax/test_data/parser/inline/ok/0096_no_semi_after_block.rast index e757249f0..e84b9164f 100644 --- a/crates/syntax/test_data/parser/inline/ok/0096_no_semi_after_block.rast +++ b/crates/syntax/test_data/parser/inline/ok/0096_no_semi_after_block.rast | |||
@@ -82,32 +82,28 @@ [email protected] | |||
82 | [email protected] "{" | 82 | [email protected] "{" |
83 | [email protected] "}" | 83 | [email protected] "}" |
84 | [email protected] "\n " | 84 | [email protected] "\n " |
85 | [email protected] | 85 | [email protected] |
86 | [email protected] | 86 | [email protected] "macro_rules" |
87 | [email protected] | 87 | [email protected] "!" |
88 | [email protected] | 88 | [email protected] " " |
89 | [email protected] | 89 | [email protected] |
90 | [email protected] "macro_rules" | 90 | [email protected] "test" |
91 | [email protected] "!" | 91 | [email protected] " " |
92 | [email protected] " " | 92 | [email protected] |
93 | [email protected] | 93 | [email protected] "{" |
94 | [email protected] "test" | 94 | [email protected] "\n " |
95 | [email protected] " " | 95 | [email protected] |
96 | [email protected] | 96 | [email protected] "(" |
97 | [email protected] "{" | 97 | [email protected] ")" |
98 | [email protected] "\n " | 98 | [email protected] " " |
99 | [email protected] | 99 | [email protected] "=" |
100 | [email protected] "(" | 100 | [email protected] ">" |
101 | [email protected] ")" | 101 | [email protected] " " |
102 | [email protected] " " | 102 | [email protected] |
103 | [email protected] "=" | 103 | [email protected] "{" |
104 | [email protected] ">" | 104 | [email protected] "}" |
105 | [email protected] " " | 105 | [email protected] "\n " |
106 | [email protected] | 106 | [email protected] "}" |
107 | [email protected] "{" | ||
108 | [email protected] "}" | ||
109 | [email protected] "\n " | ||
110 | [email protected] "}" | ||
111 | [email protected] "\n " | 107 | [email protected] "\n " |
112 | [email protected] | 108 | [email protected] |
113 | [email protected] | 109 | [email protected] |
diff --git a/crates/syntax/test_data/parser/inline/ok/0160_try_macro_rules.rast b/crates/syntax/test_data/parser/inline/ok/0160_try_macro_rules.rast index 05b89d1c3..d1c22947b 100644 --- a/crates/syntax/test_data/parser/inline/ok/0160_try_macro_rules.rast +++ b/crates/syntax/test_data/parser/inline/ok/0160_try_macro_rules.rast | |||
@@ -1,9 +1,6 @@ | |||
1 | [email protected] | 1 | [email protected] |
2 | [email protected] | 2 | [email protected] |
3 | [email protected] | 3 | [email protected] "macro_rules" |
4 | [email protected] | ||
5 | [email protected] | ||
6 | [email protected] "macro_rules" | ||
7 | [email protected] "!" | 4 | [email protected] "!" |
8 | [email protected] " " | 5 | [email protected] " " |
9 | [email protected] | 6 | [email protected] |
diff --git a/crates/syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast b/crates/syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast index be60f7a8e..87d8ebcba 100644 --- a/crates/syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast +++ b/crates/syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast | |||
@@ -1,5 +1,5 @@ | |||
1 | [email protected] | 1 | [email protected] |
2 | MACRO_CALL@0..64 | 2 | MACRO_RULES@0..64 |
3 | [email protected] "/// Some docs" | 3 | [email protected] "/// Some docs" |
4 | [email protected] "\n" | 4 | [email protected] "\n" |
5 | [email protected] | 5 | [email protected] |
@@ -11,10 +11,7 @@ [email protected] | |||
11 | [email protected] "macro_export" | 11 | [email protected] "macro_export" |
12 | [email protected] "]" | 12 | [email protected] "]" |
13 | [email protected] "\n" | 13 | [email protected] "\n" |
14 | [email protected] | 14 | [email protected] "macro_rules" |
15 | [email protected] | ||
16 | [email protected] | ||
17 | [email protected] "macro_rules" | ||
18 | [email protected] "!" | 15 | [email protected] "!" |
19 | [email protected] " " | 16 | [email protected] " " |
20 | [email protected] | 17 | [email protected] |