@@ -19,11 +19,11 @@ use crate::{
19
19
lower:: lower_to_chalk_mutability,
20
20
method_resolution, op,
21
21
primitive:: { self , UintTy } ,
22
- to_assoc_type_id , to_chalk_trait_id,
22
+ to_chalk_trait_id,
23
23
traits:: { chalk:: from_chalk, FnTrait , InEnvironment } ,
24
24
utils:: { generics, variant_data, Generics } ,
25
- AdtId , Binders , CallableDefId , DomainGoal , FnPointer , FnSig , Interner , Rawness , Scalar ,
26
- Substitution , TraitRef , Ty , TyBuilder , TyKind ,
25
+ AdtId , Binders , CallableDefId , FnPointer , FnSig , Interner , Rawness , Scalar , Substitution ,
26
+ TraitRef , Ty , TyBuilder , TyKind ,
27
27
} ;
28
28
29
29
use super :: {
@@ -73,38 +73,34 @@ impl<'a> InferenceContext<'a> {
73
73
let fn_once_trait = FnTrait :: FnOnce . get_id ( self . db , krate) ?;
74
74
let output_assoc_type =
75
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
77
let mut arg_tys = vec ! [ ] ;
83
- for _ in 0 ..num_args {
84
- let arg = self . table . new_type_var ( ) ;
85
- param_builder = param_builder. push ( arg. clone ( ) ) ;
86
- arg_tys. push ( arg) ;
87
- }
88
- let parameters = param_builder. build ( ) ;
78
+ let parameters = Substitution :: builder ( num_args)
79
+ . fill ( repeat_with ( || {
80
+ let arg = self . table . new_type_var ( ) ;
81
+ arg_tys. push ( arg. clone ( ) ) ;
82
+ arg
83
+ } ) )
84
+ . build ( ) ;
89
85
let arg_ty = TyKind :: Tuple ( num_args, parameters) . intern ( & Interner ) ;
90
- let substs =
91
- Substitution :: build_for_generics ( & generic_params) . push ( ty. clone ( ) ) . push ( arg_ty) . build ( ) ;
86
+
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
95
let trait_env = self . trait_env . env . clone ( ) ;
94
- let implements_fn_trait: DomainGoal =
95
- TraitRef { trait_id : to_chalk_trait_id ( fn_once_trait) , substitution : substs. clone ( ) }
96
- . cast ( & Interner ) ;
97
- let goal = self . canonicalizer ( ) . canonicalize_obligation ( InEnvironment {
98
- goal : implements_fn_trait. clone ( ) ,
96
+ let obligation = InEnvironment {
97
+ goal : projection. trait_ref ( self . db ) . cast ( & Interner ) ,
99
98
environment : trait_env,
100
- } ) ;
101
- if self . db . trait_solve ( krate, goal. value ) . is_some ( ) {
102
- self . push_obligation ( implements_fn_trait) ;
103
- let output_proj_ty = crate :: ProjectionTy {
104
- associated_ty_id : to_assoc_type_id ( output_assoc_type) ,
105
- substitution : substs,
106
- } ;
107
- let return_ty = self . normalize_projection_ty ( output_proj_ty) ;
99
+ } ;
100
+ let canonical = self . canonicalizer ( ) . canonicalize_obligation ( obligation. clone ( ) ) ;
101
+ if self . db . trait_solve ( krate, canonical. value ) . is_some ( ) {
102
+ self . push_obligation ( obligation. goal ) ;
103
+ let return_ty = self . normalize_projection_ty ( projection) ;
108
104
Some ( ( arg_tys, return_ty) )
109
105
} else {
110
106
None
0 commit comments