shrink_to_fit() in more places

This saves 18mb on `analysis-stats .`, without regressing speed.
This commit is contained in:
Chayim Refael Friedman 2025-04-25 09:40:53 +03:00
parent 5ff4ba347d
commit 1fe060719a
8 changed files with 51 additions and 27 deletions

View File

@ -422,8 +422,8 @@ impl CrateGraphBuilder {
edition: Edition, edition: Edition,
display_name: Option<CrateDisplayName>, display_name: Option<CrateDisplayName>,
version: Option<String>, version: Option<String>,
cfg_options: CfgOptions, mut cfg_options: CfgOptions,
potential_cfg_options: Option<CfgOptions>, mut potential_cfg_options: Option<CfgOptions>,
mut env: Env, mut env: Env,
origin: CrateOrigin, origin: CrateOrigin,
is_proc_macro: bool, is_proc_macro: bool,
@ -431,6 +431,10 @@ impl CrateGraphBuilder {
ws_data: Arc<CrateWorkspaceData>, ws_data: Arc<CrateWorkspaceData>,
) -> CrateBuilderId { ) -> CrateBuilderId {
env.entries.shrink_to_fit(); 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 { self.arena.alloc(CrateBuilder {
basic: CrateData { basic: CrateData {
root_file_id, root_file_id,

View File

@ -110,6 +110,11 @@ impl CfgOptions {
enabled.sort_unstable(); enabled.sort_unstable();
HashableCfgOptions { _enabled: enabled } HashableCfgOptions { _enabled: enabled }
} }
#[inline]
pub fn shrink_to_fit(&mut self) {
self.enabled.shrink_to_fit();
}
} }
impl Extend<CfgAtom> for CfgOptions { impl Extend<CfgAtom> for CfgOptions {

View File

@ -223,7 +223,10 @@ impl ItemTree {
} }
fn shrink_to_fit(&mut self) { 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 { let ItemTreeData {
uses, uses,
extern_crates, extern_crates,

View File

@ -493,7 +493,7 @@ pub struct InferenceResult {
/// ``` /// ```
/// the first `rest` has implicit `ref` binding mode, but the second `rest` binding mode is `move`. /// the first `rest` has implicit `ref` binding mode, but the second `rest` binding mode is `move`.
pub binding_modes: ArenaMap<PatId, BindingMode>, pub binding_modes: ArenaMap<PatId, BindingMode>,
pub expr_adjustments: FxHashMap<ExprId, Vec<Adjustment>>, pub expr_adjustments: FxHashMap<ExprId, Box<[Adjustment]>>,
pub(crate) closure_info: FxHashMap<ClosureId, (Vec<CapturedItem>, FnTrait)>, pub(crate) closure_info: FxHashMap<ClosureId, (Vec<CapturedItem>, FnTrait)>,
// FIXME: remove this field // FIXME: remove this field
pub mutated_bindings_in_closure: FxHashSet<BindingId>, pub mutated_bindings_in_closure: FxHashSet<BindingId>,
@ -785,8 +785,8 @@ impl<'a> InferenceContext<'a> {
// Comment from rustc: // Comment from rustc:
// Even though coercion casts provide type hints, we check casts after fallback for // 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. // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
let mut apply_adjustments = |expr, adj| { let mut apply_adjustments = |expr, adj: Vec<_>| {
expr_adjustments.insert(expr, adj); expr_adjustments.insert(expr, adj.into_boxed_slice());
}; };
let mut set_coercion_cast = |expr| { let mut set_coercion_cast = |expr| {
coercion_casts.insert(expr); coercion_casts.insert(expr);
@ -808,22 +808,27 @@ impl<'a> InferenceContext<'a> {
*ty = table.resolve_completely(ty.clone()); *ty = table.resolve_completely(ty.clone());
*has_errors = *has_errors || ty.contains_unknown(); *has_errors = *has_errors || ty.contains_unknown();
} }
type_of_expr.shrink_to_fit();
for ty in type_of_pat.values_mut() { for ty in type_of_pat.values_mut() {
*ty = table.resolve_completely(ty.clone()); *ty = table.resolve_completely(ty.clone());
*has_errors = *has_errors || ty.contains_unknown(); *has_errors = *has_errors || ty.contains_unknown();
} }
type_of_pat.shrink_to_fit();
for ty in type_of_binding.values_mut() { for ty in type_of_binding.values_mut() {
*ty = table.resolve_completely(ty.clone()); *ty = table.resolve_completely(ty.clone());
*has_errors = *has_errors || ty.contains_unknown(); *has_errors = *has_errors || ty.contains_unknown();
} }
type_of_binding.shrink_to_fit();
for ty in type_of_rpit.values_mut() { for ty in type_of_rpit.values_mut() {
*ty = table.resolve_completely(ty.clone()); *ty = table.resolve_completely(ty.clone());
*has_errors = *has_errors || ty.contains_unknown(); *has_errors = *has_errors || ty.contains_unknown();
} }
type_of_rpit.shrink_to_fit();
for ty in type_of_for_iterator.values_mut() { for ty in type_of_for_iterator.values_mut() {
*ty = table.resolve_completely(ty.clone()); *ty = table.resolve_completely(ty.clone());
*has_errors = *has_errors || ty.contains_unknown(); *has_errors = *has_errors || ty.contains_unknown();
} }
type_of_for_iterator.shrink_to_fit();
*has_errors |= !type_mismatches.is_empty(); *has_errors |= !type_mismatches.is_empty();
@ -838,6 +843,7 @@ impl<'a> InferenceContext<'a> {
) )
.is_ok() .is_ok()
}); });
type_mismatches.shrink_to_fit();
diagnostics.retain_mut(|diagnostic| { diagnostics.retain_mut(|diagnostic| {
use InferenceDiagnostic::*; use InferenceDiagnostic::*;
match diagnostic { match diagnostic {
@ -866,24 +872,29 @@ impl<'a> InferenceContext<'a> {
} }
true true
}); });
diagnostics.shrink_to_fit();
for (_, subst) in method_resolutions.values_mut() { for (_, subst) in method_resolutions.values_mut() {
*subst = table.resolve_completely(subst.clone()); *subst = table.resolve_completely(subst.clone());
*has_errors = *has_errors =
*has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown()); *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
} }
method_resolutions.shrink_to_fit();
for (_, subst) in assoc_resolutions.values_mut() { for (_, subst) in assoc_resolutions.values_mut() {
*subst = table.resolve_completely(subst.clone()); *subst = table.resolve_completely(subst.clone());
*has_errors = *has_errors =
*has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown()); *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
} }
assoc_resolutions.shrink_to_fit();
for adjustment in expr_adjustments.values_mut().flatten() { for adjustment in expr_adjustments.values_mut().flatten() {
adjustment.target = table.resolve_completely(adjustment.target.clone()); adjustment.target = table.resolve_completely(adjustment.target.clone());
*has_errors = *has_errors || adjustment.target.contains_unknown(); *has_errors = *has_errors || adjustment.target.contains_unknown();
} }
expr_adjustments.shrink_to_fit();
for adjustment in pat_adjustments.values_mut().flatten() { for adjustment in pat_adjustments.values_mut().flatten() {
*adjustment = table.resolve_completely(adjustment.clone()); *adjustment = table.resolve_completely(adjustment.clone());
*has_errors = *has_errors || adjustment.contains_unknown(); *has_errors = *has_errors || adjustment.contains_unknown();
} }
pat_adjustments.shrink_to_fit();
result.tuple_field_access_types = tuple_field_accesses_rev result.tuple_field_access_types = tuple_field_accesses_rev
.into_iter() .into_iter()
.enumerate() .enumerate()
@ -893,6 +904,7 @@ impl<'a> InferenceContext<'a> {
*has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown()); *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
}) })
.collect(); .collect();
result.tuple_field_access_types.shrink_to_fit();
result.diagnostics = diagnostics; result.diagnostics = diagnostics;
@ -1261,7 +1273,7 @@ impl<'a> InferenceContext<'a> {
self.result.type_of_expr.insert(expr, ty); self.result.type_of_expr.insert(expr, ty);
} }
fn write_expr_adj(&mut self, expr: ExprId, adjustments: Vec<Adjustment>) { fn write_expr_adj(&mut self, expr: ExprId, adjustments: Box<[Adjustment]>) {
if adjustments.is_empty() { if adjustments.is_empty() {
return; return;
} }

View File

@ -869,8 +869,8 @@ impl CapturedItemWithoutTy {
impl InferenceContext<'_> { impl InferenceContext<'_> {
fn place_of_expr(&mut self, tgt_expr: ExprId) -> Option<HirPlace> { fn place_of_expr(&mut self, tgt_expr: ExprId) -> Option<HirPlace> {
let r = self.place_of_expr_without_adjust(tgt_expr)?; let r = self.place_of_expr_without_adjust(tgt_expr)?;
let default = vec![]; let adjustments =
let adjustments = self.result.expr_adjustments.get(&tgt_expr).unwrap_or(&default); 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) 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 { for (derefed_callee, callee_ty, params, expr) in exprs {
if let &Expr::Call { callee, .. } = &self.body[expr] { if let &Expr::Call { callee, .. } = &self.body[expr] {
let mut adjustments = 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( self.write_fn_trait_method_resolution(
kind, kind,
&derefed_callee, &derefed_callee,
@ -1710,7 +1710,7 @@ impl InferenceContext<'_> {
&params, &params,
expr, expr,
); );
self.result.expr_adjustments.insert(callee, adjustments); self.result.expr_adjustments.insert(callee, adjustments.into_boxed_slice());
} }
} }
} }

View File

@ -148,11 +148,11 @@ impl CoerceMany {
if let (Ok(result1), Ok(result2)) = (result1, result2) { if let (Ok(result1), Ok(result2)) = (result1, result2) {
ctx.table.register_infer_ok(InferOk { value: (), goals: result1.goals }); ctx.table.register_infer_ok(InferOk { value: (), goals: result1.goals });
for &e in &self.expressions { 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 }); ctx.table.register_infer_ok(InferOk { value: (), goals: result2.goals });
if let Some(expr) = expr { 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); self.expressions.push(expr);
} }
return self.final_ty = Some(target_ty); return self.final_ty = Some(target_ty);
@ -182,7 +182,7 @@ impl CoerceMany {
{ {
self.final_ty = Some(res); self.final_ty = Some(res);
for &e in &self.expressions { for &e in &self.expressions {
ctx.write_expr_adj(e, adjustments.clone()); ctx.write_expr_adj(e, adjustments.clone().into_boxed_slice());
} }
} else { } else {
match cause { match cause {
@ -263,7 +263,7 @@ impl InferenceContext<'_> {
) -> Result<Ty, TypeError> { ) -> Result<Ty, TypeError> {
let (adjustments, ty) = self.coerce_inner(from_ty, to_ty, coerce_never)?; let (adjustments, ty) = self.coerce_inner(from_ty, to_ty, coerce_never)?;
if let Some(expr) = expr { if let Some(expr) = expr {
self.write_expr_adj(expr, adjustments); self.write_expr_adj(expr, adjustments.into_boxed_slice());
} }
Ok(ty) Ok(ty)
} }

View File

@ -812,7 +812,7 @@ impl InferenceContext<'_> {
self_ty.clone(), self_ty.clone(),
self.table.new_lifetime_var(), 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 if let Some(func) = self
.db .db
.trait_items(index_trait) .trait_items(index_trait)
@ -1356,10 +1356,10 @@ impl InferenceContext<'_> {
if let TyKind::Ref(mtbl, lt, _) = p_left.kind(Interner) { if let TyKind::Ref(mtbl, lt, _) = p_left.kind(Interner) {
self.write_expr_adj( self.write_expr_adj(
lhs, lhs,
vec![Adjustment { Box::new([Adjustment {
kind: Adjust::Borrow(AutoBorrow::Ref(lt.clone(), *mtbl)), kind: Adjust::Borrow(AutoBorrow::Ref(lt.clone(), *mtbl)),
target: p_left.clone(), target: p_left.clone(),
}], }]),
); );
} }
} }
@ -1368,10 +1368,10 @@ impl InferenceContext<'_> {
if let TyKind::Ref(mtbl, lt, _) = p_right.kind(Interner) { if let TyKind::Ref(mtbl, lt, _) = p_right.kind(Interner) {
self.write_expr_adj( self.write_expr_adj(
rhs, rhs,
vec![Adjustment { Box::new([Adjustment {
kind: Adjust::Borrow(AutoBorrow::Ref(lt.clone(), *mtbl)), kind: Adjust::Borrow(AutoBorrow::Ref(lt.clone(), *mtbl)),
target: p_right.clone(), target: p_right.clone(),
}], }]),
); );
} }
} }
@ -1627,7 +1627,7 @@ impl InferenceContext<'_> {
match self.lookup_field(&receiver_ty, name) { match self.lookup_field(&receiver_ty, name) {
Some((ty, field_id, adjustments, is_public)) => { 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); self.result.field_resolutions.insert(tgt_expr, field_id);
if !is_public { if !is_public {
if let Either::Left(field) = field_id { if let Either::Left(field) = field_id {
@ -1662,7 +1662,7 @@ impl InferenceContext<'_> {
Some((adjust, func, _)) => { Some((adjust, func, _)) => {
let (ty, adjustments) = adjust.apply(&mut self.table, receiver_ty); let (ty, adjustments) = adjust.apply(&mut self.table, receiver_ty);
let substs = self.substs_for_method_call(tgt_expr, func.into(), None); 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.write_method_resolution(tgt_expr, func, substs.clone());
self.check_method_call( self.check_method_call(
@ -1725,7 +1725,7 @@ impl InferenceContext<'_> {
tgt_expr, tgt_expr,
); );
} }
self.write_expr_adj(callee, adjustments); self.write_expr_adj(callee, adjustments.into_boxed_slice());
(params, ret_ty) (params, ret_ty)
} }
None => { None => {
@ -1809,7 +1809,7 @@ impl InferenceContext<'_> {
} }
let (ty, adjustments) = adjust.apply(&mut self.table, receiver_ty); 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); let substs = self.substs_for_method_call(tgt_expr, func.into(), generic_args);
self.write_method_resolution(tgt_expr, func, substs.clone()); 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) let field_with_same_name_exists = match self.lookup_field(&receiver_ty, method_name)
{ {
Some((ty, field_id, adjustments, _public)) => { 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); self.result.field_resolutions.insert(tgt_expr, field_id);
Some(ty) Some(ty)
} }

View File

@ -43,7 +43,7 @@ impl_internable!(
InternedWrapper<ConstData>, InternedWrapper<ConstData>,
InternedWrapper<ConstScalar>, InternedWrapper<ConstScalar>,
InternedWrapper<Vec<CanonicalVarKind>>, InternedWrapper<Vec<CanonicalVarKind>>,
InternedWrapper<Vec<ProgramClause>>, InternedWrapper<Box<[ProgramClause]>>,
InternedWrapper<Vec<QuantifiedWhereClause>>, InternedWrapper<Vec<QuantifiedWhereClause>>,
InternedWrapper<SmallVec<[Variance; 16]>>, InternedWrapper<SmallVec<[Variance; 16]>>,
); );
@ -60,7 +60,7 @@ impl chalk_ir::interner::Interner for Interner {
type InternedGoal = Arc<GoalData>; type InternedGoal = Arc<GoalData>;
type InternedGoals = Vec<Goal>; type InternedGoals = Vec<Goal>;
type InternedSubstitution = Interned<InternedWrapper<SmallVec<[GenericArg; 2]>>>; type InternedSubstitution = Interned<InternedWrapper<SmallVec<[GenericArg; 2]>>>;
type InternedProgramClauses = Interned<InternedWrapper<Vec<ProgramClause>>>; type InternedProgramClauses = Interned<InternedWrapper<Box<[ProgramClause]>>>;
type InternedProgramClause = ProgramClauseData; type InternedProgramClause = ProgramClauseData;
type InternedQuantifiedWhereClauses = Interned<InternedWrapper<Vec<QuantifiedWhereClause>>>; type InternedQuantifiedWhereClauses = Interned<InternedWrapper<Vec<QuantifiedWhereClause>>>;
type InternedVariableKinds = Interned<InternedWrapper<Vec<VariableKind>>>; type InternedVariableKinds = Interned<InternedWrapper<Vec<VariableKind>>>;