Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 7369e51

Browse files
committed
Move CompletionContext::function_def into PathKind::Expr
1 parent 309ecdd commit 7369e51

File tree

4 files changed

+82
-39
lines changed

4 files changed

+82
-39
lines changed

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

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -46,27 +46,26 @@ pub(crate) fn complete_undotted_self(
4646
if !ctx.config.enable_self_on_the_fly {
4747
return;
4848
}
49-
match path_ctx {
50-
PathCompletionCtx { qualified: Qualified::No, kind: PathKind::Expr { .. }, .. }
51-
if path_ctx.is_trivial_path() && ctx.qualifier_ctx.none() => {}
49+
let self_param = match path_ctx {
50+
PathCompletionCtx {
51+
qualified: Qualified::No,
52+
kind: PathKind::Expr { self_param: Some(self_param), .. },
53+
..
54+
} if path_ctx.is_trivial_path() && ctx.qualifier_ctx.none() => self_param,
5255
_ => return,
53-
}
56+
};
5457

55-
if let Some(func) = ctx.function_def.as_ref().and_then(|fn_| ctx.sema.to_def(fn_)) {
56-
if let Some(self_) = func.self_param(ctx.db) {
57-
let ty = self_.ty(ctx.db);
58-
complete_fields(
59-
acc,
60-
ctx,
61-
&ty,
62-
|acc, field, ty| acc.add_field(ctx, Some(hir::known::SELF_PARAM), field, &ty),
63-
|acc, field, ty| acc.add_tuple_field(ctx, Some(hir::known::SELF_PARAM), field, &ty),
64-
);
65-
complete_methods(ctx, &ty, |func| {
66-
acc.add_method(ctx, func, Some(hir::known::SELF_PARAM), None)
67-
});
68-
}
69-
}
58+
let ty = self_param.ty(ctx.db);
59+
complete_fields(
60+
acc,
61+
ctx,
62+
&ty,
63+
|acc, field, ty| acc.add_field(ctx, Some(hir::known::SELF_PARAM), field, &ty),
64+
|acc, field, ty| acc.add_tuple_field(ctx, Some(hir::known::SELF_PARAM), field, &ty),
65+
);
66+
complete_methods(ctx, &ty, |func| {
67+
acc.add_method(ctx, func, Some(hir::known::SELF_PARAM), None)
68+
});
7069
}
7170

