From 067d87e8a9f170452a5554dcc7b3e264cc12142b Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 9 Dec 2021 18:04:32 +0100 Subject: [PATCH 1/3] Remove some allocs --- crates/hir_def/src/resolver.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs index 8b2eea9d586..9f68b800a55 100644 --- a/crates/hir_def/src/resolver.rs +++ b/crates/hir_def/src/resolver.rs @@ -8,7 +8,7 @@ use hir_expand::{ }; use indexmap::IndexMap; use rustc_hash::FxHashSet; -use smallvec::SmallVec; +use smallvec::{smallvec, SmallVec}; use crate::{ body::scope::{ExprScopes, ScopeId}, @@ -567,6 +567,8 @@ pub fn resolver_for_scope( let mut r = owner.resolver(db); let scopes = db.expr_scopes(owner); let scope_chain = scopes.scope_chain(scope_id).collect::>(); + r.scopes.reserve(scope_chain.len()); + for scope in scope_chain.into_iter().rev() { if let Some(block) = scopes.block(scope) { if let Some(def_map) = db.block_def_map(block) { @@ -739,12 +741,13 @@ pub trait HasResolver: Copy { impl HasResolver for ModuleId { fn resolver(self, db: &dyn DefDatabase) -> Resolver { let mut def_map = self.def_map(db); - let mut modules = vec![(def_map.clone(), self.local_id)]; + let mut modules: SmallVec<[_; 2]> = smallvec![(def_map.clone(), self.local_id)]; while let Some(parent) = def_map.parent() { def_map = parent.def_map(db); modules.push((def_map.clone(), parent.local_id)); } let mut resolver = Resolver::default(); + resolver.scopes.reserve(modules.len()); for (def_map, module) in modules.into_iter().rev() { resolver = resolver.push_module_scope(def_map, module); } From f9c59d37524d267638ae941b19aa49c5b4baaf41 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 9 Dec 2021 18:13:15 +0100 Subject: [PATCH 2/3] Use known names instead of string literals --- crates/hir_expand/src/name.rs | 7 +++++ crates/hir_ty/src/infer.rs | 18 +++++------ crates/hir_ty/src/infer/expr.rs | 54 +++++++++++++++++---------------- 3 files changed, 43 insertions(+), 36 deletions(-) diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs index ab730b54bc3..23f81d3c7f5 100644 --- a/crates/hir_expand/src/name.rs +++ b/crates/hir_expand/src/name.rs @@ -334,6 +334,13 @@ pub mod known { gt, le, lt, + // lang items + not, + neg, + future_trait, + owned_box, + index, + partial_ord ); // self/Self cannot be used as an identifier diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index 56e554736e2..ce6cb815400 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs @@ -28,11 +28,10 @@ use hir_def::{ AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, HasModule, Lookup, TraitId, TypeAliasId, VariantId, }; -use hir_expand::name::name; +use hir_expand::name::{name, Name}; use la_arena::ArenaMap; use rustc_hash::FxHashMap; use stdx::impl_from; -use syntax::SmolStr; use crate::{ db::HirDatabase, fold_tys, infer::coerce::CoerceMany, lower::ImplTraitLoweringMode, @@ -719,10 +718,9 @@ impl<'a> InferenceContext<'a> { self.infer_expr_coerce(self.body.body_expr, &Expectation::has_type(self.return_ty.clone())); } - fn resolve_lang_item(&self, name: &str) -> Option { + fn resolve_lang_item(&self, name: Name) -> Option { let krate = self.resolver.krate()?; - let name = SmolStr::new_inline(name); - self.db.lang_item(krate, name) + self.db.lang_item(krate, name.to_smol_str()) } fn resolve_into_iter_item(&self) -> Option { @@ -743,22 +741,22 @@ impl<'a> InferenceContext<'a> { } fn resolve_ops_neg_output(&self) -> Option { - let trait_ = self.resolve_lang_item("neg")?.as_trait()?; + let trait_ = self.resolve_lang_item(name![neg])?.as_trait()?; self.db.trait_data(trait_).associated_type_by_name(&name![Output]) } fn resolve_ops_not_output(&self) -> Option { - let trait_ = self.resolve_lang_item("not")?.as_trait()?; + let trait_ = self.resolve_lang_item(name![not])?.as_trait()?; self.db.trait_data(trait_).associated_type_by_name(&name![Output]) } fn resolve_future_future_output(&self) -> Option { - let trait_ = self.resolve_lang_item("future_trait")?.as_trait()?; + let trait_ = self.resolve_lang_item(name![future_trait])?.as_trait()?; self.db.trait_data(trait_).associated_type_by_name(&name![Output]) } fn resolve_boxed_box(&self) -> Option { - let struct_ = self.resolve_lang_item("owned_box")?.as_struct()?; + let struct_ = self.resolve_lang_item(name![owned_box])?.as_struct()?; Some(struct_.into()) } @@ -799,7 +797,7 @@ impl<'a> InferenceContext<'a> { } fn resolve_ops_index(&self) -> Option { - self.resolve_lang_item("index")?.as_trait() + self.resolve_lang_item(name![index])?.as_trait() } fn resolve_ops_index_output(&self) -> Option { diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 90c68c9d3f7..2b8dc793ccb 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs @@ -1276,41 +1276,43 @@ impl<'a> InferenceContext<'a> { let (name, lang_item) = match op { BinaryOp::LogicOp(_) => return None, BinaryOp::ArithOp(aop) => match aop { - ArithOp::Add => (name!(add), "add"), - ArithOp::Mul => (name!(mul), "mul"), - ArithOp::Sub => (name!(sub), "sub"), - ArithOp::Div => (name!(div), "div"), - ArithOp::Rem => (name!(rem), "rem"), - ArithOp::Shl => (name!(shl), "shl"), - ArithOp::Shr => (name!(shr), "shr"), - ArithOp::BitXor => (name!(bitxor), "bitxor"), - ArithOp::BitOr => (name!(bitor), "bitor"), - ArithOp::BitAnd => (name!(bitand), "bitand"), + ArithOp::Add => (name!(add), name!(add)), + ArithOp::Mul => (name!(mul), name!(mul)), + ArithOp::Sub => (name!(sub), name!(sub)), + ArithOp::Div => (name!(div), name!(div)), + ArithOp::Rem => (name!(rem), name!(rem)), + ArithOp::Shl => (name!(shl), name!(shl)), + ArithOp::Shr => (name!(shr), name!(shr)), + ArithOp::BitXor => (name!(bitxor), name!(bitxor)), + ArithOp::BitOr => (name!(bitor), name!(bitor)), + ArithOp::BitAnd => (name!(bitand), name!(bitand)), }, BinaryOp::Assignment { op: Some(aop) } => match aop { - ArithOp::Add => (name!(add_assign), "add_assign"), - ArithOp::Mul => (name!(mul_assign), "mul_assign"), - ArithOp::Sub => (name!(sub_assign), "sub_assign"), - ArithOp::Div => (name!(div_assign), "div_assign"), - ArithOp::Rem => (name!(rem_assign), "rem_assign"), - ArithOp::Shl => (name!(shl_assign), "shl_assign"), - ArithOp::Shr => (name!(shr_assign), "shr_assign"), - ArithOp::BitXor => (name!(bitxor_assign), "bitxor_assign"), - ArithOp::BitOr => (name!(bitor_assign), "bitor_assign"), - ArithOp::BitAnd => (name!(bitand_assign), "bitand_assign"), + ArithOp::Add => (name!(add_assign), name!(add_assign)), + ArithOp::Mul => (name!(mul_assign), name!(mul_assign)), + ArithOp::Sub => (name!(sub_assign), name!(sub_assign)), + ArithOp::Div => (name!(div_assign), name!(div_assign)), + ArithOp::Rem => (name!(rem_assign), name!(rem_assign)), + ArithOp::Shl => (name!(shl_assign), name!(shl_assign)), + ArithOp::Shr => (name!(shr_assign), name!(shr_assign)), + ArithOp::BitXor => (name!(bitxor_assign), name!(bitxor_assign)), + ArithOp::BitOr => (name!(bitor_assign), name!(bitor_assign)), + ArithOp::BitAnd => (name!(bitand_assign), name!(bitand_assign)), }, BinaryOp::CmpOp(cop) => match cop { - CmpOp::Eq { negated: false } => (name!(eq), "eq"), - CmpOp::Eq { negated: true } => (name!(ne), "eq"), + CmpOp::Eq { negated: false } => (name!(eq), name!(eq)), + CmpOp::Eq { negated: true } => (name!(ne), name!(eq)), CmpOp::Ord { ordering: Ordering::Less, strict: false } => { - (name!(le), "partial_ord") + (name!(le), name!(partial_ord)) + } + CmpOp::Ord { ordering: Ordering::Less, strict: true } => { + (name!(lt), name!(partial_ord)) } - CmpOp::Ord { ordering: Ordering::Less, strict: true } => (name!(lt), "partial_ord"), CmpOp::Ord { ordering: Ordering::Greater, strict: false } => { - (name!(ge), "partial_ord") + (name!(ge), name!(partial_ord)) } CmpOp::Ord { ordering: Ordering::Greater, strict: true } => { - (name!(gt), "partial_ord") + (name!(gt), name!(partial_ord)) } }, BinaryOp::Assignment { op: None } => return None, From e1a236d65e8c091e6c849865d1ddce87c4324fe3 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 9 Dec 2021 18:28:10 +0100 Subject: [PATCH 3/3] Simplify --- crates/hir_ty/src/lower.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 99267e085fa..f7e2af46d29 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs @@ -96,9 +96,9 @@ impl<'a> TyLoweringContext<'a> { debruijn: DebruijnIndex, f: impl FnOnce(&TyLoweringContext) -> T, ) -> T { - let opaque_ty_data_vec = self.opaque_type_data.replace(Vec::new()); - let expander = self.expander.replace(None); - let unsized_types = self.unsized_types.replace(Default::default()); + let opaque_ty_data_vec = self.opaque_type_data.take(); + let expander = self.expander.take(); + let unsized_types = self.unsized_types.take(); let new_ctx = Self { in_binders: debruijn, impl_trait_counter: Cell::new(self.impl_trait_counter.get()), @@ -615,7 +615,7 @@ impl<'a> TyLoweringContext<'a> { // `Option::None::` are both allowed (though the former is // preferred). See also `def_ids_for_path_segments` in rustc. let len = path.segments().len(); - let penultimate = if len >= 2 { path.segments().get(len - 2) } else { None }; + let penultimate = len.checked_sub(2).and_then(|idx| path.segments().get(idx)); let segment = match penultimate { Some(segment) if segment.args_and_bindings.is_some() => segment, _ => last, @@ -841,8 +841,8 @@ impl<'a> TyLoweringContext<'a> { }; last_segment .into_iter() - .flat_map(|segment| segment.args_and_bindings.into_iter()) - .flat_map(|args_and_bindings| args_and_bindings.bindings.iter()) + .filter_map(|segment| segment.args_and_bindings) + .flat_map(|args_and_bindings| &args_and_bindings.bindings) .flat_map(move |binding| { let found = associated_type_by_name_including_super_traits( self.db, @@ -850,14 +850,14 @@ impl<'a> TyLoweringContext<'a> { &binding.name, ); let (super_trait_ref, associated_ty) = match found { - None => return SmallVec::<[QuantifiedWhereClause; 1]>::new(), + None => return SmallVec::new(), Some(t) => t, }; let projection_ty = ProjectionTy { associated_ty_id: to_assoc_type_id(associated_ty), substitution: super_trait_ref.substitution, }; - let mut preds = SmallVec::with_capacity( + let mut preds: SmallVec<[_; 1]> = SmallVec::with_capacity( binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(), ); if let Some(type_ref) = &binding.type_ref {