about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs158
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs196
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs96
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs45
4 files changed, 52 insertions, 443 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
index 65dc35337a5..07d1500fc09 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
@@ -29,7 +29,6 @@
 //!
 //! In general, any item in the `ItemTree` stores its `AstId`, which allows mapping it back to its
 //! surface syntax.
-#![allow(unexpected_cfgs)]
 
 mod lower;
 mod pretty;
@@ -51,7 +50,7 @@ use hir_expand::{
     mod_path::{ModPath, PathKind},
     name::Name,
 };
-use intern::{Interned, Symbol};
+use intern::Interned;
 use la_arena::{Arena, Idx, RawIdx};
 use rustc_hash::FxHashMap;
 use smallvec::SmallVec;
@@ -237,7 +236,6 @@ impl ItemTree {
                 structs,
                 unions,
                 enums,
-                variants,
                 consts,
                 statics,
                 traits,
@@ -258,7 +256,6 @@ impl ItemTree {
             structs.shrink_to_fit();
             unions.shrink_to_fit();
             enums.shrink_to_fit();
-            variants.shrink_to_fit();
             consts.shrink_to_fit();
             statics.shrink_to_fit();
             traits.shrink_to_fit();
@@ -310,7 +307,6 @@ struct ItemTreeData {
     structs: Arena<Struct>,
     unions: Arena<Union>,
     enums: Arena<Enum>,
-    variants: Arena<Variant>,
     consts: Arena<Const>,
     statics: Arena<Static>,
     traits: Arena<Trait>,
@@ -340,41 +336,15 @@ pub enum AttrOwner {
     ModItem(ModItem),
     /// Inner attributes of the source file.
     TopLevel,
-
-    Variant(FileItemTreeId<Variant>),
-    // while not relevant to early name resolution, fields can contain visibility
-    Field(FieldParent, ItemTreeFieldId),
 }
 
-impl AttrOwner {
-    pub fn make_field_indexed(parent: FieldParent, idx: usize) -> Self {
-        AttrOwner::Field(parent, ItemTreeFieldId::from_raw(RawIdx::from_u32(idx as u32)))
+impl From<ModItem> for AttrOwner {
+    #[inline]
+    fn from(value: ModItem) -> Self {
+        AttrOwner::ModItem(value)
     }
 }
 
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum FieldParent {
-    Struct(FileItemTreeId<Struct>),
-    Union(FileItemTreeId<Union>),
-    EnumVariant(FileItemTreeId<Variant>),
-}
-
-pub type ItemTreeFieldId = Idx<Field>;
-
-macro_rules! from_attrs {
-    ( $( $var:ident($t:ty) ),+ $(,)? ) => {
-        $(
-            impl From<$t> for AttrOwner {
-                fn from(t: $t) -> AttrOwner {
-                    AttrOwner::$var(t)
-                }
-            }
-        )+
-    };
-}
-
-from_attrs!(ModItem(ModItem), Variant(FileItemTreeId<Variant>));
-
 /// Trait implemented by all nodes in the item tree.
 pub trait ItemTreeNode: Clone {
     type Source: AstIdNode;
@@ -383,7 +353,6 @@ pub trait ItemTreeNode: Clone {
 
     /// Looks up an instance of `Self` in an item tree.
     fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self;
-    fn attr_owner(id: FileItemTreeId<Self>) -> AttrOwner;
 }
 
 pub struct FileItemTreeId<N>(Idx<N>);
@@ -547,10 +516,6 @@ macro_rules! mod_items {
                 fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self {
                     &tree.data().$fld[index]
                 }
-
-                fn attr_owner(id: FileItemTreeId<Self>) -> AttrOwner {
-                    AttrOwner::ModItem(ModItem::$typ(id))
-                }
             }
 
             impl Index<Idx<$typ>> for ItemTree {
@@ -624,22 +589,6 @@ impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree {
     }
 }
 
-impl ItemTreeNode for Variant {
-    type Source = ast::Variant;
-
-    fn ast_id(&self) -> FileAstId<Self::Source> {
-        self.ast_id
-    }
-
-    fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self {
-        &tree.data().variants[index]
-    }
-
-    fn attr_owner(id: FileItemTreeId<Self>) -> AttrOwner {
-        AttrOwner::Variant(id)
-    }
-}
-
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct Use {
     pub visibility: RawVisibilityId,
@@ -712,7 +661,6 @@ pub struct ExternCrate {
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct ExternBlock {
-    pub abi: Option<Symbol>,
     pub ast_id: FileAstId<ast::ExternBlock>,
     pub children: Box<[ModItem]>,
 }
@@ -728,7 +676,6 @@ pub struct Function {
 pub struct Struct {
     pub name: Name,
     pub visibility: RawVisibilityId,
-    pub fields: Box<[Field]>,
     pub shape: FieldsShape,
     pub ast_id: FileAstId<ast::Struct>,
 }
@@ -737,7 +684,6 @@ pub struct Struct {
 pub struct Union {
     pub name: Name,
     pub visibility: RawVisibilityId,
-    pub fields: Box<[Field]>,
     pub ast_id: FileAstId<ast::Union>,
 }
 
@@ -745,18 +691,9 @@ pub struct Union {
 pub struct Enum {
     pub name: Name,
     pub visibility: RawVisibilityId,
-    pub variants: Range<FileItemTreeId<Variant>>,
     pub ast_id: FileAstId<ast::Enum>,
 }
 
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct Variant {
-    pub name: Name,
-    pub fields: Box<[Field]>,
-    pub shape: FieldsShape,
-    pub ast_id: FileAstId<ast::Variant>,
-}
-
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
 pub enum FieldsShape {
     Record,
@@ -788,16 +725,6 @@ impl VisibilityExplicitness {
     }
 }
 
-// FIXME: Remove this from item tree?
-/// A single field of an enum variant or struct
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct Field {
-    pub name: Name,
-    pub visibility: RawVisibilityId,
-    // FIXME: Not an item tree property
-    pub is_unsafe: bool,
-}
-
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct Const {
     /// `None` for `const _: () = ();`
@@ -817,7 +744,6 @@ pub struct Static {
 pub struct Trait {
     pub name: Name,
     pub visibility: RawVisibilityId,
-    pub items: Box<[AssocItem]>,
     pub ast_id: FileAstId<ast::Trait>,
 }
 
@@ -830,7 +756,6 @@ pub struct TraitAlias {
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct Impl {
-    pub items: Box<[AssocItem]>,
     pub ast_id: FileAstId<ast::Impl>,
 }
 
@@ -971,76 +896,3 @@ impl UseTree {
         }
     }
 }
-
-macro_rules! impl_froms {
-    ($e:ident { $($v:ident ($t:ty)),* $(,)? }) => {
-        $(
-            impl From<$t> for $e {
-                fn from(it: $t) -> $e {
-                    $e::$v(it)
-                }
-            }
-        )*
-    }
-}
-
-impl ModItem {
-    pub fn as_assoc_item(&self) -> Option<AssocItem> {
-        match self {
-            ModItem::Use(_)
-            | ModItem::ExternCrate(_)
-            | ModItem::ExternBlock(_)
-            | ModItem::Struct(_)
-            | ModItem::Union(_)
-            | ModItem::Enum(_)
-            | ModItem::Static(_)
-            | ModItem::Trait(_)
-            | ModItem::TraitAlias(_)
-            | ModItem::Impl(_)
-            | ModItem::Mod(_)
-            | ModItem::MacroRules(_)
-            | ModItem::Macro2(_) => None,
-            &ModItem::MacroCall(call) => Some(AssocItem::MacroCall(call)),
-            &ModItem::Const(konst) => Some(AssocItem::Const(konst)),
-            &ModItem::TypeAlias(alias) => Some(AssocItem::TypeAlias(alias)),
-            &ModItem::Function(func) => Some(AssocItem::Function(func)),
-        }
-    }
-}
-
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
-pub enum AssocItem {
-    Function(FileItemTreeId<Function>),
-    TypeAlias(FileItemTreeId<TypeAlias>),
-    Const(FileItemTreeId<Const>),
-    MacroCall(FileItemTreeId<MacroCall>),
-}
-
-impl_froms!(AssocItem {
-    Function(FileItemTreeId<Function>),
-    TypeAlias(FileItemTreeId<TypeAlias>),
-    Const(FileItemTreeId<Const>),
-    MacroCall(FileItemTreeId<MacroCall>),
-});
-
-impl From<AssocItem> for ModItem {
-    fn from(item: AssocItem) -> Self {
-        match item {
-            AssocItem::Function(it) => it.into(),
-            AssocItem::TypeAlias(it) => it.into(),
-            AssocItem::Const(it) => it.into(),
-            AssocItem::MacroCall(it) => it.into(),
-        }
-    }
-}
-
-impl AssocItem {
-    pub fn ast_id(self, tree: &ItemTree) -> FileAstId<ast::AssocItem> {
-        match self {
-            AssocItem::Function(id) => tree[id].ast_id.upcast(),
-            AssocItem::TypeAlias(id) => tree[id].ast_id.upcast(),
-            AssocItem::Const(id) => tree[id].ast_id.upcast(),
-            AssocItem::MacroCall(id) => tree[id].ast_id.upcast(),
-        }
-    }
-}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs
index 57765427693..d9588cb487d 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs
@@ -8,23 +8,22 @@ use hir_expand::{
     name::AsName,
     span_map::{SpanMap, SpanMapRef},
 };
-use intern::{Symbol, sym};
 use la_arena::Arena;
 use span::{AstIdMap, SyntaxContext};
 use syntax::{
     AstNode,
-    ast::{self, HasModuleItem, HasName, IsString},
+    ast::{self, HasModuleItem, HasName},
 };
 use triomphe::Arc;
 
 use crate::{
     db::DefDatabase,
     item_tree::{
-        AssocItem, AttrOwner, Const, Enum, ExternBlock, ExternCrate, Field, FieldParent,
-        FieldsShape, FileItemTreeId, Function, Idx, Impl, ImportAlias, Interned, ItemTree,
-        ItemTreeData, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, ModPath, Name, Range,
-        RawAttrs, RawIdx, RawVisibility, RawVisibilityId, Static, Struct, StructKind, Trait,
-        TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind, Variant, VisibilityExplicitness,
+        AttrOwner, Const, Enum, ExternBlock, ExternCrate, FieldsShape, FileItemTreeId, Function,
+        Idx, Impl, ImportAlias, Interned, ItemTree, ItemTreeData, Macro2, MacroCall, MacroRules,
+        Mod, ModItem, ModKind, ModPath, RawAttrs, RawVisibility, RawVisibilityId, Static, Struct,
+        StructKind, Trait, TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind,
+        VisibilityExplicitness,
     },
 };
 
@@ -163,118 +162,23 @@ impl<'a> Ctx<'a> {
         }
     }
 
-    fn lower_assoc_item(&mut self, item_node: &ast::AssocItem) -> Option<AssocItem> {
-        let item: AssocItem = match item_node {
-            ast::AssocItem::Fn(ast) => self.lower_function(ast).map(Into::into),
-            ast::AssocItem::TypeAlias(ast) => self.lower_type_alias(ast).map(Into::into),
-            ast::AssocItem::Const(ast) => Some(self.lower_const(ast).into()),
-            ast::AssocItem::MacroCall(ast) => self.lower_macro_call(ast).map(Into::into),
-        }?;
-        let attrs = RawAttrs::new(self.db, item_node, self.span_map());
-        self.add_attrs(
-            match item {
-                AssocItem::Function(it) => AttrOwner::ModItem(ModItem::Function(it)),
-                AssocItem::TypeAlias(it) => AttrOwner::ModItem(ModItem::TypeAlias(it)),
-                AssocItem::Const(it) => AttrOwner::ModItem(ModItem::Const(it)),
-                AssocItem::MacroCall(it) => AttrOwner::ModItem(ModItem::MacroCall(it)),
-            },
-            attrs,
-        );
-        Some(item)
-    }
-
     fn lower_struct(&mut self, strukt: &ast::Struct) -> Option<FileItemTreeId<Struct>> {
         let visibility = self.lower_visibility(strukt);
         let name = strukt.name()?.as_name();
         let ast_id = self.source_ast_id_map.ast_id(strukt);
-        let (fields, kind, attrs) = self.lower_fields(&strukt.kind());
-        let res = Struct { name, visibility, fields, shape: kind, ast_id };
+        let shape = adt_shape(strukt.kind());
+        let res = Struct { name, visibility, shape, ast_id };
         let id = id(self.data().structs.alloc(res));
 
-        for (idx, attr) in attrs {
-            self.add_attrs(
-                AttrOwner::Field(
-                    FieldParent::Struct(id),
-                    Idx::from_raw(RawIdx::from_u32(idx as u32)),
-                ),
-                attr,
-            );
-        }
         Some(id)
     }
 
-    fn lower_fields(
-        &mut self,
-        strukt_kind: &ast::StructKind,
-    ) -> (Box<[Field]>, FieldsShape, Vec<(usize, RawAttrs)>) {
-        match strukt_kind {
-            ast::StructKind::Record(it) => {
-                let mut fields = vec![];
-                let mut attrs = vec![];
-
-                for (i, field) in it.fields().enumerate() {
-                    let data = self.lower_record_field(&field);
-                    fields.push(data);
-                    let attr = RawAttrs::new(self.db, &field, self.span_map());
-                    if !attr.is_empty() {
-                        attrs.push((i, attr))
-                    }
-                }
-                (fields.into(), FieldsShape::Record, attrs)
-            }
-            ast::StructKind::Tuple(it) => {
-                let mut fields = vec![];
-                let mut attrs = vec![];
-
-                for (i, field) in it.fields().enumerate() {
-                    let data = self.lower_tuple_field(i, &field);
-                    fields.push(data);
-                    let attr = RawAttrs::new(self.db, &field, self.span_map());
-                    if !attr.is_empty() {
-                        attrs.push((i, attr))
-                    }
-                }
-                (fields.into(), FieldsShape::Tuple, attrs)
-            }
-            ast::StructKind::Unit => (Box::default(), FieldsShape::Unit, Vec::default()),
-        }
-    }
-
-    fn lower_record_field(&mut self, field: &ast::RecordField) -> Field {
-        let name = match field.name() {
-            Some(name) => name.as_name(),
-            None => Name::missing(),
-        };
-        let visibility = self.lower_visibility(field);
-
-        Field { name, visibility, is_unsafe: field.unsafe_token().is_some() }
-    }
-
-    fn lower_tuple_field(&mut self, idx: usize, field: &ast::TupleField) -> Field {
-        let name = Name::new_tuple_field(idx);
-        let visibility = self.lower_visibility(field);
-        Field { name, visibility, is_unsafe: false }
-    }
-
     fn lower_union(&mut self, union: &ast::Union) -> Option<FileItemTreeId<Union>> {
         let visibility = self.lower_visibility(union);
         let name = union.name()?.as_name();
         let ast_id = self.source_ast_id_map.ast_id(union);
-        let (fields, _, attrs) = match union.record_field_list() {
-            Some(record_field_list) => self.lower_fields(&StructKind::Record(record_field_list)),
-            None => (Box::default(), FieldsShape::Record, Vec::default()),
-        };
-        let res = Union { name, visibility, fields, ast_id };
+        let res = Union { name, visibility, ast_id };
         let id = id(self.data().unions.alloc(res));
-        for (idx, attr) in attrs {
-            self.add_attrs(
-                AttrOwner::Field(
-                    FieldParent::Union(id),
-                    Idx::from_raw(RawIdx::from_u32(idx as u32)),
-                ),
-                attr,
-            );
-        }
         Some(id)
     }
 
@@ -282,48 +186,11 @@ impl<'a> Ctx<'a> {
         let visibility = self.lower_visibility(enum_);
         let name = enum_.name()?.as_name();
         let ast_id = self.source_ast_id_map.ast_id(enum_);
-        let variants = match &enum_.variant_list() {
-            Some(variant_list) => self.lower_variants(variant_list),
-            None => {
-                FileItemTreeId(self.next_variant_idx())..FileItemTreeId(self.next_variant_idx())
-            }
-        };
-        let res = Enum { name, visibility, variants, ast_id };
+        let res = Enum { name, visibility, ast_id };
         let id = id(self.data().enums.alloc(res));
         Some(id)
     }
 
-    fn lower_variants(&mut self, variants: &ast::VariantList) -> Range<FileItemTreeId<Variant>> {
-        let start = self.next_variant_idx();
-        for variant in variants.variants() {
-            let idx = self.lower_variant(&variant);
-            self.add_attrs(id(idx).into(), RawAttrs::new(self.db, &variant, self.span_map()));
-        }
-        let end = self.next_variant_idx();
-        FileItemTreeId(start)..FileItemTreeId(end)
-    }
-
-    fn lower_variant(&mut self, variant: &ast::Variant) -> Idx<Variant> {
-        let name = match variant.name() {
-            Some(name) => name.as_name(),
-            None => Name::missing(),
-        };
-        let (fields, kind, attrs) = self.lower_fields(&variant.kind());
-        let ast_id = self.source_ast_id_map.ast_id(variant);
-        let res = Variant { name, fields, shape: kind, ast_id };
-        let id = self.data().variants.alloc(res);
-        for (idx, attr) in attrs {
-            self.add_attrs(
-                AttrOwner::Field(
-                    FieldParent::EnumVariant(FileItemTreeId(id)),
-                    Idx::from_raw(RawIdx::from_u32(idx as u32)),
-                ),
-                attr,
-            );
-        }
-        id
-    }
-
     fn lower_function(&mut self, func: &ast::Fn) -> Option<FileItemTreeId<Function>> {
         let visibility = self.lower_visibility(func);
         let name = func.name()?.as_name();
@@ -390,14 +257,7 @@ impl<'a> Ctx<'a> {
         let visibility = self.lower_visibility(trait_def);
         let ast_id = self.source_ast_id_map.ast_id(trait_def);
 
-        let items = trait_def
-            .assoc_item_list()
-            .into_iter()
-            .flat_map(|list| list.assoc_items())
-            .filter_map(|item_node| self.lower_assoc_item(&item_node))
-            .collect();
-
-        let def = Trait { name, visibility, items, ast_id };
+        let def = Trait { name, visibility, ast_id };
         let id = id(self.data().traits.alloc(def));
         Some(id)
     }
@@ -417,16 +277,9 @@ impl<'a> Ctx<'a> {
 
     fn lower_impl(&mut self, impl_def: &ast::Impl) -> FileItemTreeId<Impl> {
         let ast_id = self.source_ast_id_map.ast_id(impl_def);
-        // We cannot use `assoc_items()` here as that does not include macro calls.
-        let items = impl_def
-            .assoc_item_list()
-            .into_iter()
-            .flat_map(|it| it.assoc_items())
-            .filter_map(|item| self.lower_assoc_item(&item))
-            .collect();
         // Note that trait impls don't get implicit `Self` unlike traits, because here they are a
         // type alias rather than a type parameter, so this is handled by the resolver.
-        let res = Impl { items, ast_id };
+        let res = Impl { ast_id };
         id(self.data().impls.alloc(res))
     }
 
@@ -489,7 +342,6 @@ impl<'a> Ctx<'a> {
 
     fn lower_extern_block(&mut self, block: &ast::ExternBlock) -> FileItemTreeId<ExternBlock> {
         let ast_id = self.source_ast_id_map.ast_id(block);
-        let abi = block.abi().map(lower_abi);
         let children: Box<[_]> = block.extern_item_list().map_or(Box::new([]), |list| {
             list.extern_items()
                 .filter_map(|item| {
@@ -510,7 +362,7 @@ impl<'a> Ctx<'a> {
                 .collect()
         });
 
-        let res = ExternBlock { abi, ast_id, children };
+        let res = ExternBlock { ast_id, children };
         id(self.data().extern_blocks.alloc(res))
     }
 
@@ -520,20 +372,6 @@ impl<'a> Ctx<'a> {
         });
         self.data().vis.alloc(vis)
     }
-
-    fn next_variant_idx(&self) -> Idx<Variant> {
-        Idx::from_raw(RawIdx::from(
-            self.tree.data.as_ref().map_or(0, |data| data.variants.len() as u32),
-        ))
-    }
-}
-
-fn lower_abi(abi: ast::Abi) -> Symbol {
-    match abi.abi_string() {
-        Some(tok) => Symbol::intern(tok.text_without_quotes()),
-        // `extern` default to be `extern "C"`.
-        _ => sym::C,
-    }
 }
 
 struct UseTreeLowering<'a> {
@@ -647,3 +485,11 @@ pub(crate) fn visibility_from_ast(
     };
     RawVisibility::Module(Interned::new(path), VisibilityExplicitness::Explicit)
 }
+
+fn adt_shape(kind: StructKind) -> FieldsShape {
+    match kind {
+        StructKind::Record(_) => FieldsShape::Record,
+        StructKind::Tuple(_) => FieldsShape::Tuple,
+        StructKind::Unit => FieldsShape::Unit,
+    }
+}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
index 8ff14751c67..0c62b86dae2 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
@@ -2,15 +2,13 @@
 
 use std::fmt::{self, Write};
 
-use la_arena::{Idx, RawIdx};
 use span::{Edition, ErasedFileAstId};
 
 use crate::{
     item_tree::{
-        AttrOwner, Const, DefDatabase, Enum, ExternBlock, ExternCrate, Field, FieldParent,
-        FieldsShape, FileItemTreeId, Function, Impl, ItemTree, Macro2, MacroCall, MacroRules, Mod,
-        ModItem, ModKind, RawAttrs, RawVisibilityId, Static, Struct, Trait, TraitAlias, TypeAlias,
-        Union, Use, UseTree, UseTreeKind, Variant,
+        AttrOwner, Const, DefDatabase, Enum, ExternBlock, ExternCrate, FieldsShape, Function, Impl,
+        ItemTree, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, RawAttrs, RawVisibilityId,
+        Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind,
     },
     visibility::RawVisibility,
 };
@@ -118,44 +116,14 @@ impl Printer<'_> {
         };
     }
 
-    fn print_fields(&mut self, parent: FieldParent, kind: FieldsShape, fields: &[Field]) {
-        let edition = self.edition;
+    fn print_fields(&mut self, kind: FieldsShape) {
         match kind {
             FieldsShape::Record => {
                 self.whitespace();
-                w!(self, "{{");
-                self.indented(|this| {
-                    for (idx, Field { name, visibility, is_unsafe }) in fields.iter().enumerate() {
-                        this.print_attrs_of(
-                            AttrOwner::Field(parent, Idx::from_raw(RawIdx::from(idx as u32))),
-                            "\n",
-                        );
-                        this.print_visibility(*visibility);
-                        if *is_unsafe {
-                            w!(this, "unsafe ");
-                        }
-
-                        wln!(this, "{},", name.display(self.db, edition));
-                    }
-                });
-                w!(self, "}}");
+                w!(self, "{{ ... }}");
             }
             FieldsShape::Tuple => {
-                w!(self, "(");
-                self.indented(|this| {
-                    for (idx, Field { name, visibility, is_unsafe }) in fields.iter().enumerate() {
-                        this.print_attrs_of(
-                            AttrOwner::Field(parent, Idx::from_raw(RawIdx::from(idx as u32))),
-                            "\n",
-                        );
-                        this.print_visibility(*visibility);
-                        if *is_unsafe {
-                            w!(this, "unsafe ");
-                        }
-                        wln!(this, "{},", name.display(self.db, edition));
-                    }
-                });
-                w!(self, ")");
+                w!(self, "(...)");
             }
             FieldsShape::Unit => {}
         }
@@ -214,13 +182,9 @@ impl Printer<'_> {
                 wln!(self, ";");
             }
             ModItem::ExternBlock(it) => {
-                let ExternBlock { abi, ast_id, children } = &self.tree[it];
+                let ExternBlock { ast_id, children } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
-                w!(self, "extern ");
-                if let Some(abi) = abi {
-                    w!(self, "\"{}\" ", abi);
-                }
-                w!(self, "{{");
+                w!(self, "extern {{");
                 self.indented(|this| {
                     for child in &**children {
                         this.print_mod_item(*child);
@@ -235,11 +199,11 @@ impl Printer<'_> {
                 wln!(self, "fn {};", name.display(self.db, self.edition));
             }
             ModItem::Struct(it) => {
-                let Struct { visibility, name, fields, shape: kind, ast_id } = &self.tree[it];
+                let Struct { visibility, name, shape: kind, ast_id } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
                 w!(self, "struct {}", name.display(self.db, self.edition));
-                self.print_fields(FieldParent::Struct(it), *kind, fields);
+                self.print_fields(*kind);
                 if matches!(kind, FieldsShape::Record) {
                     wln!(self);
                 } else {
@@ -247,30 +211,18 @@ impl Printer<'_> {
                 }
             }
             ModItem::Union(it) => {
-                let Union { name, visibility, fields, ast_id } = &self.tree[it];
+                let Union { name, visibility, ast_id } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
                 w!(self, "union {}", name.display(self.db, self.edition));
-                self.print_fields(FieldParent::Union(it), FieldsShape::Record, fields);
+                self.print_fields(FieldsShape::Record);
                 wln!(self);
             }
             ModItem::Enum(it) => {
-                let Enum { name, visibility, variants, ast_id } = &self.tree[it];
+                let Enum { name, visibility, ast_id } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
-                w!(self, "enum {} {{", name.display(self.db, self.edition));
-                let edition = self.edition;
-                self.indented(|this| {
-                    for variant in FileItemTreeId::range_iter(variants.clone()) {
-                        let Variant { name, fields, shape: kind, ast_id } = &this.tree[variant];
-                        this.print_ast_id(ast_id.erase());
-                        this.print_attrs_of(variant, "\n");
-                        w!(this, "{}", name.display(self.db, edition));
-                        this.print_fields(FieldParent::EnumVariant(variant), *kind, fields);
-                        wln!(this, ",");
-                    }
-                });
-                wln!(self, "}}");
+                w!(self, "enum {} {{ ... }}", name.display(self.db, self.edition));
             }
             ModItem::Const(it) => {
                 let Const { name, visibility, ast_id } = &self.tree[it];
@@ -293,16 +245,10 @@ impl Printer<'_> {
                 wln!(self);
             }
             ModItem::Trait(it) => {
-                let Trait { name, visibility, items, ast_id } = &self.tree[it];
+                let Trait { name, visibility, ast_id } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
-                w!(self, "trait {} {{", name.display(self.db, self.edition));
-                self.indented(|this| {
-                    for item in &**items {
-                        this.print_mod_item((*item).into());
-                    }
-                });
-                wln!(self, "}}");
+                w!(self, "trait {} {{ ... }}", name.display(self.db, self.edition));
             }
             ModItem::TraitAlias(it) => {
                 let TraitAlias { name, visibility, ast_id } = &self.tree[it];
@@ -311,15 +257,9 @@ impl Printer<'_> {
                 wln!(self, "trait {} = ..;", name.display(self.db, self.edition));
             }
             ModItem::Impl(it) => {
-                let Impl { items, ast_id } = &self.tree[it];
+                let Impl { ast_id } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
-                w!(self, "impl {{");
-                self.indented(|this| {
-                    for item in &**items {
-                        this.print_mod_item((*item).into());
-                    }
-                });
-                wln!(self, "}}");
+                w!(self, "impl {{ ... }}");
             }
             ModItem::TypeAlias(it) => {
                 let TypeAlias { name, visibility, ast_id } = &self.tree[it];
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs
index 7a85e8d175e..e39efd31c6c 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs
@@ -73,10 +73,10 @@ extern "C" {
     fn ex_fn();
 }
         "#,
-        expect![[r##"
+        expect![[r#"
             #[on_extern_block]
             // AstId: ExternBlock[0000, 0]
-            extern "C" {
+            extern {
                 #[on_extern_type]
                 // AstId: TypeAlias[9FDF, 0]
                 pub(self) type ExType;
@@ -89,7 +89,7 @@ extern "C" {
                 // AstId: Fn[452D, 0]
                 pub(self) fn ex_fn;
             }
-        "##]],
+        "#]],
     );
 }
 
@@ -129,39 +129,16 @@ enum E {
 
             #[derive(Debug)]
             // AstId: Struct[C7A1, 0]
-            pub(self) struct Struct {
-                #[doc = " fld docs"]
-                pub(self) fld,
-            }
+            pub(self) struct Struct { ... }
 
             // AstId: Struct[DAC2, 0]
-            pub(self) struct Tuple(
-                #[attr]
-                pub(self) 0,
-            );
+            pub(self) struct Tuple(...);
 
             // AstId: Union[2DBB, 0]
-            pub(self) union Ize {
-                pub(self) a,
-                pub(self) b,
-            }
+            pub(self) union Ize { ... }
 
             // AstId: Enum[7FF8, 0]
-            pub(self) enum E {
-                // AstId: Variant[C717, 0]
-                #[doc = " comment on Unit"]
-                Unit,
-                // AstId: Variant[AEAB, 0]
-                #[doc = " comment on Tuple"]
-                Tuple(
-                    pub(self) 0,
-                ),
-                // AstId: Variant[4B1B, 0]
-                Struct {
-                    #[doc = " comment on a: u8"]
-                    pub(self) a,
-                },
-            }
+            pub(self) enum E { ... }
         "#]],
     );
 }
@@ -197,13 +174,7 @@ trait Tr: SuperTrait + 'lifetime {
             pub(self) fn f;
 
             // AstId: Trait[2998, 0]
-            pub(self) trait Tr {
-                // AstId: TypeAlias[9F08, 0]
-                pub(self) type Assoc;
-
-                // AstId: Fn[6C0C, 0]
-                pub(self) fn method;
-            }
+            pub(self) trait Tr { ... }
         "#]],
     );
 }