diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs index addbb3f585..499c9b3716 100644 --- a/crates/base-db/src/input.rs +++ b/crates/base-db/src/input.rs @@ -422,8 +422,8 @@ impl CrateGraphBuilder { edition: Edition, display_name: Option, version: Option, - cfg_options: CfgOptions, - potential_cfg_options: Option, + mut cfg_options: CfgOptions, + mut potential_cfg_options: Option, mut env: Env, origin: CrateOrigin, is_proc_macro: bool, @@ -431,6 +431,10 @@ impl CrateGraphBuilder { ws_data: Arc, ) -> CrateBuilderId { env.entries.shrink_to_fit(); + cfg_options.shrink_to_fit(); + if let Some(potential_cfg_options) = &mut potential_cfg_options { + potential_cfg_options.shrink_to_fit(); + } self.arena.alloc(CrateBuilder { basic: CrateData { root_file_id, diff --git a/crates/cfg/src/lib.rs b/crates/cfg/src/lib.rs index f17e0ea7e3..906106ca5d 100644 --- a/crates/cfg/src/lib.rs +++ b/crates/cfg/src/lib.rs @@ -110,6 +110,11 @@ impl CfgOptions { enabled.sort_unstable(); HashableCfgOptions { _enabled: enabled } } + + #[inline] + pub fn shrink_to_fit(&mut self) { + self.enabled.shrink_to_fit(); + } } impl Extend for CfgOptions { diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs index 0b7e2f49cd..01d340cea6 100644 --- a/crates/hir-def/src/item_tree.rs +++ b/crates/hir-def/src/item_tree.rs @@ -223,7 +223,10 @@ impl ItemTree { } fn shrink_to_fit(&mut self) { - if let Some(data) = &mut self.data { + let ItemTree { top_level, attrs, data } = self; + top_level.shrink_to_fit(); + attrs.shrink_to_fit(); + if let Some(data) = data { let ItemTreeData { uses, extern_crates, diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index 228e67a60f..c49097d993 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -493,7 +493,7 @@ pub struct InferenceResult { /// ``` /// the first `rest` has implicit `ref` binding mode, but the second `rest` binding mode is `move`. pub binding_modes: ArenaMap, - pub expr_adjustments: FxHashMap>, + pub expr_adjustments: FxHashMap>, pub(crate) closure_info: FxHashMap, FnTrait)>, // FIXME: remove this field pub mutated_bindings_in_closure: FxHashSet, @@ -785,8 +785,8 @@ impl<'a> InferenceContext<'a> { // Comment from rustc: // Even though coercion casts provide type hints, we check casts after fallback for // backwards compatibility. This makes fallback a stronger type hint than a cast coercion. - let mut apply_adjustments = |expr, adj| { - expr_adjustments.insert(expr, adj); + let mut apply_adjustments = |expr, adj: Vec<_>| { + expr_adjustments.insert(expr, adj.into_boxed_slice()); }; let mut set_coercion_cast = |expr| { coercion_casts.insert(expr); @@ -808,22 +808,27 @@ impl<'a> InferenceContext<'a> { *ty = table.resolve_completely(ty.clone()); *has_errors = *has_errors || ty.contains_unknown(); } + type_of_expr.shrink_to_fit(); for ty in type_of_pat.values_mut() { *ty = table.resolve_completely(ty.clone()); *has_errors = *has_errors || ty.contains_unknown(); } + type_of_pat.shrink_to_fit(); for ty in type_of_binding.values_mut() { *ty = table.resolve_completely(ty.clone()); *has_errors = *has_errors || ty.contains_unknown(); } + type_of_binding.shrink_to_fit(); for ty in type_of_rpit.values_mut() { *ty = table.resolve_completely(ty.clone()); *has_errors = *has_errors || ty.contains_unknown(); } + type_of_rpit.shrink_to_fit(); for ty in type_of_for_iterator.values_mut() { *ty = table.resolve_completely(ty.clone()); *has_errors = *has_errors || ty.contains_unknown(); } + type_of_for_iterator.shrink_to_fit(); *has_errors |= !type_mismatches.is_empty(); @@ -838,6 +843,7 @@ impl<'a> InferenceContext<'a> { ) .is_ok() }); + type_mismatches.shrink_to_fit(); diagnostics.retain_mut(|diagnostic| { use InferenceDiagnostic::*; match diagnostic { @@ -866,24 +872,29 @@ impl<'a> InferenceContext<'a> { } true }); + diagnostics.shrink_to_fit(); for (_, subst) in method_resolutions.values_mut() { *subst = table.resolve_completely(subst.clone()); *has_errors = *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown()); } + method_resolutions.shrink_to_fit(); for (_, subst) in assoc_resolutions.values_mut() { *subst = table.resolve_completely(subst.clone()); *has_errors = *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown()); } + assoc_resolutions.shrink_to_fit(); for adjustment in expr_adjustments.values_mut().flatten() { adjustment.target = table.resolve_completely(adjustment.target.clone()); *has_errors = *has_errors || adjustment.target.contains_unknown(); } + expr_adjustments.shrink_to_fit(); for adjustment in pat_adjustments.values_mut().flatten() { *adjustment = table.resolve_completely(adjustment.clone()); *has_errors = *has_errors || adjustment.contains_unknown(); } + pat_adjustments.shrink_to_fit(); result.tuple_field_access_types = tuple_field_accesses_rev .into_iter() .enumerate() @@ -893,6 +904,7 @@ impl<'a> InferenceContext<'a> { *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown()); }) .collect(); + result.tuple_field_access_types.shrink_to_fit(); result.diagnostics = diagnostics; @@ -1261,7 +1273,7 @@ impl<'a> InferenceContext<'a> { self.result.type_of_expr.insert(expr, ty); } - fn write_expr_adj(&mut self, expr: ExprId, adjustments: Vec) { + fn write_expr_adj(&mut self, expr: ExprId, adjustments: Box<[Adjustment]>) { if adjustments.is_empty() { return; } diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs index e7b776a356..cf3b15d2a6 100644 --- a/crates/hir-ty/src/infer/closure.rs +++ b/crates/hir-ty/src/infer/closure.rs @@ -869,8 +869,8 @@ impl CapturedItemWithoutTy { impl InferenceContext<'_> { fn place_of_expr(&mut self, tgt_expr: ExprId) -> Option { let r = self.place_of_expr_without_adjust(tgt_expr)?; - let default = vec![]; - let adjustments = self.result.expr_adjustments.get(&tgt_expr).unwrap_or(&default); + let adjustments = + self.result.expr_adjustments.get(&tgt_expr).map(|it| &**it).unwrap_or_default(); apply_adjusts_to_place(&mut self.current_capture_span_stack, r, adjustments) } @@ -1701,7 +1701,7 @@ impl InferenceContext<'_> { for (derefed_callee, callee_ty, params, expr) in exprs { if let &Expr::Call { callee, .. } = &self.body[expr] { let mut adjustments = - self.result.expr_adjustments.remove(&callee).unwrap_or_default(); + self.result.expr_adjustments.remove(&callee).unwrap_or_default().into_vec(); self.write_fn_trait_method_resolution( kind, &derefed_callee, @@ -1710,7 +1710,7 @@ impl InferenceContext<'_> { ¶ms, expr, ); - self.result.expr_adjustments.insert(callee, adjustments); + self.result.expr_adjustments.insert(callee, adjustments.into_boxed_slice()); } } } diff --git a/crates/hir-ty/src/infer/coerce.rs b/crates/hir-ty/src/infer/coerce.rs index b0fb01a84d..847dd43a02 100644 --- a/crates/hir-ty/src/infer/coerce.rs +++ b/crates/hir-ty/src/infer/coerce.rs @@ -148,11 +148,11 @@ impl CoerceMany { if let (Ok(result1), Ok(result2)) = (result1, result2) { ctx.table.register_infer_ok(InferOk { value: (), goals: result1.goals }); for &e in &self.expressions { - ctx.write_expr_adj(e, result1.value.0.clone()); + ctx.write_expr_adj(e, result1.value.0.clone().into_boxed_slice()); } ctx.table.register_infer_ok(InferOk { value: (), goals: result2.goals }); if let Some(expr) = expr { - ctx.write_expr_adj(expr, result2.value.0); + ctx.write_expr_adj(expr, result2.value.0.into_boxed_slice()); self.expressions.push(expr); } return self.final_ty = Some(target_ty); @@ -182,7 +182,7 @@ impl CoerceMany { { self.final_ty = Some(res); for &e in &self.expressions { - ctx.write_expr_adj(e, adjustments.clone()); + ctx.write_expr_adj(e, adjustments.clone().into_boxed_slice()); } } else { match cause { @@ -263,7 +263,7 @@ impl InferenceContext<'_> { ) -> Result { let (adjustments, ty) = self.coerce_inner(from_ty, to_ty, coerce_never)?; if let Some(expr) = expr { - self.write_expr_adj(expr, adjustments); + self.write_expr_adj(expr, adjustments.into_boxed_slice()); } Ok(ty) } diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs index 643587e8af..a636ec5c20 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -812,7 +812,7 @@ impl InferenceContext<'_> { self_ty.clone(), self.table.new_lifetime_var(), )); - self.write_expr_adj(*base, adj); + self.write_expr_adj(*base, adj.into_boxed_slice()); if let Some(func) = self .db .trait_items(index_trait) @@ -1356,10 +1356,10 @@ impl InferenceContext<'_> { if let TyKind::Ref(mtbl, lt, _) = p_left.kind(Interner) { self.write_expr_adj( lhs, - vec![Adjustment { + Box::new([Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(lt.clone(), *mtbl)), target: p_left.clone(), - }], + }]), ); } } @@ -1368,10 +1368,10 @@ impl InferenceContext<'_> { if let TyKind::Ref(mtbl, lt, _) = p_right.kind(Interner) { self.write_expr_adj( rhs, - vec![Adjustment { + Box::new([Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(lt.clone(), *mtbl)), target: p_right.clone(), - }], + }]), ); } } @@ -1627,7 +1627,7 @@ impl InferenceContext<'_> { match self.lookup_field(&receiver_ty, name) { Some((ty, field_id, adjustments, is_public)) => { - self.write_expr_adj(receiver, adjustments); + self.write_expr_adj(receiver, adjustments.into_boxed_slice()); self.result.field_resolutions.insert(tgt_expr, field_id); if !is_public { if let Either::Left(field) = field_id { @@ -1662,7 +1662,7 @@ impl InferenceContext<'_> { Some((adjust, func, _)) => { let (ty, adjustments) = adjust.apply(&mut self.table, receiver_ty); let substs = self.substs_for_method_call(tgt_expr, func.into(), None); - self.write_expr_adj(receiver, adjustments); + self.write_expr_adj(receiver, adjustments.into_boxed_slice()); self.write_method_resolution(tgt_expr, func, substs.clone()); self.check_method_call( @@ -1725,7 +1725,7 @@ impl InferenceContext<'_> { tgt_expr, ); } - self.write_expr_adj(callee, adjustments); + self.write_expr_adj(callee, adjustments.into_boxed_slice()); (params, ret_ty) } None => { @@ -1809,7 +1809,7 @@ impl InferenceContext<'_> { } let (ty, adjustments) = adjust.apply(&mut self.table, receiver_ty); - self.write_expr_adj(receiver, adjustments); + self.write_expr_adj(receiver, adjustments.into_boxed_slice()); let substs = self.substs_for_method_call(tgt_expr, func.into(), generic_args); self.write_method_resolution(tgt_expr, func, substs.clone()); @@ -1828,7 +1828,7 @@ impl InferenceContext<'_> { let field_with_same_name_exists = match self.lookup_field(&receiver_ty, method_name) { Some((ty, field_id, adjustments, _public)) => { - self.write_expr_adj(receiver, adjustments); + self.write_expr_adj(receiver, adjustments.into_boxed_slice()); self.result.field_resolutions.insert(tgt_expr, field_id); Some(ty) } diff --git a/crates/hir-ty/src/interner.rs b/crates/hir-ty/src/interner.rs index bd4a53603d..fecb3f4242 100644 --- a/crates/hir-ty/src/interner.rs +++ b/crates/hir-ty/src/interner.rs @@ -43,7 +43,7 @@ impl_internable!( InternedWrapper, InternedWrapper, InternedWrapper>, - InternedWrapper>, + InternedWrapper>, InternedWrapper>, InternedWrapper>, ); @@ -60,7 +60,7 @@ impl chalk_ir::interner::Interner for Interner { type InternedGoal = Arc; type InternedGoals = Vec; type InternedSubstitution = Interned>>; - type InternedProgramClauses = Interned>>; + type InternedProgramClauses = Interned>>; type InternedProgramClause = ProgramClauseData; type InternedQuantifiedWhereClauses = Interned>>; type InternedVariableKinds = Interned>>;