about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/generics.rs101
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs88
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs35
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/lower.rs7
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/pretty.rs24
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/display.rs26
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lower.rs28
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/display.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs4
10 files changed, 178 insertions, 149 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs
index b27a97ab479..6b79850e9c4 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs
@@ -11,7 +11,10 @@ use hir_expand::{
     ExpandResult,
 };
 use la_arena::{Arena, RawIdx};
-use stdx::impl_from;
+use stdx::{
+    impl_from,
+    thin_vec::{EmptyOptimizedThinVec, ThinVec},
+};
 use syntax::ast::{self, HasGenericParams, HasName, HasTypeBounds};
 use triomphe::Arc;
 
@@ -22,7 +25,10 @@ use crate::{
     lower::LowerCtx,
     nameres::{DefMap, MacroSubNs},
     path::{AssociatedTypeBinding, GenericArg, GenericArgs, NormalPath, Path},
-    type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRef, TypeRefId, TypesMap, TypesSourceMap},
+    type_ref::{
+        ArrayType, ConstRef, FnType, LifetimeRef, RefType, TypeBound, TypeRef, TypeRefId, TypesMap,
+        TypesSourceMap,
+    },
     AdtId, ConstParamId, GenericDefId, HasModule, ItemTreeLoc, LifetimeParamId,
     LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId,
 };
@@ -590,7 +596,7 @@ impl GenericParamsCollector {
         self.where_predicates.push(predicate);
     }
 
