@@ -4,7 +4,7 @@ use crate::{
4
4
resolve:: {
5
5
error:: ResolveError ,
6
6
expr:: { static_member:: resolve_impl_mention_from_type, ResolveExprCtx } ,
7
- PolyValue ,
7
+ PolyCatalog , PolyValue ,
8
8
} ,
9
9
source_files:: { source:: Sourced , Source } ,
10
10
} ;
@@ -15,13 +15,22 @@ pub fn resolve_impl_arg(
15
15
callee : & mut Callee ,
16
16
using : & Using ,
17
17
used_names : & mut HashSet < String > ,
18
+ catalog : & mut PolyCatalog ,
18
19
) -> Result < ( ) , ResolveError > {
19
20
let impl_arg = & using. ty ;
20
21
21
22
if let ast:: TypeKind :: Polymorph ( polymorph, args_to_polymorph) = & impl_arg. kind {
22
- resolve_polymorph_impl_arg ( ctx, callee, using, polymorph, args_to_polymorph, used_names)
23
+ resolve_polymorph_impl_arg (
24
+ ctx,
25
+ callee,
26
+ using,
27
+ polymorph,
28
+ args_to_polymorph,
29
+ used_names,
30
+ catalog,
31
+ )
23
32
} else {
24
- resolve_concrete_impl_arg ( ctx, callee, using, impl_arg, used_names)
33
+ resolve_concrete_impl_arg ( ctx, callee, using, impl_arg, used_names, catalog )
25
34
}
26
35
}
27
36
@@ -31,6 +40,7 @@ fn resolve_concrete_impl_arg(
31
40
using : & Using ,
32
41
impl_arg : & ast:: Type ,
33
42
used_names : & mut HashSet < String > ,
43
+ catalog : & mut PolyCatalog ,
34
44
) -> Result < ( ) , ResolveError > {
35
45
let impl_arg_source = using. ty . source ;
36
46
let ( impl_ref, impl_poly_catalog) = resolve_impl_mention_from_type ( ctx, impl_arg) ?;
@@ -46,14 +56,14 @@ fn resolve_concrete_impl_arg(
46
56
47
57
try_register_specified_impl (
48
58
ctx,
49
- callee,
50
59
callee_func,
51
60
using,
52
61
impl_arg_source,
53
62
used_names,
54
63
PolyValue :: Impl ( impl_ref) ,
55
64
& arg_concrete_trait,
56
65
& callee_func. impl_params ,
66
+ catalog,
57
67
)
58
68
}
59
69
@@ -64,6 +74,7 @@ fn resolve_polymorph_impl_arg(
64
74
polymorph : & str ,
65
75
args_to_polymorph : & [ ast:: Type ] ,
66
76
used_names : & mut HashSet < String > ,
77
+ catalog : & mut PolyCatalog ,
67
78
) -> Result < ( ) , ResolveError > {
68
79
let impl_arg_source = using. ty . source ;
69
80
let callee_func = ctx. asg . funcs . get ( callee. func_ref ) . unwrap ( ) ;
@@ -97,27 +108,27 @@ fn resolve_polymorph_impl_arg(
97
108
98
109
try_register_specified_impl (
99
110
ctx,
100
- callee,
101
111
callee_func,
102
112
using,
103
113
impl_arg_source,
104
114
used_names,
105
115
PolyValue :: PolyImpl ( polymorph. into ( ) ) ,
106
116
arg_concrete_trait,
107
117
& callee_func. impl_params ,
118
+ catalog,
108
119
)
109
120
}
110
121
111
122
fn try_register_specified_impl (
112
123
ctx : & ResolveExprCtx ,
113
- callee : & mut Callee ,
114
124
callee_func : & asg:: Func ,
115
125
using : & Using ,
116
126
impl_arg_source : Source ,
117
127
used_names : & mut HashSet < String > ,
118
128
poly_value : PolyValue ,
119
129
arg_concrete_trait : & GenericTraitRef ,
120
130
impl_params : & ImplParams ,
131
+ catalog : & mut PolyCatalog ,
121
132
) -> Result < ( ) , ResolveError > {
122
133
let target_param = match & using. name {
123
134
Some ( name_and_source) => name_and_source. as_ref ( ) ,
@@ -166,7 +177,36 @@ fn try_register_specified_impl(
166
177
) ) ;
167
178
}
168
179
169
- let param_concrete_trait = callee. recipe . resolve_trait ( param_generic_trait) ?;
180
+ if param_generic_trait. args . len ( ) != arg_concrete_trait. args . len ( ) {
181
+ return Err ( ResolveError :: other (
182
+ "Mismatching number of arguments expected for trait implementation" ,
183
+ target_param. source ,
184
+ ) ) ;
185
+ }
186
+
187
+ for ( pattern, concrete) in param_generic_trait
188
+ . args
189
+ . iter ( )
190
+ . zip ( arg_concrete_trait. args . iter ( ) )
191
+ {
192
+ match catalog. match_type ( ctx, pattern, concrete) {
193
+ Ok ( ( ) ) => { }
194
+ Err ( _) => {
195
+ return Err ( ResolveError :: other (
196
+ format ! (
197
+ "Implementation of '{}' cannot be used for '{}'" ,
198
+ arg_concrete_trait. display( ctx. asg) ,
199
+ param_generic_trait. display( ctx. asg)
200
+ ) ,
201
+ impl_arg_source,
202
+ ) ) ;
203
+ }
204
+ }
205
+ }
206
+
207
+ // TODO: PERFORMANCE: We shouldn't need to clone this
208
+ let recipe = catalog. clone ( ) . bake ( ) ;
209
+ let param_concrete_trait = recipe. resolve_trait ( param_generic_trait) ?;
170
210
171
211
if * arg_concrete_trait != param_concrete_trait {
172
212
return Err ( ResolveError :: other (
@@ -179,8 +219,7 @@ fn try_register_specified_impl(
179
219
) ) ;
180
220
}
181
221
182
- callee
183
- . recipe
222
+ catalog
184
223
. polymorphs
185
224
. insert ( target_param. inner ( ) . to_string ( ) , poly_value)
186
225
. is_some ( )
0 commit comments