Skip to content

Commit 329adb5

Browse files
committed
Auto merge of #17671 - Veykril:binding-size, r=Veykril
internal: Shrink size of `Binding` This should save a bit of memory now that we LRU the source map
2 parents 36f58f5 + 7c374a1 commit 329adb5

File tree

15 files changed

+94
-56
lines changed

15 files changed

+94
-56
lines changed

crates/hir-def/src/body.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ pub mod scope;
66
#[cfg(test)]
77
mod tests;
88

9-
use std::ops::Index;
9+
use std::ops::{Deref, Index};
1010

1111
use base_db::CrateId;
1212
use cfg::{CfgExpr, CfgOptions};
1313
use hir_expand::{name::Name, InFile};
1414
use la_arena::{Arena, ArenaMap};
1515
use rustc_hash::FxHashMap;
16+
use smallvec::SmallVec;
1617
use span::MacroFileId;
1718
use syntax::{ast, AstPtr, SyntaxNodePtr};
1819
use triomphe::Arc;
@@ -91,6 +92,7 @@ pub struct BodySourceMap {
9192
label_map_back: ArenaMap<LabelId, LabelSource>,
9293

9394
self_param: Option<InFile<AstPtr<ast::SelfParam>>>,
95+
binding_definitions: FxHashMap<BindingId, SmallVec<[PatId; 4]>>,
9496

9597
/// We don't create explicit nodes for record fields (`S { record_field: 92 }`).
9698
/// Instead, we use id of expression (`92`) to identify the field.
@@ -377,6 +379,10 @@ impl BodySourceMap {
377379
self.label_map_back[label]
378380
}
379381

382+
pub fn patterns_for_binding(&self, binding: BindingId) -> &[PatId] {
383+
self.binding_definitions.get(&binding).map_or(&[], Deref::deref)
384+
}
385+
380386
pub fn node_label(&self, node: InFile<&ast::Label>) -> Option<LabelId> {
381387
let src = node.map(AstPtr::new);
382388
self.label_map.get(&src).cloned()
@@ -428,6 +434,7 @@ impl BodySourceMap {
428434
expansions,
429435
format_args_template_map,
430436
diagnostics,
437+
binding_definitions,
431438
} = self;
432439
format_args_template_map.shrink_to_fit();
433440
expr_map.shrink_to_fit();
@@ -440,5 +447,6 @@ impl BodySourceMap {
440447
pat_field_map_back.shrink_to_fit();
441448
expansions.shrink_to_fit();
442449
diagnostics.shrink_to_fit();
450+
binding_definitions.shrink_to_fit();
443451
}
444452
}

crates/hir-def/src/body/lower.rs

+5-10
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use hir_expand::{
1111
};
1212
use intern::{sym, Interned, Symbol};
1313
use rustc_hash::FxHashMap;
14-
use smallvec::SmallVec;
1514
use span::AstIdMap;
1615
use stdx::never;
1716
use syntax::{
@@ -1437,11 +1436,12 @@ impl ExprCollector<'_> {
14371436
args: AstChildren<ast::Pat>,
14381437
has_leading_comma: bool,
14391438
binding_list: &mut BindingList,
1440-
) -> (Box<[PatId]>, Option<usize>) {
1439+
) -> (Box<[PatId]>, Option<u32>) {
14411440
let args: Vec<_> = args.map(|p| self.collect_pat_possibly_rest(p, binding_list)).collect();
14421441
// Find the location of the `..`, if there is one. Note that we do not
14431442
// consider the possibility of there being multiple `..` here.
1444-
let ellipsis = args.iter().position(|p| p.is_right());
1443+
let ellipsis = args.iter().position(|p| p.is_right()).map(|it| it as u32);
1444+
14451445
// We want to skip the `..` pattern here, since we account for it above.
14461446
let mut args: Vec<_> = args.into_iter().filter_map(Either::left).collect();
14471447
// if there is a leading comma, the user is most likely to type out a leading pattern
@@ -1512,7 +1512,7 @@ impl ExprCollector<'_> {
15121512
}
15131513

15141514
fn add_definition_to_binding(&mut self, binding_id: BindingId, pat_id: PatId) {
1515-
self.body.bindings[binding_id].definitions.push(pat_id);
1515+
self.source_map.binding_definitions.entry(binding_id).or_default().push(pat_id);
15161516
}
15171517

15181518
// region: labels
@@ -2058,12 +2058,7 @@ impl ExprCollector<'_> {
20582058
}
20592059

