diff options
author | Aleksey Kladov <[email protected]> | 2019-08-07 14:14:22 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-08-07 14:14:22 +0100 |
commit | 6efc79b89d50b1b2ad9127afb2073bebe4b35290 (patch) | |
tree | c7209226fc680c545a02b0deb6da25c61a64500f | |
parent | 39967a85e1f04676062d46b04e7ac8399c57df66 (diff) |
implement while let desugaring
-rw-r--r-- | crates/ra_hir/src/expr.rs | 40 | ||||
-rw-r--r-- | crates/ra_hir/src/marks.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 20 | ||||
-rw-r--r-- | crates/ra_ide_api/src/inlay_hints.rs | 36 |
4 files changed, 76 insertions, 21 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index b59787a83..f33676655 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -11,17 +11,16 @@ use ra_syntax::{ | |||
11 | }, | 11 | }, |
12 | AstNode, AstPtr, SyntaxNodePtr, | 12 | AstNode, AstPtr, SyntaxNodePtr, |
13 | }; | 13 | }; |
14 | use test_utils::tested_by; | ||
14 | 15 | ||
15 | use crate::{ | 16 | use crate::{ |
16 | name::{AsName, SELF_PARAM}, | 17 | name::{AsName, SELF_PARAM}, |
18 | path::GenericArgs, | ||
19 | ty::primitive::{FloatTy, IntTy, UncertainFloatTy, UncertainIntTy}, | ||
17 | type_ref::{Mutability, TypeRef}, | 20 | type_ref::{Mutability, TypeRef}, |
18 | DefWithBody, Either, HasSource, HirDatabase, HirFileId, MacroCallLoc, MacroFileKind, Name, | 21 | DefWithBody, Either, HasSource, HirDatabase, HirFileId, MacroCallLoc, MacroFileKind, Name, |
19 | Path, Resolver, | 22 | Path, Resolver, |
20 | }; | 23 | }; |
21 | use crate::{ | ||
22 | path::GenericArgs, | ||
23 | ty::primitive::{FloatTy, IntTy, UncertainFloatTy, UncertainIntTy}, | ||
24 | }; | ||
25 | 24 | ||
26 | pub use self::scope::ExprScopes; | 25 | pub use self::scope::ExprScopes; |
27 | 26 | ||
@@ -603,17 +602,30 @@ where | |||
603 | self.alloc_expr(Expr::Loop { body }, syntax_ptr) | 602 | self.alloc_expr(Expr::Loop { body }, syntax_ptr) |
604 | } | 603 | } |
605 | ast::ExprKind::WhileExpr(e) => { | 604 | ast::ExprKind::WhileExpr(e) => { |
606 | let condition = if let Some(condition) = e.condition() { | ||
607 | if condition.pat().is_none() { | ||
608 | self.collect_expr_opt(condition.expr()) | ||
609 | } else { | ||
610 | // FIXME handle while let | ||
611 | return self.alloc_expr(Expr::Missing, syntax_ptr); | ||
612 | } | ||
613 | } else { | ||
614 | self.exprs.alloc(Expr::Missing) | ||
615 | }; | ||
616 | let body = self.collect_block_opt(e.loop_body()); | 605 | let body = self.collect_block_opt(e.loop_body()); |
606 | |||
607 | let condition = match e.condition() { | ||
608 | None => self.exprs.alloc(Expr::Missing), | ||
609 | Some(condition) => match condition.pat() { | ||
610 | None => self.collect_expr_opt(condition.expr()), | ||
611 | // if let -- desugar to match | ||
612 | Some(pat) => { | ||
613 | tested_by!(infer_while_let); | ||
614 | let pat = self.collect_pat(pat); | ||
615 | let match_expr = self.collect_expr_opt(condition.expr()); | ||
616 | let placeholder_pat = self.pats.alloc(Pat::Missing); | ||
617 | let break_ = self.exprs.alloc(Expr::Break { expr: None }); | ||
618 | let arms = vec![ | ||
619 | MatchArm { pats: vec![pat], expr: body, guard: None }, | ||
620 | MatchArm { pats: vec![placeholder_pat], expr: break_, guard: None }, | ||
621 | ]; | ||
622 | let match_expr = | ||
623 | self.exprs.alloc(Expr::Match { expr: match_expr, arms }); | ||
624 | return self.alloc_expr(Expr::Loop { body: match_expr }, syntax_ptr); | ||
625 | } | ||
626 | }, | ||
627 | }; | ||
628 | |||
617 | self.alloc_expr(Expr::While { condition, body }, syntax_ptr) | 629 | self.alloc_expr(Expr::While { condition, body }, syntax_ptr) |
618 | } | 630 | } |
619 | ast::ExprKind::ForExpr(e) => { | 631 | ast::ExprKind::ForExpr(e) => { |
diff --git a/crates/ra_hir/src/marks.rs b/crates/ra_hir/src/marks.rs index 2d831f0d8..5b15eee90 100644 --- a/crates/ra_hir/src/marks.rs +++ b/crates/ra_hir/src/marks.rs | |||
@@ -10,4 +10,5 @@ test_utils::marks!( | |||
10 | std_prelude | 10 | std_prelude |
11 | match_ergonomics_ref | 11 | match_ergonomics_ref |
12 | trait_resolution_on_fn_type | 12 | trait_resolution_on_fn_type |
13 | infer_while_let | ||
13 | ); | 14 | ); |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 36dea17a3..d5f7a4d25 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -145,6 +145,26 @@ mod collections { | |||
145 | } | 145 | } |
146 | 146 | ||
147 | #[test] | 147 | #[test] |
148 | fn infer_while_let() { | ||
149 | covers!(infer_while_let); | ||
150 | let (db, pos) = MockDatabase::with_position( | ||
151 | r#" | ||
152 | //- /main.rs | ||
153 | enum Option<T> { Some(T), None } | ||
154 | |||
155 | fn test() { | ||
156 | let foo: Option<f32> = None; | ||
157 | while let Option::Some(x) = foo { | ||
158 | <|>x | ||
159 | } | ||
160 | } | ||
161 | |||
162 | "#, | ||
163 | ); | ||
164 | assert_eq!("f32", type_at_pos(&db, pos)); | ||
165 | } | ||
166 | |||
167 | #[test] | ||
148 | fn infer_basics() { | 168 | fn infer_basics() { |
149 | assert_snapshot_matches!( | 169 | assert_snapshot_matches!( |
150 | infer(r#" | 170 | infer(r#" |
diff --git a/crates/ra_ide_api/src/inlay_hints.rs b/crates/ra_ide_api/src/inlay_hints.rs index 7b9190314..0b3c96d26 100644 --- a/crates/ra_ide_api/src/inlay_hints.rs +++ b/crates/ra_ide_api/src/inlay_hints.rs | |||
@@ -414,13 +414,35 @@ fn main() { | |||
414 | }"#, | 414 | }"#, |
415 | ); | 415 | ); |
416 | 416 | ||
417 | assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[ | 417 | assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r###" |
418 | InlayHint { | 418 | ⋮[ |
419 | range: [166; 170), | 419 | ⋮ InlayHint { |
420 | kind: TypeHint, | 420 | ⋮ range: [166; 170), |
421 | label: "CustomOption<Test>", | 421 | ⋮ kind: TypeHint, |
422 | }, | 422 | ⋮ label: "CustomOption<Test>", |
423 | ]"# | 423 | ⋮ }, |
424 | ⋮ InlayHint { | ||
425 | ⋮ range: [343; 347), | ||
426 | ⋮ kind: TypeHint, | ||
427 | ⋮ label: "&Test", | ||
428 | ⋮ }, | ||
429 | ⋮ InlayHint { | ||
430 | ⋮ range: [401; 402), | ||
431 | ⋮ kind: TypeHint, | ||
432 | ⋮ label: "&CustomOption<u32>", | ||
433 | ⋮ }, | ||
434 | ⋮ InlayHint { | ||
435 | ⋮ range: [404; 405), | ||
436 | ⋮ kind: TypeHint, | ||
437 | ⋮ label: "&u8", | ||
438 | ⋮ }, | ||
439 | ⋮ InlayHint { | ||
440 | ⋮ range: [549; 550), | ||
441 | ⋮ kind: TypeHint, | ||
442 | ⋮ label: "&u32", | ||
443 | ⋮ }, | ||
444 | ⋮] | ||
445 | "### | ||
424 | ); | 446 | ); |
425 | } | 447 | } |
426 | 448 | ||