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::{
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());
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) {
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)
});
};
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)?;
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)
}
}
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(
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 {
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());
}
}
// 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);