Skip to content

Commit 1e2738b

Browse files
committed
Collapse term search exprs before Cartesian product to avoid OOM
1 parent c50b357 commit 1e2738b

File tree

4 files changed

+43
-20
lines changed

4 files changed

+43
-20
lines changed

src/tools/rust-analyzer/crates/hir/src/term_search.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,13 @@ impl LookupTable {
127127
self.types_wishlist.insert(ty.clone());
128128
}
129129

130+
// Collapse suggestions if there are many
131+
if let Some(res) = &res {
132+
if res.len() > self.many_threshold {
133+
return Some(vec![Expr::Many(ty.clone())]);
134+
}
135+
}
136+
130137
res
131138
}
132139

@@ -158,6 +165,13 @@ impl LookupTable {
158165
self.types_wishlist.insert(ty.clone());
159166
}
160167

168+
// Collapse suggestions if there are many
169+
if let Some(res) = &res {
170+
if res.len() > self.many_threshold {
171+
return Some(vec![Expr::Many(ty.clone())]);
172+
}
173+
}
174+
161175
res
162176
}
163177

@@ -176,11 +190,11 @@ impl LookupTable {
176190
}
177191
None => {
178192
self.data.insert(ty.clone(), AlternativeExprs::new(self.many_threshold, exprs));
179-
for it in self.new_types.values_mut() {
180-
it.push(ty.clone());
181-
}
182193
}
183194
}
195+
for it in self.new_types.values_mut() {
196+
it.push(ty.clone());
197+
}
184198
}
185199

186200
/// Iterate all the reachable types

src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -211,13 +211,13 @@ impl Expr {
211211
}
212212
}
213213
Expr::Method { func, target, params, .. } => {
214-
if target.contains_many_in_illegal_pos() {
214+
if self.contains_many_in_illegal_pos(db) {
215215
return Ok(many_formatter(&target.ty(db)));
216216
}
217217

218218
let func_name = func.name(db).display(db.upcast()).to_string();
219219
let self_param = func.self_param(db).unwrap();
220-
let target = target.gen_source_code(
220+
let target_str = target.gen_source_code(
221221
sema_scope,
222222
many_formatter,
223223
prefer_no_std,
@@ -236,17 +236,20 @@ impl Expr {
236236
Some(trait_) => {
237237
let trait_name = mod_item_path_str(sema_scope, &ModuleDef::Trait(trait_))?;
238238
let target = match self_param.access(db) {
239-
crate::Access::Shared => format!("&{target}"),
240-
crate::Access::Exclusive => format!("&mut {target}"),
241-
crate::Access::Owned => target,
239+
crate::Access::Shared if !target.is_many() => format!("&{target_str}"),
240+
crate::Access::Exclusive if !target.is_many() => {
241+
format!("&mut {target_str}")
242+
}
243+
crate::Access::Owned => target_str,
244+
_ => many_formatter(&target.ty(db)),
242245
};
243246
let res = match args.is_empty() {
244247
true => format!("{trait_name}::{func_name}({target})",),
245248
false => format!("{trait_name}::{func_name}({target}, {args})",),
246249
};
247250
Ok(res)
248251
}
249-
None => Ok(format!("{target}.{func_name}({args})")),
252+
None => Ok(format!("{target_str}.{func_name}({args})")),
250253
}
251254
}
252255
Expr::Variant { variant, generics, params } => {
@@ -381,7 +384,7 @@ impl Expr {
381384
Ok(res)
382385
}
383386
Expr::Field { expr, field } => {
384-
if expr.contains_many_in_illegal_pos() {
387+
if expr.contains_many_in_illegal_pos(db) {
385388
return Ok(many_formatter(&expr.ty(db)));
386389
}
387390

@@ -395,7 +398,7 @@ impl Expr {
395398
Ok(format!("{strukt}.{field}"))
396399
}
397400
Expr::Reference(expr) => {
398-
if expr.contains_many_in_illegal_pos() {
401+
if expr.contains_many_in_illegal_pos(db) {
399402
return Ok(many_formatter(&expr.ty(db)));
400403
}
401404

@@ -466,10 +469,17 @@ impl Expr {
466469
/// macro!().bar()
467470
/// &macro!()
468471
/// ```
469-
fn contains_many_in_illegal_pos(&self) -> bool {
472+
fn contains_many_in_illegal_pos(&self, db: &dyn HirDatabase) -> bool {
470473
match self {
471-
Expr::Method { target, .. } => target.contains_many_in_illegal_pos(),
472-
Expr::Field { expr, .. } => expr.contains_many_in_illegal_pos(),
474+
Expr::Method { target, func, .. } => {
475+
match func.as_assoc_item(db).and_then(|it| it.container_or_implemented_trait(db)) {
476+
Some(_) => false,
477+
None => {
478+
target.is_many()
479+
}
480+
}
481+
}
482+
Expr::Field { expr, .. } => expr.contains_many_in_illegal_pos(db),
473483
Expr::Reference(target) => target.is_many(),
474484
Expr::Many(_) => true,
475485
_ => false,

src/tools/rust-analyzer/crates/ide-completion/src/render.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1808,8 +1808,7 @@ fn f() { A { bar: b$0 }; }
18081808
fn baz() [type]
18091809
ex baz() [type]
18101810
ex bar() [type]
1811-
ex A { bar: baz() }.bar [type]
1812-
ex A { bar: bar() }.bar [type]
1811+
ex A { bar: ... }.bar [type]
18131812
st A []
18141813
fn f() []
18151814
"#]],
@@ -1947,8 +1946,8 @@ fn main() {
19471946
}
19481947
"#,
19491948
expect![[r#"
1950-
ex core::ops::Deref::deref(&T(S)) (use core::ops::Deref) [type_could_unify]
19511949
ex core::ops::Deref::deref(&t) (use core::ops::Deref) [type_could_unify]
1950+
ex core::ops::Deref::deref(&T(S)) (use core::ops::Deref) [type_could_unify]
19521951
lc m [local]
19531952
lc t [local]
19541953
lc &t [type+local]
@@ -1997,8 +1996,8 @@ fn main() {
19971996
}
19981997
"#,
19991998
expect![[r#"
2000-
ex core::ops::DerefMut::deref_mut(&mut T(S)) (use core::ops::DerefMut) [type_could_unify]
20011999
ex core::ops::DerefMut::deref_mut(&mut t) (use core::ops::DerefMut) [type_could_unify]
2000+
ex core::ops::DerefMut::deref_mut(&mut T(S)) (use core::ops::DerefMut) [type_could_unify]
20022001
lc m [local]
20032002
lc t [local]
20042003
lc &mut t [type+local]

src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ impl Foo for Baz {
274274
}
275275
fn asd() -> Bar {
276276
let a = Baz;
277-
Foo::foo(a)
277+
Foo::foo(_)
278278
}
279279
",
280280
);
@@ -363,7 +363,7 @@ impl Foo for A {
363363
}
364364
fn main() {
365365
let a = A;
366-
let c: Bar = Foo::foo(&a);
366+
let c: Bar = Foo::foo(_);
367367
}"#,
368368
);
369369
}

0 commit comments

Comments
 (0)