From 6674bd898ed0e85fd61dba2b018144477ef6347c Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 11 Nov 2022 15:25:15 +0100 Subject: [PATCH] fix: Add trait alias grammar to rust.ungram --- crates/hir-def/src/data.rs | 18 +++++++++++++----- crates/hir-def/src/item_tree.rs | 3 ++- crates/hir-def/src/item_tree/lower.rs | 10 +--------- crates/hir-def/src/item_tree/pretty.rs | 19 ++++++++++++++----- crates/syntax/rust.ungram | 7 +++++-- crates/syntax/src/ast/generated/nodes.rs | 2 ++ 6 files changed, 37 insertions(+), 22 deletions(-) diff --git a/crates/hir-def/src/data.rs b/crates/hir-def/src/data.rs index 2dc69b00ac..9c76969086 100644 --- a/crates/hir-def/src/data.rs +++ b/crates/hir-def/src/data.rs @@ -236,11 +236,19 @@ impl TraitData { .by_key("rustc_skip_array_during_method_dispatch") .exists(); - let mut collector = - AssocItemCollector::new(db, module_id, tree_id.file_id(), ItemContainerId::TraitId(tr)); - collector.collect(&item_tree, tree_id.tree_id(), &tr_def.items); - let (items, attribute_calls, diagnostics) = collector.finish(); - + let (items, attribute_calls, diagnostics) = match &tr_def.items { + Some(items) => { + let mut collector = AssocItemCollector::new( + db, + module_id, + tree_id.file_id(), + ItemContainerId::TraitId(tr), + ); + collector.collect(&item_tree, tree_id.tree_id(), items); + collector.finish() + } + None => Default::default(), + }; ( Arc::new(TraitData { name, diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs index 570344596d..0aa531eff7 100644 --- a/crates/hir-def/src/item_tree.rs +++ b/crates/hir-def/src/item_tree.rs @@ -666,7 +666,8 @@ pub struct Trait { pub generic_params: Interned, pub is_auto: bool, pub is_unsafe: bool, - pub items: Box<[AssocItem]>, + /// This is [`None`] if this Trait is a trait alias. + pub items: Option>, pub ast_id: FileAstId, } diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs index 79249757d9..b25274bccc 100644 --- a/crates/hir-def/src/item_tree/lower.rs +++ b/crates/hir-def/src/item_tree/lower.rs @@ -451,15 +451,7 @@ impl<'a> Ctx<'a> { .collect() }); let ast_id = self.source_ast_id_map.ast_id(trait_def); - let res = Trait { - name, - visibility, - generic_params, - is_auto, - is_unsafe, - items: items.unwrap_or_default(), - ast_id, - }; + let res = Trait { name, visibility, generic_params, is_auto, is_unsafe, items, ast_id }; Some(id(self.data().traits.alloc(res))) } diff --git a/crates/hir-def/src/item_tree/pretty.rs b/crates/hir-def/src/item_tree/pretty.rs index da1643152c..48c40df22f 100644 --- a/crates/hir-def/src/item_tree/pretty.rs +++ b/crates/hir-def/src/item_tree/pretty.rs @@ -375,12 +375,21 @@ impl<'a> Printer<'a> { } w!(self, "trait {}", name); self.print_generic_params(generic_params); - self.print_where_clause_and_opening_brace(generic_params); - self.indented(|this| { - for item in &**items { - this.print_mod_item((*item).into()); + match items { + Some(items) => { + self.print_where_clause_and_opening_brace(generic_params); + self.indented(|this| { + for item in &**items { + this.print_mod_item((*item).into()); + } + }); } - }); + None => { + w!(self, " = "); + // FIXME: Print the aliased traits + self.print_where_clause_and_opening_brace(generic_params); + } + } wln!(self, "}}"); } ModItem::Impl(it) => { diff --git a/crates/syntax/rust.ungram b/crates/syntax/rust.ungram index 5379732ac6..0a0cb0290d 100644 --- a/crates/syntax/rust.ungram +++ b/crates/syntax/rust.ungram @@ -239,8 +239,11 @@ Static = Trait = Attr* Visibility? 'unsafe'? 'auto'? - 'trait' Name GenericParamList? (':' TypeBoundList?)? WhereClause? - AssocItemList + 'trait' Name GenericParamList? + ( + (':' TypeBoundList?)? WhereClause? AssocItemList + | '=' TypeBoundList? WhereClause? ';' + ) AssocItemList = '{' Attr* AssocItem* '}' diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs index 6cfb98d92f..2ea715f47f 100644 --- a/crates/syntax/src/ast/generated/nodes.rs +++ b/crates/syntax/src/ast/generated/nodes.rs @@ -407,6 +407,8 @@ impl Trait { 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 assoc_item_list(&self) -> Option { support::child(&self.syntax) } + pub fn eq_token(&self) -> Option { support::token(&self.syntax, T![=]) } + pub fn semicolon_token(&self) -> Option { support::token(&self.syntax, T![;]) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)]