aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty
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
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')
-rw-r--r--crates/hir_ty/src/infer/expr.rs22
-rw-r--r--crates/hir_ty/src/tests/coercion.rs2
2 files changed, 17 insertions, 7 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 };
diff --git a/crates/hir_ty/src/tests/coercion.rs b/crates/hir_ty/src/tests/coercion.rs
index c2afaf6ec..190471069 100644
--- a/crates/hir_ty/src/tests/coercion.rs
+++ b/crates/hir_ty/src/tests/coercion.rs
@@ -93,7 +93,7 @@ fn coerce_places() {
93 340..345 '[arr]': [&[u8]; 1] 93 340..345 '[arr]': [&[u8]; 1]
94 341..344 'arr': &[u8; 1] 94 341..344 'arr': &[u8; 1]
95 355..356 'f': [&[u8]; 2] 95 355..356 'f': [&[u8]; 2]
96 370..378 '[arr; 2]': [&[u8]; _] 96 370..378 '[arr; 2]': [&[u8]; 2]
97 371..374 'arr': &[u8; 1] 97 371..374 'arr': &[u8; 1]
98 376..377 '2': usize 98 376..377 '2': usize
99 388..389 'g': (&[u8], &[u8]) 99 388..389 'g': (&[u8], &[u8])