@@ -414,42 +414,10 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
414414 // variant or we wouldn't have gotten here -- the constant
415415 // checker forbids paths that don't map to C-like enum
416416 // variants.
417- let ety = ty:: expr_ty ( cx. tcx , e) ;
418- let llty = type_of:: type_of ( cx, ety) ;
419-
420- // Can't use `discrims` from the crate context here
421- // because those discriminants have an extra level of
422- // indirection, and there's no LLVM constant load
423- // instruction.
424- let mut lldiscrim_opt = None ;
425- for ty:: enum_variants( cx. tcx, enum_did) . each
426- |variant_info| {
427- if variant_info. id == variant_did {
428- lldiscrim_opt = Some ( C_int ( cx,
429- variant_info. disr_val ) ) ;
430- break ;
431- }
432- }
433-
434- let lldiscrim;
435- match lldiscrim_opt {
436- None => {
437- cx. tcx . sess . span_bug ( e. span ,
438- ~"didn' t find discriminant?!") ;
439- }
440- Some ( found_lldiscrim) => {
441- lldiscrim = found_lldiscrim;
442- }
443- }
444- let fields = if ty:: enum_is_univariant ( cx. tcx , enum_did) {
445- ~[ lldiscrim]
446- } else {
447- let llstructtys =
448- lib:: llvm:: struct_element_types ( llty) ;
449- ~[ lldiscrim, C_null ( llstructtys[ 1 ] ) ]
450- } ;
451-
452- C_named_struct ( llty, fields)
417+ let lldiscrim = base:: get_discrim_val ( cx, e. span ,
418+ enum_did,
419+ variant_did) ;
420+ C_struct ( ~[ lldiscrim] )
453421 }
454422 Some ( ast:: def_struct( _) ) => {
455423 let ety = ty:: expr_ty ( cx. tcx , e) ;
@@ -475,6 +443,24 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
475443 C_named_struct ( llty, ~[ llstructbody ] )
476444 }
477445 }
446+ Some ( ast:: def_variant( tid, vid) ) => {
447+ let ety = ty:: expr_ty ( cx. tcx , e) ;
448+ let degen = ty:: enum_is_univariant ( cx. tcx , tid) ;
449+ let size = shape:: static_size_of_enum ( cx, ety) ;
450+
451+ let discrim = base:: get_discrim_val ( cx, e. span , tid, vid) ;
452+ let c_args = C_struct ( args. map ( |a| const_expr ( cx, * a) ) ) ;
453+
454+ let fields = if !degen {
455+ ~[ discrim, c_args]
456+ } else if size == 0 {
457+ ~[ discrim]
458+ } else {
459+ ~[ c_args]
460+ } ;
461+
462+ C_struct ( fields)
463+ }
478464 _ => cx. sess . span_bug ( e. span , ~"expected a struct def")
479465 }
480466 }
@@ -485,12 +471,13 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
485471 }
486472}
487473
488- fn trans_const( ccx: @crate_ctxt, e : @ast:: expr, id: ast:: node_id) {
474+ fn trans_const( ccx: @crate_ctxt, _e : @ast:: expr, id: ast:: node_id) {
489475 unsafe {
490476 let _icx = ccx. insn_ctxt ( "trans_const" ) ;
491477 let g = base:: get_item_val ( ccx, id) ;
492- let v = const_expr ( ccx, e) ;
493- ccx. const_values . insert ( id, v) ;
478+ // At this point, get_item_val has already translated the
479+ // constant's initializer to determine its LLVM type.
480+ let v = ccx. const_values . get ( id) ;
494481 llvm:: LLVMSetInitializer ( g, v) ;
495482 llvm:: LLVMSetGlobalConstant ( g, True ) ;
496483 }
0 commit comments