]> git.lizzy.rs Git - rust.git/commitdiff
Implement const pat inference
authorLukas Wirth <lukastw97@gmail.com>
Wed, 23 Dec 2020 11:15:38 +0000 (12:15 +0100)
committerLukas Wirth <lukastw97@gmail.com>
Wed, 23 Dec 2020 11:15:38 +0000 (12:15 +0100)
crates/hir_def/src/body/lower.rs
crates/hir_def/src/expr.rs
crates/hir_ty/src/infer/pat.rs
crates/hir_ty/src/tests/patterns.rs

index 978c3a32498c0ed51eea9ee06014e61c99a6daf3..4492a7d7734d09d67c9b9d6ca3ad49bca9faec65 100644 (file)
@@ -932,10 +932,16 @@ fn collect_pat(&mut self, pat: ast::Pat) -> PatId {
                 let inner = self.collect_pat_opt(boxpat.pat());
                 Pat::Box { inner }
             }
-            // FIXME: implement
-            ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) | ast::Pat::ConstBlockPat(_) => {
-                Pat::Missing
+            ast::Pat::ConstBlockPat(const_block_pat) => {
+                if let Some(expr) = const_block_pat.block_expr() {
+                    let expr_id = self.collect_block(expr);
+                    Pat::ConstBlock(expr_id)
+                } else {
+                    Pat::Missing
+                }
             }
+            // FIXME: implement
+            ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing,
         };
         let ptr = AstPtr::new(&pat);
         self.alloc_pat(pattern, Either::Left(ptr))
index e5d740a3653a46f861371ac995aa72b31b1107a9..b1e57c693186cc5b1fda5c6456547ae91c04148d 100644 (file)
@@ -399,12 +399,18 @@ pub enum Pat {
     TupleStruct { path: Option<Path>, args: Vec<PatId>, ellipsis: Option<usize> },
     Ref { pat: PatId, mutability: Mutability },
     Box { inner: PatId },
+    ConstBlock(ExprId),
 }
 
 impl Pat {
     pub fn walk_child_pats(&self, mut f: impl FnMut(PatId)) {
         match self {
-            Pat::Range { .. } | Pat::Lit(..) | Pat::Path(..) | Pat::Wild | Pat::Missing => {}
+            Pat::Range { .. }
+            | Pat::Lit(..)
+            | Pat::Path(..)
+            | Pat::ConstBlock(..)
+            | Pat::Wild
+            | Pat::Missing => {}
             Pat::Bind { subpat, .. } => {
                 subpat.iter().copied().for_each(f);
             }
index b70ec55eb5c50bf9a0f9b41b35981112933a623e..d974f805b5ba82ac3a7f8ae45d63fea52713d956 100644 (file)
@@ -243,6 +243,9 @@ pub(super) fn infer_pat(
                 }
                 None => Ty::Unknown,
             },
+            Pat::ConstBlock(expr) => {
+                self.infer_expr(*expr, &Expectation::has_type(expected.clone()))
+            }
             Pat::Missing => Ty::Unknown,
         };
         // use a new type variable if we got Ty::Unknown here
@@ -264,8 +267,9 @@ fn is_non_ref_pat(body: &hir_def::body::Body, pat: PatId) -> bool {
         | Pat::Range { .. }
         | Pat::Slice { .. } => true,
         Pat::Or(pats) => pats.iter().all(|p| is_non_ref_pat(body, *p)),
-        // FIXME: Path/Lit might actually evaluate to ref, but inference is unimplemented.
+        // FIXME: ConstBlock/Path/Lit might actually evaluate to ref, but inference is unimplemented.
         Pat::Path(..) => true,
+        Pat::ConstBlock(..) => true,
         Pat::Lit(expr) => match body[*expr] {
             Expr::Literal(Literal::String(..)) => false,
             _ => true,
index 5a5f48fd05b28a8234c5f335f368ef80f9847204..2053d8f56ee085bc933f16249c634a64ad8dc0d3 100644 (file)
@@ -774,3 +774,33 @@ fn foo(tuple: Tuple) {
         "#]],
     );
 }
+
+#[test]
+fn const_block_pattern() {
+    check_infer(
+        r#"
+struct Foo(usize);
+fn foo(foo: Foo) {
+    match foo {
+        const { Foo(15 + 32) } => {},
+        _ => {}
+    }
+}"#,
+        expect![[r#"
+            26..29 'foo': Foo
+            36..115 '{     ...   } }': ()
+            42..113 'match ...     }': ()
+            48..51 'foo': Foo
+            62..84 'const ... 32) }': Foo
+            68..84 '{ Foo(... 32) }': Foo
+            70..73 'Foo': Foo(usize) -> Foo
+            70..82 'Foo(15 + 32)': Foo
+            74..76 '15': usize
+            74..81 '15 + 32': usize
+            79..81 '32': usize
+            88..90 '{}': ()
+            100..101 '_': Foo
+            105..107 '{}': ()
+        "#]],
+    );
+}