aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/hir_ty/src/infer/expr.rs54
-rw-r--r--crates/hir_ty/src/lib.rs4
2 files changed, 25 insertions, 33 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 5eb07126e..9f5624eb0 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, TyBuilder, TyKind, 26 TraitRef, Ty, TyBuilder, TyKind,
27}; 27};
28 28
29use super::{ 29use super::{
@@ -73,38 +73,34 @@ 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 parameters = Substitution::builder(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 }))
84 .build();
89 let arg_ty = TyKind::Tuple(num_args, parameters).intern(&Interner); 85 let arg_ty = TyKind::Tuple(num_args, parameters).intern(&Interner);
90 let substs = 86
91 Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 87 let projection = {
88 let b = TyBuilder::assoc_type_projection(self.db, output_assoc_type);
89 if b.remaining() != 2 {
90 return None;
91 }
92 b.push(ty.clone()).push(arg_ty).build()
93 };
92 94
93 let trait_env = self.trait_env.env.clone(); 95 let trait_env = self.trait_env.env.clone();
94 let implements_fn_trait: DomainGoal = 96 let obligation = InEnvironment {
95 TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() } 97 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, 98 environment: trait_env,
100 }); 99 };
101 if self.db.trait_solve(krate, goal.value).is_some() { 100 let canonical = self.canonicalizer().canonicalize_obligation(obligation.clone());
102 self.push_obligation(implements_fn_trait); 101 if self.db.trait_solve(krate, canonical.value).is_some() {
103 let output_proj_ty = crate::ProjectionTy { 102 self.push_obligation(obligation.goal);
104 associated_ty_id: to_assoc_type_id(output_assoc_type), 103 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)) 104 Some((arg_tys, return_ty))
109 } else { 105 } else {
110 None 106 None
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 75bf8bcd9..b37566958 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -493,10 +493,6 @@ impl Substitution {
493 ) 493 )
494 } 494 }
495 495
496 pub(crate) fn build_for_generics(generic_params: &Generics) -> SubstsBuilder {
497 Substitution::builder(generic_params.len())
498 }
499
500 fn builder(param_count: usize) -> SubstsBuilder { 496 fn builder(param_count: usize) -> SubstsBuilder {
501 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } 497 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count }
502 } 498 }