@@ -30,8 +30,10 @@ pub(crate) fn const_caller_location(
3030 ConstValue :: Scalar ( loc_place. ptr )
3131}
3232
33- // this function uses `unwrap` copiously, because an already validated constant
34- // must have valid fields and can thus never fail outside of compiler bugs
33+ /// This function uses `unwrap` copiously, because an already validated constant
34+ /// must have valid fields and can thus never fail outside of compiler bugs. However, it is
35+ /// invoked from the pretty printer, where it can receive enums with no variants and e.g.
36+ /// `read_discriminant` needs to be able to handle that.
3537pub ( crate ) fn destructure_const < ' tcx > (
3638 tcx : TyCtxt < ' tcx > ,
3739 param_env : ty:: ParamEnv < ' tcx > ,
@@ -41,17 +43,21 @@ pub(crate) fn destructure_const<'tcx>(
4143 let ecx = mk_eval_cx ( tcx, DUMMY_SP , param_env, false ) ;
4244 let op = ecx. eval_const_to_op ( val, None ) . unwrap ( ) ;
4345
44- let variant = ecx. read_discriminant ( op) . unwrap ( ) . 1 ;
45-
4646 // We go to `usize` as we cannot allocate anything bigger anyway.
47- let field_count = match val. ty . kind {
48- ty:: Array ( _, len) => usize:: try_from ( len. eval_usize ( tcx, param_env) ) . unwrap ( ) ,
49- ty:: Adt ( def, _) => def. variants [ variant] . fields . len ( ) ,
50- ty:: Tuple ( substs) => substs. len ( ) ,
47+ let ( field_count, variant, down) = match val. ty . kind {
48+ ty:: Array ( _, len) => ( usize:: try_from ( len. eval_usize ( tcx, param_env) ) . unwrap ( ) , None , op) ,
49+ ty:: Adt ( def, _) if def. variants . is_empty ( ) => {
50+ return mir:: DestructuredConst { variant : None , fields : tcx. arena . alloc_slice ( & [ ] ) } ;
51+ }
52+ ty:: Adt ( def, _) => {
53+ let variant = ecx. read_discriminant ( op) . unwrap ( ) . 1 ;
54+ let down = ecx. operand_downcast ( op, variant) . unwrap ( ) ;
55+ ( def. variants [ variant] . fields . len ( ) , Some ( variant) , down)
56+ }
57+ ty:: Tuple ( substs) => ( substs. len ( ) , None , op) ,
5158 _ => bug ! ( "cannot destructure constant {:?}" , val) ,
5259 } ;
5360
54- let down = ecx. operand_downcast ( op, variant) . unwrap ( ) ;
5561 let fields_iter = ( 0 ..field_count) . map ( |i| {
5662 let field_op = ecx. operand_field ( down, i) . unwrap ( ) ;
5763 let val = op_to_const ( & ecx, field_op) ;
0 commit comments