diff options
Diffstat (limited to 'crates/hir_ty/src/infer/expr.rs')
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 91 |
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 @@ | |||
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, 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,15 +15,16 @@ 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, 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 | ||
29 | use super::{ | 30 | use 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(¶meters), | 480 | .substitute(&Interner, ¶meters), |
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(¶meters), | 494 | .substitute(&Interner, ¶meters), |
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), |