diff options
Diffstat (limited to 'crates/ra_hir_ty/src/infer')
-rw-r--r-- | crates/ra_hir_ty/src/infer/expr.rs | 77 |
1 files changed, 36 insertions, 41 deletions
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index 171330274..a9565a58d 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs | |||
@@ -15,7 +15,7 @@ use ra_syntax::ast::RangeOp; | |||
15 | 15 | ||
16 | use crate::{ | 16 | use crate::{ |
17 | autoderef, method_resolution, op, | 17 | autoderef, method_resolution, op, |
18 | traits::{FnTrait, Guidance, InEnvironment, SolutionVariables}, | 18 | traits::{FnTrait, InEnvironment}, |
19 | utils::{generics, variant_data, Generics}, | 19 | utils::{generics, variant_data, Generics}, |
20 | ApplicationTy, Binders, CallableDef, InferTy, IntTy, Mutability, Obligation, Rawness, Substs, | 20 | ApplicationTy, Binders, CallableDef, InferTy, IntTy, Mutability, Obligation, Rawness, Substs, |
21 | TraitRef, Ty, TypeCtor, | 21 | TraitRef, Ty, TypeCtor, |
@@ -23,7 +23,7 @@ use crate::{ | |||
23 | 23 | ||
24 | use super::{ | 24 | use super::{ |
25 | find_breakable, BindingMode, BreakableContext, Diverges, Expectation, InferenceContext, | 25 | find_breakable, BindingMode, BreakableContext, Diverges, Expectation, InferenceContext, |
26 | InferenceDiagnostic, Solution, TypeMismatch, | 26 | InferenceDiagnostic, TypeMismatch, |
27 | }; | 27 | }; |
28 | 28 | ||
29 | impl<'a> InferenceContext<'a> { | 29 | impl<'a> InferenceContext<'a> { |
@@ -65,52 +65,47 @@ impl<'a> InferenceContext<'a> { | |||
65 | 65 | ||
66 | fn callable_sig_from_fn_trait(&mut self, ty: &Ty, num_args: usize) -> Option<(Vec<Ty>, Ty)> { | 66 | fn callable_sig_from_fn_trait(&mut self, ty: &Ty, num_args: usize) -> Option<(Vec<Ty>, Ty)> { |
67 | let krate = self.resolver.krate()?; | 67 | let krate = self.resolver.krate()?; |
68 | let fn_traits: Vec<crate::TraitId> = [FnTrait::FnOnce, FnTrait::FnMut, FnTrait::Fn] | ||
69 | .iter() | ||
70 | .filter_map(|f| f.get_id(self.db, krate)) | ||
71 | .collect(); | ||
72 | let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?; | 68 | let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?; |
73 | let output_assoc_type = | 69 | let output_assoc_type = |
74 | self.db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?; | 70 | self.db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?; |
75 | for fn_trait in fn_traits { | 71 | let generic_params = generics(self.db.upcast(), fn_once_trait.into()); |
76 | let generic_params = generics(self.db.upcast(), fn_trait.into()); | 72 | if generic_params.len() != 2 { |
77 | if generic_params.len() != 2 { | 73 | return None; |
78 | continue; | 74 | } |
79 | } | 75 | |
80 | 76 | let mut param_builder = Substs::builder(num_args); | |
81 | let mut param_builder = Substs::builder(num_args); | 77 | let mut arg_tys = vec![]; |
82 | for _ in 0..num_args { | 78 | for _ in 0..num_args { |
83 | param_builder = param_builder.push(self.table.new_type_var()); | 79 | let arg = self.table.new_type_var(); |
84 | } | 80 | param_builder = param_builder.push(arg.clone()); |
85 | let arg_ty = Ty::Apply(ApplicationTy { | 81 | arg_tys.push(arg); |
86 | ctor: TypeCtor::Tuple { cardinality: num_args as u16 }, | 82 | } |
87 | parameters: param_builder.build(), | 83 | let parameters = param_builder.build(); |
88 | }); | 84 | let arg_ty = Ty::Apply(ApplicationTy { |
89 | let substs = Substs::build_for_generics(&generic_params) | 85 | ctor: TypeCtor::Tuple { cardinality: num_args as u16 }, |
90 | .push(ty.clone()) | 86 | parameters, |
91 | .push(arg_ty.clone()) | 87 | }); |
92 | .build(); | 88 | let substs = Substs::build_for_generics(&generic_params) |
93 | 89 | .push(ty.clone()) | |
94 | let trait_ref = TraitRef { trait_: fn_trait, substs: substs.clone() }; | 90 | .push(arg_ty.clone()) |
95 | let trait_env = Arc::clone(&self.trait_env); | 91 | .build(); |
96 | let implements_fn_goal = self.canonicalizer().canonicalize_obligation(InEnvironment { | 92 | |
97 | value: Obligation::Trait(trait_ref), | 93 | let trait_env = Arc::clone(&self.trait_env); |
98 | environment: trait_env, | 94 | let implements_fn_trait = |
99 | }); | 95 | Obligation::Trait(TraitRef { trait_: fn_once_trait, substs: substs.clone() }); |
100 | let solution = match self.db.trait_solve(krate, implements_fn_goal.value.clone()) { | 96 | let goal = self.canonicalizer().canonicalize_obligation(InEnvironment { |
101 | Some(Solution::Unique(SolutionVariables(solution))) | 97 | value: implements_fn_trait.clone(), |
102 | | Some(Solution::Ambig(Guidance::Definite(SolutionVariables(solution)))) | 98 | environment: trait_env, |
103 | | Some(Solution::Ambig(Guidance::Suggested(SolutionVariables(solution)))) => { | 99 | }); |
104 | solution | 100 | if self.db.trait_solve(krate, goal.value).is_some() { |
105 | } | 101 | self.obligations.push(implements_fn_trait); |
106 | _ => continue, | ||
107 | }; | ||
108 | let output_proj_ty = | 102 | let output_proj_ty = |
109 | crate::ProjectionTy { associated_ty: output_assoc_type, parameters: substs }; | 103 | crate::ProjectionTy { associated_ty: output_assoc_type, parameters: substs }; |
110 | let return_ty = self.normalize_projection_ty(output_proj_ty); | 104 | let return_ty = self.normalize_projection_ty(output_proj_ty); |
111 | return Some((solution.value, return_ty)); | 105 | Some((arg_tys, return_ty)) |
106 | } else { | ||
107 | None | ||
112 | } | 108 | } |
113 | None | ||
114 | } | 109 | } |
115 | 110 | ||
116 | pub fn callable_sig(&mut self, ty: &Ty, num_args: usize) -> Option<(Vec<Ty>, Ty)> { | 111 | pub fn callable_sig(&mut self, ty: &Ty, num_args: usize) -> Option<(Vec<Ty>, Ty)> { |