@@ -11,7 +11,8 @@ use rustc_middle::{
1111use  rustc_span:: { source_map:: DUMMY_SP ,  symbol:: Symbol } ; 
1212
1313use  crate :: interpret:: { 
14-     intern_const_alloc_recursive,  ConstValue ,  InternKind ,  InterpCx ,  MPlaceTy ,  MemPlaceMeta ,  Scalar , 
14+     intern_const_alloc_recursive,  ConstValue ,  InternKind ,  InterpCx ,  InterpResult ,  MPlaceTy , 
15+     MemPlaceMeta ,  Scalar , 
1516} ; 
1617
1718mod  error; 
@@ -132,42 +133,39 @@ fn const_to_valtree_inner<'tcx>(
132133    } 
133134} 
134135
135- /// This function uses `unwrap` copiously, because an already validated constant 
136- /// must have valid fields and can thus never fail outside of compiler bugs. However, it is 
137- /// invoked from the pretty printer, where it can receive enums with no variants and e.g. 
138- /// `read_discriminant` needs to be able to handle that. 
139- pub ( crate )  fn  destructure_const < ' tcx > ( 
136+ /// This function should never fail for validated constants. However, it is also invoked from the 
137+ /// pretty printer which might attempt to format invalid constants and in that case it might fail. 
138+ pub ( crate )  fn  try_destructure_const < ' tcx > ( 
140139    tcx :  TyCtxt < ' tcx > , 
141140    param_env :  ty:: ParamEnv < ' tcx > , 
142141    val :  ty:: Const < ' tcx > , 
143- )  -> mir:: DestructuredConst < ' tcx >  { 
142+ )  -> InterpResult < ' tcx ,   mir:: DestructuredConst < ' tcx > >  { 
144143    trace ! ( "destructure_const: {:?}" ,  val) ; 
145144    let  ecx = mk_eval_cx ( tcx,  DUMMY_SP ,  param_env,  false ) ; 
146-     let  op = ecx. const_to_op ( val,  None ) . unwrap ( ) ; 
145+     let  op = ecx. const_to_op ( val,  None ) ? ; 
147146
148147    // We go to `usize` as we cannot allocate anything bigger anyway. 
149148    let  ( field_count,  variant,  down)  = match  val. ty ( ) . kind ( )  { 
150149        ty:: Array ( _,  len)  => ( usize:: try_from ( len. eval_usize ( tcx,  param_env) ) . unwrap ( ) ,  None ,  op) , 
151-         ty:: Adt ( def,  _)  if  def. variants . is_empty ( )  => { 
152-             return  mir:: DestructuredConst  {  variant :  None ,  fields :  & [ ]  } ; 
153-         } 
154150        ty:: Adt ( def,  _)  => { 
155-             let  variant = ecx. read_discriminant ( & op) . unwrap ( ) . 1 ; 
156-             let  down = ecx. operand_downcast ( & op,  variant) . unwrap ( ) ; 
151+             let  variant = ecx. read_discriminant ( & op) ? . 1 ; 
152+             let  down = ecx. operand_downcast ( & op,  variant) ? ; 
157153            ( def. variants [ variant] . fields . len ( ) ,  Some ( variant) ,  down) 
158154        } 
159155        ty:: Tuple ( substs)  => ( substs. len ( ) ,  None ,  op) , 
160156        _ => bug ! ( "cannot destructure constant {:?}" ,  val) , 
161157    } ; 
162158
163-     let  fields_iter = ( 0 ..field_count) . map ( |i| { 
164-         let  field_op = ecx. operand_field ( & down,  i) . unwrap ( ) ; 
165-         let  val = op_to_const ( & ecx,  & field_op) ; 
166-         ty:: Const :: from_value ( tcx,  val,  field_op. layout . ty ) 
167-     } ) ; 
168-     let  fields = tcx. arena . alloc_from_iter ( fields_iter) ; 
159+     let  fields = ( 0 ..field_count) 
160+         . map ( |i| { 
161+             let  field_op = ecx. operand_field ( & down,  i) ?; 
162+             let  val = op_to_const ( & ecx,  & field_op) ; 
163+             Ok ( ty:: Const :: from_value ( tcx,  val,  field_op. layout . ty ) ) 
164+         } ) 
165+         . collect :: < InterpResult < ' tcx ,  Vec < _ > > > ( ) ?; 
166+     let  fields = tcx. arena . alloc_from_iter ( fields) ; 
169167
170-     mir:: DestructuredConst  {  variant,  fields } 
168+     Ok ( mir:: DestructuredConst  {  variant,  fields } ) 
171169} 
172170
173171pub ( crate )  fn  deref_const < ' tcx > ( 
0 commit comments