7271
fn complete_fields(

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ pub(crate) fn complete_expr_path(
1414
path_ctx: &PathCompletionCtx,
1515
) {
1616
let _p = profile::span("complete_expr_path");
17-
17+
if !ctx.qualifier_ctx.none() {
18+
return;
19+
}
1820
let (
1921
qualified,
2022
in_block_expr,
@@ -23,6 +25,7 @@ pub(crate) fn complete_expr_path(
2325
after_if_expr,
2426
wants_mut_token,
2527
in_condition,
28+
ty,
2629
) = match path_ctx {
2730
&PathCompletionCtx {
2831
kind:
@@ -33,17 +36,20 @@ pub(crate) fn complete_expr_path(
3336
in_condition,
3437
ref ref_expr_parent,
3538
ref is_func_update,
39+
ref innermost_ret_ty,
40+
..
3641
},
3742
ref qualified,
3843
..
39-
} if ctx.qualifier_ctx.none() => (
44+
} => (
4045
qualified,
4146
in_block_expr,
4247
in_loop_body,
4348
is_func_update.is_some(),
4449
after_if_expr,
4550
ref_expr_parent.as_ref().map(|it| it.mut_token().is_none()).unwrap_or(false),
4651
in_condition,
52+
innermost_ret_ty,
4753
),
4854
_ => return,
4955
};
@@ -252,10 +258,10 @@ pub(crate) fn complete_expr_path(
252258
}
253259
}
254260

255-
if let Some(fn_def) = &ctx.function_def {
261+
if let Some(ty) = ty {
256262
add_keyword(
257263
"return",
258-
match (in_block_expr, fn_def.ret_type().is_some()) {
264+
match (in_block_expr, ty.is_unit()) {
259265
(true, true) => "return ;",
260266
(true, false) => "return;",
261267
(false, true) => "return $0",

crates/ide-completion/src/context.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ pub(super) enum PathKind {
9595
in_condition: bool,
9696
ref_expr_parent: Option<ast::RefExpr>,
9797
is_func_update: Option<ast::RecordExpr>,
98+
self_param: Option<hir::SelfParam>,
99+
innermost_ret_ty: Option<hir::Type>,
98100
},
99101
Type {
100102
location: TypeLocation,
@@ -317,9 +319,6 @@ pub(crate) struct CompletionContext<'a> {
317319
/// The expected type of what we are completing.
318320
pub(super) expected_type: Option<Type>,
319321

320-
/// The parent function of the cursor position if it exists.
321-
// FIXME: This probably doesn't belong here
322-
pub(super) function_def: Option<ast::Fn>,
323322
/// The parent impl of the cursor position if it exists.
324323
// FIXME: This probably doesn't belong here
325324
pub(super) impl_def: Option<ast::Impl>,
@@ -500,7 +499,6 @@ impl<'a> CompletionContext<'a> {
500499
module,
501500
expected_name: None,
502501
expected_type: None,
503-
function_def: None,
504502
impl_def: None,
505503
incomplete_let: false,
506504
previous_token: None,

crates/ide-completion/src/context/analysis.rs

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -404,18 +404,6 @@ impl<'a> CompletionContext<'a> {
404404
ast::Item::Impl(impl_) => Some(impl_),
405405
_ => None,
406406
});
407-
self.function_def = self
408-
.sema
409-
.token_ancestors_with_macros(self.token.clone())
410-
.take_while(|it| {
411-
it.kind() != SyntaxKind::SOURCE_FILE && it.kind() != SyntaxKind::MODULE
412-
})
413-
.filter_map(ast::Item::cast)
414-
.take(2)
415-
.find_map(|it| match it {
416-
ast::Item::Fn(fn_) => Some(fn_),
417-
_ => None,
418-
});
419407

420408
match name_like {
421409
ast::NameLike::Lifetime(lifetime) => {
@@ -727,6 +715,56 @@ impl<'a> CompletionContext<'a> {
727715
let after_if_expr = after_if_expr(it.clone());
728716
let ref_expr_parent =
729717
path.as_single_name_ref().and_then(|_| it.parent()).and_then(ast::RefExpr::cast);
718+
let (innermost_ret_ty, self_param) = {
719+
let find_ret_ty = |it: SyntaxNode| {
720+
if let Some(item) = ast::Item::cast(it.clone()) {
721+
match item {
722+
ast::Item::Fn(f) => {
723+
Some(sema.to_def(&f).map(|it| it.ret_type(sema.db)))
724+
}
725+
ast::Item::MacroCall(_) => None,
726+
_ => Some(None),
727+
}
728+
} else {
729+
let expr = ast::Expr::cast(it)?;
730+
let callable = match expr {
731+
// FIXME
732+
// ast::Expr::BlockExpr(b) if b.async_token().is_some() || b.try_token().is_some() => sema.type_of_expr(b),
733+
ast::Expr::ClosureExpr(_) => sema.type_of_expr(&expr),
734+
_ => return None,
735+
};
736+
Some(
737+
callable
738+
.and_then(|c| c.adjusted().as_callable(sema.db))
739+
.map(|it| it.return_type()),
740+
)
741+
}
742+
};
743+
let find_fn_self_param = |it| match it {
744+
ast::Item::Fn(fn_) => {
745+
Some(sema.to_def(&fn_).and_then(|it| it.self_param(sema.db)))
746+
}
747+
ast::Item::MacroCall(_) => None,
748+
_ => Some(None),
749+
};
750+
751+
match dbg!(find_node_in_file_compensated(original_file, &expr)) {
752+
Some(it) => {
753+
let innermost_ret_ty = sema
754+
.ancestors_with_macros(it.syntax().clone())
755+
.find_map(find_ret_ty)
756+
.flatten();
757+
758+
let self_param = sema
759+
.ancestors_with_macros(it.syntax().clone())
760+
.filter_map(ast::Item::cast)
761+
.find_map(find_fn_self_param)
762+
.flatten();
763+
(innermost_ret_ty, self_param)
764+
}
765+
None => (None, None),
766+
}
767+
};
730768
let is_func_update = func_update_record(it);
731769
let in_condition = is_in_condition(&expr);
732770

@@ -737,6 +775,8 @@ impl<'a> CompletionContext<'a> {
737775
in_condition,
738776
ref_expr_parent,
739777
is_func_update,
778+
innermost_ret_ty,
779+
self_param,
740780
}
741781
};
742782
let make_path_kind_type = |ty: ast::Type| {

0 commit comments

Comments
 (0)