@@ -6,14 +6,14 @@ use rustc_hir::Mutability;
66use rustc_middle:: ty:: { self , TyCtxt } ;
77use rustc_middle:: {
88 mir:: { self , interpret:: ConstAlloc } ,
9- ty:: { ScalarInt , Ty } ,
9+ ty:: ScalarInt ,
1010} ;
1111use rustc_span:: { source_map:: DUMMY_SP , symbol:: Symbol } ;
1212use rustc_target:: abi:: VariantIdx ;
1313
1414use crate :: interpret:: {
15- intern_const_alloc_recursive, ConstValue , InternKind , InterpCx , InterpResult , MPlaceTy ,
16- MemPlaceMeta , Scalar ,
15+ intern_const_alloc_recursive, ConstValue , Immediate , InternKind , InterpCx , InterpResult ,
16+ MPlaceTy , MemPlaceMeta , Scalar ,
1717} ;
1818
1919mod error;
@@ -80,19 +80,28 @@ fn branches<'tcx>(
8080 Some ( ty:: ValTree :: Branch ( ecx. tcx . arena . alloc_from_iter ( branches. collect :: < Option < Vec < _ > > > ( ) ?) ) )
8181}
8282
83+ fn slice_branches < ' tcx > (
84+ ecx : & CompileTimeEvalContext < ' tcx , ' tcx > ,
85+ place : & MPlaceTy < ' tcx > ,
86+ n : u64 ,
87+ ) -> Option < ty:: ValTree < ' tcx > > {
88+ let elems = ( 0 ..n) . map ( |i| {
89+ let place_elem = ecx. mplace_index ( place, i) . unwrap ( ) ;
90+ const_to_valtree_inner ( ecx, & place_elem)
91+ } ) ;
92+
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+
97+ Some ( ty:: ValTree :: Branch ( ecx. tcx . arena . alloc_from_iter ( branches. collect :: < Option < Vec < _ > > > ( ) ?) ) )
98+ }
99+
83100#[ instrument( skip( ecx) , level = "debug" ) ]
84101fn const_to_valtree_inner < ' tcx > (
85102 ecx : & CompileTimeEvalContext < ' tcx , ' tcx > ,
86103 place : & MPlaceTy < ' tcx > ,
87104) -> Option < ty:: ValTree < ' tcx > > {
88- // We only want to use raw bytes in ValTrees for string slices or &[<integer_ty>]
89- let use_bytes_for_ref = |ty : Ty < ' tcx > | -> bool {
90- match ty. kind ( ) {
91- ty:: Str | ty:: Char | ty:: Uint ( _) | ty:: Int ( _) | ty:: Bool => true ,
92- _ => false ,
93- }
94- } ;
95-
96105 match place. layout . ty . kind ( ) {
97106 ty:: FnDef ( ..) => Some ( ty:: ValTree :: zst ( ) ) ,
98107 ty:: Bool | ty:: Int ( _) | ty:: Uint ( _) | ty:: Float ( _) | ty:: Char => {
@@ -107,75 +116,52 @@ fn const_to_valtree_inner<'tcx>(
107116 // agree with runtime equality tests.
108117 ty:: FnPtr ( _) | ty:: RawPtr ( _) => None ,
109118
110- ty:: Ref ( _, ref_ty, _) if place. layout . ty . is_slice ( ) => {
111- match ecx. try_read_immediate_from_mplace ( & place) {
112- Ok ( Some ( imm) ) => {
113- // `imm` is a ScalarPair. We try to get the underlying bytes behind that
114- // fat pointer for string slices and slices of integer types. For any other
115- // slice types we use `branches` to recursively construct the Valtree.
116-
117- if use_bytes_for_ref ( * ref_ty) {
118- let ( alloc, range) = ecx. get_alloc_from_imm_scalar_pair ( imm) ;
119- let alloc_bytes = match alloc. get_bytes ( & ecx. tcx , range) {
120- Ok ( bytes) => bytes,
121- Err ( _e) => return None ,
122- } ;
123- debug ! ( ?alloc_bytes) ;
124-
125- let bytes = ecx. tcx . arena . alloc_slice ( alloc_bytes) ;
126- let len = bytes. len ( ) ;
127- debug ! ( ?bytes, ?len) ;
128-
129- let slice = ty:: ValSlice { bytes} ;
130-
131- Some ( ty:: ValTree :: SliceOrStr ( slice) )
132- } else {
133- let derefd = ecx. deref_operand ( & imm. into ( ) ) . expect ( & format ! ( "couldnt deref {:?}" , imm) ) ;
134- debug ! ( "derefd: {:?}" , derefd) ;
135-
136- let derefd_imm = match ecx. try_read_immediate_from_mplace ( & derefd) {
137- Ok ( Some ( imm) ) => imm,
138- _ => return None ,
139- } ;
140- debug ! ( ?derefd_imm) ;
141-
142- let tcx = ecx. tcx . tcx ;
143- let scalar_len= derefd. meta . unwrap_meta ( ) ;
144- let len = match scalar_len {
145- Scalar :: Int ( int) => {
146- int. try_to_machine_usize ( tcx) . expect ( & format ! ( "Expected a valid ScalarInt in {:?}" , scalar_len) )
147- }
148- _ => bug ! ( "expected a ScalarInt in meta data for {:?}" , place) ,
149- } ;
150- debug ! ( ?len) ;
151-
152- let valtree = branches ( ecx, place, len. try_into ( ) . expect ( "BLA" ) , None ) ;
153- debug ! ( ?valtree) ;
154-
155- valtree
119+ ty:: Ref ( _, inner_ty, _) => {
120+ match inner_ty. kind ( ) {
121+ ty:: Slice ( _) | ty:: Str => {
122+ match ecx. try_read_immediate_from_mplace ( & place) {
123+ Ok ( Some ( imm) ) => {
124+ let mplace_ref = ecx. ref_to_mplace ( & imm) . unwrap ( ) ;
125+ let derefd = ecx. deref_operand ( & place. into ( ) ) . expect ( & format ! ( "couldnt deref {:?}" , imm) ) ;
126+ debug ! ( ?mplace_ref, ?derefd) ;
127+
128+ let len = match imm. imm {
129+ Immediate :: ScalarPair ( _, b) => {
130+ let len = b. to_machine_usize ( & ecx. tcx . tcx ) . unwrap ( ) ;
131+ len
132+ }
133+ _ => bug ! ( "expected ScalarPair for &[T] or &str" ) ,
134+ } ;
135+ debug ! ( ?len) ;
136+
137+ let valtree = slice_branches ( ecx, & derefd, len) ;
138+ debug ! ( ?valtree) ;
139+
140+ valtree
141+ }
142+ _ => {
143+ None
144+ }
156145 }
157146 }
158147 _ => {
159- None
160- }
161- }
162- }
148+ let imm = ecx. try_read_immediate_from_mplace ( & place) . unwrap_or_else ( |e| bug ! ( "couldnt read immediate from {:?}, error: {:?}" , place, e) ) ;
163149
164- ty:: Ref ( _, inner_ty, _) => {
165- debug ! ( "Ref with inner_ty: {:?}" , inner_ty) ;
166- let imm = ecx. try_read_immediate_from_mplace ( & place) . unwrap_or_else ( |e| bug ! ( "couldnt read immediate from {:?}, error: {:?}" , place, e) ) ;
167- match imm {
168- Some ( imm) => {
169- debug ! ( ?imm) ;
150+ match imm {
151+ Some ( imm) => {
152+ debug ! ( ?imm) ;
170153
171- let derefd_place = ecx. deref_mplace ( place) . unwrap_or_else ( |e| bug ! ( "couldn't deref {:?}, error: {:?}" , place, e) ) ;
172- debug ! ( ?derefd_place) ;
154+ let derefd_place = ecx. deref_operand ( & place. into ( ) ) . unwrap_or_else ( |e| bug ! ( "couldn't deref {:?}, error: {:?}" , place, e) ) ;
155+ debug ! ( ?derefd_place) ;
173156
174- const_to_valtree_inner ( ecx, & derefd_place)
157+ const_to_valtree_inner ( ecx, & derefd_place)
158+ }
159+ None => bug ! ( "couldn't read immediate from {:?}" , place) ,
160+ }
175161 }
176- None => None ,
177162 }
178163 }
164+
179165 ty:: Str => {
180166 bug ! ( "ty::Str should have been handled in ty::Ref branch that uses raw bytes" ) ;
181167 }
0 commit comments