@@ -106,15 +106,46 @@ fn const_addr_of(cx: @CrateContext, cv: ValueRef) -> ValueRef {
106
106
}
107
107
}
108
108
109
- pub fn const_deref ( cx : @CrateContext , v : ValueRef ) -> ValueRef {
109
+ fn const_deref_ptr ( cx : @CrateContext , v : ValueRef ) -> ValueRef {
110
+ let v = match cx. const_globals . find ( & ( v as int ) ) {
111
+ Some ( v) => v,
112
+ None => v
113
+ } ;
110
114
unsafe {
111
- let v = match cx. const_globals . find ( & ( v as int ) ) {
112
- Some ( v) => v,
113
- None => v
114
- } ;
115
115
fail_unless ! ( llvm:: LLVMIsGlobalConstant ( v) == True ) ;
116
- let v = llvm:: LLVMGetInitializer ( v) ;
117
- v
116
+ llvm:: LLVMGetInitializer ( v)
117
+ }
118
+ }
119
+
120
+ fn const_deref_newtype ( cx : @CrateContext , v : ValueRef , t : ty:: t )
121
+ -> ValueRef {
122
+ let repr = adt:: represent_type ( cx, t) ;
123
+ adt:: const_get_field ( cx, repr, v, 0 , 0 )
124
+ }
125
+
126
+ fn const_deref ( cx : @CrateContext , v : ValueRef , t : ty:: t , explicit : bool )
127
+ -> ( ValueRef , ty:: t ) {
128
+ match ty:: deref ( cx. tcx , t, explicit) {
129
+ Some ( ref mt) => {
130
+ fail_unless ! ( mt. mutbl != ast:: m_mutbl) ;
131
+ let dv = match ty:: get ( t) . sty {
132
+ ty:: ty_ptr( * ) | ty:: ty_rptr( * ) => {
133
+ const_deref_ptr ( cx, v)
134
+ }
135
+ ty:: ty_enum( * ) | ty:: ty_struct( * ) => {
136
+ const_deref_newtype ( cx, v, t)
137
+ }
138
+ _ => {
139
+ cx. sess . bug ( fmt ! ( "Unexpected dereferenceable type %s" ,
140
+ ty_to_str( cx. tcx, t) ) )
141
+ }
142
+ } ;
143
+ ( dv, mt. ty )
144
+ }
145
+ None => {
146
+ cx. sess . bug ( fmt ! ( "Can't dereference const of type %s" ,
147
+ ty_to_str( cx. tcx, t) ) )
148
+ }
118
149
}
119
150
}
120
151
@@ -150,8 +181,11 @@ pub fn const_expr(cx: @CrateContext, e: @ast::expr) -> ValueRef {
150
181
region %? sigil %?", * r, * s) )
151
182
}
152
183
Some ( @ty:: AutoDerefRef ( ref adj) ) => {
184
+ let mut ty = ety;
153
185
for adj. autoderefs. times {
154
- llconst = const_deref( cx, llconst)
186
+ let ( dv, dt) = const_deref( cx, llconst, ty, false ) ;
187
+ llconst = dv;
188
+ ty = dt;
155
189
}
156
190
157
191
match adj. autoref {
@@ -263,7 +297,10 @@ fn const_expr_unadjusted(cx: @CrateContext, e: @ast::expr) -> ValueRef {
263
297
return match u {
264
298
ast : : box( _) |
265
299
ast:: uniq( _) |
266
- ast:: deref => const_deref( cx, te) ,
300
+ ast:: deref => {
301
+ let ( dv, _dt) = const_deref( cx, te, ty, true ) ;
302
+ dv
303
+ }
267
304
ast:: not => {
268
305
match ty:: get( ty) . sty {
269
306
ty : : ty_bool => {
@@ -313,7 +350,7 @@ fn const_expr_unadjusted(cx: @CrateContext, e: @ast::expr) -> ValueRef {
313
350
let llunitty = type_of:: type_of( cx, unit_ty) ;
314
351
let unit_sz = machine:: llsize_of( cx, llunitty) ;
315
352
316
- ( const_deref ( cx, const_get_elt( cx, bv, [ 0 ] ) ) ,
353
+ ( const_deref_ptr ( cx, const_get_elt( cx, bv, [ 0 ] ) ) ,
317
354
llvm:: LLVMConstUDiv ( const_get_elt( cx, bv, [ 1 ] ) ,
318
355
unit_sz) )
319
356
} ,
0 commit comments