diff options
author | Florian Diebold <[email protected]> | 2021-04-03 21:28:10 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2021-04-04 12:16:38 +0100 |
commit | eaa03ef4465765a16951faa54dd8ebc53095e2c8 (patch) | |
tree | 1a528fdbd7d97cc7c507dac60e4cbb4fa5be669d /crates/hir_ty/src/infer | |
parent | 5d2b488aeb17410aec3b89eac69038c51f332448 (diff) |
Some more TyBuilder use
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 54 |
1 files changed, 25 insertions, 29 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 | ||
29 | use super::{ | 29 | use 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 |