1010
1111use core:: prelude:: * ;
1212
13+ use back:: abi;
1314use lib:: llvm:: { llvm, ValueRef , TypeRef , Bool , True , False } ;
1415use metadata:: csearch;
1516use middle:: const_eval;
@@ -117,22 +118,6 @@ pub fn const_deref(cx: @CrateContext, v: ValueRef) -> ValueRef {
117118 }
118119}
119120
120- pub fn const_autoderef ( cx : @CrateContext , ty : ty:: t , v : ValueRef )
121- -> ( ty:: t , ValueRef ) {
122- let mut t1 = ty;
123- let mut v1 = v;
124- loop {
125- // Only rptrs can be autoderef'ed in a const context.
126- match ty:: get ( t1) . sty {
127- ty:: ty_rptr( _, mt) => {
128- t1 = mt. ty ;
129- v1 = const_deref ( cx, v1) ;
130- }
131- _ => return ( t1, v1)
132- }
133- }
134- }
135-
136121pub fn get_const_val ( cx : @CrateContext , def_id : ast:: def_id ) -> ValueRef {
137122 let mut def_id = def_id;
138123 if !ast_util:: is_local ( def_id) ||
@@ -153,15 +138,59 @@ pub fn get_const_val(cx: @CrateContext, def_id: ast::def_id) -> ValueRef {
153138}
154139
155140pub fn const_expr( cx : @CrateContext , e : @ast:: expr ) -> ValueRef {
156- let ety = ty:: expr_ty_adjusted ( cx. tcx , e) ;
157- let llty = type_of:: sizing_type_of ( cx, ety) ;
158- let llconst = const_expr_unchecked ( cx, e) ;
141+ let mut llconst = const_expr_unadjusted ( cx, e) ;
142+ let ety = ty:: expr_ty ( cx. tcx , e) ;
143+ match cx. tcx . adjustments . find ( & e. id ) {
144+ None => { }
145+ Some ( @ty:: AutoAddEnv ( ty:: re_static, ast:: BorrowedSigil ) ) => {
146+ llconst = C_struct ( ~[ llconst, C_null ( T_opaque_box_ptr ( cx) ) ] )
147+ }
148+ Some ( @ty:: AutoAddEnv ( ref r, ref s) ) => {
149+ cx. sess . span_bug ( e. span , fmt ! ( "unexpected const function: \
150+ region %? sigil %?", * r, * s) )
151+ }
152+ Some ( @ty:: AutoDerefRef ( ref adj) ) => {
153+ for adj. autoderefs. times {
154+ llconst = const_deref( cx, llconst)
155+ }
156+
157+ match adj. autoref {
158+ None => { }
159+ Some ( ref autoref) => {
160+ fail_unless ! ( autoref. region == ty:: re_static) ;
161+ fail_unless ! ( autoref. mutbl != ast:: m_mutbl) ;
162+ match autoref. kind {
163+ ty : : AutoPtr => {
164+ llconst = const_addr_of( cx, llconst) ;
165+ }
166+ ty:: AutoBorrowVec => {
167+ let base = const_addr_of( cx, llconst) ;
168+ let size = machine:: llsize_of( cx,
169+ val_ty( llconst) ) ;
170+ fail_unless ! ( abi:: slice_elt_base == 0 ) ;
171+ fail_unless ! ( abi:: slice_elt_len == 1 ) ;
172+ llconst = C_struct ( ~[ base, size] ) ;
173+ }
174+ _ => {
175+ cx. sess. span_bug( e. span,
176+ fmt ! ( "unimplemented const \
177+ autoref %?", autoref) )
178+ }
179+ }
180+ }
181+ }
182+ }
183+ }
184+
185+ let ety_adjusted = ty:: expr_ty_adjusted( cx. tcx, e) ;
186+ let llty = type_of:: sizing_type_of( cx, ety_adjusted) ;
159187 let csize = machine:: llsize_of_alloc( cx, val_ty( llconst) ) ;
160188 let tsize = machine:: llsize_of_alloc( cx, llty) ;
161189 if csize != tsize {
162190 unsafe {
191+ // XXX these values could use some context
163192 llvm : : LLVMDumpValue ( llconst) ;
164- llvm:: LLVMDumpValue ( C_null ( llty) ) ;
193+ llvm:: LLVMDumpValue ( C_undef ( llty) ) ;
165194 }
166195 cx. sess. bug( fmt ! ( "const %s of type %s has size %u instead of %u" ,
167196 expr_repr( cx. tcx, e) , ty_to_str( cx. tcx, ety) ,
@@ -170,7 +199,7 @@ pub fn const_expr(cx: @CrateContext, e: @ast::expr) -> ValueRef {
170199 llconst
171200}
172201
173- fn const_expr_unchecked ( cx : @CrateContext , e : @ast:: expr ) -> ValueRef {
202+ fn const_expr_unadjusted ( cx: @CrateContext , e: @ast:: expr) -> ValueRef {
174203 unsafe {
175204 let _icx = cx. insn_ctxt( "const_expr" ) ;
176205 return match /*bad*/ copy e. node {
@@ -254,20 +283,18 @@ fn const_expr_unchecked(cx: @CrateContext, e: @ast::expr) -> ValueRef {
254283 }
255284 }
256285 ast:: expr_field( base, field, _) => {
257- let bt = ty:: expr_ty ( cx. tcx , base) ;
286+ let bt = ty:: expr_ty_adjusted ( cx. tcx, base) ;
258287 let brepr = adt:: represent_type( cx, bt) ;
259288 let bv = const_expr( cx, base) ;
260- let ( bt, bv) = const_autoderef ( cx, bt, bv) ;
261289 do expr:: with_field_tys( cx. tcx, bt, None ) |discr, field_tys| {
262290 let ix = ty:: field_idx_strict( cx. tcx, field, field_tys) ;
263291 adt:: const_get_field( cx, brepr, bv, discr, ix)
264292 }
265293 }
266294
267295 ast:: expr_index( base, index) => {
268- let bt = ty:: expr_ty ( cx. tcx , base) ;
296+ let bt = ty:: expr_ty_adjusted ( cx. tcx, base) ;
269297 let bv = const_expr( cx, base) ;
270- let ( bt, bv) = const_autoderef ( cx, bt, bv) ;
271298 let iv = match const_eval:: eval_const_expr( cx. tcx, index) {
272299 const_eval:: const_int( i) => i as u64,
273300 const_eval:: const_uint( u) => u,
@@ -425,26 +452,12 @@ fn const_expr_unchecked(cx: @CrateContext, e: @ast::expr) -> ValueRef {
425452 fail_unless ! ( pth. types. len( ) == 0 ) ;
426453 match cx. tcx. def_map. find( & e. id) {
427454 Some ( ast:: def_fn( def_id, _purity) ) => {
428- let f = if !ast_util:: is_local ( def_id) {
455+ if !ast_util:: is_local( def_id) {
429456 let ty = csearch:: get_type( cx. tcx, def_id) . ty;
430457 base:: trans_external_path( cx, def_id, ty)
431458 } else {
432459 fail_unless ! ( ast_util:: is_local( def_id) ) ;
433460 base:: get_item_val( cx, def_id. node)
434- } ;
435- let ety = ty:: expr_ty_adjusted ( cx. tcx , e) ;
436- match ty:: get ( ety) . sty {
437- ty:: ty_bare_fn( * ) | ty:: ty_ptr( * ) => {
438- llvm:: LLVMConstPointerCast ( f, T_ptr ( T_i8 ( ) ) )
439- }
440- ty:: ty_closure( * ) => {
441- C_struct ( ~[ f, C_null ( T_opaque_box_ptr ( cx) ) ] )
442- }
443- _ => {
444- cx. sess . span_bug ( e. span , fmt ! (
445- "unexpected const fn type: %s" ,
446- ty_to_str( cx. tcx, ety) ) )
447- }
448461 }
449462 }
450463 Some ( ast:: def_const( def_id) ) => {
0 commit comments