@@ -20,6 +20,7 @@ use middle::trans::expr;
2020use middle:: trans:: machine;
2121use middle:: trans:: type_of;
2222use middle:: ty;
23+ use util:: ppaux:: { expr_repr, ty_to_str} ;
2324
2425use core:: libc:: c_uint;
2526use syntax:: { ast, ast_util, codemap, ast_map} ;
@@ -150,6 +151,24 @@ pub fn get_const_val(cx: @CrateContext, def_id: ast::def_id) -> ValueRef {
150151}
151152
152153pub fn const_expr ( cx : @CrateContext , e : @ast:: expr ) -> ValueRef {
154+ let ety = ty:: expr_ty_adjusted ( cx. tcx , e) ;
155+ let llty = type_of:: sizing_type_of ( cx, ety) ;
156+ let llconst = const_expr_unchecked ( cx, e) ;
157+ let csize = machine:: llsize_of_alloc ( cx, val_ty ( llconst) ) ;
158+ let tsize = machine:: llsize_of_alloc ( cx, llty) ;
159+ if csize != tsize {
160+ unsafe {
161+ llvm:: LLVMDumpValue ( llconst) ;
162+ llvm:: LLVMDumpValue ( C_null ( llty) ) ;
163+ }
164+ cx. sess . bug ( fmt ! ( "const %s of type %s has size %u instead of %u" ,
165+ expr_repr( cx. tcx, e) , ty_to_str( cx. tcx, ety) ,
166+ csize, tsize) ) ;
167+ }
168+ llconst
169+ }
170+
171+ fn const_expr_unchecked( cx : @CrateContext , e : @ast:: expr ) -> ValueRef {
153172 unsafe {
154173 let _icx = cx. insn_ctxt ( "const_expr" ) ;
155174 return match /*bad*/ copy e. node {
@@ -394,13 +413,22 @@ pub fn const_expr(cx: @CrateContext, e: @ast::expr) -> ValueRef {
394413 ast:: expr_path ( pth) => {
395414 assert pth. types . len ( ) == 0 ;
396415 match cx. tcx . def_map . find ( & e. id ) {
397- Some ( ast:: def_fn( def_id, purity ) ) => {
416+ Some ( ast:: def_fn( def_id, _purity ) ) => {
398417 assert ast_util:: is_local ( def_id) ;
399418 let f = base:: get_item_val ( cx, def_id. node ) ;
400- match purity {
401- ast:: extern_fn =>
402- llvm:: LLVMConstPointerCast ( f, T_ptr ( T_i8 ( ) ) ) ,
403- _ => C_struct ( ~[ f, C_null ( T_opaque_box_ptr ( cx) ) ] )
419+ let ety = ty:: expr_ty_adjusted ( cx. tcx , e) ;
420+ match ty:: get ( ety) . sty {
421+ ty:: ty_bare_fn( * ) | ty:: ty_ptr( * ) => {
422+ llvm:: LLVMConstPointerCast ( f, T_ptr ( T_i8 ( ) ) )
423+ }
424+ ty:: ty_closure( * ) => {
425+ C_struct ( ~[ f, C_null ( T_opaque_box_ptr ( cx) ) ] )
426+ }
427+ _ => {
428+ cx. sess . span_bug ( e. span , fmt ! (
429+ "unexpected const fn type: %s" ,
430+ ty_to_str( cx. tcx, ety) ) )
431+ }
404432 }
405433 }
406434 Some ( ast:: def_const( def_id) ) => {
0 commit comments