aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer/expr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/infer/expr.rs')
-rw-r--r--crates/hir_ty/src/infer/expr.rs91
1 files changed, 55 insertions, 36 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index c584a2c08..50497eecb 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, 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,15 +15,16 @@ use stdx::always;
15use syntax::ast::RangeOp; 15use syntax::ast::RangeOp;
16 16
17use crate::{ 17use crate::{
18 autoderef, 18 autoderef, dummy_usize_const,
19 lower::lower_to_chalk_mutability, 19 lower::lower_to_chalk_mutability,
20 mapping::from_chalk,
20 method_resolution, op, 21 method_resolution, op,
21 primitive::{self, UintTy}, 22 primitive::{self, UintTy},
22 to_chalk_trait_id, 23 static_lifetime, to_chalk_trait_id,
23 traits::{chalk::from_chalk, FnTrait, InEnvironment}, 24 traits::FnTrait,
24 utils::{generics, variant_data, Generics}, 25 utils::{generics, Generics},
25 AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Rawness, Scalar, Substitution, 26 AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner,
26 TraitRef, Ty, TyBuilder, TyKind, 27 ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind,
27}; 28};
28 29
29use super::{ 30use super::{
@@ -180,7 +181,8 @@ impl<'a> InferenceContext<'a> {
180 let inner_ty = self.infer_expr(*body, &Expectation::none()); 181 let inner_ty = self.infer_expr(*body, &Expectation::none());
181 let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body); 182 let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body);
182 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into(); 183 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
183 TyKind::OpaqueType(opaque_ty_id, Substitution::single(inner_ty)).intern(&Interner) 184 TyKind::OpaqueType(opaque_ty_id, Substitution::from1(&Interner, inner_ty))
185 .intern(&Interner)
184 } 186 }
185 Expr::Loop { body, label } => { 187 Expr::Loop { body, label } => {
186 self.breakables.push(BreakableContext { 188 self.breakables.push(BreakableContext {
@@ -259,14 +261,17 @@ impl<'a> InferenceContext<'a> {
259 }; 261 };
260 sig_tys.push(ret_ty.clone()); 262 sig_tys.push(ret_ty.clone());
261 let sig_ty = TyKind::Function(FnPointer { 263 let sig_ty = TyKind::Function(FnPointer {
262 num_args: sig_tys.len() - 1, 264 num_binders: 0,
263 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, 265 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
264 substs: Substitution::from_iter(&Interner, sig_tys.clone()), 266 substitution: FnSubst(
267 Substitution::from_iter(&Interner, sig_tys.clone()).shifted_in(&Interner),
268 ),
265 }) 269 })
266 .intern(&Interner); 270 .intern(&Interner);
267 let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into(); 271 let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into();
268 let closure_ty = 272 let closure_ty =
269 TyKind::Closure(closure_id, Substitution::single(sig_ty)).intern(&Interner); 273 TyKind::Closure(closure_id, Substitution::from1(&Interner, sig_ty))
274 .intern(&Interner);
270 275
271 // Eagerly try to relate the closure type with the expected 276 // Eagerly try to relate the closure type with the expected
272 // type, otherwise we often won't have enough information to 277 // type, otherwise we often won't have enough information to
@@ -313,7 +318,13 @@ impl<'a> InferenceContext<'a> {
313 self.normalize_associated_types_in(ret_ty) 318 self.normalize_associated_types_in(ret_ty)
314 } 319 }
315 Expr::MethodCall { receiver, args, method_name, generic_args } => self 320 Expr::MethodCall { receiver, args, method_name, generic_args } => self
316 .infer_method_call(tgt_expr, *receiver, &args, &method_name, generic_args.as_ref()), 321 .infer_method_call(
322 tgt_expr,
323 *receiver,
324 &args,
325 &method_name,
326 generic_args.as_deref(),
327 ),
317 Expr::Match { expr, arms } => { 328 Expr::Match { expr, arms } => {
318 let input_ty = self.infer_expr(*expr, &Expectation::none()); 329 let input_ty = self.infer_expr(*expr, &Expectation::none());
319 330
@@ -394,16 +405,19 @@ impl<'a> InferenceContext<'a> {
394 TyKind::Never.intern(&Interner) 405 TyKind::Never.intern(&Interner)
395 } 406 }
396 Expr::RecordLit { path, fields, spread } => { 407 Expr::RecordLit { path, fields, spread } => {
397 let (ty, def_id) = self.resolve_variant(path.as_ref()); 408 let (ty, def_id) = self.resolve_variant(path.as_deref());
398 if let Some(variant) = def_id { 409 if let Some(variant) = def_id {
399 self.write_variant_resolution(tgt_expr.into(), variant); 410 self.write_variant_resolution(tgt_expr.into(), variant);
400 } 411 }
401 412
402 self.unify(&ty, &expected.ty); 413 self.unify(&ty, &expected.ty);
403 414
404 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner)); 415 let substs = ty
416 .as_adt()
417 .map(|(_, s)| s.clone())
418 .unwrap_or_else(|| Substitution::empty(&Interner));
405 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); 419 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default();
406 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); 420 let variant_data = def_id.map(|it| it.variant_data(self.db.upcast()));
407 for field in fields.iter() { 421 for field in fields.iter() {
408 let field_def = 422 let field_def =
409 variant_data.as_ref().and_then(|it| match it.field(&field.name) { 423 variant_data.as_ref().and_then(|it| match it.field(&field.name) {
@@ -415,11 +429,8 @@ impl<'a> InferenceContext<'a> {
415 None 429 None
416 } 430 }
417 }); 431 });
418 if let Some(field_def) = field_def {
419 self.result.record_field_resolutions.insert(field.expr, field_def);
420 }
421 let field_ty = field_def.map_or(self.err_ty(), |it| { 432 let field_ty = field_def.map_or(self.err_ty(), |it| {
422 field_types[it.local_id].clone().subst(&substs) 433 field_types[it.local_id].clone().substitute(&Interner, &substs)
423 }); 434 });
424 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); 435 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
425 } 436 }
@@ -453,7 +464,7 @@ impl<'a> InferenceContext<'a> {
453 match canonicalized.decanonicalize_ty(derefed_ty.value).kind(&Interner) { 464 match canonicalized.decanonicalize_ty(derefed_ty.value).kind(&Interner) {
454 TyKind::Tuple(_, substs) => name.as_tuple_index().and_then(|idx| { 465 TyKind::Tuple(_, substs) => name.as_tuple_index().and_then(|idx| {
455 substs 466 substs
456 .interned(&Interner) 467 .as_slice(&Interner)
457 .get(idx) 468 .get(idx)
458 .map(|a| a.assert_ty_ref(&Interner)) 469 .map(|a| a.assert_ty_ref(&Interner))
459 .cloned() 470 .cloned()
@@ -466,7 +477,7 @@ impl<'a> InferenceContext<'a> {
466 Some( 477 Some(
467 self.db.field_types((*s).into())[field.local_id] 478 self.db.field_types((*s).into())[field.local_id]
468 .clone() 479 .clone()
469 .subst(&parameters), 480 .substitute(&Interner, &parameters),
470 ) 481 )
471 } else { 482 } else {
472 None 483 None
@@ -480,7 +491,7 @@ impl<'a> InferenceContext<'a> {
480 Some( 491 Some(
481 self.db.field_types((*u).into())[field.local_id] 492 self.db.field_types((*u).into())[field.local_id]
482 .clone() 493 .clone()
483 .subst(&parameters), 494 .substitute(&Interner, &parameters),
484 ) 495 )
485 } else { 496 } else {
486 None 497 None
@@ -527,7 +538,7 @@ impl<'a> InferenceContext<'a> {
527 let inner_ty = self.infer_expr_inner(*expr, &expectation); 538 let inner_ty = self.infer_expr_inner(*expr, &expectation);
528 match rawness { 539 match rawness {
529 Rawness::RawPtr => TyKind::Raw(mutability, inner_ty), 540 Rawness::RawPtr => TyKind::Raw(mutability, inner_ty),
530 Rawness::Ref => TyKind::Ref(mutability, inner_ty), 541 Rawness::Ref => TyKind::Ref(mutability, static_lifetime(), inner_ty),
531 } 542 }
532 .intern(&Interner) 543 .intern(&Interner)
533 } 544 }
@@ -702,7 +713,7 @@ impl<'a> InferenceContext<'a> {
702 } 713 }
703 Expr::Array(array) => { 714 Expr::Array(array) => {
704 let elem_ty = match expected.ty.kind(&Interner) { 715 let elem_ty = match expected.ty.kind(&Interner) {
705 TyKind::Array(st) | TyKind::Slice(st) => st.clone(), 716 TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(),
706 _ => self.table.new_type_var(), 717 _ => self.table.new_type_var(),
707 }; 718 };
708 719
@@ -726,17 +737,19 @@ impl<'a> InferenceContext<'a> {
726 } 737 }
727 } 738 }
728 739
729 TyKind::Array(elem_ty).intern(&Interner) 740 TyKind::Array(elem_ty, dummy_usize_const()).intern(&Interner)
730 } 741 }
731 Expr::Literal(lit) => match lit { 742 Expr::Literal(lit) => match lit {
732 Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), 743 Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
733 Literal::String(..) => { 744 Literal::String(..) => {
734 TyKind::Ref(Mutability::Not, TyKind::Str.intern(&Interner)).intern(&Interner) 745 TyKind::Ref(Mutability::Not, static_lifetime(), TyKind::Str.intern(&Interner))
746 .intern(&Interner)
735 } 747 }
736 Literal::ByteString(..) => { 748 Literal::ByteString(..) => {
737 let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner); 749 let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner);
738 let array_type = TyKind::Array(byte_type).intern(&Interner); 750 let array_type =
739 TyKind::Ref(Mutability::Not, array_type).intern(&Interner) 751 TyKind::Array(byte_type, dummy_usize_const()).intern(&Interner);
752 TyKind::Ref(Mutability::Not, static_lifetime(), array_type).intern(&Interner)
740 } 753 }
741 Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner), 754 Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner),
742 Literal::Int(_v, ty) => match ty { 755 Literal::Int(_v, ty) => match ty {
@@ -853,10 +866,10 @@ impl<'a> InferenceContext<'a> {
853 self.write_method_resolution(tgt_expr, func); 866 self.write_method_resolution(tgt_expr, func);
854 (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) 867 (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into())))
855 } 868 }
856 None => (receiver_ty, Binders::new(0, self.err_ty()), None), 869 None => (receiver_ty, Binders::empty(&Interner, self.err_ty()), None),
857 }; 870 };
858 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); 871 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty);
859 let method_ty = method_ty.subst(&substs); 872 let method_ty = method_ty.substitute(&Interner, &substs);
860 let method_ty = self.insert_type_vars(method_ty); 873 let method_ty = self.insert_type_vars(method_ty);
861 self.register_obligations_for_call(&method_ty); 874 self.register_obligations_for_call(&method_ty);
862 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) { 875 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) {
@@ -872,7 +885,9 @@ impl<'a> InferenceContext<'a> {
872 // Apply autoref so the below unification works correctly 885 // Apply autoref so the below unification works correctly
873 // FIXME: return correct autorefs from lookup_method 886 // FIXME: return correct autorefs from lookup_method
874 let actual_receiver_ty = match expected_receiver_ty.as_reference() { 887 let actual_receiver_ty = match expected_receiver_ty.as_reference() {
875 Some((_, mutability)) => TyKind::Ref(mutability, derefed_receiver_ty).intern(&Interner), 888 Some((_, lifetime, mutability)) => {
889 TyKind::Ref(mutability, lifetime, derefed_receiver_ty).intern(&Interner)
890 }
876 _ => derefed_receiver_ty, 891 _ => derefed_receiver_ty,
877 }; 892 };
878 self.unify(&expected_receiver_ty, &actual_receiver_ty); 893 self.unify(&expected_receiver_ty, &actual_receiver_ty);
@@ -953,9 +968,11 @@ impl<'a> InferenceContext<'a> {
953 let def: CallableDefId = from_chalk(self.db, *fn_def); 968 let def: CallableDefId = from_chalk(self.db, *fn_def);
954 let generic_predicates = self.db.generic_predicates(def.into()); 969 let generic_predicates = self.db.generic_predicates(def.into());
955 for predicate in generic_predicates.iter() { 970 for predicate in generic_predicates.iter() {
956 let (predicate, binders) = 971 let (predicate, binders) = predicate
957 predicate.clone().subst(parameters).into_value_and_skipped_binders(); 972 .clone()
958 always!(binders == 0); // quantified where clauses not yet handled 973 .substitute(&Interner, parameters)
974 .into_value_and_skipped_binders();
975 always!(binders.len(&Interner) == 0); // quantified where clauses not yet handled
959 self.push_obligation(predicate.cast(&Interner)); 976 self.push_obligation(predicate.cast(&Interner));
960 } 977 }
961 // add obligation for trait implementation, if this is a trait method 978 // add obligation for trait implementation, if this is a trait method
@@ -964,8 +981,10 @@ impl<'a> InferenceContext<'a> {
964 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container 981 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container
965 { 982 {
966 // construct a TraitRef 983 // construct a TraitRef
967 let substs = 984 let substs = crate::subst_prefix(
968 parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); 985 &*parameters,
986 generics(self.db.upcast(), trait_.into()).len(),
987 );
969 self.push_obligation( 988 self.push_obligation(
970 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs } 989 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }
971 .cast(&Interner), 990 .cast(&Interner),