@@ -369,15 +369,51 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
369
369
ast:: expr_path ( pth) => {
370
370
assert pth. types . len ( ) == 0 ;
371
371
match cx. tcx . def_map . find ( e. id ) {
372
- Some ( ast:: def_fn( def_id, _) ) => {
373
- assert ast_util:: is_local ( def_id) ;
374
- let f = base:: get_item_val ( cx, def_id. node ) ;
375
- C_struct ( ~[ f, C_null ( T_opaque_box_ptr ( cx) ) ] )
376
- }
377
- Some ( ast:: def_const( def_id) ) => {
378
- get_const_val ( cx, def_id)
379
- }
380
- _ => cx. sess . span_bug ( e. span , ~"expected a const or fn def")
372
+ Some ( ast:: def_fn( def_id, _) ) => {
373
+ assert ast_util:: is_local ( def_id) ;
374
+ let f = base:: get_item_val ( cx, def_id. node ) ;
375
+ C_struct ( ~[ f, C_null ( T_opaque_box_ptr ( cx) ) ] )
376
+ }
377
+ Some ( ast:: def_const( def_id) ) => {
378
+ get_const_val ( cx, def_id)
379
+ }
380
+ Some ( ast:: def_variant( enum_did, variant_did) ) => {
381
+ // Note that we know this is a C-like (nullary) enum variant,
382
+ // or we wouldn't have gotten here -- the constant checker
383
+ // forbids paths that don't map to C-like enum variants.
384
+ let ety = ty:: expr_ty ( cx. tcx , e) ;
385
+ let llty = type_of:: type_of ( cx, ety) ;
386
+ let llstructtys = lib:: llvm:: struct_element_types ( llty) ;
387
+
388
+ // Can't use `discrims` from the crate context here because
389
+ // those discriminants have an extra level of indirection,
390
+ // and there's no LLVM constant load instruction.
391
+ let mut lldiscrim_opt = None ;
392
+ for ty:: enum_variants( cx. tcx, enum_did) . each |variant_info| {
393
+ if variant_info. id == variant_did {
394
+ lldiscrim_opt = Some ( C_int ( cx,
395
+ variant_info. disr_val ) ) ;
396
+ break ;
397
+ }
398
+ }
399
+
400
+ let lldiscrim;
401
+ match lldiscrim_opt {
402
+ None => {
403
+ cx. tcx . sess . span_bug ( e. span ,
404
+ ~"didn' t find discriminant?!") ;
405
+ }
406
+ Some ( found_lldiscrim) => {
407
+ lldiscrim = found_lldiscrim;
408
+ }
409
+ }
410
+
411
+ C_named_struct ( llty, ~[ lldiscrim, C_null ( llstructtys[ 1 ] ) ] )
412
+ }
413
+ _ => {
414
+ cx. sess . span_bug ( e. span ,
415
+ ~"expected a const , fn, or variant def")
416
+ }
381
417
}
382
418
}
383
419
ast:: expr_paren ( e) => { return const_expr ( cx, e) ; }
0 commit comments