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.rs102
1 files changed, 45 insertions, 57 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index dd3914ec3..c584a2c08 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -19,11 +19,11 @@ use crate::{
19 lower::lower_to_chalk_mutability, 19 lower::lower_to_chalk_mutability,
20 method_resolution, op, 20 method_resolution, op,
21 primitive::{self, UintTy}, 21 primitive::{self, UintTy},
22 to_assoc_type_id, to_chalk_trait_id, 22 to_chalk_trait_id,
23 traits::{chalk::from_chalk, FnTrait, InEnvironment}, 23 traits::{chalk::from_chalk, FnTrait, InEnvironment},
24 utils::{generics, variant_data, Generics}, 24 utils::{generics, variant_data, Generics},
25 AdtId, Binders, CallableDefId, DomainGoal, FnPointer, FnSig, Interner, Rawness, Scalar, 25 AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Rawness, Scalar, Substitution,
26 Substitution, TraitRef, Ty, TyKind, 26 TraitRef, Ty, TyBuilder, TyKind,
27}; 27};
28 28
29use super::{ 29use super::{
@@ -73,38 +73,33 @@ impl<'a> InferenceContext<'a> {
73 let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?; 73 let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?;
74 let output_assoc_type = 74 let output_assoc_type =
75 self.db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?; 75 self.db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?;
76 let generic_params = generics(self.db.upcast(), fn_once_trait.into());
77 if generic_params.len() != 2 {
78 return None;
79 }
80 76
81 let mut param_builder = Substitution::builder(num_args);
82 let mut arg_tys = vec![]; 77 let mut arg_tys = vec![];
83 for _ in 0..num_args { 78 let arg_ty = TyBuilder::tuple(num_args)
84 let arg = self.table.new_type_var(); 79 .fill(repeat_with(|| {
85 param_builder = param_builder.push(arg.clone()); 80 let arg = self.table.new_type_var();
86 arg_tys.push(arg); 81 arg_tys.push(arg.clone());
87 } 82 arg
88 let parameters = param_builder.build(); 83 }))
89 let arg_ty = TyKind::Tuple(num_args, parameters).intern(&Interner); 84 .build();
90 let substs = 85
91 Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 86 let projection = {
87 let b = TyBuilder::assoc_type_projection(self.db, output_assoc_type);
88 if b.remaining() != 2 {
89 return None;
90 }
91 b.push(ty.clone()).push(arg_ty).build()
92 };
92 93
93 let trait_env = self.trait_env.env.clone(); 94 let trait_env = self.trait_env.env.clone();
94 let implements_fn_trait: DomainGoal = 95 let obligation = InEnvironment {
95 TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() } 96 goal: projection.trait_ref(self.db).cast(&Interner),
96 .cast(&Interner);
97 let goal = self.canonicalizer().canonicalize_obligation(InEnvironment {
98 goal: implements_fn_trait.clone(),
99 environment: trait_env, 97 environment: trait_env,
100 }); 98 };
101 if self.db.trait_solve(krate, goal.value).is_some() { 99 let canonical = self.canonicalizer().canonicalize_obligation(obligation.clone());
102 self.push_obligation(implements_fn_trait); 100 if self.db.trait_solve(krate, canonical.value).is_some() {
103 let output_proj_ty = crate::ProjectionTy { 101 self.push_obligation(obligation.goal);
104 associated_ty_id: to_assoc_type_id(output_assoc_type), 102 let return_ty = self.normalize_projection_ty(projection);
105 substitution: substs,
106 };
107 let return_ty = self.normalize_projection_ty(output_proj_ty);
108 Some((arg_tys, return_ty)) 103 Some((arg_tys, return_ty))
109 } else { 104 } else {
110 None 105 None
@@ -138,7 +133,7 @@ impl<'a> InferenceContext<'a> {
138 both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe); 133 both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe);
139 let else_ty = match else_branch { 134 let else_ty = match else_branch {
140 Some(else_branch) => self.infer_expr_inner(*else_branch, &expected), 135 Some(else_branch) => self.infer_expr_inner(*else_branch, &expected),
141 None => Ty::unit(), 136 None => TyBuilder::unit(),
142 }; 137 };
143 both_arms_diverge &= self.diverges; 138 both_arms_diverge &= self.diverges;
144 139
@@ -193,7 +188,7 @@ impl<'a> InferenceContext<'a> {
193 break_ty: self.table.new_type_var(), 188 break_ty: self.table.new_type_var(),
194 label: label.map(|label| self.body[label].name.clone()), 189 label: label.map(|label| self.body[label].name.clone()),
195 }); 190 });
196 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 191 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
197 192
198 let ctxt = self.breakables.pop().expect("breakable stack broken"); 193 let ctxt = self.breakables.pop().expect("breakable stack broken");
199 if ctxt.may_break { 194 if ctxt.may_break {
@@ -217,11 +212,11 @@ impl<'a> InferenceContext<'a> {
217 *condition, 212 *condition,
218 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), 213 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)),
219 ); 214 );
220 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 215 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
221 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 216 let _ctxt = self.breakables.pop().expect("breakable stack broken");
222 // the body may not run, so it diverging doesn't mean we diverge 217 // the body may not run, so it diverging doesn't mean we diverge
223 self.diverges = Diverges::Maybe; 218 self.diverges = Diverges::Maybe;
224 Ty::unit() 219 TyBuilder::unit()
225 } 220 }
226 Expr::For { iterable, body, pat, label } => { 221 Expr::For { iterable, body, pat, label } => {
227 let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); 222 let iterable_ty = self.infer_expr(*iterable, &Expectation::none());
@@ -236,11 +231,11 @@ impl<'a> InferenceContext<'a> {
236 231
237 self.infer_pat(*pat, &pat_ty, BindingMode::default()); 232 self.infer_pat(*pat, &pat_ty, BindingMode::default());
238 233
239 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 234 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
240 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 235 let _ctxt = self.breakables.pop().expect("breakable stack broken");
241 // the body may not run, so it diverging doesn't mean we diverge 236 // the body may not run, so it diverging doesn't mean we diverge
242 self.diverges = Diverges::Maybe; 237 self.diverges = Diverges::Maybe;
243 Ty::unit() 238 TyBuilder::unit()
244 } 239 }
245 Expr::Lambda { body, args, ret_type, arg_types } => { 240 Expr::Lambda { body, args, ret_type, arg_types } => {
246 assert_eq!(args.len(), arg_types.len()); 241 assert_eq!(args.len(), arg_types.len());
@@ -360,7 +355,7 @@ impl<'a> InferenceContext<'a> {
360 let val_ty = if let Some(expr) = expr { 355 let val_ty = if let Some(expr) = expr {
361 self.infer_expr(*expr, &Expectation::none()) 356 self.infer_expr(*expr, &Expectation::none())
362 } else { 357 } else {
363 Ty::unit() 358 TyBuilder::unit()
364 }; 359 };
365 360
366 let last_ty = 361 let last_ty =
@@ -386,7 +381,7 @@ impl<'a> InferenceContext<'a> {
386 if let Some(expr) = expr { 381 if let Some(expr) = expr {
387 self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone())); 382 self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone()));
388 } else { 383 } else {
389 let unit = Ty::unit(); 384 let unit = TyBuilder::unit();
390 self.coerce(&unit, &self.return_ty.clone()); 385 self.coerce(&unit, &self.return_ty.clone());
391 } 386 }
392 TyKind::Never.intern(&Interner) 387 TyKind::Never.intern(&Interner)
@@ -539,17 +534,10 @@ impl<'a> InferenceContext<'a> {
539 Expr::Box { expr } => { 534 Expr::Box { expr } => {
540 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 535 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
541 if let Some(box_) = self.resolve_boxed_box() { 536 if let Some(box_) = self.resolve_boxed_box() {
542 let mut sb = 537 TyBuilder::adt(self.db, box_)
543 Substitution::build_for_generics(&generics(self.db.upcast(), box_.into())); 538 .push(inner_ty)
544 sb = sb.push(inner_ty); 539 .fill_with_defaults(self.db, || self.table.new_type_var())
545 match self.db.generic_defaults(box_.into()).get(1) { 540 .build()
546 Some(alloc_ty) if !alloc_ty.value.is_unknown() && sb.remaining() > 0 => {
547 sb = sb.push(alloc_ty.value.clone());
548 }
549 _ => (),
550 }
551 sb = sb.fill(repeat_with(|| self.table.new_type_var()));
552 Ty::adt_ty(box_, sb.build())
553 } else { 541 } else {
554 self.err_ty() 542 self.err_ty()
555 } 543 }
@@ -639,31 +627,31 @@ impl<'a> InferenceContext<'a> {
639 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); 627 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect));
640 match (range_type, lhs_ty, rhs_ty) { 628 match (range_type, lhs_ty, rhs_ty) {
641 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 629 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
642 Some(adt) => Ty::adt_ty(adt, Substitution::empty(&Interner)), 630 Some(adt) => TyBuilder::adt(self.db, adt).build(),
643 None => self.err_ty(), 631 None => self.err_ty(),
644 }, 632 },
645 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 633 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
646 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 634 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
647 None => self.err_ty(), 635 None => self.err_ty(),
648 }, 636 },
649 (RangeOp::Inclusive, None, Some(ty)) => { 637 (RangeOp::Inclusive, None, Some(ty)) => {
650 match self.resolve_range_to_inclusive() { 638 match self.resolve_range_to_inclusive() {
651 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 639 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
652 None => self.err_ty(), 640 None => self.err_ty(),
653 } 641 }
654 } 642 }
655 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { 643 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
656 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 644 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
657 None => self.err_ty(), 645 None => self.err_ty(),
658 }, 646 },
659 (RangeOp::Inclusive, Some(_), Some(ty)) => { 647 (RangeOp::Inclusive, Some(_), Some(ty)) => {
660 match self.resolve_range_inclusive() { 648 match self.resolve_range_inclusive() {
661 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 649 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
662 None => self.err_ty(), 650 None => self.err_ty(),
663 } 651 }
664 } 652 }
665 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { 653 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
666 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 654 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
667 None => self.err_ty(), 655 None => self.err_ty(),
668 }, 656 },
669 (RangeOp::Inclusive, _, None) => self.err_ty(), 657 (RangeOp::Inclusive, _, None) => self.err_ty(),
@@ -828,8 +816,8 @@ impl<'a> InferenceContext<'a> {
828 // we don't even make an attempt at coercion 816 // we don't even make an attempt at coercion
829 self.table.new_maybe_never_var() 817 self.table.new_maybe_never_var()
830 } else { 818 } else {
831 self.coerce(&Ty::unit(), &expected.coercion_target()); 819 self.coerce(&TyBuilder::unit(), &expected.coercion_target());
832 Ty::unit() 820 TyBuilder::unit()
833 } 821 }
834 }; 822 };
835 ty 823 ty