implement while let desugaring
This commit is contained in:
parent
39967a85e1
commit
6efc79b89d
@ -11,17 +11,16 @@ use ra_syntax::{
|
||||
},
|
||||
AstNode, AstPtr, SyntaxNodePtr,
|
||||
};
|
||||
use test_utils::tested_by;
|
||||
|
||||
use crate::{
|
||||
name::{AsName, SELF_PARAM},
|
||||
path::GenericArgs,
|
||||
ty::primitive::{FloatTy, IntTy, UncertainFloatTy, UncertainIntTy},
|
||||
type_ref::{Mutability, TypeRef},
|
||||
DefWithBody, Either, HasSource, HirDatabase, HirFileId, MacroCallLoc, MacroFileKind, Name,
|
||||
Path, Resolver,
|
||||
};
|
||||
use crate::{
|
||||
path::GenericArgs,
|
||||
ty::primitive::{FloatTy, IntTy, UncertainFloatTy, UncertainIntTy},
|
||||
};
|
||||
|
||||
pub use self::scope::ExprScopes;
|
||||
|
||||
@ -603,17 +602,30 @@ where
|
||||
self.alloc_expr(Expr::Loop { body }, syntax_ptr)
|
||||
}
|
||||
ast::ExprKind::WhileExpr(e) => {
|
||||
let condition = if let Some(condition) = e.condition() {
|
||||
if condition.pat().is_none() {
|
||||
self.collect_expr_opt(condition.expr())
|
||||
} else {
|
||||
// FIXME handle while let
|
||||
return self.alloc_expr(Expr::Missing, syntax_ptr);
|
||||
}
|
||||
} else {
|
||||
self.exprs.alloc(Expr::Missing)
|
||||
};
|
||||
let body = self.collect_block_opt(e.loop_body());
|
||||
|
||||
let condition = match e.condition() {
|
||||
None => self.exprs.alloc(Expr::Missing),
|
||||
Some(condition) => match condition.pat() {
|
||||
None => self.collect_expr_opt(condition.expr()),
|
||||
// if let -- desugar to match
|
||||
Some(pat) => {
|
||||
tested_by!(infer_while_let);
|
||||
let pat = self.collect_pat(pat);
|
||||
let match_expr = self.collect_expr_opt(condition.expr());
|
||||
let placeholder_pat = self.pats.alloc(Pat::Missing);
|
||||
let break_ = self.exprs.alloc(Expr::Break { expr: None });
|
||||
let arms = vec![
|
||||
MatchArm { pats: vec![pat], expr: body, guard: None },
|
||||
MatchArm { pats: vec![placeholder_pat], expr: break_, guard: None },
|
||||
];
|
||||
let match_expr =
|
||||
self.exprs.alloc(Expr::Match { expr: match_expr, arms });
|
||||
return self.alloc_expr(Expr::Loop { body: match_expr }, syntax_ptr);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
self.alloc_expr(Expr::While { condition, body }, syntax_ptr)
|
||||
}
|
||||
ast::ExprKind::ForExpr(e) => {
|
||||
|
@ -10,4 +10,5 @@ test_utils::marks!(
|
||||
std_prelude
|
||||
match_ergonomics_ref
|
||||
trait_resolution_on_fn_type
|
||||
infer_while_let
|
||||
);
|
||||
|
@ -144,6 +144,26 @@ mod collections {
|
||||
assert_eq!("&str", type_at_pos(&db, pos));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_while_let() {
|
||||
covers!(infer_while_let);
|
||||
let (db, pos) = MockDatabase::with_position(
|
||||
r#"
|
||||
//- /main.rs
|
||||
enum Option<T> { Some(T), None }
|
||||
|
||||
fn test() {
|
||||
let foo: Option<f32> = None;
|
||||
while let Option::Some(x) = foo {
|
||||
<|>x
|
||||
}
|
||||
}
|
||||
|
||||
"#,
|
||||
);
|
||||
assert_eq!("f32", type_at_pos(&db, pos));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_basics() {
|
||||
assert_snapshot_matches!(
|
||||
|
@ -414,13 +414,35 @@ fn main() {
|
||||
}"#,
|
||||
);
|
||||
|
||||
assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[
|
||||
InlayHint {
|
||||
range: [166; 170),
|
||||
kind: TypeHint,
|
||||
label: "CustomOption<Test>",
|
||||
},
|
||||
]"#
|
||||
assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r###"
|
||||
⋮[
|
||||
⋮ InlayHint {
|
||||
⋮ range: [166; 170),
|
||||
⋮ kind: TypeHint,
|
||||
⋮ label: "CustomOption<Test>",
|
||||
⋮ },
|
||||
⋮ InlayHint {
|
||||
⋮ range: [343; 347),
|
||||
⋮ kind: TypeHint,
|
||||
⋮ label: "&Test",
|
||||
⋮ },
|
||||
⋮ InlayHint {
|
||||
⋮ range: [401; 402),
|
||||
⋮ kind: TypeHint,
|
||||
⋮ label: "&CustomOption<u32>",
|
||||
⋮ },
|
||||
⋮ InlayHint {
|
||||
⋮ range: [404; 405),
|
||||
⋮ kind: TypeHint,
|
||||
⋮ label: "&u8",
|
||||
⋮ },
|
||||
⋮ InlayHint {
|
||||
⋮ range: [549; 550),
|
||||
⋮ kind: TypeHint,
|
||||
⋮ label: "&u32",
|
||||
⋮ },
|
||||
⋮]
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user