diff options
author | Jade <[email protected]> | 2021-05-12 13:59:35 +0100 |
---|---|---|
committer | Jade <[email protected]> | 2021-05-13 05:22:46 +0100 |
commit | e666589e63fd4de16baa5f1ebda4ab07aa5a5437 (patch) | |
tree | 0581e4a85c1f3b58a96111d8836386216f297354 /crates/hir_ty/src/infer | |
parent | 73023c0299d4adeada026648c3684621f129e038 (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.rs | 22 |
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 | ||
3 | use std::iter::{repeat, repeat_with}; | 3 | use std::{ |
4 | convert::TryInto, | ||
5 | iter::{repeat, repeat_with}, | ||
6 | }; | ||
4 | use std::{mem, sync::Arc}; | 7 | use std::{mem, sync::Arc}; |
5 | 8 | ||
6 | use chalk_ir::{cast::Cast, fold::Shift, ConstData, Mutability, TyVariableKind}; | 9 | use chalk_ir::{cast::Cast, fold::Shift, ConstData, Mutability, TyVariableKind}; |
7 | use hir_def::{ | 10 | use 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 | }; |