Skip to content

Commit 88964c0

Browse files
committed
Optionally disable term search for autocompletion
1 parent 0b838e3 commit 88964c0

File tree

13 files changed

+163
-41
lines changed

13 files changed

+163
-41
lines changed

crates/hir/src/term_search/expr.rs

Lines changed: 99 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ use crate::{
1111
};
1212

1313
/// Helper function to get path to `ModuleDef`
14-
fn mod_item_path(sema_scope: &SemanticsScope<'_>, def: &ModuleDef) -> Option<ModPath> {
14+
fn mod_item_path(
15+
sema_scope: &SemanticsScope<'_>,
16+
def: &ModuleDef,
17+
prefer_no_std: bool,
18+
prefer_prelude: bool,
19+
) -> Option<ModPath> {
1520
let db = sema_scope.db;
1621
// Account for locals shadowing items from module
1722
let name_hit_count = def.name(db).map(|def_name| {
@@ -26,25 +31,43 @@ fn mod_item_path(sema_scope: &SemanticsScope<'_>, def: &ModuleDef) -> Option<Mod
2631

2732
let m = sema_scope.module();
2833
match name_hit_count {
29-
Some(0..=1) | None => m.find_use_path(db.upcast(), *def, false, true),
30-
Some(_) => m.find_use_path_prefixed(db.upcast(), *def, PrefixKind::ByCrate, false, true),
34+
Some(0..=1) | None => m.find_use_path(db.upcast(), *def, prefer_no_std, prefer_prelude),
35+
Some(_) => m.find_use_path_prefixed(
36+
db.upcast(),
37+
*def,
38+
PrefixKind::ByCrate,
39+
prefer_no_std,
40+
prefer_prelude,
41+
),
3142
}
3243
}
3344

3445
/// Helper function to get path to `ModuleDef` as string
35-
fn mod_item_path_str(sema_scope: &SemanticsScope<'_>, def: &ModuleDef) -> String {
36-
let path = mod_item_path(sema_scope, def);
46+
fn mod_item_path_str(
47+
sema_scope: &SemanticsScope<'_>,
48+
def: &ModuleDef,
49+
prefer_no_std: bool,
50+
prefer_prelude: bool,
51+
) -> String {
52+
let path = mod_item_path(sema_scope, def, prefer_no_std, prefer_prelude);
3753
path.map(|it| it.display(sema_scope.db.upcast()).to_string()).unwrap()
3854
}
3955

4056
/// Helper function to get path to `Type`
41-
fn type_path(sema_scope: &SemanticsScope<'_>, ty: &Type) -> String {
57+
fn type_path(
58+
sema_scope: &SemanticsScope<'_>,
59+
ty: &Type,
60+
prefer_no_std: bool,
61+
prefer_prelude: bool,
62+
) -> String {
4263
let db = sema_scope.db;
4364
match ty.as_adt() {
4465
Some(adt) => {
4566
let ty_name = ty.display(db).to_string();
4667

47-
let mut path = mod_item_path(sema_scope, &ModuleDef::Adt(adt)).unwrap();
68+
let mut path =
69+
mod_item_path(sema_scope, &ModuleDef::Adt(adt), prefer_no_std, prefer_prelude)
70+
.unwrap();
4871
path.pop_segment();
4972
let path = path.display(db.upcast()).to_string();
5073
match path.is_empty() {
@@ -125,17 +148,24 @@ impl Expr {
125148
&self,
126149
sema_scope: &SemanticsScope<'_>,
127150
many_formatter: &mut dyn FnMut(&Type) -> String,
151+
prefer_no_std: bool,
152+
prefer_prelude: bool,
128153
) -> String {
129154
let db = sema_scope.db;
155+
let mod_item_path_str = |s, def| mod_item_path_str(s, def, prefer_no_std, prefer_prelude);
130156
match self {
131157
Expr::Const(it) => mod_item_path_str(sema_scope, &ModuleDef::Const(*it)),
132158
Expr::Static(it) => mod_item_path_str(sema_scope, &ModuleDef::Static(*it)),
133159
Expr::Local(it) => return it.name(db).display(db.upcast()).to_string(),
134160
Expr::ConstParam(it) => return it.name(db).display(db.upcast()).to_string(),
135161
Expr::FamousType { value, .. } => return value.to_string(),
136162
Expr::Function { func, params, .. } => {
137-
let args =
138-
params.iter().map(|f| f.gen_source_code(sema_scope, many_formatter)).join(", ");
163+
let args = params
164+
.iter()
165+
.map(|f| {
166+
f.gen_source_code(sema_scope, many_formatter, prefer_no_std, prefer_prelude)
167+
})
168+
.join(", ");
139169

140170
match func.as_assoc_item(db).map(|it| it.container(db)) {
141171
Some(container) => {
@@ -146,10 +176,14 @@ impl Expr {
146176
crate::AssocItemContainer::Impl(imp) => {
147177
let self_ty = imp.self_ty(db);
148178
// Should it be guaranteed that `mod_item_path` always exists?
149-
match self_ty
150-
.as_adt()
151-
.and_then(|adt| mod_item_path(sema_scope, &adt.into()))
152-
{
179+
match self_ty.as_adt().and_then(|adt| {
180+
mod_item_path(
181+
sema_scope,
182+
&adt.into(),
183+
prefer_no_std,
184+
prefer_prelude,
185+
)
186+
}) {
153187
Some(path) => path.display(sema_scope.db.upcast()).to_string(),
154188
None => self_ty.display(db).to_string(),
155189
}
@@ -171,9 +205,18 @@ impl Expr {
171205

172206
let func_name = func.name(db).display(db.upcast()).to_string();
173207
let self_param = func.self_param(db).unwrap();
174-
let target = target.gen_source_code(sema_scope, many_formatter);
175-
let args =
176-
params.iter().map(|f| f.gen_source_code(sema_scope, many_formatter)).join(", ");
208+
let target = target.gen_source_code(
209+
sema_scope,
210+
many_formatter,
211+
prefer_no_std,
212+
prefer_prelude,
213+
);
214+
let args = params
215+
.iter()
216+
.map(|f| {
217+
f.gen_source_code(sema_scope, many_formatter, prefer_no_std, prefer_prelude)
218+
})
219+
.join(", ");
177220

178221
match func.as_assoc_item(db).and_then(|it| it.containing_trait_or_trait_impl(db)) {
179222
Some(trait_) => {
@@ -196,16 +239,25 @@ impl Expr {
196239
let generics_str = match generics.is_empty() {
197240
true => String::new(),
198241
false => {
199-
let generics =
200-
generics.iter().map(|it| type_path(sema_scope, it)).join(", ");
242+
let generics = generics
243+
.iter()
244+
.map(|it| type_path(sema_scope, it, prefer_no_std, prefer_prelude))
245+
.join(", ");
201246
format!("::<{generics}>")
202247
}
203248
};
204249
let inner = match variant.kind(db) {
205250
StructKind::Tuple => {
206251
let args = params
207252
.iter()
208-
.map(|f| f.gen_source_code(sema_scope, many_formatter))
253+
.map(|f| {
254+
f.gen_source_code(
255+
sema_scope,
256+
many_formatter,
257+
prefer_no_std,
258+
prefer_prelude,
259+
)
260+
})
209261
.join(", ");
210262
format!("{generics_str}({args})")
211263
}
@@ -218,7 +270,12 @@ impl Expr {
218270
format!(
219271
"{}: {}",
220272
f.name(db).display(db.upcast()).to_string(),
221-
a.gen_source_code(sema_scope, many_formatter)
273+
a.gen_source_code(
274+
sema_scope,
275+
many_formatter,
276+
prefer_no_std,
277+
prefer_prelude
278+
)
222279
)
223280
})
224281
.join(", ");
@@ -236,7 +293,14 @@ impl Expr {
236293
StructKind::Tuple => {
237294
let args = params
238295
.iter()
239-
.map(|a| a.gen_source_code(sema_scope, many_formatter))
296+
.map(|a| {
297+
a.gen_source_code(
298+
sema_scope,
299+
many_formatter,
300+
prefer_no_std,
301+
prefer_prelude,
302+
)
303+
})
240304
.join(", ");
241305
format!("({args})")
242306
}
@@ -249,7 +313,12 @@ impl Expr {
249313
format!(
250314
"{}: {}",
251315
f.name(db).display(db.upcast()).to_string(),
252-
a.gen_source_code(sema_scope, many_formatter)
316+
a.gen_source_code(
317+
sema_scope,
318+
many_formatter,
319+
prefer_no_std,
320+
prefer_prelude
321+
)
253322
)
254323
})
255324
.join(", ");
@@ -258,8 +327,10 @@ impl Expr {
258327
StructKind::Unit => match generics.is_empty() {
259328
true => String::new(),
260329
false => {
261-
let generics =
262-
generics.iter().map(|it| type_path(sema_scope, it)).join(", ");
330+
let generics = generics
331+
.iter()
332+
.map(|it| type_path(sema_scope, it, prefer_no_std, prefer_prelude))
333+
.join(", ");
263334
format!("::<{generics}>")
264335
}
265336
},
@@ -273,7 +344,8 @@ impl Expr {
273344
return many_formatter(&expr.ty(db));
274345
}
275346

276-
let strukt = expr.gen_source_code(sema_scope, many_formatter);
347+
let strukt =
348+
expr.gen_source_code(sema_scope, many_formatter, prefer_no_std, prefer_prelude);
277349
let field = field.name(db).display(db.upcast()).to_string();
278350
format!("{strukt}.{field}")
279351
}
@@ -282,7 +354,8 @@ impl Expr {
282354
return many_formatter(&expr.ty(db));
283355
}
284356

285-
let inner = expr.gen_source_code(sema_scope, many_formatter);
357+
let inner =
358+
expr.gen_source_code(sema_scope, many_formatter, prefer_no_std, prefer_prelude);
286359
format!("&{inner}")
287360
}
288361
Expr::Many(ty) => many_formatter(ty),

crates/hir/src/term_search/tactics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,7 @@ pub(super) fn impl_static_method<'a, DB: HirDatabase>(
760760
.count();
761761

762762
// Ignore bigger number of generics for now as they kill the performance
763-
if non_default_type_params_len > 0 {
763+
if non_default_type_params_len > 1 {
764764
return None;
765765
}
766766

crates/ide-assists/src/handlers/term_search.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,12 @@ pub(crate) fn term_search(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
3838

3939
let mut formatter = |_: &hir::Type| String::from("todo!()");
4040
for path in paths.iter().unique() {
41-
let code = path.gen_source_code(&scope, &mut formatter);
41+
let code = path.gen_source_code(
42+
&scope,
43+
&mut formatter,
44+
ctx.config.prefer_no_std,
45+
ctx.config.prefer_prelude,
46+
);
4247
acc.add_group(
4348
&GroupLabel(String::from("Term search")),
4449
AssistId("term_search", AssistKind::Generate),

crates/ide-completion/src/completions/expr.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,11 @@ pub(crate) fn complete_expr_path(
331331

332332
pub(crate) fn complete_expr(acc: &mut Completions, ctx: &CompletionContext<'_>) {
333333
let _p = tracing::span!(tracing::Level::INFO, "complete_expr").entered();
334+
335+
if !ctx.config.enable_term_search {
336+
return;
337+
}
338+
334339
if !ctx.qualifier_ctx.none() {
335340
return;
336341
}

crates/ide-completion/src/config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub struct CompletionConfig {
1414
pub enable_imports_on_the_fly: bool,
1515
pub enable_self_on_the_fly: bool,
1616
pub enable_private_editable: bool,
17+
pub enable_term_search: bool,
1718
pub full_function_signatures: bool,
1819
pub callable: Option<CallableSnippets>,
1920
pub snippet_cap: Option<SnippetCap>,

crates/ide-completion/src/render.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,12 @@ pub(crate) fn render_expr(
295295
.unwrap_or_else(|| String::from("..."))
296296
};
297297

298-
let label = expr.gen_source_code(&ctx.scope, &mut label_formatter);
298+
let label = expr.gen_source_code(
299+
&ctx.scope,
300+
&mut label_formatter,
301+
ctx.config.prefer_no_std,
302+
ctx.config.prefer_prelude,
303+
);
299304

300305
let source_range = match ctx.original_token.parent() {
301306
Some(node) => match node.ancestors().find_map(|n| ast::Path::cast(n)) {
@@ -307,7 +312,15 @@ pub(crate) fn render_expr(
307312

308313
let mut item = CompletionItem::new(CompletionItemKind::Snippet, source_range, label.clone());
309314

310-
let snippet = format!("{}$0", expr.gen_source_code(&ctx.scope, &mut snippet_formatter));
315+
let snippet = format!(
316+
"{}$0",
317+
expr.gen_source_code(
318+
&ctx.scope,
319+
&mut snippet_formatter,
320+
ctx.config.prefer_no_std,
321+
ctx.config.prefer_prelude
322+
)
323+
);
311324
let edit = TextEdit::replace(source_range, snippet);
312325
item.snippet_edit(ctx.config.snippet_cap?, edit);
313326
item.documentation(Documentation::new(String::from("Autogenerated expression by term search")));

crates/ide-completion/src/tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ pub(crate) const TEST_CONFIG: CompletionConfig = CompletionConfig {
6565
enable_imports_on_the_fly: true,
6666
enable_self_on_the_fly: true,
6767
enable_private_editable: false,
68+
enable_term_search: true,
6869
full_function_signatures: false,
6970
callable: Some(CallableSnippets::FillArguments),
7071
snippet_cap: SnippetCap::new(true),

crates/ide-diagnostics/src/handlers/typed_hole.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
use hir::{
22
db::ExpandDatabase,
33
term_search::{term_search, TermSearchCtx},
4-
ClosureStyle, HirDisplay, Semantics,
4+
ClosureStyle, HirDisplay,
55
};
66
use ide_db::{
77
assists::{Assist, AssistId, AssistKind, GroupLabel},
88
label::Label,
99
source_change::SourceChange,
10-
RootDatabase,
1110
};
1211
use itertools::Itertools;
1312
use text_edit::TextEdit;
@@ -29,29 +28,38 @@ pub(crate) fn typed_hole(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole) -> Di
2928
"invalid `_` expression, expected type `{}`",
3029
d.expected.display(ctx.sema.db).with_closure_style(ClosureStyle::ClosureWithId),
3130
),
32-
fixes(&ctx.sema, d),
31+
fixes(ctx, d),
3332
)
3433
};
3534

3635
Diagnostic::new(DiagnosticCode::RustcHardError("typed-hole"), message, display_range)
3736
.with_fixes(fixes)
3837
}
3938

40-
fn fixes(sema: &Semantics<'_, RootDatabase>, d: &hir::TypedHole) -> Option<Vec<Assist>> {
41-
let db = sema.db;
39+
fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole) -> Option<Vec<Assist>> {
40+
let db = ctx.sema.db;
4241
let root = db.parse_or_expand(d.expr.file_id);
4342
let (original_range, _) =
4443
d.expr.as_ref().map(|it| it.to_node(&root)).syntax().original_file_range_opt(db)?;
45-
let scope = sema.scope(d.expr.value.to_node(&root).syntax())?;
44+
let scope = ctx.sema.scope(d.expr.value.to_node(&root).syntax())?;
4645

47-
let ctx =
48-
TermSearchCtx { sema, scope: &scope, goal: d.expected.clone(), config: Default::default() };
49-
let paths = term_search(&ctx);
46+
let term_search_ctx = TermSearchCtx {
47+
sema: &ctx.sema,
48+
scope: &scope,
49+
goal: d.expected.clone(),
50+
config: Default::default(),
51+
};
52+
let paths = term_search(&term_search_ctx);
5053

5154
let mut assists = vec![];
5255
let mut formatter = |_: &hir::Type| String::from("_");
5356
for path in paths.into_iter().unique() {
54-
let code = path.gen_source_code(&scope, &mut formatter);
57+
let code = path.gen_source_code(
58+
&scope,
59+
&mut formatter,
60+
ctx.config.prefer_no_std,
61+
ctx.config.prefer_prelude,
62+
);
5563

5664
assists.push(Assist {
5765
id: AssistId("typed-hole", AssistKind::QuickFix),

crates/rust-analyzer/src/cli/analysis_stats.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ impl flags::AnalysisStats {
432432
let mut formatter = |_: &hir::Type| todo.clone();
433433
let mut syntax_hit_found = false;
434434
for term in found_terms {
435-
let generated = term.gen_source_code(&scope, &mut formatter);
435+
let generated = term.gen_source_code(&scope, &mut formatter, false, true);
436436
syntax_hit_found |= trim(&original_text) == trim(&generated);
437437

438438
// Validate if type-checks

0 commit comments

Comments
 (0)