aboutsummaryrefslogtreecommitdiff
path: root/crates
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
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')
-rw-r--r--crates/hir_def/src/body/lower.rs5
-rw-r--r--crates/hir_def/src/expr.rs4
-rw-r--r--crates/hir_ty/src/infer/expr.rs22
-rw-r--r--crates/hir_ty/src/tests/coercion.rs2
4 files changed, 22 insertions, 11 deletions
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index b00dcbdf0..2a7e0205f 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -1006,16 +1006,17 @@ impl From<ast::BinOp> for BinaryOp {
1006impl From<ast::LiteralKind> for Literal { 1006impl From<ast::LiteralKind> for Literal {
1007 fn from(ast_lit_kind: ast::LiteralKind) -> Self { 1007 fn from(ast_lit_kind: ast::LiteralKind) -> Self {
1008 match ast_lit_kind { 1008 match ast_lit_kind {
1009 // FIXME: these should have actual values filled in, but unsure on perf impact
1009 LiteralKind::IntNumber(lit) => { 1010 LiteralKind::IntNumber(lit) => {
1010 if let builtin @ Some(_) = lit.suffix().and_then(BuiltinFloat::from_suffix) { 1011 if let builtin @ Some(_) = lit.suffix().and_then(BuiltinFloat::from_suffix) {
1011 return Literal::Float(Default::default(), builtin); 1012 return Literal::Float(Default::default(), builtin);
1012 } else if let builtin @ Some(_) = 1013 } else if let builtin @ Some(_) =
1013 lit.suffix().and_then(|it| BuiltinInt::from_suffix(&it)) 1014 lit.suffix().and_then(|it| BuiltinInt::from_suffix(&it))
1014 { 1015 {
1015 Literal::Int(Default::default(), builtin) 1016 Literal::Int(lit.value().unwrap_or(0) as i128, builtin)
1016 } else { 1017 } else {
1017 let builtin = lit.suffix().and_then(|it| BuiltinUint::from_suffix(&it)); 1018 let builtin = lit.suffix().and_then(|it| BuiltinUint::from_suffix(&it));
1018 Literal::Uint(Default::default(), builtin) 1019 Literal::Uint(lit.value().unwrap_or(0), builtin)
1019 } 1020 }
1020 } 1021 }
1021 LiteralKind::FloatNumber(lit) => { 1022 LiteralKind::FloatNumber(lit) => {
diff --git a/crates/hir_def/src/expr.rs b/crates/hir_def/src/expr.rs
index 0c3b41080..2ba619d23 100644
--- a/crates/hir_def/src/expr.rs
+++ b/crates/hir_def/src/expr.rs
@@ -43,8 +43,8 @@ pub enum Literal {
43 ByteString(Vec<u8>), 43 ByteString(Vec<u8>),
44 Char(char), 44 Char(char),
45 Bool(bool), 45 Bool(bool),
46 Int(u64, Option<BuiltinInt>), 46 Int(i128, Option<BuiltinInt>),
47 Uint(u64, Option<BuiltinUint>), 47 Uint(u128, Option<BuiltinUint>),
48 Float(u64, Option<BuiltinFloat>), // FIXME: f64 is not Eq 48 Float(u64, Option<BuiltinFloat>), // FIXME: f64 is not Eq
49} 49}
50 50
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])