-    fn fill_impl_trait_bounds(&mut self, impl_bounds: Vec<Vec<TypeBound>>) {
+    fn fill_impl_trait_bounds(&mut self, impl_bounds: Vec<ThinVec<TypeBound>>) {
         for bounds in impl_bounds {
             let param = TypeParamData {
                 name: None,
@@ -598,10 +604,10 @@ impl GenericParamsCollector {
                 provenance: TypeParamProvenance::ArgumentImplTrait,
             };
             let param_id = self.type_or_consts.alloc(param.into());
-            for bound in bounds {
+            for bound in &bounds {
                 self.where_predicates.push(WherePredicate::TypeBound {
                     target: WherePredicateTypeTarget::TypeOrConstParam(param_id),
-                    bound,
+                    bound: bound.clone(),
                 });
             }
         }
@@ -725,46 +731,45 @@ fn copy_type_ref(
     to_source_map: &mut TypesSourceMap,
 ) -> TypeRefId {
     let result = match &from[type_ref] {
-        &TypeRef::Fn { ref params, is_varargs, is_unsafe, ref abi } => {
-            let params = params
-                .iter()
-                .map(|(name, param_type)| {
-                    (
-                        name.clone(),
-                        copy_type_ref(*param_type, from, from_source_map, to, to_source_map),
-                    )
-                })
-                .collect();
-            TypeRef::Fn { params, is_varargs, is_unsafe, abi: abi.clone() }
+        TypeRef::Fn(fn_) => {
+            let params = fn_.params().iter().map(|(name, param_type)| {
+                (name.clone(), copy_type_ref(*param_type, from, from_source_map, to, to_source_map))
+            });
+            TypeRef::Fn(FnType::new(fn_.is_varargs(), fn_.is_unsafe(), fn_.abi().clone(), params))
         }
-        TypeRef::Tuple(types) => TypeRef::Tuple(
-            types
-                .iter()
-                .map(|&t| copy_type_ref(t, from, from_source_map, to, to_source_map))
-                .collect(),
-        ),
+        TypeRef::Tuple(types) => TypeRef::Tuple(EmptyOptimizedThinVec::from_iter(
+            types.iter().map(|&t| copy_type_ref(t, from, from_source_map, to, to_source_map)),
+        )),
         &TypeRef::RawPtr(type_ref, mutbl) => TypeRef::RawPtr(
             copy_type_ref(type_ref, from, from_source_map, to, to_source_map),
             mutbl,
         ),
-        TypeRef::Reference(type_ref, lifetime, mutbl) => TypeRef::Reference(
-            copy_type_ref(*type_ref, from, from_source_map, to, to_source_map),
-            lifetime.clone(),
-            *mutbl,
-        ),
-        TypeRef::Array(type_ref, len) => TypeRef::Array(
-            copy_type_ref(*type_ref, from, from_source_map, to, to_source_map),
-            len.clone(),
-        ),
+        TypeRef::Reference(ref_) => TypeRef::Reference(Box::new(RefType {
+            ty: copy_type_ref(ref_.ty, from, from_source_map, to, to_source_map),
+            lifetime: ref_.lifetime.clone(),
+            mutability: ref_.mutability,
+        })),
+        TypeRef::Array(array) => TypeRef::Array(Box::new(ArrayType {
+            ty: copy_type_ref(array.ty, from, from_source_map, to, to_source_map),
+            len: array.len.clone(),
+        })),
         &TypeRef::Slice(type_ref) => {
             TypeRef::Slice(copy_type_ref(type_ref, from, from_source_map, to, to_source_map))
         }
-        TypeRef::ImplTrait(bounds) => TypeRef::ImplTrait(
-            copy_type_bounds(bounds, from, from_source_map, to, to_source_map).into(),
-        ),
-        TypeRef::DynTrait(bounds) => TypeRef::DynTrait(
-            copy_type_bounds(bounds, from, from_source_map, to, to_source_map).into(),
-        ),
+        TypeRef::ImplTrait(bounds) => TypeRef::ImplTrait(ThinVec::from_iter(copy_type_bounds(
+            bounds,
+            from,
+            from_source_map,
+            to,
+            to_source_map,
+        ))),
+        TypeRef::DynTrait(bounds) => TypeRef::DynTrait(ThinVec::from_iter(copy_type_bounds(
+            bounds,
+            from,
+            from_source_map,
+            to,
+            to_source_map,
+        ))),
         TypeRef::Path(path) => {
             TypeRef::Path(copy_path(path, from, from_source_map, to, to_source_map))
         }
@@ -833,7 +838,8 @@ fn copy_generic_args(
                     copy_type_ref(type_ref, from, from_source_map, to, to_source_map)
                 });
                 let bounds =
-                    copy_type_bounds(&binding.bounds, from, from_source_map, to, to_source_map);
+                    copy_type_bounds(&binding.bounds, from, from_source_map, to, to_source_map)
+                        .collect();
                 AssociatedTypeBinding { name, args, type_ref, bounds }
             })
             .collect();
@@ -846,17 +852,14 @@ fn copy_generic_args(
     })
 }
 
-fn copy_type_bounds(
-    bounds: &[TypeBound],
-    from: &TypesMap,
-    from_source_map: &TypesSourceMap,
-    to: &mut TypesMap,
-    to_source_map: &mut TypesSourceMap,
-) -> Box<[TypeBound]> {
-    bounds
-        .iter()
-        .map(|bound| copy_type_bound(bound, from, from_source_map, to, to_source_map))
-        .collect()
+fn copy_type_bounds<'a>(
+    bounds: &'a [TypeBound],
+    from: &'a TypesMap,
+    from_source_map: &'a TypesSourceMap,
+    to: &'a mut TypesMap,
+    to_source_map: &'a mut TypesSourceMap,
+) -> impl stdx::thin_vec::TrustedLen<Item = TypeBound> + 'a {
+    bounds.iter().map(|bound| copy_type_bound(bound, from, from_source_map, to, to_source_map))
 }
 
 fn copy_type_bound(
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs
index 38d95084e73..2582340c0f8 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs
@@ -12,6 +12,7 @@ use hir_expand::{
 use intern::{sym, Symbol};
 use la_arena::{Arena, ArenaMap, Idx};
 use span::Edition;
+use stdx::thin_vec::{thin_vec_with_header_struct, EmptyOptimizedThinVec, ThinVec};
 use syntax::{
     ast::{self, HasGenericArgs, HasName, IsString},
     AstPtr,
@@ -108,31 +109,51 @@ impl TraitRef {
     }
 }
 
+thin_vec_with_header_struct! {
+    pub new(pub(crate)) struct FnType, FnTypeHeader {
+        pub params: [(Option<Name>, TypeRefId)],
+        pub is_varargs: bool,
+        pub is_unsafe: bool,
+        pub abi: Option<Symbol>; ref,
+    }
+}
+
+#[derive(Clone, PartialEq, Eq, Hash, Debug)]
+pub struct ArrayType {
+    pub ty: TypeRefId,
+    // FIXME: This should be Ast<ConstArg>
+    pub len: ConstRef,
+}
+
+#[derive(Clone, PartialEq, Eq, Hash, Debug)]
+pub struct RefType {
+    pub ty: TypeRefId,
+    pub lifetime: Option<LifetimeRef>,
+    pub mutability: Mutability,
+}
+
 /// Compare ty::Ty
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub enum TypeRef {
     Never,
     Placeholder,
-    Tuple(Vec<TypeRefId>),
+    Tuple(EmptyOptimizedThinVec<TypeRefId>),
     Path(Path),
     RawPtr(TypeRefId, Mutability),
-    Reference(TypeRefId, Option<LifetimeRef>, Mutability),
-    // FIXME: This should be Array(TypeRefId, Ast<ConstArg>),
-    Array(TypeRefId, ConstRef),
+    Reference(Box<RefType>),
+    Array(Box<ArrayType>),
     Slice(TypeRefId),
     /// A fn pointer. Last element of the vector is the return type.
-    Fn {
-        params: Box<[(Option<Name>, TypeRefId)]>,
-        is_varargs: bool,
-        is_unsafe: bool,
-        abi: Option<Symbol>,
-    },
-    ImplTrait(Vec<TypeBound>),
-    DynTrait(Vec<TypeBound>),
+    Fn(FnType),
+    ImplTrait(ThinVec<TypeBound>),
+    DynTrait(ThinVec<TypeBound>),
     Macro(AstId<ast::MacroCall>),
     Error,
 }
 
+#[cfg(target_arch = "x86_64")]
+const _: () = assert!(size_of::<TypeRef>() == 16);
+
 pub type TypeRefId = Idx<TypeRef>;
 
 #[derive(Default, Clone, PartialEq, Eq, Debug, Hash)]
@@ -222,9 +243,9 @@ impl TypeRef {
     pub fn from_ast(ctx: &LowerCtx<'_>, node: ast::Type) -> TypeRefId {
         let ty = match &node {
             ast::Type::ParenType(inner) => return TypeRef::from_ast_opt(ctx, inner.ty()),
-            ast::Type::TupleType(inner) => {
-                TypeRef::Tuple(inner.fields().map(|it| TypeRef::from_ast(ctx, it)).collect())
-            }
+            ast::Type::TupleType(inner) => TypeRef::Tuple(EmptyOptimizedThinVec::from_iter(
+                Vec::from_iter(inner.fields().map(|it| TypeRef::from_ast(ctx, it))),
+            )),
             ast::Type::NeverType(..) => TypeRef::Never,
             ast::Type::PathType(inner) => {
                 // FIXME: Use `Path::from_src`
@@ -241,14 +262,17 @@ impl TypeRef {
             }
             ast::Type::ArrayType(inner) => {
                 let len = ConstRef::from_const_arg(ctx, inner.const_arg());
-                TypeRef::Array(TypeRef::from_ast_opt(ctx, inner.ty()), len)
+                TypeRef::Array(Box::new(ArrayType {
+                    ty: TypeRef::from_ast_opt(ctx, inner.ty()),
+                    len,
+                }))
             }
             ast::Type::SliceType(inner) => TypeRef::Slice(TypeRef::from_ast_opt(ctx, inner.ty())),
             ast::Type::RefType(inner) => {
                 let inner_ty = TypeRef::from_ast_opt(ctx, inner.ty());
                 let lifetime = inner.lifetime().map(|lt| LifetimeRef::new(&lt));
                 let mutability = Mutability::from_mutable(inner.mut_token().is_some());
-                TypeRef::Reference(inner_ty, lifetime, mutability)
+                TypeRef::Reference(Box::new(RefType { ty: inner_ty, lifetime, mutability }))
             }
             ast::Type::InferType(_inner) => TypeRef::Placeholder,
             ast::Type::FnPtrType(inner) => {
@@ -256,7 +280,7 @@ impl TypeRef {
                     .ret_type()
                     .and_then(|rt| rt.ty())
                     .map(|it| TypeRef::from_ast(ctx, it))
-                    .unwrap_or_else(|| ctx.alloc_type_ref_desugared(TypeRef::Tuple(Vec::new())));
+                    .unwrap_or_else(|| ctx.alloc_type_ref_desugared(TypeRef::unit()));
                 let mut is_varargs = false;
                 let mut params = if let Some(pl) = inner.param_list() {
                     if let Some(param) = pl.params().last() {
@@ -288,12 +312,7 @@ impl TypeRef {
 
                 let abi = inner.abi().map(lower_abi);
                 params.push((None, ret_ty));
-                TypeRef::Fn {
-                    params: params.into(),
-                    is_varargs,
-                    is_unsafe: inner.unsafe_token().is_some(),
-                    abi,
-                }
+                TypeRef::Fn(FnType::new(is_varargs, inner.unsafe_token().is_some(), abi, params))
             }
             // for types are close enough for our purposes to the inner type for now...
             ast::Type::ForType(inner) => return TypeRef::from_ast_opt(ctx, inner.ty()),
@@ -325,7 +344,7 @@ impl TypeRef {
     }
 
     pub(crate) fn unit() -> TypeRef {
-        TypeRef::Tuple(Vec::new())
+        TypeRef::Tuple(EmptyOptimizedThinVec::empty())
     }
 
     pub fn walk(this: TypeRefId, map: &TypesMap, f: &mut impl FnMut(&TypeRef)) {
@@ -335,14 +354,13 @@ impl TypeRef {
             let type_ref = &map[type_ref];
             f(type_ref);
             match type_ref {
-                TypeRef::Fn { params, is_varargs: _, is_unsafe: _, abi: _ } => {
-                    params.iter().for_each(|&(_, param_type)| go(param_type, f, map))
+                TypeRef::Fn(fn_) => {
+                    fn_.params().iter().for_each(|&(_, param_type)| go(param_type, f, map))
                 }
                 TypeRef::Tuple(types) => types.iter().for_each(|&t| go(t, f, map)),
-                TypeRef::RawPtr(type_ref, _)
-                | TypeRef::Reference(type_ref, ..)
-                | TypeRef::Array(type_ref, _)
-                | TypeRef::Slice(type_ref) => go(*type_ref, f, map),
+                TypeRef::RawPtr(type_ref, _) | TypeRef::Slice(type_ref) => go(*type_ref, f, map),
+                TypeRef::Reference(it) => go(it.ty, f, map),
+                TypeRef::Array(it) => go(it.ty, f, map),
                 TypeRef::ImplTrait(bounds) | TypeRef::DynTrait(bounds) => {
                     for bound in bounds {
                         match bound {
@@ -394,11 +412,13 @@ impl TypeRef {
 pub(crate) fn type_bounds_from_ast(
     lower_ctx: &LowerCtx<'_>,
     type_bounds_opt: Option<ast::TypeBoundList>,
-) -> Vec<TypeBound> {
+) -> ThinVec<TypeBound> {
     if let Some(type_bounds) = type_bounds_opt {
-        type_bounds.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect()
+        ThinVec::from_iter(Vec::from_iter(
+            type_bounds.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)),
+        ))
     } else {
-        vec![]
+        ThinVec::from_iter([])
     }
 }
 
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 3367d5540f5..bd17fce37b7 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
@@ -12,6 +12,7 @@ use intern::{sym, Symbol};
 use la_arena::Arena;
 use rustc_hash::FxHashMap;
 use span::{AstIdMap, SyntaxContextId};
+use stdx::thin_vec::ThinVec;
 use syntax::{
     ast::{self, HasModuleItem, HasName, HasTypeBounds, IsString},
     AstNode,
@@ -33,8 +34,8 @@ use crate::{
     lower::LowerCtx,
     path::AssociatedTypeBinding,
     type_ref::{
-        LifetimeRef, TraitBoundModifier, TraitRef, TypeBound, TypeRef, TypeRefId, TypesMap,
-        TypesSourceMap,
+        LifetimeRef, RefType, TraitBoundModifier, TraitRef, TypeBound, TypeRef, TypeRefId,
+        TypesMap, TypesSourceMap,
     },
     visibility::RawVisibility,
     LocalLifetimeParamId, LocalTypeOrConstParamId,
@@ -463,20 +464,20 @@ impl<'a> Ctx<'a> {
                         ));
                         match self_param.kind() {
                             ast::SelfParamKind::Owned => self_type,
-                            ast::SelfParamKind::Ref => {
-                                body_ctx.alloc_type_ref_desugared(TypeRef::Reference(
-                                    self_type,
-                                    self_param.lifetime().as_ref().map(LifetimeRef::new),
-                                    Mutability::Shared,
-                                ))
-                            }
-                            ast::SelfParamKind::MutRef => {
-                                body_ctx.alloc_type_ref_desugared(TypeRef::Reference(
-                                    self_type,
-                                    self_param.lifetime().as_ref().map(LifetimeRef::new),
-                                    Mutability::Mut,
-                                ))
-                            }
+                            ast::SelfParamKind::Ref => body_ctx.alloc_type_ref_desugared(
+                                TypeRef::Reference(Box::new(RefType {
+                                    ty: self_type,
+                                    lifetime: self_param.lifetime().as_ref().map(LifetimeRef::new),
+                                    mutability: Mutability::Shared,
+                                })),
+                            ),
+                            ast::SelfParamKind::MutRef => body_ctx.alloc_type_ref_desugared(
+                                TypeRef::Reference(Box::new(RefType {
+                                    ty: self_type,
+                                    lifetime: self_param.lifetime().as_ref().map(LifetimeRef::new),
+                                    mutability: Mutability::Mut,
+                                })),
+                            ),
                         }
                     }
                 };
@@ -511,7 +512,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, TraitBoundModifier::None);
-            body_ctx.alloc_type_ref_desugared(TypeRef::ImplTrait(vec![ty_bound]))
+            body_ctx.alloc_type_ref_desugared(TypeRef::ImplTrait(ThinVec::from_iter([ty_bound])))
         } else {
             ret_type
         };
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/lower.rs
index fef3b344233..df5847929c5 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/lower.rs
@@ -6,6 +6,7 @@ use hir_expand::{
     AstId, HirFileId, InFile,
 };
 use span::{AstIdMap, AstIdNode};
+use stdx::thin_vec::ThinVec;
 use syntax::ast;
 use triomphe::Arc;
 
@@ -20,7 +21,7 @@ pub struct LowerCtx<'a> {
     file_id: HirFileId,
     span_map: OnceCell<SpanMap>,
     ast_id_map: OnceCell<Arc<AstIdMap>>,
-    impl_trait_bounds: RefCell<Vec<Vec<TypeBound>>>,
+    impl_trait_bounds: RefCell<Vec<ThinVec<TypeBound>>>,
     // Prevent nested impl traits like `impl Foo<impl Bar>`.
     outer_impl_trait: RefCell<bool>,
     types_map: RefCell<(&'a mut TypesMap, &'a mut TypesSourceMap)>,
@@ -95,11 +96,11 @@ impl<'a> LowerCtx<'a> {
         )
     }
 
-    pub fn update_impl_traits_bounds(&self, bounds: Vec<TypeBound>) {
+    pub fn update_impl_traits_bounds(&self, bounds: ThinVec<TypeBound>) {
         self.impl_trait_bounds.borrow_mut().push(bounds);
     }
 
-    pub fn take_impl_traits_bounds(&self) -> Vec<Vec<TypeBound>> {
+    pub fn take_impl_traits_bounds(&self) -> Vec<ThinVec<TypeBound>> {
         self.impl_trait_bounds.take()
     }
 
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs
index df036ef3b60..c328b9c6ce2 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs
@@ -9,6 +9,7 @@ use hir_expand::{
     name::{AsName, Name},
 };
 use intern::{sym, Interned};
+use stdx::thin_vec::EmptyOptimizedThinVec;
 use syntax::ast::{self, AstNode, HasGenericArgs, HasTypeBounds};
 
 use crate::{
@@ -267,8 +268,9 @@ fn lower_generic_args_from_fn_path(
         let type_ref = TypeRef::from_ast_opt(ctx, param.ty());
         param_types.push(type_ref);
     }
-    let args =
-        Box::new([GenericArg::Type(ctx.alloc_type_ref_desugared(TypeRef::Tuple(param_types)))]);
+    let args = Box::new([GenericArg::Type(
+        ctx.alloc_type_ref_desugared(TypeRef::Tuple(EmptyOptimizedThinVec::from_iter(param_types))),
+    )]);
     let bindings = if let Some(ret_type) = ret_type {
         let type_ref = TypeRef::from_ast_opt(ctx, ret_type.ty());
         Box::new([AssociatedTypeBinding {
@@ -279,7 +281,7 @@ fn lower_generic_args_from_fn_path(
         }])
     } else {
         // -> ()
-        let type_ref = ctx.alloc_type_ref_desugared(TypeRef::Tuple(Vec::new()));
+        let type_ref = ctx.alloc_type_ref_desugared(TypeRef::unit());
         Box::new([AssociatedTypeBinding {
             name: Name::new_symbol_root(sym::Output.clone()),
             args: None,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs
index f8fd5cfb775..9ceb82d5fd6 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs
@@ -187,35 +187,35 @@ pub(crate) fn print_type_ref(
             write!(buf, "{mtbl} ")?;
             print_type_ref(db, *pointee, map, buf, edition)?;
         }
-        TypeRef::Reference(pointee, lt, mtbl) => {
-            let mtbl = match mtbl {
+        TypeRef::Reference(ref_) => {
+            let mtbl = match ref_.mutability {
                 Mutability::Shared => "",
                 Mutability::Mut => "mut ",
             };
             write!(buf, "&")?;
-            if let Some(lt) = lt {
+            if let Some(lt) = &ref_.lifetime {
                 write!(buf, "{} ", lt.name.display(db.upcast(), edition))?;
             }
             write!(buf, "{mtbl}")?;
-            print_type_ref(db, *pointee, map, buf, edition)?;
+            print_type_ref(db, ref_.ty, map, buf, edition)?;
         }
-        TypeRef::Array(elem, len) => {
+        TypeRef::Array(array) => {
             write!(buf, "[")?;
-            print_type_ref(db, *elem, map, buf, edition)?;
-            write!(buf, "; {}]", len.display(db.upcast(), edition))?;
+            print_type_ref(db, array.ty, map, buf, edition)?;
+            write!(buf, "; {}]", array.len.display(db.upcast(), edition))?;
         }
         TypeRef::Slice(elem) => {
             write!(buf, "[")?;
             print_type_ref(db, *elem, map, buf, edition)?;
             write!(buf, "]")?;
         }
-        TypeRef::Fn { params: args_and_ret, is_varargs: varargs, is_unsafe, abi } => {
+        TypeRef::Fn(fn_) => {
             let ((_, return_type), args) =
-                args_and_ret.split_last().expect("TypeRef::Fn is missing return type");
-            if *is_unsafe {
+                fn_.params().split_last().expect("TypeRef::Fn is missing return type");
+            if fn_.is_unsafe() {
                 write!(buf, "unsafe ")?;
             }
-            if let Some(abi) = abi {
+            if let Some(abi) = fn_.abi() {
                 buf.write_str("extern ")?;
                 buf.write_str(abi.as_str())?;
                 buf.write_char(' ')?;
@@ -227,7 +227,7 @@ pub(crate) fn print_type_ref(
                 }
                 print_type_ref(db, *typeref, map, buf, edition)?;
             }
-            if *varargs {
+            if fn_.is_varargs() {
                 if !args.is_empty() {
                     write!(buf, ", ")?;
                 }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
index e5c3c35e2bc..277dabe9aa3 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -1964,39 +1964,39 @@ impl HirDisplayWithTypesMap for TypeRefId {
                 write!(f, "{mutability}")?;
                 inner.hir_fmt(f, types_map)?;
             }
-            TypeRef::Reference(inner, lifetime, mutability) => {
-                let mutability = match mutability {
+            TypeRef::Reference(ref_) => {
+                let mutability = match ref_.mutability {
                     hir_def::type_ref::Mutability::Shared => "",
                     hir_def::type_ref::Mutability::Mut => "mut ",
                 };
                 write!(f, "&")?;
-                if let Some(lifetime) = lifetime {
+                if let Some(lifetime) = &ref_.lifetime {
                     write!(f, "{} ", lifetime.name.display(f.db.upcast(), f.edition()))?;
                 }
                 write!(f, "{mutability}")?;
-                inner.hir_fmt(f, types_map)?;
+                ref_.ty.hir_fmt(f, types_map)?;
             }
-            TypeRef::Array(inner, len) => {
+            TypeRef::Array(array) => {
                 write!(f, "[")?;
-                inner.hir_fmt(f, types_map)?;
-                write!(f, "; {}]", len.display(f.db.upcast(), f.edition()))?;
+                array.ty.hir_fmt(f, types_map)?;
+                write!(f, "; {}]", array.len.display(f.db.upcast(), f.edition()))?;
             }
             TypeRef::Slice(inner) => {
                 write!(f, "[")?;
                 inner.hir_fmt(f, types_map)?;
                 write!(f, "]")?;
             }
-            &TypeRef::Fn { params: ref parameters, is_varargs, is_unsafe, ref abi } => {
-                if is_unsafe {
+            TypeRef::Fn(fn_) => {
+                if fn_.is_unsafe() {
                     write!(f, "unsafe ")?;
                 }
-                if let Some(abi) = abi {
+                if let Some(abi) = fn_.abi() {
                     f.write_str("extern \"")?;
                     f.write_str(abi.as_str())?;
                     f.write_str("\" ")?;
                 }
                 write!(f, "fn(")?;
-                if let Some(((_, return_type), function_parameters)) = parameters.split_last() {
+                if let Some(((_, return_type), function_parameters)) = fn_.params().split_last() {
                     for index in 0..function_parameters.len() {
                         let (param_name, param_type) = &function_parameters[index];
                         if let Some(name) = param_name {
@@ -2009,8 +2009,8 @@ impl HirDisplayWithTypesMap for TypeRefId {
                             write!(f, ", ")?;
                         }
                     }
-                    if is_varargs {
-                        write!(f, "{}...", if parameters.len() == 1 { "" } else { ", " })?;
+                    if fn_.is_varargs() {
+                        write!(f, "{}...", if fn_.params().len() == 1 { "" } else { ", " })?;
                     }
                     write!(f, ")")?;
                     match &types_map[*return_type] {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
index ed1ee483749..e3a92e52f61 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
@@ -297,37 +297,39 @@ impl<'a> TyLoweringContext<'a> {
                 let inner_ty = self.lower_ty(inner);
                 TyKind::Raw(lower_to_chalk_mutability(mutability), inner_ty).intern(Interner)
             }
-            TypeRef::Array(inner, len) => {
-                let inner_ty = self.lower_ty(*inner);
-                let const_len = self.lower_const(len, TyBuilder::usize());
+            TypeRef::Array(array) => {
+                let inner_ty = self.lower_ty(array.ty);
+                let const_len = self.lower_const(&array.len, TyBuilder::usize());
                 TyKind::Array(inner_ty, const_len).intern(Interner)
             }
             &TypeRef::Slice(inner) => {
                 let inner_ty = self.lower_ty(inner);
                 TyKind::Slice(inner_ty).intern(Interner)
             }
-            TypeRef::Reference(inner, lifetime, mutability) => {
-                let inner_ty = self.lower_ty(*inner);
+            TypeRef::Reference(ref_) => {
+                let inner_ty = self.lower_ty(ref_.ty);
                 // FIXME: It should infer the eldided lifetimes instead of stubbing with static
-                let lifetime =
-                    lifetime.as_ref().map_or_else(error_lifetime, |lr| self.lower_lifetime(lr));
-                TyKind::Ref(lower_to_chalk_mutability(*mutability), lifetime, inner_ty)
+                let lifetime = ref_
+                    .lifetime
+                    .as_ref()
+                    .map_or_else(error_lifetime, |lr| self.lower_lifetime(lr));
+                TyKind::Ref(lower_to_chalk_mutability(ref_.mutability), lifetime, inner_ty)
                     .intern(Interner)
             }
             TypeRef::Placeholder => TyKind::Error.intern(Interner),
-            &TypeRef::Fn { ref params, is_varargs: variadic, is_unsafe, ref abi } => {
+            TypeRef::Fn(fn_) => {
                 let substs = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
                     Substitution::from_iter(
                         Interner,
-                        params.iter().map(|&(_, tr)| ctx.lower_ty(tr)),
+                        fn_.params().iter().map(|&(_, tr)| ctx.lower_ty(tr)),
                     )
                 });
                 TyKind::Function(FnPointer {
                     num_binders: 0, // FIXME lower `for<'a> fn()` correctly
                     sig: FnSig {
-                        abi: abi.as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol),
-                        safety: if is_unsafe { Safety::Unsafe } else { Safety::Safe },
-                        variadic,
+                        abi: fn_.abi().as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol),
+                        safety: if fn_.is_unsafe() { Safety::Unsafe } else { Safety::Safe },
+                        variadic: fn_.is_varargs(),
                     },
                     substitution: FnSubst(substs),
                 })
diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs
index 80370c7421e..9275f45d881 100644
--- a/src/tools/rust-analyzer/crates/hir/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/display.rs
@@ -196,13 +196,13 @@ impl HirDisplay for SelfParam {
         let param = *data.params.first().unwrap();
         match &data.types_map[param] {
             TypeRef::Path(p) if p.is_self_type() => f.write_str("self"),
-            TypeRef::Reference(inner, lifetime, mut_) if matches!(&data.types_map[*inner], TypeRef::Path(p) if p.is_self_type()) =>
+            TypeRef::Reference(ref_) if matches!(&data.types_map[ref_.ty], TypeRef::Path(p) if p.is_self_type()) =>
             {
                 f.write_char('&')?;
-                if let Some(lifetime) = lifetime {
+                if let Some(lifetime) = &ref_.lifetime {
                     write!(f, "{} ", lifetime.name.display(f.db.upcast(), f.edition()))?;
                 }
-                if let hir_def::type_ref::Mutability::Mut = mut_ {
+                if let hir_def::type_ref::Mutability::Mut = ref_.mutability {
                     f.write_str("mut ")?;
                 }
                 f.write_str("self")
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index d264bb3901f..4e994cae849 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -2420,8 +2420,8 @@ impl SelfParam {
         func_data
             .params
             .first()
-            .map(|&param| match func_data.types_map[param] {
-                TypeRef::Reference(.., mutability) => match mutability {
+            .map(|&param| match &func_data.types_map[param] {
+                TypeRef::Reference(ref_) => match ref_.mutability {
                     hir_def::type_ref::Mutability::Shared => Access::Shared,
                     hir_def::type_ref::Mutability::Mut => Access::Exclusive,
                 },