Skip to content

Commit c74a829

Browse files
committed
fix(ide-completion): fix handling of for in impl T for A in function body
1 parent 13ac53e commit c74a829

File tree

2 files changed

+75
-2
lines changed

2 files changed

+75
-2
lines changed

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

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,68 @@ fn foo(a: A) { a.$0 }
150150
);
151151
}
152152

153+
#[test]
154+
fn for_in_impl() {
155+
check_edit(
156+
"for",
157+
r#"
158+
struct X;
159+
impl X $0 {}
160+
"#,
161+
r#"
162+
struct X;
163+
impl X for $0 {}
164+
"#,
165+
);
166+
check_edit(
167+
"for",
168+
r#"
169+
fn foo() {
170+
struct X;
171+
impl X $0 {}
172+
}
173+
"#,
174+
r#"
175+
fn foo() {
176+
struct X;
177+
impl X for $0 {}
178+
}
179+
"#,
180+
);
181+
check_edit(
182+
"for",
183+
r#"
184+
fn foo() {
185+
struct X;
186+
impl X $0
187+
}
188+
"#,
189+
r#"
190+
fn foo() {
191+
struct X;
192+
impl X for $0
193+
}
194+
"#,
195+
);
196+
check_edit(
197+
"for",
198+
r#"
199+
fn foo() {
200+
struct X;
201+
impl X { fn bar() { $0 } }
202+
}
203+
"#,
204+
r#"
205+
fn foo() {
206+
struct X;
207+
impl X { fn bar() { for $1 in $2 {
208+
$0
209+
} } }
210+
}
211+
"#,
212+
);
213+
}
214+
153215
#[test]
154216
fn let_semi() {
155217
cov_mark::check!(let_semi);

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,10 +1132,15 @@ fn classify_name_ref(
11321132
ast::PathType(it) => make_path_kind_type(it.into()),
11331133
ast::PathExpr(it) => {
11341134
if let Some(p) = it.syntax().parent() {
1135-
if ast::ExprStmt::can_cast(p.kind()) {
1135+
let p_kind = p.kind();
1136+
if ast::ExprStmt::can_cast(p_kind) {
11361137
if let Some(kind) = inbetween_body_and_decl_check(p) {
11371138
return Some(make_res(NameRefKind::Keyword(kind)));
11381139
}
1140+
} else if ast::StmtList::can_cast(p_kind) {
1141+
if let Some(kind) = inbetween_body_and_decl_check(it.syntax().clone()) {
1142+
return Some(make_res(NameRefKind::Keyword(kind)));
1143+
}
11391144
}
11401145
}
11411146

@@ -1199,7 +1204,13 @@ fn classify_name_ref(
11991204
}
12001205
}
12011206
},
1202-
ast::RecordExpr(it) => make_path_kind_expr(it.into()),
1207+
ast::RecordExpr(it) => {
1208+
// A record expression in this position is usually a result of parsing recovery, so check that
1209+
if let Some(kind) = inbetween_body_and_decl_check(it.syntax().clone()) {
1210+
return Some(make_res(NameRefKind::Keyword(kind)));
1211+
}
1212+
make_path_kind_expr(it.into())
1213+
},
12031214
_ => return None,
12041215
}
12051216
};

0 commit comments

Comments
 (0)