Repository: rust-analyzer/rust-analyzer (rust)

Issue:
Stop storing supertraits in the `ItemTree`
Currently when we lower traits, we lower any supertrait bounds to where-clauses in the traits's `GenericParams`, but we *also* store them redundantly in the `bounds` field:

https://github.com/rust-analyzer/rust-analyzer/blob/f3aaae65553550cc9b7101a844ecbc3d426a1bef/crates/hir_def/src/item_tree.rs#L647

The field is only used to display the trait, so it should be removed. When displaying the trait, we currently display *both* the supertrait bounds, *and* all where-clauses in the `GenericParams`, so the supertrait bounds actually appear twice:

```rust
pub trait HirDisplay: Clone {}
```
results in:
```
pub trait HirDisplay: Clone
where
    Self: Clone,
```

Pull request:
internal: Don't store supertraits in ItemTree
Closes #9010

Patch:
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs
index c5cf803fd3..72f0d9b5f7 100644
--- a/crates/hir/src/display.rs
+++ b/crates/hir/src/display.rs
@@ -427,10 +427,6 @@ impl HirDisplay for Trait {
         write!(f, "trait {}", data.name)?;
         let def_id = GenericDefId::TraitId(self.id);
         write_generic_params(def_id, f)?;
-        if !data.bounds.is_empty() {
-            write!(f, ": ")?;
-            f.write_joined(&*data.bounds, " + ")?;
-        }
         write_where_clause(def_id, f)?;
         Ok(())
     }
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs
index 8bcac60ef5..a04f73352b 100644
--- a/crates/hir_def/src/data.rs
+++ b/crates/hir_def/src/data.rs
@@ -141,7 +141,6 @@ pub struct TraitData {
     pub is_auto: bool,
     pub is_unsafe: bool,
     pub visibility: RawVisibility,
-    pub bounds: Box<[Interned<TypeBound>]>,
 }
 
 impl TraitData {
@@ -155,7 +154,6 @@ impl TraitData {
         let module_id = tr_loc.container;
         let container = AssocContainerId::TraitId(tr);
         let visibility = item_tree[tr_def.visibility].clone();
-        let bounds = tr_def.bounds.clone();
         let mut expander = Expander::new(db, tr_loc.id.file_id(), module_id);
 
         let items = collect_items(
@@ -168,7 +166,7 @@ impl TraitData {
             100,
         );
 
-        Arc::new(TraitData { name, items, is_auto, is_unsafe, visibility, bounds })
+        Arc::new(TraitData { name, items, is_auto, is_unsafe, visibility })
     }
 
     pub fn associated_types(&self) -> impl Iterator<Item = TypeAliasId> + '_ {
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index f84c4cf2b6..c4d20c416b 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -661,7 +661,6 @@ pub struct Trait {
     pub generic_params: Interned<GenericParams>,
     pub is_auto: bool,
     pub is_unsafe: bool,
-    pub bounds: Box<[Interned<TypeBound>]>,
     pub items: Box<[AssocItem]>,
     pub ast_id: FileAstId<ast::Trait>,
 }
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index 40f3428b7b..b83adec46a 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -474,7 +474,6 @@ impl<'a> Ctx<'a> {
             self.lower_generic_params_and_inner_items(GenericsOwner::Trait(trait_def), trait_def);
         let is_auto = trait_def.auto_token().is_some();
         let is_unsafe = trait_def.unsafe_token().is_some();
-        let bounds = self.lower_type_bounds(trait_def);
         let items = trait_def.assoc_item_list().map(|list| {
             let db = self.db;
             self.with_inherited_visibility(visibility, |this| {
@@ -497,7 +496,6 @@ impl<'a> Ctx<'a> {
             generic_params,
             is_auto,
             is_unsafe,
-            bounds: bounds.into(),
             items: items.unwrap_or_default(),
             ast_id,
         };
diff --git a/crates/hir_def/src/item_tree/pretty.rs b/crates/hir_def/src/item_tree/pretty.rs
index 53631ab192..d1ee697cb5 100644
--- a/crates/hir_def/src/item_tree/pretty.rs
+++ b/crates/hir_def/src/item_tree/pretty.rs
@@ -345,7 +345,6 @@ impl<'a> Printer<'a> {
                     visibility,
                     is_auto,
                     is_unsafe,
-                    bounds,
                     items,
                     generic_params,
                     ast_id: _,
@@ -359,10 +358,6 @@ impl<'a> Printer<'a> {
                 }
                 w!(self, "trait {}", name);
                 self.print_generic_params(generic_params);
-                if !bounds.is_empty() {
-                    w!(self, ": ");
-                    self.print_type_bounds(bounds);
-                }
                 self.print_where_clause_and_opening_brace(generic_params);
                 self.indented(|this| {
                     for item in &**items {


Test patch:
diff --git a/crates/hir_def/src/item_tree/tests.rs b/crates/hir_def/src/item_tree/tests.rs
index 20773aa699..b362add5c9 100644
--- a/crates/hir_def/src/item_tree/tests.rs
+++ b/crates/hir_def/src/item_tree/tests.rs
@@ -180,7 +180,7 @@ trait Tr: SuperTrait + 'lifetime {
                 _: (),
             ) -> ();
 
-            pub(self) trait Tr<Self>: SuperTrait + 'lifetime
+            pub(self) trait Tr<Self>
             where
                 Self: SuperTrait,
                 Self: 'lifetime
@@ -350,7 +350,7 @@ trait Tr<'a, T: 'a>: Super {}
             pub(self) union Union<'a, T, const U: u8> {
             }
 
-            pub(self) trait Tr<'a, Self, T>: Super
+            pub(self) trait Tr<'a, Self, T>
             where
                 Self: Super,
                 T: 'a