]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir_ty/src/infer/expr.rs
Address final feedback
[rust.git] / crates / hir_ty / src / infer / expr.rs
index ff564106b7dca46325ac5ba75903991d60b54c3e..b6b5a1b750c5c414b54a3f9e944532fa427d8bb0 100644 (file)
@@ -3,7 +3,7 @@
 use std::iter::{repeat, repeat_with};
 use std::{mem, sync::Arc};
 
-use chalk_ir::{cast::Cast, Mutability, TyVariableKind};
+use chalk_ir::{cast::Cast, fold::Shift, Mutability, TyVariableKind};
 use hir_def::{
     expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
     path::{GenericArg, GenericArgs},
 use syntax::ast::RangeOp;
 
 use crate::{
-    autoderef,
+    autoderef, consteval,
     lower::lower_to_chalk_mutability,
+    mapping::from_chalk,
     method_resolution, op,
     primitive::{self, UintTy},
-    to_chalk_trait_id,
-    traits::{chalk::from_chalk, FnTrait},
-    utils::{generics, variant_data, Generics},
+    static_lifetime, to_chalk_trait_id,
+    traits::FnTrait,
+    utils::{generics, Generics},
     AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner,
-    ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyKind, TypeWalk,
+    ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind,
 };
 
 use super::{
@@ -317,7 +318,13 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
                 self.normalize_associated_types_in(ret_ty)
             }
             Expr::MethodCall { receiver, args, method_name, generic_args } => self
-                .infer_method_call(tgt_expr, *receiver, &args, &method_name, generic_args.as_ref()),
+                .infer_method_call(
+                    tgt_expr,
+                    *receiver,
+                    &args,
+                    &method_name,
+                    generic_args.as_deref(),
+                ),
             Expr::Match { expr, arms } => {
                 let input_ty = self.infer_expr(*expr, &Expectation::none());
 
@@ -398,16 +405,19 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
                 TyKind::Never.intern(&Interner)
             }
             Expr::RecordLit { path, fields, spread } => {
-                let (ty, def_id) = self.resolve_variant(path.as_ref());
+                let (ty, def_id) = self.resolve_variant(path.as_deref());
                 if let Some(variant) = def_id {
                     self.write_variant_resolution(tgt_expr.into(), variant);
                 }
 
                 self.unify(&ty, &expected.ty);
 
-                let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
+                let substs = ty
+                    .as_adt()
+                    .map(|(_, s)| s.clone())
+                    .unwrap_or_else(|| Substitution::empty(&Interner));
                 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default();
-                let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it));
+                let variant_data = def_id.map(|it| it.variant_data(self.db.upcast()));
                 for field in fields.iter() {
                     let field_def =
                         variant_data.as_ref().and_then(|it| match it.field(&field.name) {
@@ -419,9 +429,6 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
                                 None
                             }
                         });
-                    if let Some(field_def) = field_def {
-                        self.result.record_field_resolutions.insert(field.expr, field_def);
-                    }
                     let field_ty = field_def.map_or(self.err_ty(), |it| {
                         field_types[it.local_id].clone().substitute(&Interner, &substs)
                     });
@@ -456,7 +463,11 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
                     };
                     match canonicalized.decanonicalize_ty(derefed_ty.value).kind(&Interner) {
                         TyKind::Tuple(_, substs) => name.as_tuple_index().and_then(|idx| {
-                            substs.interned().get(idx).map(|a| a.assert_ty_ref(&Interner)).cloned()
+                            substs
+                                .as_slice(&Interner)
+                                .get(idx)
+                                .map(|a| a.assert_ty_ref(&Interner))
+                                .cloned()
                         }),
                         TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => {
                             let local_id = self.db.struct_data(*s).variant_data.field(name)?;
@@ -527,7 +538,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
                 let inner_ty = self.infer_expr_inner(*expr, &expectation);
                 match rawness {
                     Rawness::RawPtr => TyKind::Raw(mutability, inner_ty),
-                    Rawness::Ref => TyKind::Ref(mutability, inner_ty),
+                    Rawness::Ref => TyKind::Ref(mutability, static_lifetime(), inner_ty),
                 }
                 .intern(&Interner)
             }
@@ -702,15 +713,16 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
             }
             Expr::Array(array) => {
                 let elem_ty = match expected.ty.kind(&Interner) {
-                    TyKind::Array(st) | TyKind::Slice(st) => st.clone(),
+                    TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(),
                     _ => self.table.new_type_var(),
                 };
 
-                match array {
+                let len = match array {
                     Array::ElementList(items) => {
                         for expr in items.iter() {
                             self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone()));
                         }
+                        Some(items.len() as u64)
                     }
                     Array::Repeat { initializer, repeat } => {
                         self.infer_expr_coerce(
@@ -723,20 +735,27 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
                                 TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner),
                             ),
                         );
+
+                        let repeat_expr = &self.body.exprs[*repeat];
+                        consteval::eval_usize(repeat_expr)
                     }
-                }
+                };
 
-                TyKind::Array(elem_ty).intern(&Interner)
+                TyKind::Array(elem_ty, consteval::usize_const(len)).intern(&Interner)
             }
             Expr::Literal(lit) => match lit {
                 Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
                 Literal::String(..) => {
-                    TyKind::Ref(Mutability::Not, TyKind::Str.intern(&Interner)).intern(&Interner)
+                    TyKind::Ref(Mutability::Not, static_lifetime(), TyKind::Str.intern(&Interner))
+                        .intern(&Interner)
                 }
-                Literal::ByteString(..) => {
+                Literal::ByteString(bs) => {
                     let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner);
-                    let array_type = TyKind::Array(byte_type).intern(&Interner);
-                    TyKind::Ref(Mutability::Not, array_type).intern(&Interner)
+
+                    let len = consteval::usize_const(Some(bs.len() as u64));
+
+                    let array_type = TyKind::Array(byte_type, len).intern(&Interner);
+                    TyKind::Ref(Mutability::Not, static_lifetime(), array_type).intern(&Interner)
                 }
                 Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner),
                 Literal::Int(_v, ty) => match ty {
@@ -796,7 +815,7 @@ fn infer_block(
                     let ty = self.resolve_ty_as_possible(ty);
                     self.infer_pat(*pat, &ty, BindingMode::default());
                 }
-                Statement::Expr(expr) => {
+                Statement::Expr { expr, .. } => {
                     self.infer_expr(*expr, &Expectation::none());
                 }
             }
@@ -872,7 +891,9 @@ fn infer_method_call(
         // Apply autoref so the below unification works correctly
         // FIXME: return correct autorefs from lookup_method
         let actual_receiver_ty = match expected_receiver_ty.as_reference() {
-            Some((_, mutability)) => TyKind::Ref(mutability, derefed_receiver_ty).intern(&Interner),
+            Some((_, lifetime, mutability)) => {
+                TyKind::Ref(mutability, lifetime, derefed_receiver_ty).intern(&Interner)
+            }
             _ => derefed_receiver_ty,
         };
         self.unify(&expected_receiver_ty, &actual_receiver_ty);