diff --git a/crates/ra_assists/src/handlers/add_missing_impl_members.rs b/crates/ra_assists/src/handlers/add_missing_impl_members.rs index f185e61e595..a2d9006e488 100644 --- a/crates/ra_assists/src/handlers/add_missing_impl_members.rs +++ b/crates/ra_assists/src/handlers/add_missing_impl_members.rs @@ -112,7 +112,7 @@ fn add_missing_impl_members_inner( ) -> Option<()> { let _p = ra_prof::profile("add_missing_impl_members_inner"); let impl_def = ctx.find_node_at_offset::()?; - let impl_item_list = impl_def.item_list()?; + let impl_item_list = impl_def.assoc_item_list()?; let trait_ = resolve_target_trait(&ctx.sema, &impl_def)?; @@ -121,6 +121,7 @@ fn add_missing_impl_members_inner( ast::AssocItem::FnDef(def) => def.name(), ast::AssocItem::TypeAliasDef(def) => def.name(), ast::AssocItem::ConstDef(def) => def.name(), + ast::AssocItem::MacroCall(_) => None, } .map(|it| it.text().clone()) }; diff --git a/crates/ra_assists/src/handlers/generate_new.rs b/crates/ra_assists/src/handlers/generate_new.rs index e27def1d8ab..25bc171bfb1 100644 --- a/crates/ra_assists/src/handlers/generate_new.rs +++ b/crates/ra_assists/src/handlers/generate_new.rs @@ -158,7 +158,7 @@ fn find_struct_impl(ctx: &AssistContext, strukt: &ast::StructDef) -> Option bool { - if let Some(il) = imp.item_list() { + if let Some(il) = imp.assoc_item_list() { for item in il.assoc_items() { if let ast::AssocItem::FnDef(f) = item { if let Some(name) = f.name() { diff --git a/crates/ra_assists/src/handlers/move_bounds.rs b/crates/ra_assists/src/handlers/move_bounds.rs index ba3dafb9955..6b73fff44cd 100644 --- a/crates/ra_assists/src/handlers/move_bounds.rs +++ b/crates/ra_assists/src/handlers/move_bounds.rs @@ -38,8 +38,8 @@ pub(crate) fn move_bounds_to_where_clause(acc: &mut Assists, ctx: &AssistContext let anchor = match_ast! { match parent { ast::FnDef(it) => it.body()?.syntax().clone().into(), - ast::TraitDef(it) => it.item_list()?.syntax().clone().into(), - ast::ImplDef(it) => it.item_list()?.syntax().clone().into(), + ast::TraitDef(it) => it.assoc_item_list()?.syntax().clone().into(), + ast::ImplDef(it) => it.assoc_item_list()?.syntax().clone().into(), ast::EnumDef(it) => it.variant_list()?.syntax().clone().into(), ast::StructDef(it) => { it.syntax().children_with_tokens() diff --git a/crates/ra_assists/src/utils.rs b/crates/ra_assists/src/utils.rs index 02de902d6ed..27c33df2320 100644 --- a/crates/ra_assists/src/utils.rs +++ b/crates/ra_assists/src/utils.rs @@ -63,7 +63,7 @@ pub fn get_missing_assoc_items( let mut impl_fns_consts = FxHashSet::default(); let mut impl_type = FxHashSet::default(); - if let Some(item_list) = impl_def.item_list() { + if let Some(item_list) = impl_def.assoc_item_list() { for item in item_list.assoc_items() { match item { ast::AssocItem::FnDef(f) => { @@ -83,6 +83,7 @@ pub fn get_missing_assoc_items( impl_fns_consts.insert(n.syntax().to_string()); } } + ast::AssocItem::MacroCall(_) => (), } } } diff --git a/crates/ra_hir_def/src/item_tree/lower.rs b/crates/ra_hir_def/src/item_tree/lower.rs index eb1da463207..4fc21a642ce 100644 --- a/crates/ra_hir_def/src/item_tree/lower.rs +++ b/crates/ra_hir_def/src/item_tree/lower.rs @@ -153,13 +153,12 @@ fn collect_inner_items(&mut self, container: &SyntaxNode) { self.forced_visibility = forced_vis; } - fn lower_assoc_item(&mut self, item: &ast::Item) -> Option { + fn lower_assoc_item(&mut self, item: &ast::AssocItem) -> Option { match item { - ast::Item::FnDef(ast) => self.lower_function(ast).map(Into::into), - ast::Item::TypeAliasDef(ast) => self.lower_type_alias(ast).map(Into::into), - ast::Item::ConstDef(ast) => Some(self.lower_const(ast).into()), - ast::Item::MacroCall(ast) => self.lower_macro_call(ast).map(Into::into), - _ => None, + ast::AssocItem::FnDef(ast) => self.lower_function(ast).map(Into::into), + ast::AssocItem::TypeAliasDef(ast) => self.lower_type_alias(ast).map(Into::into), + ast::AssocItem::ConstDef(ast) => Some(self.lower_const(ast).into()), + ast::AssocItem::MacroCall(ast) => self.lower_macro_call(ast).map(Into::into), } } @@ -419,9 +418,9 @@ fn lower_trait(&mut self, trait_def: &ast::TraitDef) -> Option Option // We cannot use `assoc_items()` here as that does not include macro calls. let items = impl_def - .item_list() + .assoc_item_list() .into_iter() - .flat_map(|it| it.items()) + .flat_map(|it| it.assoc_items()) .filter_map(|item| { self.collect_inner_items(item.syntax()); let assoc = self.lower_assoc_item(&item)?; diff --git a/crates/ra_ide/src/completion/complete_fn_param.rs b/crates/ra_ide/src/completion/complete_fn_param.rs index 7a53083f540..d4b6112a5a6 100644 --- a/crates/ra_ide/src/completion/complete_fn_param.rs +++ b/crates/ra_ide/src/completion/complete_fn_param.rs @@ -18,26 +18,36 @@ pub(super) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext) } let mut params = FxHashMap::default(); + let me = ctx.token.ancestors().find_map(ast::FnDef::cast); + let mut process_fn = |func: ast::FnDef| { + if Some(&func) == me.as_ref() { + return; + } + func.param_list().into_iter().flat_map(|it| it.params()).for_each(|param| { + let text = param.syntax().text().to_string(); + params.entry(text).or_insert(param); + }) + }; + for node in ctx.token.parent().ancestors() { - let items = match_ast! { + match_ast! { match node { - ast::SourceFile(it) => it.items(), - ast::ItemList(it) => it.items(), + ast::SourceFile(it) => it.items().filter_map(|item| match item { + ast::Item::FnDef(it) => Some(it), + _ => None, + }).for_each(&mut process_fn), + ast::ItemList(it) => it.items().filter_map(|item| match item { + ast::Item::FnDef(it) => Some(it), + _ => None, + }).for_each(&mut process_fn), + ast::AssocItemList(it) => it.assoc_items().filter_map(|item| match item { + ast::AssocItem::FnDef(it) => Some(it), + _ => None, + }).for_each(&mut process_fn), _ => continue, } }; - for item in items { - if let ast::Item::FnDef(func) = item { - if Some(&func) == me.as_ref() { - continue; - } - func.param_list().into_iter().flat_map(|it| it.params()).for_each(|param| { - let text = param.syntax().text().to_string(); - params.entry(text).or_insert(param); - }) - } - } } params diff --git a/crates/ra_ide/src/completion/complete_keyword.rs b/crates/ra_ide/src/completion/complete_keyword.rs index fcdaeef49b0..1581b2d5d8e 100644 --- a/crates/ra_ide/src/completion/complete_keyword.rs +++ b/crates/ra_ide/src/completion/complete_keyword.rs @@ -66,27 +66,24 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte add_keyword(ctx, acc, "fn", "fn $0() {}") } - if (ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent) - || ctx.block_expr_parent - { + if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent { add_keyword(ctx, acc, "trait", "trait $0 {}"); add_keyword(ctx, acc, "impl", "impl $0 {}"); } return; } - if ctx.has_item_list_or_source_file_parent || ctx.block_expr_parent { + if ctx.has_item_list_or_source_file_parent || has_trait_or_impl_parent || ctx.block_expr_parent + { add_keyword(ctx, acc, "fn", "fn $0() {}"); } - if (ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent) - || ctx.block_expr_parent - { + if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent { add_keyword(ctx, acc, "use", "use "); add_keyword(ctx, acc, "impl", "impl $0 {}"); add_keyword(ctx, acc, "trait", "trait $0 {}"); } - if ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent { + if ctx.has_item_list_or_source_file_parent { add_keyword(ctx, acc, "enum", "enum $0 {}"); add_keyword(ctx, acc, "struct", "struct $0"); add_keyword(ctx, acc, "union", "union $0 {}"); @@ -108,29 +105,28 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte add_keyword(ctx, acc, "else", "else {$0}"); add_keyword(ctx, acc, "else if", "else if $0 {}"); } - if (ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent) - || ctx.block_expr_parent - { + if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent { add_keyword(ctx, acc, "mod", "mod $0 {}"); } if ctx.bind_pat_parent || ctx.ref_pat_parent { add_keyword(ctx, acc, "mut", "mut "); } - if ctx.has_item_list_or_source_file_parent || ctx.block_expr_parent { + if ctx.has_item_list_or_source_file_parent || has_trait_or_impl_parent || ctx.block_expr_parent + { add_keyword(ctx, acc, "const", "const "); add_keyword(ctx, acc, "type", "type "); } - if (ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent) - || ctx.block_expr_parent - { + if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent { add_keyword(ctx, acc, "static", "static "); }; - if (ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent) - || ctx.block_expr_parent - { + if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent { add_keyword(ctx, acc, "extern", "extern "); } - if ctx.has_item_list_or_source_file_parent || ctx.block_expr_parent || ctx.is_match_arm { + if ctx.has_item_list_or_source_file_parent + || has_trait_or_impl_parent + || ctx.block_expr_parent + || ctx.is_match_arm + { add_keyword(ctx, acc, "unsafe", "unsafe "); } if ctx.in_loop_body { @@ -142,7 +138,7 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte add_keyword(ctx, acc, "break", "break"); } } - if ctx.has_item_list_or_source_file_parent && !ctx.has_trait_parent { + if ctx.has_item_list_or_source_file_parent || ctx.has_impl_parent { add_keyword(ctx, acc, "pub", "pub ") } diff --git a/crates/ra_ide/src/completion/patterns.rs b/crates/ra_ide/src/completion/patterns.rs index b2fe13280a8..175209d8ac7 100644 --- a/crates/ra_ide/src/completion/patterns.rs +++ b/crates/ra_ide/src/completion/patterns.rs @@ -13,7 +13,7 @@ pub(crate) fn has_trait_parent(element: SyntaxElement) -> bool { not_same_range_ancestor(element) - .filter(|it| it.kind() == ITEM_LIST) + .filter(|it| it.kind() == ASSOC_ITEM_LIST) .and_then(|it| it.parent()) .filter(|it| it.kind() == TRAIT_DEF) .is_some() @@ -25,7 +25,7 @@ fn test_has_trait_parent() { pub(crate) fn has_impl_parent(element: SyntaxElement) -> bool { not_same_range_ancestor(element) - .filter(|it| it.kind() == ITEM_LIST) + .filter(|it| it.kind() == ASSOC_ITEM_LIST) .and_then(|it| it.parent()) .filter(|it| it.kind() == IMPL_DEF) .is_some() @@ -73,7 +73,7 @@ pub(crate) fn has_item_list_or_source_file_parent(element: SyntaxElement) -> boo #[test] fn test_has_item_list_or_source_file_parent() { check_pattern_is_applicable(r"i<|>", has_item_list_or_source_file_parent); - check_pattern_is_applicable(r"impl { f<|> }", has_item_list_or_source_file_parent); + check_pattern_is_applicable(r"mod foo { f<|> }", has_item_list_or_source_file_parent); } pub(crate) fn is_match_arm(element: SyntaxElement) -> bool { diff --git a/crates/ra_parser/src/grammar/items/traits.rs b/crates/ra_parser/src/grammar/items/traits.rs index c819e33be97..ef9c8ff5b03 100644 --- a/crates/ra_parser/src/grammar/items/traits.rs +++ b/crates/ra_parser/src/grammar/items/traits.rs @@ -50,7 +50,7 @@ pub(crate) fn trait_item_list(p: &mut Parser) { item_or_macro(p, true, ItemFlavor::Trait); } p.expect(T!['}']); - m.complete(p, ITEM_LIST); + m.complete(p, ASSOC_ITEM_LIST); } // test impl_def @@ -107,7 +107,7 @@ pub(crate) fn impl_item_list(p: &mut Parser) { item_or_macro(p, true, ItemFlavor::Mod); } p.expect(T!['}']); - m.complete(p, ITEM_LIST); + m.complete(p, ASSOC_ITEM_LIST); } // test impl_type_params diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs index 625f0c82296..56dadc6af0e 100644 --- a/crates/ra_parser/src/syntax_kind/generated.rs +++ b/crates/ra_parser/src/syntax_kind/generated.rs @@ -213,6 +213,7 @@ pub enum SyntaxKind { TUPLE_FIELD_DEF, ENUM_VARIANT_LIST, ITEM_LIST, + ASSOC_ITEM_LIST, ATTR, META_ITEM, USE_TREE, diff --git a/crates/ra_syntax/src/ast/edit.rs b/crates/ra_syntax/src/ast/edit.rs index abc7a646c2c..01a310f66de 100644 --- a/crates/ra_syntax/src/ast/edit.rs +++ b/crates/ra_syntax/src/ast/edit.rs @@ -80,9 +80,12 @@ fn make_multiline(node: N) -> N } } -impl ast::ItemList { +impl ast::AssocItemList { #[must_use] - pub fn append_items(&self, items: impl IntoIterator) -> ast::ItemList { + pub fn append_items( + &self, + items: impl IntoIterator, + ) -> ast::AssocItemList { let mut res = self.clone(); if !self.syntax().text().contains_char('\n') { res = make_multiline(res); @@ -92,7 +95,7 @@ pub fn append_items(&self, items: impl IntoIterator) -> a } #[must_use] - pub fn append_item(&self, item: ast::AssocItem) -> ast::ItemList { + pub fn append_item(&self, item: ast::AssocItem) -> ast::AssocItemList { let (indent, position) = match self.assoc_items().last() { Some(it) => ( leading_indent(it.syntax()).unwrap_or_default().to_string(), diff --git a/crates/ra_syntax/src/ast/generated/nodes.rs b/crates/ra_syntax/src/ast/generated/nodes.rs index dfda7955028..7ccb7ea7fac 100644 --- a/crates/ra_syntax/src/ast/generated/nodes.rs +++ b/crates/ra_syntax/src/ast/generated/nodes.rs @@ -112,7 +112,7 @@ pub fn unsafe_token(&self) -> Option { support::token(&self.syntax, pub fn impl_token(&self) -> Option { support::token(&self.syntax, T![impl]) } pub fn excl_token(&self) -> Option { support::token(&self.syntax, T![!]) } pub fn for_token(&self) -> Option { support::token(&self.syntax, T![for]) } - pub fn item_list(&self) -> Option { support::child(&self.syntax) } + pub fn assoc_item_list(&self) -> Option { support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct MacroCall { @@ -180,7 +180,7 @@ impl TraitDef { pub fn unsafe_token(&self) -> Option { support::token(&self.syntax, T![unsafe]) } pub fn auto_token(&self) -> Option { support::token(&self.syntax, T![auto]) } pub fn trait_token(&self) -> Option { support::token(&self.syntax, T![trait]) } - pub fn item_list(&self) -> Option { support::child(&self.syntax) } + pub fn assoc_item_list(&self) -> Option { support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct TypeAliasDef { @@ -238,11 +238,6 @@ pub fn path(&self) -> Option { support::child(&self.syntax) } pub fn r_paren_token(&self) -> Option { support::token(&self.syntax, T![')']) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Abi { - pub(crate) syntax: SyntaxNode, -} -impl Abi {} -#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Name { pub(crate) syntax: SyntaxNode, } @@ -250,6 +245,20 @@ impl Name { pub fn ident_token(&self) -> Option { support::token(&self.syntax, T![ident]) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct ItemList { + pub(crate) syntax: SyntaxNode, +} +impl ast::ModuleItemOwner for ItemList {} +impl ItemList { + pub fn l_curly_token(&self) -> Option { support::token(&self.syntax, T!['{']) } + pub fn r_curly_token(&self) -> Option { support::token(&self.syntax, T!['}']) } +} +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Abi { + pub(crate) syntax: SyntaxNode, +} +impl Abi {} +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct TypeParamList { pub(crate) syntax: SyntaxNode, } @@ -367,11 +376,10 @@ impl TypeBoundList { pub fn bounds(&self) -> AstChildren { support::children(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct ItemList { +pub struct AssocItemList { pub(crate) syntax: SyntaxNode, } -impl ast::ModuleItemOwner for ItemList {} -impl ItemList { +impl AssocItemList { pub fn l_curly_token(&self) -> Option { support::token(&self.syntax, T!['{']) } pub fn assoc_items(&self) -> AstChildren { support::children(&self.syntax) } pub fn r_curly_token(&self) -> Option { support::token(&self.syntax, T!['}']) } @@ -1336,10 +1344,10 @@ pub enum AssocItem { FnDef(FnDef), TypeAliasDef(TypeAliasDef), ConstDef(ConstDef), + MacroCall(MacroCall), } impl ast::AttrsOwner for AssocItem {} impl ast::NameOwner for AssocItem {} -impl ast::VisibilityOwner for AssocItem {} #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Pat { OrPat(OrPat), @@ -1574,8 +1582,8 @@ fn cast(syntax: SyntaxNode) -> Option { } fn syntax(&self) -> &SyntaxNode { &self.syntax } } -impl AstNode for Abi { - fn can_cast(kind: SyntaxKind) -> bool { kind == ABI } +impl AstNode for Name { + fn can_cast(kind: SyntaxKind) -> bool { kind == NAME } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1585,8 +1593,19 @@ fn cast(syntax: SyntaxNode) -> Option { } fn syntax(&self) -> &SyntaxNode { &self.syntax } } -impl AstNode for Name { - fn can_cast(kind: SyntaxKind) -> bool { kind == NAME } +impl AstNode for ItemList { + fn can_cast(kind: SyntaxKind) -> bool { kind == ITEM_LIST } + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +impl AstNode for Abi { + fn can_cast(kind: SyntaxKind) -> bool { kind == ABI } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1728,8 +1747,8 @@ fn cast(syntax: SyntaxNode) -> Option { } fn syntax(&self) -> &SyntaxNode { &self.syntax } } -impl AstNode for ItemList { - fn can_cast(kind: SyntaxKind) -> bool { kind == ITEM_LIST } +impl AstNode for AssocItemList { + fn can_cast(kind: SyntaxKind) -> bool { kind == ASSOC_ITEM_LIST } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -3144,10 +3163,13 @@ fn from(node: TypeAliasDef) -> AssocItem { AssocItem::TypeAliasDef(node) } impl From for AssocItem { fn from(node: ConstDef) -> AssocItem { AssocItem::ConstDef(node) } } +impl From for AssocItem { + fn from(node: MacroCall) -> AssocItem { AssocItem::MacroCall(node) } +} impl AstNode for AssocItem { fn can_cast(kind: SyntaxKind) -> bool { match kind { - FN_DEF | TYPE_ALIAS_DEF | CONST_DEF => true, + FN_DEF | TYPE_ALIAS_DEF | CONST_DEF | MACRO_CALL => true, _ => false, } } @@ -3156,6 +3178,7 @@ fn cast(syntax: SyntaxNode) -> Option { FN_DEF => AssocItem::FnDef(FnDef { syntax }), TYPE_ALIAS_DEF => AssocItem::TypeAliasDef(TypeAliasDef { syntax }), CONST_DEF => AssocItem::ConstDef(ConstDef { syntax }), + MACRO_CALL => AssocItem::MacroCall(MacroCall { syntax }), _ => return None, }; Some(res) @@ -3165,6 +3188,7 @@ fn syntax(&self) -> &SyntaxNode { AssocItem::FnDef(it) => &it.syntax, AssocItem::TypeAliasDef(it) => &it.syntax, AssocItem::ConstDef(it) => &it.syntax, + AssocItem::MacroCall(it) => &it.syntax, } } } @@ -3515,12 +3539,17 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for Abi { +impl std::fmt::Display for Name { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for Name { +impl std::fmt::Display for ItemList { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} +impl std::fmt::Display for Abi { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } @@ -3585,7 +3614,7 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for ItemList { +impl std::fmt::Display for AssocItemList { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs index 83449437bb2..d2a408e775c 100644 --- a/xtask/src/ast_src.rs +++ b/xtask/src/ast_src.rs @@ -186,6 +186,7 @@ pub(crate) struct KindsSrc<'a> { "TUPLE_FIELD_DEF", "ENUM_VARIANT_LIST", "ITEM_LIST", + "ASSOC_ITEM_LIST", "ATTR", "META_ITEM", // not an item actually "USE_TREE", diff --git a/xtask/src/codegen/rust.ungram b/xtask/src/codegen/rust.ungram index a93cb381587..d0518ceadf3 100644 --- a/xtask/src/codegen/rust.ungram +++ b/xtask/src/codegen/rust.ungram @@ -19,6 +19,13 @@ Item = | UnionDef | UseItem +Module = + Attr* Visibility? 'mod' Name + (ItemList | ';') + +ItemList = + '{' Item* '}' + FnDef = Attr* Visibility? Abi? 'const' 'default' 'async' 'unsafe' 'fn' Name TypeParamList? ParamList RetType? @@ -67,17 +74,10 @@ EnumVariant = TraitDef = Attr* Visibility? 'unsafe'? 'auto'? 'trait' Name TypeParamList (':' TypeBoundList?)? WhereClause - ItemList + AssocItemList -Module = - Attr* Visibility? 'mod' Name - (ItemList | ';') - -ItemList = - '{' - AssocItem* - Item* - '}' +AssocItemList = + '{' AssocItem* '}' ConstDef = Attr* Visibility? 'default'? 'const' Name ':' ascribed_type:TypeRef @@ -94,7 +94,7 @@ TypeAliasDef = ImplDef = Attr* Visibility? 'const'? 'default'? 'unsafe'? 'impl' TypeParamList? '!'? 'for' WhereClause? - ItemList + AssocItemList ParenType = '(' TypeRef ')' @@ -467,6 +467,7 @@ AssocItem = FnDef | TypeAliasDef | ConstDef +| MacroCall ExternItem = FnDef | StaticDef