From bf7edd378367ea4cc756ce915615df5305ec4ed9 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sun, 20 Oct 2024 01:56:51 +0300 Subject: [PATCH] Shrink `TypeRef` from 16 from 32 bytes Only references and arrays need to be boxed, and they comprise only 9.4% of the types (according to counting on r-a's code). This saves 17mb. --- crates/hir-def/src/generics.rs | 101 +++++++++++++------------- crates/hir-def/src/hir/type_ref.rs | 88 +++++++++++++--------- crates/hir-def/src/item_tree/lower.rs | 35 ++++----- crates/hir-def/src/lower.rs | 7 +- crates/hir-def/src/path/lower.rs | 8 +- crates/hir-def/src/pretty.rs | 24 +++--- crates/hir-ty/src/display.rs | 26 +++---- crates/hir-ty/src/lower.rs | 28 +++---- crates/hir/src/display.rs | 6 +- crates/hir/src/lib.rs | 4 +- 10 files changed, 178 insertions(+), 149 deletions(-) diff --git a/crates/hir-def/src/generics.rs b/crates/hir-def/src/generics.rs index b27a97ab47..6b79850e9c 100644 --- a/crates/hir-def/src/generics.rs +++ b/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>) { + fn fill_impl_trait_bounds(&mut self, impl_bounds: Vec>) { 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 + 'a { + bounds.iter().map(|bound| copy_type_bound(bound, from, from_source_map, to, to_source_map)) } fn copy_type_bound( diff --git a/crates/hir-def/src/hir/type_ref.rs b/crates/hir-def/src/hir/type_ref.rs index 38d95084e7..2582340c0f 100644 --- a/crates/hir-def/src/hir/type_ref.rs +++ b/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, TypeRefId)], + pub is_varargs: bool, + pub is_unsafe: bool, + pub abi: Option; ref, + } +} + +#[derive(Clone, PartialEq, Eq, Hash, Debug)] +pub struct ArrayType { + pub ty: TypeRefId, + // FIXME: This should be Ast + pub len: ConstRef, +} + +#[derive(Clone, PartialEq, Eq, Hash, Debug)] +pub struct RefType { + pub ty: TypeRefId, + pub lifetime: Option, + pub mutability: Mutability, +} + /// Compare ty::Ty #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub enum TypeRef { Never, Placeholder, - Tuple(Vec), + Tuple(EmptyOptimizedThinVec), Path(Path), RawPtr(TypeRefId, Mutability), - Reference(TypeRefId, Option, Mutability), - // FIXME: This should be Array(TypeRefId, Ast), - Array(TypeRefId, ConstRef), + Reference(Box), + Array(Box), Slice(TypeRefId), /// A fn pointer. Last element of the vector is the return type. - Fn { - params: Box<[(Option, TypeRefId)]>, - is_varargs: bool, - is_unsafe: bool, - abi: Option, - }, - ImplTrait(Vec), - DynTrait(Vec), + Fn(FnType), + ImplTrait(ThinVec), + DynTrait(ThinVec), Macro(AstId), Error, } +#[cfg(target_arch = "x86_64")] +const _: () = assert!(size_of::() == 16); + pub type TypeRefId = Idx; #[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(<)); 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, -) -> Vec { +) -> ThinVec { 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/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs index 3367d5540f..bd17fce37b 100644 --- a/crates/hir-def/src/item_tree/lower.rs +++ b/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/crates/hir-def/src/lower.rs b/crates/hir-def/src/lower.rs index fef3b34423..df5847929c 100644 --- a/crates/hir-def/src/lower.rs +++ b/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, ast_id_map: OnceCell>, - impl_trait_bounds: RefCell>>, + impl_trait_bounds: RefCell>>, // Prevent nested impl traits like `impl Foo`. outer_impl_trait: RefCell, 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) { + pub fn update_impl_traits_bounds(&self, bounds: ThinVec) { self.impl_trait_bounds.borrow_mut().push(bounds); } - pub fn take_impl_traits_bounds(&self) -> Vec> { + pub fn take_impl_traits_bounds(&self) -> Vec> { self.impl_trait_bounds.take() } diff --git a/crates/hir-def/src/path/lower.rs b/crates/hir-def/src/path/lower.rs index df036ef3b6..c328b9c6ce 100644 --- a/crates/hir-def/src/path/lower.rs +++ b/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/crates/hir-def/src/pretty.rs b/crates/hir-def/src/pretty.rs index f8fd5cfb77..9ceb82d5fd 100644 --- a/crates/hir-def/src/pretty.rs +++ b/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/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index e5c3c35e2b..277dabe9aa 100644 --- a/crates/hir-ty/src/display.rs +++ b/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/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index ed1ee48374..e3a92e52f6 100644 --- a/crates/hir-ty/src/lower.rs +++ b/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/crates/hir/src/display.rs b/crates/hir/src/display.rs index 80370c7421..9275f45d88 100644 --- a/crates/hir/src/display.rs +++ b/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/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index d264bb3901..4e994cae84 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -2420,8 +2420,8 @@ impl SelfParam { func_data .params .first() - .map(|¶m| match func_data.types_map[param] { - TypeRef::Reference(.., mutability) => match mutability { + .map(|¶m| 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, },