aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer
diff options
context:
space:
mode:
authorJade <[email protected]>2021-05-12 13:59:35 +0100
committerJade <[email protected]>2021-05-13 05:22:46 +0100
commite666589e63fd4de16baa5f1ebda4ab07aa5a5437 (patch)
tree0581e4a85c1f3b58a96111d8836386216f297354 /crates/hir_ty/src/infer
parent73023c0299d4adeada026648c3684621f129e038 (diff)
Add support for lengths in array repeats, if they are literals
Now we will get the type of `[0u8; 4]`.
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r--crates/hir_ty/src/infer/expr.rs22
1 files changed, 16 insertions, 6 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 46e4777a4..0b36ac861 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -1,10 +1,14 @@
1//! Type inference for expressions. 1//! Type inference for expressions.
2 2
3use std::iter::{repeat, repeat_with}; 3use std::{
4 convert::TryInto,
5 iter::{repeat, repeat_with},
6};
4use std::{mem, sync::Arc}; 7use std::{mem, sync::Arc};
5 8
6use chalk_ir::{cast::Cast, fold::Shift, ConstData, Mutability, TyVariableKind}; 9use chalk_ir::{cast::Cast, fold::Shift, ConstData, Mutability, TyVariableKind};
7use hir_def::{ 10use hir_def::{
11 builtin_type::BuiltinUint,
8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, 12 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
9 path::{GenericArg, GenericArgs}, 13 path::{GenericArg, GenericArgs},
10 resolver::resolver_for_expr, 14 resolver::resolver_for_expr,
@@ -724,7 +728,7 @@ impl<'a> InferenceContext<'a> {
724 for expr in items.iter() { 728 for expr in items.iter() {
725 self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone())); 729 self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone()));
726 } 730 }
727 Some(items.len()) 731 Some(items.len() as u64)
728 } 732 }
729 Array::Repeat { initializer, repeat } => { 733 Array::Repeat { initializer, repeat } => {
730 self.infer_expr_coerce( 734 self.infer_expr_coerce(
@@ -737,9 +741,15 @@ impl<'a> InferenceContext<'a> {
737 TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner), 741 TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner),
738 ), 742 ),
739 ); 743 );
740 // FIXME: we don't know the length here because hir Exprs don't actually 744
741 // get the value out of the AST, even though it is there. 745 let repeat_expr = &self.body.exprs[*repeat];
742 None 746 match repeat_expr {
747 Expr::Literal(Literal::Uint(v, None))
748 | Expr::Literal(Literal::Uint(v, Some(BuiltinUint::Usize))) => {
749 (*v).try_into().ok()
750 }
751 _ => None,
752 }
743 } 753 }
744 }; 754 };
745 755
@@ -747,7 +757,7 @@ impl<'a> InferenceContext<'a> {
747 ty: TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner), 757 ty: TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner),
748 value: ConstValue::Concrete(chalk_ir::ConcreteConst { 758 value: ConstValue::Concrete(chalk_ir::ConcreteConst {
749 interned: len 759 interned: len
750 .map(|len| ConstScalar::Usize(len as u64)) 760 .map(|len| ConstScalar::Usize(len))
751 .unwrap_or(ConstScalar::Unknown), 761 .unwrap_or(ConstScalar::Unknown),
752 }), 762 }),
753 }; 763 };