33use std:: convert:: TryFrom ;
44
55use rustc_hir:: Mutability ;
6+ use rustc_middle:: ty:: layout:: HasTyCtxt ;
67use rustc_middle:: ty:: { self , TyCtxt } ;
78use rustc_middle:: {
89 mir:: { self , interpret:: ConstAlloc } ,
@@ -74,7 +75,7 @@ fn branches<'tcx>(
7475 let field = ecx. mplace_field ( & place, i) . unwrap ( ) ;
7576 const_to_valtree_inner ( ecx, & field)
7677 } ) ;
77- // For enums, we preped their variant index before the variant's fields so we can figure out
78+ // For enums, we prepend their variant index before the variant's fields so we can figure out
7879 // the variant again when just seeing a valtree.
7980 let branches = variant. into_iter ( ) . chain ( fields) ;
8081 Some ( ty:: ValTree :: Branch ( ecx. tcx . arena . alloc_from_iter ( branches. collect :: < Option < Vec < _ > > > ( ) ?) ) )
@@ -83,17 +84,13 @@ fn branches<'tcx>(
8384fn slice_branches < ' tcx > (
8485 ecx : & CompileTimeEvalContext < ' tcx , ' tcx > ,
8586 place : & MPlaceTy < ' tcx > ,
86- n : u64 ,
8787) -> Option < ty:: ValTree < ' tcx > > {
88- let elems = ( 0 ..n) . map ( |i| {
88+ let n = place. len ( & ecx. tcx ( ) ) . expect ( & format ! ( "expected to use len of place {:?}" , place) ) ;
89+ let branches = ( 0 ..n) . map ( |i| {
8990 let place_elem = ecx. mplace_index ( place, i) . unwrap ( ) ;
9091 const_to_valtree_inner ( ecx, & place_elem)
9192 } ) ;
9293
93- // Need `len` for the ValTree -> ConstValue conversion
94- let len = Some ( Some ( ty:: ValTree :: Leaf ( ScalarInt :: from ( n) ) ) ) ;
95- let branches = len. into_iter ( ) . chain ( elems) ;
96-
9794 Some ( ty:: ValTree :: Branch ( ecx. tcx . arena . alloc_from_iter ( branches. collect :: < Option < Vec < _ > > > ( ) ?) ) )
9895}
9996
@@ -116,41 +113,26 @@ fn const_to_valtree_inner<'tcx>(
116113 // agree with runtime equality tests.
117114 ty:: FnPtr ( _) | ty:: RawPtr ( _) => None ,
118115
119- ty:: Ref ( _, inner_ty, _) => {
120- match inner_ty. kind ( ) {
121- ty:: Slice ( _) | ty:: Str => {
122- let derefd = ecx. deref_operand ( & place. into ( ) ) . unwrap ( ) ;
123- debug ! ( ?derefd) ;
124- let len = derefd. len ( & ecx. tcx . tcx ) . unwrap ( ) ;
125- let valtree = slice_branches ( ecx, & derefd, len) ;
126- debug ! ( ?valtree) ;
127-
128- valtree
129- }
130- _ => {
131- let derefd_place = ecx. deref_operand ( & place. into ( ) ) . unwrap_or_else ( |e| bug ! ( "couldn't deref {:?}, error: {:?}" , place, e) ) ;
132- debug ! ( ?derefd_place) ;
116+ ty:: Ref ( _, _, _) => {
117+ let derefd_place = ecx. deref_operand ( & place. into ( ) ) . unwrap_or_else ( |e| bug ! ( "couldn't deref {:?}, error: {:?}" , place, e) ) ;
118+ debug ! ( ?derefd_place) ;
133119
134- const_to_valtree_inner ( ecx, & derefd_place)
135- }
136- }
120+ const_to_valtree_inner ( ecx, & derefd_place)
137121 }
138122
139- ty:: Str => {
140- bug ! ( "ty::Str should have been handled in ty::Ref branch that uses raw bytes" ) ;
141- }
142- ty:: Slice ( _) => {
143- bug ! ( "should have been handled in the Ref arm" ) ;
144- }
123+ ty:: Str | ty:: Slice ( _) | ty:: Array ( _, _) => {
124+ let valtree = slice_branches ( ecx, place) ;
125+ debug ! ( ?valtree) ;
145126
127+ valtree
128+ }
146129 // Trait objects are not allowed in type level constants, as we have no concept for
147130 // resolving their backing type, even if we can do that at const eval time. We may
148131 // hypothetically be able to allow `dyn StructuralEq` trait objects in the future,
149132 // but it is unclear if this is useful.
150133 ty:: Dynamic ( ..) => None ,
151134
152135 ty:: Tuple ( substs) => branches ( ecx, place, substs. len ( ) , None ) ,
153- ty:: Array ( _, len) => branches ( ecx, place, usize:: try_from ( len. eval_usize ( ecx. tcx . tcx , ecx. param_env ) ) . unwrap ( ) , None ) ,
154136
155137 ty:: Adt ( def, _) => {
156138 if def. variants ( ) . is_empty ( ) {
0 commit comments