@@ -111,6 +111,10 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
111
111
let tpt = ty:: lookup_item_type( ccx. tcx, fn_id) ;
112
112
let llitem_ty = tpt. ty;
113
113
114
+ // We need to do special handling of the substitutions if we are
115
+ // calling a static provided method. This is sort of unfortunate.
116
+ let mut is_static_provided = None ;
117
+
114
118
let map_node = session:: expect(
115
119
ccx. sess,
116
120
ccx. tcx. items. find_copy( & fn_id. node) ,
@@ -129,6 +133,12 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
129
133
return ( get_item_val( ccx, fn_id. node) , true ) ;
130
134
}
131
135
ast_map:: node_trait_method( @ast:: provided( m) , _, pt) => {
136
+ // If this is a static provided method, indicate that
137
+ // and stash the number of params on the method.
138
+ if m. explicit_self. node == ast:: sty_static {
139
+ is_static_provided = Some ( m. generics. ty_params. len( ) ) ;
140
+ }
141
+
132
142
( pt, m. ident, m. span)
133
143
}
134
144
ast_map:: node_trait_method( @ast:: required( _) , _, _) => {
@@ -153,8 +163,36 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
153
163
ast_map:: node_struct_ctor( _, i, pt) => ( pt, i. ident, i. span)
154
164
} ;
155
165
156
- let mono_ty = ty:: subst_tps( ccx. tcx, psubsts. tys,
157
- psubsts. self_ty, llitem_ty) ;
166
+ debug ! ( "monomorphic_fn about to subst into %s" , llitem_ty. repr( ccx. tcx) ) ;
167
+ let mono_ty = match is_static_provided {
168
+ None => ty:: subst_tps( ccx. tcx, psubsts. tys,
169
+ psubsts. self_ty, llitem_ty) ,
170
+ Some ( num_method_ty_params) => {
171
+ // Static default methods are a little unfortunate, in
172
+ // that the "internal" and "external" type of them differ.
173
+ // Internally, the method body can refer to Self, but the
174
+ // externally visable type of the method has a type param
175
+ // inserted in between the trait type params and the
176
+ // method type params. The substs that we are given are
177
+ // the proper substs *internally* to the method body, so
178
+ // we have to use those when compiling it.
179
+ //
180
+ // In order to get the proper substitution to use on the
181
+ // type of the method, we pull apart the substitution and
182
+ // stick a substitution for the self type in.
183
+ // This is a bit unfortunate.
184
+
185
+ let idx = psubsts. tys. len( ) - num_method_ty_params;
186
+ let substs =
187
+ ( psubsts. tys. slice( 0 , idx) +
188
+ & [ psubsts. self_ty. get( ) ] +
189
+ psubsts. tys. tailn( idx) ) ;
190
+ debug ! ( "static default: changed substitution to %s" ,
191
+ substs. repr( ccx. tcx) ) ;
192
+
193
+ ty:: subst_tps( ccx. tcx, substs, None , llitem_ty)
194
+ }
195
+ } ;
158
196
let llfty = type_of_fn_from_ty( ccx, mono_ty) ;
159
197
160
198
ccx. stats. n_monos += 1 ;
0 commit comments