4
4
use lib:: llvm:: llvm:: { LLVMCountParams , LLVMGetParam } ;
5
5
use middle:: trans:: base:: { GEP_enum , finish_fn, get_insn_ctxt, get_item_val} ;
6
6
use middle:: trans:: base:: { new_fn_ctxt, sub_block, top_scope_block} ;
7
+ use middle:: trans:: base;
7
8
use middle:: trans:: build:: { AddCase , Br , CondBr , GEPi , Load , PointerCast } ;
8
9
use middle:: trans:: build:: { Store , Switch , Unreachable , ValueRef } ;
9
10
use middle:: trans:: callee;
@@ -14,7 +15,8 @@ use middle::trans::common::{C_bool, C_int, T_ptr, block, crate_ctxt};
14
15
use middle:: trans:: common:: { fn_ctxt} ;
15
16
use middle:: trans:: expr:: SaveIn ;
16
17
use middle:: trans:: type_of:: type_of;
17
- use middle:: ty:: DerivedFieldInfo ;
18
+ use middle:: ty:: { DerivedFieldInfo , re_static} ;
19
+ use middle:: typeck:: check:: method;
18
20
use middle:: typeck:: method_static;
19
21
use syntax:: ast;
20
22
use syntax:: ast:: { def_id, ident, node_id, ty_param} ;
@@ -78,14 +80,33 @@ pub fn trans_deriving_impl(ccx: @crate_ctxt,
78
80
for method_dids. each |method_did| {
79
81
let kind = DerivingKind :: of_item ( ccx, * method_did) ;
80
82
let llfn = get_item_val ( ccx, method_did. node ) ;
83
+
84
+ // Transform the self type as appropriate.
85
+ let derived_method_info =
86
+ ccx. tcx . automatically_derived_methods . get ( * method_did) ;
87
+ let transformed_self_ty =
88
+ method:: transform_self_type_for_method (
89
+ ccx. tcx ,
90
+ Some ( re_static) ,
91
+ self_ty. ty ,
92
+ derived_method_info. method_info . self_type ) ;
93
+
81
94
match ty:: get ( self_ty. ty ) . sty {
82
95
ty:: ty_class( * ) => {
83
- trans_deriving_struct_method ( ccx, llfn, impl_def_id,
84
- self_ty. ty , kind) ;
96
+ trans_deriving_struct_method ( ccx,
97
+ llfn,
98
+ impl_def_id,
99
+ self_ty. ty ,
100
+ transformed_self_ty,
101
+ kind) ;
85
102
}
86
103
ty:: ty_enum( * ) => {
87
- trans_deriving_enum_method ( ccx, llfn, impl_def_id,
88
- self_ty. ty , kind) ;
104
+ trans_deriving_enum_method ( ccx,
105
+ llfn,
106
+ impl_def_id,
107
+ self_ty. ty ,
108
+ transformed_self_ty,
109
+ kind) ;
89
110
}
90
111
_ => {
91
112
ccx. tcx . sess . bug ( ~"translation of non-struct \
@@ -119,6 +140,7 @@ fn trans_deriving_struct_method(ccx: @crate_ctxt,
119
140
llfn : ValueRef ,
120
141
impl_did : def_id ,
121
142
self_ty : ty:: t ,
143
+ transformed_self_ty : ty:: t ,
122
144
kind : DerivingKind ) {
123
145
let _icx = ccx. insn_ctxt ( "trans_deriving_struct_method" ) ;
124
146
let fcx = new_fn_ctxt ( ccx, ~[ ] , llfn, None ) ;
@@ -128,8 +150,10 @@ fn trans_deriving_struct_method(ccx: @crate_ctxt,
128
150
129
151
let llextraparams = get_extra_params ( llfn, kind) ;
130
152
131
- let llselfty = type_of ( ccx, self_ty) ;
132
- let llselfval = PointerCast ( bcx, fcx. llenv , T_ptr ( llselfty) ) ;
153
+ let lltransformedselfty = type_of ( ccx, transformed_self_ty) ;
154
+ let lltransformedselfval =
155
+ PointerCast ( bcx, fcx. llenv , T_ptr ( lltransformedselfty) ) ;
156
+ let llselfval = Load ( bcx, lltransformedselfval) ;
133
157
134
158
// If there is an "other" value, then get it. The "other" value is the
135
159
// value we're comparing against in the case of Eq and Ord.
@@ -155,6 +179,9 @@ fn trans_deriving_struct_method(ccx: @crate_ctxt,
155
179
for ccx. tcx. deriving_struct_methods. get( impl_did) . eachi
156
180
|i, derived_method_info| {
157
181
let llselfval = GEPi ( bcx, llselfval, [ 0 , 0 , i] ) ;
182
+ let llselfallocaty = common:: val_ty ( llselfval) ;
183
+ let llselfalloca = base:: alloca ( bcx, llselfallocaty) ;
184
+ Store ( bcx, llselfval, llselfalloca) ;
158
185
159
186
let llotherval_opt = llotherval_opt. map (
160
187
|llotherval| GEPi ( bcx, * llotherval, [ 0 , 0 , i] ) ) ;
@@ -163,7 +190,7 @@ fn trans_deriving_struct_method(ccx: @crate_ctxt,
163
190
bcx = call_substructure_method ( bcx,
164
191
derived_method_info,
165
192
self_ty,
166
- llselfval ,
193
+ llselfalloca ,
167
194
llotherval_opt,
168
195
llextraparams) ;
169
196
@@ -197,6 +224,7 @@ fn trans_deriving_enum_method(ccx: @crate_ctxt,
197
224
llfn : ValueRef ,
198
225
impl_did : def_id ,
199
226
self_ty : ty:: t ,
227
+ transformed_self_ty : ty:: t ,
200
228
kind : DerivingKind ) {
201
229
let _icx = ccx. insn_ctxt ( "trans_deriving_enum_method" ) ;
202
230
let fcx = new_fn_ctxt ( ccx, ~[ ] , llfn, None ) ;
@@ -206,8 +234,10 @@ fn trans_deriving_enum_method(ccx: @crate_ctxt,
206
234
207
235
let llextraparams = get_extra_params ( llfn, kind) ;
208
236
209
- let llselfty = type_of ( ccx, self_ty) ;
210
- let llselfval = PointerCast ( bcx, fcx. llenv , T_ptr ( llselfty) ) ;
237
+ let lltransformedselfty = type_of ( ccx, transformed_self_ty) ;
238
+ let lltransformedselfval =
239
+ PointerCast ( bcx, fcx. llenv , T_ptr ( lltransformedselfty) ) ;
240
+ let llselfval = Load ( bcx, lltransformedselfval) ;
211
241
212
242
let llotherval_opt;
213
243
match kind {
@@ -280,6 +310,9 @@ fn trans_deriving_enum_method(ccx: @crate_ctxt,
280
310
enum_variant_infos[ self_variant_index] . id ;
281
311
let llselfval = GEP_enum ( match_bcx, llselfpayload, enum_id,
282
312
variant_def_id, enum_substs. tps , i) ;
313
+ let llselfallocaty = common:: val_ty ( llselfval) ;
314
+ let llselfalloca = base:: alloca ( match_bcx, llselfallocaty) ;
315
+ Store ( match_bcx, llselfval, llselfalloca) ;
283
316
284
317
let llotherval_opt = llotherpayload_opt. map ( |llotherpayload|
285
318
GEP_enum ( match_bcx, * llotherpayload, enum_id,
@@ -289,7 +322,7 @@ fn trans_deriving_enum_method(ccx: @crate_ctxt,
289
322
match_bcx = call_substructure_method ( match_bcx,
290
323
derived_method_info,
291
324
self_ty,
292
- llselfval ,
325
+ llselfalloca ,
293
326
llotherval_opt,
294
327
llextraparams) ;
295
328
0 commit comments