aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-05-16 02:53:12 +0100
committerGitHub <[email protected]>2021-05-16 02:53:12 +0100
commita57bd59f351600c408ef9d2a4df3f2c10e817d0d (patch)
tree73af1b67227643ef4e8caa77ba50f2ad738ddd4e /crates/hir_ty/src/infer
parent92abc56bc928fb2a11b8f5b2a37e3c9ee31102d7 (diff)
parentde0ed9860d86c3b905a967b1a7b5243499d32d67 (diff)
Merge #8813
8813: Get some more array lengths! r=lf- a=lf- This is built on #8799 and thus contains its changes. I'll rebase it onto master when that one gets merged. It adds support for r-a understanding the length of: * `let a: [u8; 2] = ...` * `let a = b"aaa"` * `let a = [0u8; 4]` I have added support for getting the values of byte strings, which was not previously there. I am least confident in the correctness of this part and it probably needs some more tests, as we currently have only one test that exercised that part (!). Fixes #2922. Co-authored-by: Jade <[email protected]>
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r--crates/hir_ty/src/infer/expr.rs32
1 files changed, 12 insertions, 20 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 2178ffd07..b6b5a1b75 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -3,7 +3,7 @@
3use std::iter::{repeat, repeat_with}; 3use std::iter::{repeat, repeat_with};
4use std::{mem, sync::Arc}; 4use std::{mem, sync::Arc};
5 5
6use chalk_ir::{cast::Cast, fold::Shift, ConstData, Mutability, TyVariableKind}; 6use chalk_ir::{cast::Cast, fold::Shift, Mutability, TyVariableKind};
7use hir_def::{ 7use hir_def::{
8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, 8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
9 path::{GenericArg, GenericArgs}, 9 path::{GenericArg, GenericArgs},
@@ -15,9 +15,7 @@ use stdx::always;
15use syntax::ast::RangeOp; 15use syntax::ast::RangeOp;
16 16
17use crate::{ 17use crate::{
18 autoderef, 18 autoderef, consteval,
19 consts::ConstScalar,
20 dummy_usize_const,
21 lower::lower_to_chalk_mutability, 19 lower::lower_to_chalk_mutability,
22 mapping::from_chalk, 20 mapping::from_chalk,
23 method_resolution, op, 21 method_resolution, op,
@@ -25,7 +23,7 @@ use crate::{
25 static_lifetime, to_chalk_trait_id, 23 static_lifetime, to_chalk_trait_id,
26 traits::FnTrait, 24 traits::FnTrait,
27 utils::{generics, Generics}, 25 utils::{generics, Generics},
28 AdtId, Binders, CallableDefId, ConstValue, FnPointer, FnSig, FnSubst, InEnvironment, Interner, 26 AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner,
29 ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind, 27 ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind,
30}; 28};
31 29
@@ -724,7 +722,7 @@ impl<'a> InferenceContext<'a> {
724 for expr in items.iter() { 722 for expr in items.iter() {
725 self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone())); 723 self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone()));
726 } 724 }
727 Some(items.len()) 725 Some(items.len() as u64)
728 } 726 }
729 Array::Repeat { initializer, repeat } => { 727 Array::Repeat { initializer, repeat } => {
730 self.infer_expr_coerce( 728 self.infer_expr_coerce(
@@ -737,20 +735,13 @@ impl<'a> InferenceContext<'a> {
737 TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner), 735 TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner),
738 ), 736 ),
739 ); 737 );
740 // FIXME: support length for Repeat array expressions 738
741 None 739 let repeat_expr = &self.body.exprs[*repeat];
740 consteval::eval_usize(repeat_expr)
742 } 741 }
743 }; 742 };
744 743
745 let cd = ConstData { 744 TyKind::Array(elem_ty, consteval::usize_const(len)).intern(&Interner)
746 ty: TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner),
747 value: ConstValue::Concrete(chalk_ir::ConcreteConst {
748 interned: len
749 .map(|len| ConstScalar::Usize(len as u64))
750 .unwrap_or(ConstScalar::Unknown),
751 }),
752 };
753 TyKind::Array(elem_ty, cd.intern(&Interner)).intern(&Interner)
754 } 745 }
755 Expr::Literal(lit) => match lit { 746 Expr::Literal(lit) => match lit {
756 Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), 747 Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
@@ -758,11 +749,12 @@ impl<'a> InferenceContext<'a> {
758 TyKind::Ref(Mutability::Not, static_lifetime(), TyKind::Str.intern(&Interner)) 749 TyKind::Ref(Mutability::Not, static_lifetime(), TyKind::Str.intern(&Interner))
759 .intern(&Interner) 750 .intern(&Interner)
760 } 751 }
761 Literal::ByteString(..) => { 752 Literal::ByteString(bs) => {
762 let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner); 753 let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner);
763 754
764 let array_type = 755 let len = consteval::usize_const(Some(bs.len() as u64));
765 TyKind::Array(byte_type, dummy_usize_const()).intern(&Interner); 756
757 let array_type = TyKind::Array(byte_type, len).intern(&Interner);
766 TyKind::Ref(Mutability::Not, static_lifetime(), array_type).intern(&Interner) 758 TyKind::Ref(Mutability::Not, static_lifetime(), array_type).intern(&Interner)
767 } 759 }
768 Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner), 760 Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner),