3
3
use std:: convert:: TryFrom ;
4
4
5
5
use rustc_hir:: Mutability ;
6
+ use rustc_middle:: ty:: layout:: HasTyCtxt ;
6
7
use rustc_middle:: ty:: { self , TyCtxt } ;
7
8
use rustc_middle:: {
8
9
mir:: { self , interpret:: ConstAlloc } ,
@@ -74,7 +75,7 @@ fn branches<'tcx>(
74
75
let field = ecx. mplace_field ( & place, i) . unwrap ( ) ;
75
76
const_to_valtree_inner ( ecx, & field)
76
77
} ) ;
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
78
79
// the variant again when just seeing a valtree.
79
80
let branches = variant. into_iter ( ) . chain ( fields) ;
80
81
Some ( ty:: ValTree :: Branch ( ecx. tcx . arena . alloc_from_iter ( branches. collect :: < Option < Vec < _ > > > ( ) ?) ) )
@@ -83,17 +84,13 @@ fn branches<'tcx>(
83
84
fn slice_branches < ' tcx > (
84
85
ecx : & CompileTimeEvalContext < ' tcx , ' tcx > ,
85
86
place : & MPlaceTy < ' tcx > ,
86
- n : u64 ,
87
87
) -> 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| {
89
90
let place_elem = ecx. mplace_index ( place, i) . unwrap ( ) ;
90
91
const_to_valtree_inner ( ecx, & place_elem)
91
92
} ) ;
92
93
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
94
Some ( ty:: ValTree :: Branch ( ecx. tcx . arena . alloc_from_iter ( branches. collect :: < Option < Vec < _ > > > ( ) ?) ) )
98
95
}
99
96
@@ -116,41 +113,26 @@ fn const_to_valtree_inner<'tcx>(
116
113
// agree with runtime equality tests.
117
114
ty:: FnPtr ( _) | ty:: RawPtr ( _) => None ,
118
115
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) ;
133
119
134
- const_to_valtree_inner ( ecx, & derefd_place)
135
- }
136
- }
120
+ const_to_valtree_inner ( ecx, & derefd_place)
137
121
}
138
122
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) ;
145
126
127
+ valtree
128
+ }
146
129
// Trait objects are not allowed in type level constants, as we have no concept for
147
130
// resolving their backing type, even if we can do that at const eval time. We may
148
131
// hypothetically be able to allow `dyn StructuralEq` trait objects in the future,
149
132
// but it is unclear if this is useful.
150
133
ty:: Dynamic ( ..) => None ,
151
134
152
135
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 ) ,
154
136
155
137
ty:: Adt ( def, _) => {
156
138
if def. variants ( ) . is_empty ( ) {
0 commit comments