aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2021-03-21 00:10:59 +0000
committerLukas Wirth <[email protected]>2021-03-21 00:28:42 +0000
commit64957acb5f359763395a54e314d1f5d5cfc6ccf3 (patch)
tree00cec518c2cfd88dac252a4aad824372c7afc898
parent62a4677dbc6cf1c90e4558c3c73fef201a0d1080 (diff)
Fix incorrect scoping in while expressions
-rw-r--r--crates/hir_def/src/body/scope.rs2
-rw-r--r--crates/ide_completion/src/completions/lifetime.rs29
-rw-r--r--crates/ide_completion/src/context.rs24
3 files changed, 41 insertions, 14 deletions
diff --git a/crates/hir_def/src/body/scope.rs b/crates/hir_def/src/body/scope.rs
index 7f0d8f915..bd7005ca6 100644
--- a/crates/hir_def/src/body/scope.rs
+++ b/crates/hir_def/src/body/scope.rs
@@ -188,8 +188,8 @@ fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope
188 compute_expr_scopes(*body_expr, body, scopes, scope); 188 compute_expr_scopes(*body_expr, body, scopes, scope);
189 } 189 }
190 Expr::While { condition, body: body_expr, label } => { 190 Expr::While { condition, body: body_expr, label } => {
191 compute_expr_scopes(*condition, body, scopes, scope);
192 let scope = scopes.new_labeled_scope(scope, make_label(label)); 191 let scope = scopes.new_labeled_scope(scope, make_label(label));
192 compute_expr_scopes(*condition, body, scopes, scope);
193 compute_expr_scopes(*body_expr, body, scopes, scope); 193 compute_expr_scopes(*body_expr, body, scopes, scope);
194 } 194 }
195 Expr::Loop { body: body_expr, label } => { 195 Expr::Loop { body: body_expr, label } => {
diff --git a/crates/ide_completion/src/completions/lifetime.rs b/crates/ide_completion/src/completions/lifetime.rs
index 07be28e9c..628c1fb9b 100644
--- a/crates/ide_completion/src/completions/lifetime.rs
+++ b/crates/ide_completion/src/completions/lifetime.rs
@@ -253,4 +253,33 @@ fn foo() {
253 "#]], 253 "#]],
254 ); 254 );
255 } 255 }
256
257 #[test]
258 fn complete_label_in_while_cond() {
259 check(
260 r#"
261fn foo() {
262 'outer: while { 'inner: loop { break '$0 } } {}
263}
264"#,
265 expect![[r#"
266 lb 'inner
267 lb 'outer
268 "#]],
269 );
270 }
271
272 #[test]
273 fn complete_label_in_for_iterable() {
274 check(
275 r#"
276fn foo() {
277 'outer: for _ in [{ 'inner: loop { break '$0 } }] {}
278}
279"#,
280 expect![[r#"
281 lb 'inner
282 "#]],
283 );
284 }
256} 285}
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index 6cb7e5264..67e2d6f6c 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -475,19 +475,17 @@ impl<'a> CompletionContext<'a> {
475 return; 475 return;
476 } 476 }
477 477
478 if parent.kind() != syntax::SyntaxKind::LABEL { 478 match_ast! {
479 match_ast! { 479 match parent {
480 match parent { 480 ast::LifetimeParam(_it) => {
481 ast::LifetimeParam(_it) => { 481 self.lifetime_allowed = true;
482 self.lifetime_allowed = true; 482 self.lifetime_param_syntax =
483 self.lifetime_param_syntax = 483 self.sema.find_node_at_offset_with_macros(original_file, offset);
484 self.sema.find_node_at_offset_with_macros(original_file, offset); 484 },
485 }, 485 ast::BreakExpr(_it) => self.is_label_ref = true,
486 ast::BreakExpr(_it) => self.is_label_ref = true, 486 ast::ContinueExpr(_it) => self.is_label_ref = true,
487 ast::ContinueExpr(_it) => self.is_label_ref = true, 487 ast::Label(_it) => (),
488 ast::Label(_it) => (), 488 _ => self.lifetime_allowed = true,
489 _ => self.lifetime_allowed = true,
490 }
491 } 489 }
492 } 490 }
493 } 491 }