From 8ebb8d29e18d7cb18bd2b57b004dcecd65a96232 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 24 May 2021 15:13:23 +0200 Subject: internal: intern `TypeBound`s Doesn't save much memory (~2 mb), but interning things is generally a good pattern to follow --- crates/hir/src/display.rs | 2 +- crates/hir_def/src/data.rs | 4 ++-- crates/hir_def/src/generics.rs | 20 +++++++++++++++----- crates/hir_def/src/intern.rs | 1 + crates/hir_def/src/item_tree.rs | 4 ++-- crates/hir_def/src/item_tree/lower.rs | 11 ++++++----- crates/hir_def/src/item_tree/pretty.rs | 4 ++-- crates/hir_def/src/path.rs | 2 +- crates/hir_def/src/path/lower.rs | 4 +++- crates/hir_def/src/type_ref.rs | 14 +++++++------- crates/hir_ty/src/display.rs | 7 +++++++ crates/hir_ty/src/lower.rs | 3 ++- 12 files changed, 49 insertions(+), 27 deletions(-) diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs index 508ac37c2..c5cf803fd 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 135a6698e..8bcac60ef 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, + pub bounds: Vec>, } 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]>, } impl TraitData { diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs index de5acced8..44d22b918 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`. #[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, + }, + Lifetime { + target: LifetimeRef, + bound: LifetimeRef, + }, + ForLifetime { + lifetimes: Box<[Name]>, + target: WherePredicateTypeTarget, + bound: Interned, + }, } #[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 5cc7f2df6..8b3f799e2 100644 --- a/crates/hir_def/src/intern.rs +++ b/crates/hir_def/src/intern.rs @@ -216,6 +216,7 @@ 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, GenericParams, str, diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 4a5f44027..11767d100 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, pub is_auto: bool, pub is_unsafe: bool, - pub bounds: Box<[TypeBound]>, + pub bounds: Box<[Interned]>, pub items: Box<[AssocItem]>, pub ast_id: FileAstId, } @@ -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]>, pub generic_params: Interned, pub type_ref: Option>, 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 91cf75371..1a0e54413 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 { + fn lower_type_bounds(&mut self, node: &impl ast::TypeBoundsOwner) -> Vec> { 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(), } } diff --git a/crates/hir_def/src/item_tree/pretty.rs b/crates/hir_def/src/item_tree/pretty.rs index 4bc87a0e2..9394a5de6 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]) { 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 9b8873fd2..7bd7d9d4f 100644 --- a/crates/hir_def/src/path.rs +++ b/crates/hir_def/src/path.rs @@ -165,7 +165,7 @@ pub struct AssociatedTypeBinding { /// Bounds for the associated type, like in `Iterator`. (This is the unstable `associated_type_bounds` /// feature.) - pub bounds: Vec, + pub bounds: Vec>, } /// A single generic argument. diff --git a/crates/hir_def/src/path/lower.rs b/crates/hir_def/src/path/lower.rs index a873325b2..cf4e7c02e 100644 --- a/crates/hir_def/src/path/lower.rs +++ b/crates/hir_def/src/path/lower.rs @@ -171,7 +171,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 cdcab7110..cbde6b940 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, bool /*varargs*/), // For - ImplTrait(Vec), - DynTrait(Vec), + ImplTrait(Vec>), + DynTrait(Vec>), Macro(AstId), 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, -) -> Vec { +) -> Vec> { 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 7bbd1a1f7..637bbc634 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 HirDisplay for &'_ T { } } +impl HirDisplay for Interned { + 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 8a375b973..1645ac533 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]) -> ReturnTypeImplTrait { cov_mark::hit!(lower_rpit); let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner); -- cgit v1.2.3