Skip to content

Commit 272f6df

Browse files
committed
Micro-optimize type hints to avoid allocations
1 parent bd96d0b commit 272f6df

File tree

1 file changed

+38
-39
lines changed

1 file changed

+38
-39
lines changed

crates/ra_ide/src/inlay_hints.rs

Lines changed: 38 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,20 @@ pub(crate) fn inlay_hints(
3030
max_inlay_hint_length: Option<usize>,
3131
) -> Vec<InlayHint> {
3232
let mut sb = SourceBinder::new(db);
33-
file.syntax()
34-
.descendants()
35-
.flat_map(|node| get_inlay_hints(&mut sb, file_id, &node, max_inlay_hint_length))
36-
.flatten()
37-
.collect()
33+
let mut res = Vec::new();
34+
for node in file.syntax().descendants() {
35+
get_inlay_hints(&mut res, &mut sb, file_id, &node, max_inlay_hint_length);
36+
}
37+
res
3838
}
3939

4040
fn get_inlay_hints(
41+
acc: &mut Vec<InlayHint>,
4142
sb: &mut SourceBinder<RootDatabase>,
4243
file_id: FileId,
4344
node: &SyntaxNode,
4445
max_inlay_hint_length: Option<usize>,
45-
) -> Option<Vec<InlayHint>> {
46+
) -> Option<()> {
4647
let _p = profile("get_inlay_hints");
4748
let db = sb.db;
4849
let analyzer = Lazy::new(move || sb.analyze(hir::InFile::new(file_id.into(), node), None));
@@ -53,62 +54,58 @@ fn get_inlay_hints(
5354
return None;
5455
}
5556
let pat = it.pat()?;
56-
Some(get_pat_type_hints(db, &analyzer, pat, false, max_inlay_hint_length))
57+
get_pat_type_hints(acc, db, &analyzer, pat, false, max_inlay_hint_length);
5758
},
5859
ast::LambdaExpr(it) => {
5960
it.param_list().map(|param_list| {
6061
param_list
6162
.params()
6263
.filter(|closure_param| closure_param.ascribed_type().is_none())
6364
.filter_map(|closure_param| closure_param.pat())
64-
.map(|root_pat| get_pat_type_hints(db, &analyzer, root_pat, false, max_inlay_hint_length))
65-
.flatten()
66-
.collect()
67-
})
65+
.for_each(|root_pat| get_pat_type_hints(acc, db, &analyzer, root_pat, false, max_inlay_hint_length))
66+
});
6867
},
6968
ast::ForExpr(it) => {
7069
let pat = it.pat()?;
71-
Some(get_pat_type_hints(db, &analyzer, pat, false, max_inlay_hint_length))
70+
get_pat_type_hints(acc, db, &analyzer, pat, false, max_inlay_hint_length);
7271
},
7372
ast::IfExpr(it) => {
7473
let pat = it.condition()?.pat()?;
75-
Some(get_pat_type_hints(db, &analyzer, pat, true, max_inlay_hint_length))
74+
get_pat_type_hints(acc, db, &analyzer, pat, true, max_inlay_hint_length);
7675
},
7776
ast::WhileExpr(it) => {
7877
let pat = it.condition()?.pat()?;
79-
Some(get_pat_type_hints(db, &analyzer, pat, true, max_inlay_hint_length))
78+
get_pat_type_hints(acc, db, &analyzer, pat, true, max_inlay_hint_length);
8079
},
8180
ast::MatchArmList(it) => {
82-
Some(
83-
it
84-
.arms()
85-
.map(|match_arm| match_arm.pats())
86-
.flatten()
87-
.map(|root_pat| get_pat_type_hints(db, &analyzer, root_pat, true, max_inlay_hint_length))
88-
.flatten()
89-
.collect(),
90-
)
81+
it.arms()
82+
.map(|match_arm| match_arm.pats())
83+
.flatten()
84+
.for_each(|root_pat| get_pat_type_hints(acc, db, &analyzer, root_pat, true, max_inlay_hint_length));
9185
},
9286
ast::CallExpr(it) => {
93-
get_param_name_hints(db, &analyzer, ast::Expr::from(it))
87+
get_param_name_hints(acc, db, &analyzer, ast::Expr::from(it));
9488
},
9589
ast::MethodCallExpr(it) => {
96-
get_param_name_hints(db, &analyzer, ast::Expr::from(it))
90+
get_param_name_hints(acc, db, &analyzer, ast::Expr::from(it));
9791
},
98-
_ => None,
92+
_ => (),
9993
}
100-
}
94+
};
95+
Some(())
10196
}
97+
10298
fn get_param_name_hints(
99+
acc: &mut Vec<InlayHint>,
103100
db: &RootDatabase,
104101
analyzer: &SourceAnalyzer,
105102
expr: ast::Expr,
106-
) -> Option<Vec<InlayHint>> {
103+
) -> Option<()> {
107104
let args = match &expr {
108-
ast::Expr::CallExpr(expr) => Some(expr.arg_list()?.args()),
109-
ast::Expr::MethodCallExpr(expr) => Some(expr.arg_list()?.args()),
110-
_ => None,
111-
}?;
105+
ast::Expr::CallExpr(expr) => expr.arg_list()?.args(),
106+
ast::Expr::MethodCallExpr(expr) => expr.arg_list()?.args(),
107+
_ => return None,
108+
};
112109

113110
let mut parameters = get_fn_signature(db, analyzer, &expr)?.parameter_names.into_iter();
114111

@@ -129,10 +126,10 @@ fn get_param_name_hints(
129126
range,
130127
kind: InlayKind::ParameterHint,
131128
label: param_name.into(),
132-
})
133-
.collect();
129+
});
134130

135-
Some(hints)
131+
acc.extend(hints);
132+
Some(())
136133
}
137134

138135
fn get_fn_signature(
@@ -164,15 +161,16 @@ fn get_fn_signature(
164161
}
165162

166163
fn get_pat_type_hints(
164+
acc: &mut Vec<InlayHint>,
167165
db: &RootDatabase,
168166
analyzer: &SourceAnalyzer,
169167
root_pat: ast::Pat,
170168
skip_root_pat_hint: bool,
171169
max_inlay_hint_length: Option<usize>,
172-
) -> Vec<InlayHint> {
170+
) {
173171
let original_pat = &root_pat.clone();
174172

175-
get_leaf_pats(root_pat)
173+
let hints = get_leaf_pats(root_pat)
176174
.into_iter()
177175
.filter(|pat| !skip_root_pat_hint || pat != original_pat)
178176
.filter_map(|pat| {
@@ -186,8 +184,9 @@ fn get_pat_type_hints(
186184
range,
187185
kind: InlayKind::TypeHint,
188186
label: pat_type.display_truncated(db, max_inlay_hint_length).to_string().into(),
189-
})
190-
.collect()
187+
});
188+
189+
acc.extend(hints);
191190
}
192191

193192
fn get_leaf_pats(root_pat: ast::Pat) -> Vec<ast::Pat> {

0 commit comments

Comments
 (0)