about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-05-24 13:58:44 +0000
committerGitHub <noreply@github.com>2021-05-24 13:58:44 +0000
commit01f8d40c5cb28854091d2081b7aa607ad9902930 (patch)
treeaeb89306e864bff3fc612d26ab6242a75b3e3885
parent05fc97e31b1d04bf5d5885edd98a1510f0931a62 (diff)
parent533e9207d39c27dc22de2645fc65891189a71739 (diff)
Merge #8965
8965: internal: intern `TypeBound` and `GenericArgs` r=jonas-schievink a=jonas-schievink

Saves a few MB, but not much

bors r+

Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
-rw-r--r--crates/hir/src/display.rs2
-rw-r--r--crates/hir_def/src/data.rs4
-rw-r--r--crates/hir_def/src/generics.rs20
-rw-r--r--crates/hir_def/src/intern.rs2
-rw-r--r--crates/hir_def/src/item_tree.rs4
-rw-r--r--crates/hir_def/src/item_tree/lower.rs13
-rw-r--r--crates/hir_def/src/item_tree/pretty.rs4
-rw-r--r--crates/hir_def/src/path.rs9
-rw-r--r--crates/hir_def/src/path/lower.rs15
-rw-r--r--crates/hir_def/src/type_ref.rs14
-rw-r--r--crates/hir_ty/src/display.rs7
-rw-r--r--crates/hir_ty/src/lower.rs3
12 files changed, 59 insertions, 38 deletions
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs
index 508ac37c22a..c5cf803fd33 100644
--- a/crates/hir/src/display.rs
+++ b/crates/hir/src/display.rs
@@ -92,7 +92,7 @@ impl HirDisplay for Function {
             &data.ret_type
         } else {
             match &*data.ret_type {
-                TypeRef::ImplTrait(bounds) => match &bounds[0] {
+                TypeRef::ImplTrait(bounds) => match bounds[0].as_ref() {
                     TypeBound::Path(path) => {
                         path.segments().iter().last().unwrap().args_and_bindings.unwrap().bindings
                             [0]
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs
index 135a6698e15..8bcac60ef55 100644
--- a/crates/hir_def/src/data.rs
+++ b/crates/hir_def/src/data.rs
@@ -112,7 +112,7 @@ pub struct TypeAliasData {
     pub visibility: RawVisibility,
     pub is_extern: bool,
     /// Bounds restricting the type alias itself (eg. `type Ty: Bound;` in a trait or impl).
-    pub bounds: Vec<TypeBound>,
+    pub bounds: Vec<Interned<TypeBound>>,
 }
 
 impl TypeAliasData {
@@ -141,7 +141,7 @@ pub struct TraitData {
     pub is_auto: bool,
     pub is_unsafe: bool,
     pub visibility: RawVisibility,
-    pub bounds: Box<[TypeBound]>,
+    pub bounds: Box<[Interned<TypeBound>]>,
 }
 
 impl TraitData {
diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs
index de5acced8cf..44d22b91870 100644
--- a/crates/hir_def/src/generics.rs
+++ b/crates/hir_def/src/generics.rs
@@ -68,9 +68,19 @@ pub struct GenericParams {
 /// associated type bindings like `Iterator<Item = u32>`.
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum WherePredicate {
-    TypeBound { target: WherePredicateTypeTarget, bound: TypeBound },
-    Lifetime { target: LifetimeRef, bound: LifetimeRef },
-    ForLifetime { lifetimes: Box<[Name]>, target: WherePredicateTypeTarget, bound: TypeBound },
+    TypeBound {
+        target: WherePredicateTypeTarget,
+        bound: Interned<TypeBound>,
+    },
+    Lifetime {
+        target: LifetimeRef,
+        bound: LifetimeRef,
+    },
+    ForLifetime {
+        lifetimes: Box<[Name]>,
+        target: WherePredicateTypeTarget,
+        bound: Interned<TypeBound>,
+    },
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -339,11 +349,11 @@ impl GenericParams {
                 Some(hrtb_lifetimes) => WherePredicate::ForLifetime {
                     lifetimes: hrtb_lifetimes.clone(),
                     target: WherePredicateTypeTarget::TypeRef(Interned::new(type_ref)),
-                    bound,
+                    bound: Interned::new(bound),
                 },
                 None => WherePredicate::TypeBound {
                     target: WherePredicateTypeTarget::TypeRef(Interned::new(type_ref)),
-                    bound,
+                    bound: Interned::new(bound),
                 },
             },
             (Either::Right(lifetime), TypeBound::Lifetime(bound)) => {
diff --git a/crates/hir_def/src/intern.rs b/crates/hir_def/src/intern.rs
index 5cc7f2df659..1189c9327d6 100644
--- a/crates/hir_def/src/intern.rs
+++ b/crates/hir_def/src/intern.rs
@@ -216,7 +216,9 @@ pub use crate::_impl_internable as impl_internable;
 impl_internable!(
     crate::type_ref::TypeRef,
     crate::type_ref::TraitRef,
+    crate::type_ref::TypeBound,
     crate::path::ModPath,
+    crate::path::GenericArgs,
     GenericParams,
     str,
 );
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index 4a5f44027ed..11767d100f9 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -644,7 +644,7 @@ pub struct Trait {
     pub generic_params: Interned<GenericParams>,
     pub is_auto: bool,
     pub is_unsafe: bool,
-    pub bounds: Box<[TypeBound]>,
+    pub bounds: Box<[Interned<TypeBound>]>,
     pub items: Box<[AssocItem]>,
     pub ast_id: FileAstId<ast::Trait>,
 }
@@ -664,7 +664,7 @@ pub struct TypeAlias {
     pub name: Name,
     pub visibility: RawVisibilityId,
     /// Bounds on the type alias itself. Only valid in trait declarations, eg. `type Assoc: Copy;`.
-    pub bounds: Box<[TypeBound]>,
+    pub bounds: Box<[Interned<TypeBound>]>,
     pub generic_params: Interned<GenericParams>,
     pub type_ref: Option<Interned<TypeRef>>,
     pub is_extern: bool,
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index 91cf7537192..b4389371fbb 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -384,7 +384,7 @@ impl<'a> Ctx<'a> {
 
         let ret_type = if func.async_token().is_some() {
             let future_impl = desugar_future_path(ret_type);
-            let ty_bound = TypeBound::Path(future_impl);
+            let ty_bound = Interned::new(TypeBound::Path(future_impl));
             TypeRef::ImplTrait(vec![ty_bound])
         } else {
             ret_type
@@ -738,11 +738,12 @@ impl<'a> Ctx<'a> {
         Interned::new(generics)
     }
 
-    fn lower_type_bounds(&mut self, node: &impl ast::TypeBoundsOwner) -> Vec<TypeBound> {
+    fn lower_type_bounds(&mut self, node: &impl ast::TypeBoundsOwner) -> Vec<Interned<TypeBound>> {
         match node.type_bound_list() {
-            Some(bound_list) => {
-                bound_list.bounds().map(|it| TypeBound::from_ast(&self.body_ctx, it)).collect()
-            }
+            Some(bound_list) => bound_list
+                .bounds()
+                .map(|it| Interned::new(TypeBound::from_ast(&self.body_ctx, it)))
+                .collect(),
             None => Vec::new(),
         }
     }
@@ -810,7 +811,7 @@ fn desugar_future_path(orig: TypeRef) -> Path {
     let binding =
         AssociatedTypeBinding { name: name![Output], type_ref: Some(orig), bounds: Vec::new() };
     last.bindings.push(binding);
-    generic_args.push(Some(Arc::new(last)));
+    generic_args.push(Some(Interned::new(last)));
 
     Path::from_known_path(path, generic_args)
 }
diff --git a/crates/hir_def/src/item_tree/pretty.rs b/crates/hir_def/src/item_tree/pretty.rs
index 4bc87a0e20b..9394a5de66b 100644
--- a/crates/hir_def/src/item_tree/pretty.rs
+++ b/crates/hir_def/src/item_tree/pretty.rs
@@ -513,13 +513,13 @@ impl<'a> Printer<'a> {
         }
     }
 
-    fn print_type_bounds(&mut self, bounds: &[TypeBound]) {
+    fn print_type_bounds(&mut self, bounds: &[Interned<TypeBound>]) {
         for (i, bound) in bounds.iter().enumerate() {
             if i != 0 {
                 w!(self, " + ");
             }
 
-            match bound {
+            match bound.as_ref() {
                 TypeBound::Path(path) => self.print_path(path),
                 TypeBound::Lifetime(lt) => w!(self, "{}", lt.name),
                 TypeBound::Error => w!(self, "{{unknown}}"),
diff --git a/crates/hir_def/src/path.rs b/crates/hir_def/src/path.rs
index 9b8873fd258..45ab9d0ffbf 100644
--- a/crates/hir_def/src/path.rs
+++ b/crates/hir_def/src/path.rs
@@ -4,7 +4,6 @@ mod lower;
 use std::{
     fmt::{self, Display},
     iter,
-    sync::Arc,
 };
 
 use crate::{body::LowerCtx, db::DefDatabase, intern::Interned, type_ref::LifetimeRef};
@@ -136,7 +135,7 @@ pub struct Path {
     type_anchor: Option<Interned<TypeRef>>,
     mod_path: Interned<ModPath>,
     /// Invariant: the same len as `self.mod_path.segments`
-    generic_args: Vec<Option<Arc<GenericArgs>>>,
+    generic_args: Vec<Option<Interned<GenericArgs>>>,
 }
 
 /// Generic arguments to a path segment (e.g. the `i32` in `Option<i32>`). This
@@ -165,7 +164,7 @@ pub struct AssociatedTypeBinding {
     /// Bounds for the associated type, like in `Iterator<Item:
     /// SomeOtherTrait>`. (This is the unstable `associated_type_bounds`
     /// feature.)
-    pub bounds: Vec<TypeBound>,
+    pub bounds: Vec<Interned<TypeBound>>,
 }
 
 /// A single generic argument.
@@ -185,7 +184,7 @@ impl Path {
     /// Converts a known mod path to `Path`.
     pub(crate) fn from_known_path(
         path: ModPath,
-        generic_args: Vec<Option<Arc<GenericArgs>>>,
+        generic_args: Vec<Option<Interned<GenericArgs>>>,
     ) -> Path {
         Path { type_anchor: None, mod_path: Interned::new(path), generic_args }
     }
@@ -239,7 +238,7 @@ pub struct PathSegment<'a> {
 
 pub struct PathSegments<'a> {
     segments: &'a [Name],
-    generic_args: &'a [Option<Arc<GenericArgs>>],
+    generic_args: &'a [Option<Interned<GenericArgs>>],
 }
 
 impl<'a> PathSegments<'a> {
diff --git a/crates/hir_def/src/path/lower.rs b/crates/hir_def/src/path/lower.rs
index a873325b24b..5d5dd9c8f8a 100644
--- a/crates/hir_def/src/path/lower.rs
+++ b/crates/hir_def/src/path/lower.rs
@@ -3,7 +3,6 @@
 mod lower_use;
 
 use crate::intern::Interned;
-use std::sync::Arc;
 
 use either::Either;
 use hir_expand::name::{name, AsName};
@@ -48,7 +47,7 @@ pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx) -> Option<Path> {
                                     segment.ret_type(),
                                 )
                             })
-                            .map(Arc::new);
+                            .map(Interned::new);
                         segments.push(name);
                         generic_args.push(args)
                     }
@@ -87,13 +86,13 @@ pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx) -> Option<Path> {
                         // Insert the type reference (T in the above example) as Self parameter for the trait
                         let last_segment =
                             generic_args.iter_mut().rev().nth(num_segments.saturating_sub(1))?;
-                        if last_segment.is_none() {
-                            *last_segment = Some(Arc::new(GenericArgs::empty()));
+                        let mut args_inner = match last_segment {
+                            Some(it) => it.as_ref().clone(),
+                            None => GenericArgs::empty(),
                         };
-                        let args = last_segment.as_mut().unwrap();
-                        let mut args_inner = Arc::make_mut(args);
                         args_inner.has_self_type = true;
                         args_inner.args.insert(0, GenericArg::Type(self_type));
+                        *last_segment = Some(Interned::new(args_inner));
                     }
                 }
             }
@@ -171,7 +170,9 @@ pub(super) fn lower_generic_args(
                     let name = name_ref.as_name();
                     let type_ref = assoc_type_arg.ty().map(|it| TypeRef::from_ast(lower_ctx, it));
                     let bounds = if let Some(l) = assoc_type_arg.type_bound_list() {
-                        l.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect()
+                        l.bounds()
+                            .map(|it| Interned::new(TypeBound::from_ast(lower_ctx, it)))
+                            .collect()
                     } else {
                         Vec::new()
                     };
diff --git a/crates/hir_def/src/type_ref.rs b/crates/hir_def/src/type_ref.rs
index cdcab71102d..cbde6b94026 100644
--- a/crates/hir_def/src/type_ref.rs
+++ b/crates/hir_def/src/type_ref.rs
@@ -5,7 +5,7 @@ use hir_expand::{name::Name, AstId, InFile};
 use std::convert::TryInto;
 use syntax::ast;
 
-use crate::{body::LowerCtx, path::Path};
+use crate::{body::LowerCtx, intern::Interned, path::Path};
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub enum Mutability {
@@ -91,8 +91,8 @@ pub enum TypeRef {
     /// A fn pointer. Last element of the vector is the return type.
     Fn(Vec<TypeRef>, bool /*varargs*/),
     // For
-    ImplTrait(Vec<TypeBound>),
-    DynTrait(Vec<TypeBound>),
+    ImplTrait(Vec<Interned<TypeBound>>),
+    DynTrait(Vec<Interned<TypeBound>>),
     Macro(AstId<ast::MacroCall>),
     Error,
 }
@@ -232,7 +232,7 @@ impl TypeRef {
                 | TypeRef::Slice(type_ref) => go(&type_ref, f),
                 TypeRef::ImplTrait(bounds) | TypeRef::DynTrait(bounds) => {
                     for bound in bounds {
-                        match bound {
+                        match bound.as_ref() {
                             TypeBound::Path(path) => go_path(path, f),
                             TypeBound::Lifetime(_) | TypeBound::Error => (),
                         }
@@ -262,7 +262,7 @@ impl TypeRef {
                             go(type_ref, f);
                         }
                         for bound in &binding.bounds {
-                            match bound {
+                            match bound.as_ref() {
                                 TypeBound::Path(path) => go_path(path, f),
                                 TypeBound::Lifetime(_) | TypeBound::Error => (),
                             }
@@ -277,9 +277,9 @@ impl TypeRef {
 pub(crate) fn type_bounds_from_ast(
     lower_ctx: &LowerCtx,
     type_bounds_opt: Option<ast::TypeBoundList>,
-) -> Vec<TypeBound> {
+) -> Vec<Interned<TypeBound>> {
     if let Some(type_bounds) = type_bounds_opt {
-        type_bounds.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect()
+        type_bounds.bounds().map(|it| Interned::new(TypeBound::from_ast(lower_ctx, it))).collect()
     } else {
         vec![]
     }
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 7bbd1a1f7da..637bbc634d5 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -13,6 +13,7 @@ use hir_def::{
     db::DefDatabase,
     find_path,
     generics::TypeParamProvenance,
+    intern::{Internable, Interned},
     item_scope::ItemInNs,
     path::{Path, PathKind},
     type_ref::{TypeBound, TypeRef},
@@ -256,6 +257,12 @@ impl<T: HirDisplay> HirDisplay for &'_ T {
     }
 }
 
+impl<T: HirDisplay + Internable> HirDisplay for Interned<T> {
+    fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
+        HirDisplay::hir_fmt(self.as_ref(), f)
+    }
+}
+
 impl HirDisplay for ProjectionTy {
     fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
         if f.should_truncate() {
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 8a375b97348..1645ac53356 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -10,6 +10,7 @@ use std::{iter, sync::Arc};
 
 use base_db::CrateId;
 use chalk_ir::{cast::Cast, fold::Shift, interner::HasInterner, Mutability, Safety};
+use hir_def::intern::Interned;
 use hir_def::{
     adt::StructKind,
     body::{Expander, LowerCtx},
@@ -843,7 +844,7 @@ impl<'a> TyLoweringContext<'a> {
             })
     }
 
-    fn lower_impl_trait(&self, bounds: &[TypeBound]) -> ReturnTypeImplTrait {
+    fn lower_impl_trait(&self, bounds: &[Interned<TypeBound>]) -> ReturnTypeImplTrait {
         cov_mark::hit!(lower_rpit);
         let self_ty =
             TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner);