Skip to content

Commit

Permalink
Auto merge of #18005 - rami3l:fix/for-completion-in-impl, r=Veykril
Browse files Browse the repository at this point in the history
fix(ide-completion): fix handling of `for` in `impl T for A` in function body

Closes #17787.
  • Loading branch information
bors committed Aug 30, 2024
2 parents e77de38 + 9afdc3a commit 27979ad
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,68 @@ fn foo(a: A) { a.$0 }
);
}

#[test]
fn for_in_impl() {
check_edit(
"for",
r#"
struct X;
impl X $0 {}
"#,
r#"
struct X;
impl X for $0 {}
"#,
);
check_edit(
"for",
r#"
fn foo() {
struct X;
impl X $0 {}
}
"#,
r#"
fn foo() {
struct X;
impl X for $0 {}
}
"#,
);
check_edit(
"for",
r#"
fn foo() {
struct X;
impl X $0
}
"#,
r#"
fn foo() {
struct X;
impl X for $0
}
"#,
);
check_edit(
"for",
r#"
fn foo() {
struct X;
impl X { fn bar() { $0 } }
}
"#,
r#"
fn foo() {
struct X;
impl X { fn bar() { for $1 in $2 {
$0
} } }
}
"#,
);
}

#[test]
fn let_semi() {
cov_mark::check!(let_semi);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1132,10 +1132,18 @@ fn classify_name_ref(
ast::PathType(it) => make_path_kind_type(it.into()),
ast::PathExpr(it) => {
if let Some(p) = it.syntax().parent() {
if ast::ExprStmt::can_cast(p.kind()) {
if let Some(kind) = inbetween_body_and_decl_check(p) {
return Some(make_res(NameRefKind::Keyword(kind)));
}
let p_kind = p.kind();
// The syntax node of interest, for which we want to check whether
// it is sandwiched between an item decl signature and its body.
let probe = if ast::ExprStmt::can_cast(p_kind) {
Some(p)
} else if ast::StmtList::can_cast(p_kind) {
Some(it.syntax().clone())
} else {
None
};
if let Some(kind) = probe.and_then(inbetween_body_and_decl_check) {
return Some(make_res(NameRefKind::Keyword(kind)));
}
}

Expand Down Expand Up @@ -1199,7 +1207,13 @@ fn classify_name_ref(
}
}
},
ast::RecordExpr(it) => make_path_kind_expr(it.into()),
ast::RecordExpr(it) => {
// A record expression in this position is usually a result of parsing recovery, so check that
if let Some(kind) = inbetween_body_and_decl_check(it.syntax().clone()) {
return Some(make_res(NameRefKind::Keyword(kind)));
}
make_path_kind_expr(it.into())
},
_ => return None,
}
};
Expand Down

0 comments on commit 27979ad

Please sign in to comment.