@@ -106,15 +106,46 @@ fn const_addr_of(cx: @CrateContext, cv: ValueRef) -> ValueRef {
106106 }
107107}
108108
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+ } ;
110114 unsafe {
111- let v = match cx. const_globals . find ( & ( v as int ) ) {
112- Some ( v) => v,
113- None => v
114- } ;
115115 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+ }
118149 }
119150}
120151
@@ -150,8 +181,11 @@ pub fn const_expr(cx: @CrateContext, e: @ast::expr) -> ValueRef {
150181 region %? sigil %?", * r, * s) )
151182 }
152183 Some ( @ty:: AutoDerefRef ( ref adj) ) => {
184+ let mut ty = ety;
153185 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;
155189 }
156190
157191 match adj. autoref {
@@ -263,7 +297,10 @@ fn const_expr_unadjusted(cx: @CrateContext, e: @ast::expr) -> ValueRef {
263297 return match u {
264298 ast : : box( _) |
265299 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+ }
267304 ast:: not => {
268305 match ty:: get( ty) . sty {
269306 ty : : ty_bool => {
@@ -313,7 +350,7 @@ fn const_expr_unadjusted(cx: @CrateContext, e: @ast::expr) -> ValueRef {
313350 let llunitty = type_of:: type_of( cx, unit_ty) ;
314351 let unit_sz = machine:: llsize_of( cx, llunitty) ;
315352
316- ( const_deref ( cx, const_get_elt( cx, bv, [ 0 ] ) ) ,
353+ ( const_deref_ptr ( cx, const_get_elt( cx, bv, [ 0 ] ) ) ,
317354 llvm:: LLVMConstUDiv ( const_get_elt( cx, bv, [ 1 ] ) ,
318355 unit_sz) )
319356 } ,
0 commit comments