Add support for lengths in array repeats, if they are literals

Now we will get the type of `[0u8; 4]`.
This commit is contained in:
Jade 2021-05-12 05:59:35 -07:00
parent 73023c0299
commit e666589e63
4 changed files with 22 additions and 11 deletions

View file

@ -1006,16 +1006,17 @@ impl From<ast::BinOp> for BinaryOp {
impl From<ast::LiteralKind> for Literal { impl From<ast::LiteralKind> for Literal {
fn from(ast_lit_kind: ast::LiteralKind) -> Self { fn from(ast_lit_kind: ast::LiteralKind) -> Self {
match ast_lit_kind { match ast_lit_kind {
// FIXME: these should have actual values filled in, but unsure on perf impact
LiteralKind::IntNumber(lit) => { LiteralKind::IntNumber(lit) => {
if let builtin @ Some(_) = lit.suffix().and_then(BuiltinFloat::from_suffix) { if let builtin @ Some(_) = lit.suffix().and_then(BuiltinFloat::from_suffix) {
return Literal::Float(Default::default(), builtin); return Literal::Float(Default::default(), builtin);
} else if let builtin @ Some(_) = } else if let builtin @ Some(_) =
lit.suffix().and_then(|it| BuiltinInt::from_suffix(&it)) lit.suffix().and_then(|it| BuiltinInt::from_suffix(&it))
{ {
Literal::Int(Default::default(), builtin) Literal::Int(lit.value().unwrap_or(0) as i128, builtin)
} else { } else {
let builtin = lit.suffix().and_then(|it| BuiltinUint::from_suffix(&it)); let builtin = lit.suffix().and_then(|it| BuiltinUint::from_suffix(&it));
Literal::Uint(Default::default(), builtin) Literal::Uint(lit.value().unwrap_or(0), builtin)
} }
} }
LiteralKind::FloatNumber(lit) => { LiteralKind::FloatNumber(lit) => {

View file

@ -43,8 +43,8 @@ pub enum Literal {
ByteString(Vec<u8>), ByteString(Vec<u8>),
Char(char), Char(char),
Bool(bool), Bool(bool),
Int(u64, Option<BuiltinInt>), Int(i128, Option<BuiltinInt>),
Uint(u64, Option<BuiltinUint>), Uint(u128, Option<BuiltinUint>),
Float(u64, Option<BuiltinFloat>), // FIXME: f64 is not Eq Float(u64, Option<BuiltinFloat>), // FIXME: f64 is not Eq
} }

View file

@ -1,10 +1,14 @@
//! Type inference for expressions. //! Type inference for expressions.
use std::iter::{repeat, repeat_with}; use std::{
convert::TryInto,
iter::{repeat, repeat_with},
};
use std::{mem, sync::Arc}; use std::{mem, sync::Arc};
use chalk_ir::{cast::Cast, fold::Shift, ConstData, Mutability, TyVariableKind}; use chalk_ir::{cast::Cast, fold::Shift, ConstData, Mutability, TyVariableKind};
use hir_def::{ use hir_def::{
builtin_type::BuiltinUint,
expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
path::{GenericArg, GenericArgs}, path::{GenericArg, GenericArgs},
resolver::resolver_for_expr, resolver::resolver_for_expr,
@ -724,7 +728,7 @@ impl<'a> InferenceContext<'a> {
for expr in items.iter() { for expr in items.iter() {
self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone())); self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone()));
} }
Some(items.len()) Some(items.len() as u64)
} }
Array::Repeat { initializer, repeat } => { Array::Repeat { initializer, repeat } => {
self.infer_expr_coerce( self.infer_expr_coerce(
@ -737,9 +741,15 @@ impl<'a> InferenceContext<'a> {
TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner),
), ),
); );
// FIXME: we don't know the length here because hir Exprs don't actually
// get the value out of the AST, even though it is there. let repeat_expr = &self.body.exprs[*repeat];
None match repeat_expr {
Expr::Literal(Literal::Uint(v, None))
| Expr::Literal(Literal::Uint(v, Some(BuiltinUint::Usize))) => {
(*v).try_into().ok()
}
_ => None,
}
} }
}; };
@ -747,7 +757,7 @@ impl<'a> InferenceContext<'a> {
ty: TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner), ty: TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner),
value: ConstValue::Concrete(chalk_ir::ConcreteConst { value: ConstValue::Concrete(chalk_ir::ConcreteConst {
interned: len interned: len
.map(|len| ConstScalar::Usize(len as u64)) .map(|len| ConstScalar::Usize(len))
.unwrap_or(ConstScalar::Unknown), .unwrap_or(ConstScalar::Unknown),
}), }),
}; };

View file

@ -93,7 +93,7 @@ fn coerce_places() {
340..345 '[arr]': [&[u8]; 1] 340..345 '[arr]': [&[u8]; 1]
341..344 'arr': &[u8; 1] 341..344 'arr': &[u8; 1]
355..356 'f': [&[u8]; 2] 355..356 'f': [&[u8]; 2]
370..378 '[arr; 2]': [&[u8]; _] 370..378 '[arr; 2]': [&[u8]; 2]
371..374 'arr': &[u8; 1] 371..374 'arr': &[u8; 1]
376..377 '2': usize 376..377 '2': usize
388..389 'g': (&[u8], &[u8]) 388..389 'g': (&[u8], &[u8])