20602060
fn alloc_binding(&mut self, name: Name, mode: BindingAnnotation) -> BindingId {
2061-
let binding = self.body.bindings.alloc(Binding {
2062-
name,
2063-
mode,
2064-
definitions: SmallVec::new(),
2065-
problems: None,
2066-
});
2061+
let binding = self.body.bindings.alloc(Binding { name, mode, problems: None });
20672062
if let Some(owner) = self.current_binding_owner {
20682063
self.body.binding_owners.insert(binding, owner);
20692064
}

crates/hir-def/src/body/pretty.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ impl Printer<'_> {
517517
if i != 0 {
518518
w!(self, ", ");
519519
}
520-
if *ellipsis == Some(i) {
520+
if *ellipsis == Some(i as u32) {
521521
w!(self, ".., ");
522522
}
523523
self.print_pat(*pat);
@@ -595,7 +595,7 @@ impl Printer<'_> {
595595
if i != 0 {
596596
w!(self, ", ");
597597
}
598-
if *ellipsis == Some(i) {
598+
if *ellipsis == Some(i as u32) {
599599
w!(self, ", ..");
600600
}
601601
self.print_pat(*arg);

crates/hir-def/src/body/scope.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ fn foo() {
484484
let function = find_function(&db, file_id.file_id());
485485

486486
let scopes = db.expr_scopes(function.into());
487-
let (body, source_map) = db.body_with_source_map(function.into());
487+
let (_, source_map) = db.body_with_source_map(function.into());
488488

489489
let expr_scope = {
490490
let expr_ast = name_ref.syntax().ancestors().find_map(ast::Expr::cast).unwrap();
@@ -495,7 +495,7 @@ fn foo() {
495495

496496
let resolved = scopes.resolve_name_in_scope(expr_scope, &name_ref.as_name()).unwrap();
497497
let pat_src = source_map
498-
.pat_syntax(*body.bindings[resolved.binding()].definitions.first().unwrap())
498+
.pat_syntax(*source_map.binding_definitions[&resolved.binding()].first().unwrap())
499499
.unwrap();
500500

501501
let local_name = pat_src.value.syntax_node_ptr().to_node(file.syntax());

crates/hir-def/src/hir.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ use hir_expand::name::Name;
2121
use intern::{Interned, Symbol};
2222
use la_arena::{Idx, RawIdx};
2323
use rustc_apfloat::ieee::{Half as f16, Quad as f128};
24-
use smallvec::SmallVec;
2524
use syntax::ast;
2625

2726
use crate::{
@@ -525,7 +524,6 @@ pub enum BindingProblems {
525524
pub struct Binding {
526525
pub name: Name,
527526
pub mode: BindingAnnotation,
528-
pub definitions: SmallVec<[PatId; 1]>,
529527
pub problems: Option<BindingProblems>,
530528
}
531529

@@ -540,15 +538,15 @@ pub struct RecordFieldPat {
540538
pub enum Pat {
541539
Missing,
542540
Wild,
543-
Tuple { args: Box<[PatId]>, ellipsis: Option<usize> },
541+
Tuple { args: Box<[PatId]>, ellipsis: Option<u32> },
544542
Or(Box<[PatId]>),
545543
Record { path: Option<Box<Path>>, args: Box<[RecordFieldPat]>, ellipsis: bool },
546544
Range { start: Option<Box<LiteralOrConst>>, end: Option<Box<LiteralOrConst>> },
547545
Slice { prefix: Box<[PatId]>, slice: Option<PatId>, suffix: Box<[PatId]> },
548546
Path(Box<Path>),
549547
Lit(ExprId),
550548
Bind { id: BindingId, subpat: Option<PatId> },
551-
TupleStruct { path: Option<Box<Path>>, args: Box<[PatId]>, ellipsis: Option<usize> },
549+
TupleStruct { path: Option<Box<Path>>, args: Box<[PatId]>, ellipsis: Option<u32> },
552550
Ref { pat: PatId, mutability: Mutability },
553551
Box { inner: PatId },
554552
ConstBlock(ExprId),

crates/hir-ty/src/diagnostics/match_check.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -206,15 +206,15 @@ impl<'a> PatCtxt<'a> {
206206
&mut self,
207207
pats: &[PatId],
208208
expected_len: usize,
209-
ellipsis: Option<usize>,
209+
ellipsis: Option<u32>,
210210
) -> Vec<FieldPat> {
211211
if pats.len() > expected_len {
212212
self.errors.push(PatternError::ExtraFields);
213213
return Vec::new();
214214
}
215215

216216
pats.iter()
217-
.enumerate_and_adjust(expected_len, ellipsis)
217+
.enumerate_and_adjust(expected_len, ellipsis.map(|it| it as usize))
218218
.map(|(i, &subpattern)| FieldPat {
219219
field: LocalFieldId::from_raw((i as u32).into()),
220220
pattern: self.lower_pattern(subpattern),

crates/hir-ty/src/infer/closure.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,7 @@ impl InferenceContext<'_> {
889889
match &self.body[pat] {
890890
Pat::Missing | Pat::Wild => (),
891891
Pat::Tuple { args, ellipsis } => {
892-
let (al, ar) = args.split_at(ellipsis.unwrap_or(args.len()));
892+
let (al, ar) = args.split_at(ellipsis.map_or(args.len(), |it| it as usize));
893893
let field_count = match self.result[pat].kind(Interner) {
894894
TyKind::Tuple(_, s) => s.len(Interner),
895895
_ => return,
@@ -964,7 +964,7 @@ impl InferenceContext<'_> {
964964
}
965965
VariantId::StructId(s) => {
966966
let vd = &*self.db.struct_data(s).variant_data;
967-
let (al, ar) = args.split_at(ellipsis.unwrap_or(args.len()));
967+
let (al, ar) = args.split_at(ellipsis.map_or(args.len(), |it| it as usize));
968968
let fields = vd.fields().iter();
969969
let it =
970970
al.iter().zip(fields.clone()).chain(ar.iter().rev().zip(fields.rev()));

crates/hir-ty/src/infer/expr.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1170,7 +1170,7 @@ impl InferenceContext<'_> {
11701170
Expr::Tuple { exprs, .. } => {
11711171
// We don't consider multiple ellipses. This is analogous to
11721172
// `hir_def::body::lower::ExprCollector::collect_tuple_pat()`.
1173-
let ellipsis = exprs.iter().position(|e| is_rest_expr(*e));
1173+
let ellipsis = exprs.iter().position(|e| is_rest_expr(*e)).map(|it| it as u32);
11741174
let exprs: Vec<_> = exprs.iter().filter(|e| !is_rest_expr(**e)).copied().collect();
11751175

11761176
self.infer_tuple_pat_like(&rhs_ty, (), ellipsis, &exprs)
@@ -1184,7 +1184,7 @@ impl InferenceContext<'_> {
11841184

11851185
// We don't consider multiple ellipses. This is analogous to
11861186
// `hir_def::body::lower::ExprCollector::collect_tuple_pat()`.
1187-
let ellipsis = args.iter().position(|e| is_rest_expr(*e));
1187+
let ellipsis = args.iter().position(|e| is_rest_expr(*e)).map(|it| it as u32);
11881188
let args: Vec<_> = args.iter().filter(|e| !is_rest_expr(**e)).copied().collect();
11891189

11901190
self.infer_tuple_struct_pat_like(path, &rhs_ty, (), lhs, ellipsis, &args)

crates/hir-ty/src/infer/pat.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ impl InferenceContext<'_> {
6868
expected: &Ty,
6969
default_bm: T::BindingMode,
7070
id: T,
71-
ellipsis: Option<usize>,
71+
ellipsis: Option<u32>,
7272
subs: &[T],
7373
) -> Ty {
7474
let (ty, def) = self.resolve_variant(path, true);
@@ -98,7 +98,7 @@ impl InferenceContext<'_> {
9898
let visibilities = self.db.field_visibilities(def);
9999

100100
let (pre, post) = match ellipsis {
101-
Some(idx) => subs.split_at(idx),
101+
Some(idx) => subs.split_at(idx as usize),
102102
None => (subs, &[][..]),
103103
};
104104
let post_idx_offset = field_types.iter().count().saturating_sub(post.len());
@@ -219,7 +219,7 @@ impl InferenceContext<'_> {
219219
&mut self,
220220
expected: &Ty,
221221
default_bm: T::BindingMode,
222-
ellipsis: Option<usize>,
222+
ellipsis: Option<u32>,
223223
subs: &[T],
224224
) -> Ty {
225225
let expected = self.resolve_ty_shallow(expected);
@@ -229,7 +229,9 @@ impl InferenceContext<'_> {
229229
};
230230

231231
let ((pre, post), n_uncovered_patterns) = match ellipsis {
232-
Some(idx) => (subs.split_at(idx), expectations.len().saturating_sub(subs.len())),
232+
Some(idx) => {
233+
(subs.split_at(idx as usize), expectations.len().saturating_sub(subs.len()))
234+
}
233235
None => ((subs, &[][..]), 0),
234236
};
235237
let mut expectations_iter = expectations

crates/hir-ty/src/mir.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,7 @@ impl MirBody {
11641164
pub enum MirSpan {
11651165
ExprId(ExprId),
11661166
PatId(PatId),
1167+
BindingId(BindingId),
11671168
SelfParam,
11681169
Unknown,
11691170
}

crates/hir-ty/src/mir/eval.rs

+10
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,16 @@ impl MirEvalError {
388388
Ok(s) => s.map(|it| it.syntax_node_ptr()),
389389
Err(_) => continue,
390390
},
391+
MirSpan::BindingId(b) => {
392+
match source_map
393+
.patterns_for_binding(*b)
394+
.iter()
395+
.find_map(|p| source_map.pat_syntax(*p).ok())
396+
{
397+
Some(s) => s.map(|it| it.syntax_node_ptr()),
398+
None => continue,
399+
}
400+
}
391401
MirSpan::SelfParam => match source_map.self_param_syntax() {
392402
Some(s) => s.map(|it| it.syntax_node_ptr()),
393403
None => continue,

crates/hir-ty/src/mir/lower.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -1720,14 +1720,8 @@ impl<'ctx> MirLowerCtx<'ctx> {
17201720
/// This function push `StorageLive` statement for the binding, and applies changes to add `StorageDead` and
17211721
/// `Drop` in the appropriated places.
17221722
fn push_storage_live(&mut self, b: BindingId, current: BasicBlockId) -> Result<()> {
1723-
let span = self.body.bindings[b]
1724-
.definitions
1725-
.first()
1726-
.copied()
1727-
.map(MirSpan::PatId)
1728-
.unwrap_or(MirSpan::Unknown);
17291723
let l = self.binding_local(b)?;
1730-
self.push_storage_live_for_local(l, current, span)
1724+
self.push_storage_live_for_local(l, current, MirSpan::BindingId(b))
17311725
}
17321726

17331727
fn push_storage_live_for_local(

crates/hir-ty/src/mir/lower/pattern_matching.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ macro_rules! not_supported {
2323
}
2424

2525
pub(super) enum AdtPatternShape<'a> {
26-
Tuple { args: &'a [PatId], ellipsis: Option<usize> },
26+
Tuple { args: &'a [PatId], ellipsis: Option<u32> },
2727
Record { args: &'a [RecordFieldPat] },
2828
Unit,
2929
}
@@ -627,12 +627,12 @@ impl MirLowerCtx<'_> {
627627
current: BasicBlockId,
628628
current_else: Option<BasicBlockId>,
629629
args: &[PatId],
630-
ellipsis: Option<usize>,
630+
ellipsis: Option<u32>,
631631
fields: impl DoubleEndedIterator<Item = PlaceElem> + Clone,
632632
cond_place: &Place,
633633
mode: MatchingMode,
634634
) -> Result<(BasicBlockId, Option<BasicBlockId>)> {
635-
let (al, ar) = args.split_at(ellipsis.unwrap_or(args.len()));
635+
let (al, ar) = args.split_at(ellipsis.map_or(args.len(), |it| it as usize));
636636
let it = al
637637
.iter()
638638
.zip(fields.clone())

crates/hir/src/lib.rs

+26-6
Original file line numberDiff line numberDiff line change
@@ -1806,6 +1806,16 @@ impl DefWithBody {
18061806
Some(s) => s.map(|it| it.into()),
18071807
None => continue,
18081808
},
1809+
mir::MirSpan::BindingId(b) => {
1810+
match source_map
1811+
.patterns_for_binding(b)
1812+
.iter()
1813+
.find_map(|p| source_map.pat_syntax(*p).ok())
1814+
{
1815+
Some(s) => s.map(|it| it.into()),
1816+
None => continue,
1817+
}
1818+
}
18091819
mir::MirSpan::Unknown => continue,
18101820
};
18111821
acc.push(
@@ -1822,8 +1832,8 @@ impl DefWithBody {
18221832
let Some(&local) = mir_body.binding_locals.get(binding_id) else {
18231833
continue;
18241834
};
1825-
if body[binding_id]
1826-
.definitions
1835+
if source_map
1836+
.patterns_for_binding(binding_id)
18271837
.iter()
18281838
.any(|&pat| source_map.pat_syntax(pat).is_err())
18291839
{
@@ -1859,6 +1869,16 @@ impl DefWithBody {
18591869
Ok(s) => s.map(|it| it.into()),
18601870
Err(_) => continue,
18611871
},
1872+
mir::MirSpan::BindingId(b) => {
1873+
match source_map
1874+
.patterns_for_binding(*b)
1875+
.iter()
1876+
.find_map(|p| source_map.pat_syntax(*p).ok())
1877+
{
1878+
Some(s) => s.map(|it| it.into()),
1879+
None => continue,
1880+
}
1881+
}
18621882
mir::MirSpan::SelfParam => match source_map.self_param_syntax()
18631883
{
18641884
Some(s) => s.map(|it| it.into()),
@@ -3291,8 +3311,8 @@ impl Local {
32913311
source: source.map(|ast| Either::Right(ast.to_node(&root))),
32923312
}]
32933313
}
3294-
_ => body[self.binding_id]
3295-
.definitions
3314+
_ => source_map
3315+
.patterns_for_binding(self.binding_id)
32963316
.iter()
32973317
.map(|&definition| {
32983318
let src = source_map.pat_syntax(definition).unwrap(); // Hmm...
@@ -3320,8 +3340,8 @@ impl Local {
33203340
source: source.map(|ast| Either::Right(ast.to_node(&root))),
33213341
}
33223342
}
3323-
_ => body[self.binding_id]
3324-
.definitions
3343+
_ => source_map
3344+
.patterns_for_binding(self.binding_id)
33253345
.first()
33263346
.map(|&definition| {
33273347
let src = source_map.pat_syntax(definition).unwrap(); // Hmm...

0 commit comments

Comments
 (0)