diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-05-16 02:53:12 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2021-05-16 02:53:12 +0100 |
commit | a57bd59f351600c408ef9d2a4df3f2c10e817d0d (patch) | |
tree | 73af1b67227643ef4e8caa77ba50f2ad738ddd4e /crates/hir_ty/src/infer | |
parent | 92abc56bc928fb2a11b8f5b2a37e3c9ee31102d7 (diff) | |
parent | de0ed9860d86c3b905a967b1a7b5243499d32d67 (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.rs | 32 |
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 @@ | |||
3 | use std::iter::{repeat, repeat_with}; | 3 | use std::iter::{repeat, repeat_with}; |
4 | use std::{mem, sync::Arc}; | 4 | use std::{mem, sync::Arc}; |
5 | 5 | ||
6 | use chalk_ir::{cast::Cast, fold::Shift, ConstData, Mutability, TyVariableKind}; | 6 | use chalk_ir::{cast::Cast, fold::Shift, Mutability, TyVariableKind}; |
7 | use hir_def::{ | 7 | use 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; | |||
15 | use syntax::ast::RangeOp; | 15 | use syntax::ast::RangeOp; |
16 | 16 | ||
17 | use crate::{ | 17 | use 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), |