@@ -8,7 +8,7 @@ use crate::{
8
8
resolve:: {
9
9
conform:: { conform_expr, to_default:: conform_expr_to_default, ConformMode , Perform } ,
10
10
error:: { ResolveError , ResolveErrorKind } ,
11
- Initialized ,
11
+ Initialized , PolyValue ,
12
12
} ,
13
13
source_files:: Source ,
14
14
} ;
@@ -81,18 +81,65 @@ pub fn call_callee(
81
81
let num_required = function. params . required . len ( ) ;
82
82
83
83
for ( expected_name, expected_trait) in function. impl_params . params . iter ( ) {
84
- if !used_names. contains ( expected_name) {
85
- return Err ( ResolveError :: other (
86
- format ! (
87
- "Missing '${} {}' trait implementation required by function call" ,
88
- expected_name,
89
- expected_trait. display( & ctx. asg) ,
90
- ) ,
91
- source,
92
- ) ) ;
84
+ if used_names. contains ( expected_name) {
85
+ continue ;
86
+ }
87
+
88
+ // NOTE: PERFORMANCE: TODO: This could probably be optimized
89
+ if let Some ( caller) = ctx
90
+ . func_ref
91
+ . map ( |caller_func_ref| ctx. asg . funcs . get ( caller_func_ref) . unwrap ( ) )
92
+ {
93
+ let from_env = caller. impl_params . params . iter ( ) . filter ( |( _, param_trait) | {
94
+ callee
95
+ . recipe
96
+ . resolve_trait ( expected_trait)
97
+ . map_or ( false , |expected_trait| * * param_trait == expected_trait)
98
+ } ) ;
99
+
100
+ match from_env. exactly_one ( ) {
101
+ Ok ( ( param_name, _) ) => {
102
+ if callee
103
+ . recipe
104
+ . polymorphs
105
+ . insert ( expected_name. into ( ) , PolyValue :: PolyImpl ( param_name. into ( ) ) )
106
+ . is_some ( )
107
+ {
108
+ return Err ( ResolveError :: other (
109
+ format ! (
110
+ "Could not automatically supply trait implementation for '${} {}' required by function call, since the polymorph is already in use" ,
111
+ expected_name,
112
+ expected_trait. display( & ctx. asg) ,
113
+ ) ,
114
+ source,
115
+ ) ) ;
116
+ }
117
+ }
118
+ Err ( mut non_unique) => {
119
+ return Err ( ResolveError :: other (
120
+ if non_unique. next ( ) . is_some ( ) {
121
+ format ! (
122
+ "Ambiguous trait implementation for '${} {}' required by function call, please specify manually" ,
123
+ expected_name,
124
+ expected_trait. display( & ctx. asg) ,
125
+ )
126
+ } else {
127
+ format ! (
128
+ "Missing '${} {}' trait implementation required by function call" ,
129
+ expected_name,
130
+ expected_trait. display( & ctx. asg) ,
131
+ )
132
+ } ,
133
+ source,
134
+ ) ) ;
135
+ }
136
+ }
93
137
}
94
138
}
95
139
140
+ // We shouldn't use used_names after this, since we know all names were satisfied
141
+ drop ( used_names) ;
142
+
96
143
for ( i, arg) in args. iter_mut ( ) . enumerate ( ) {
97
144
let function = ctx. asg . funcs . get ( callee. func_ref ) . unwrap ( ) ;
98
145
0 commit comments