@@ -4,7 +4,6 @@ use std::fmt::Write;
4
4
use rustc:: hir:: def_id:: DefId ;
5
5
use rustc:: hir:: map:: definitions:: DefPathData ;
6
6
use rustc:: middle:: const_val:: ConstVal ;
7
- use rustc_const_math:: { ConstInt , ConstUsize } ;
8
7
use rustc:: mir;
9
8
use rustc:: traits:: Reveal ;
10
9
use rustc:: ty:: layout:: { self , Layout , Size } ;
@@ -15,7 +14,6 @@ use rustc_data_structures::indexed_vec::Idx;
15
14
use syntax:: codemap:: { self , DUMMY_SP , Span } ;
16
15
use syntax:: ast;
17
16
use syntax:: abi:: Abi ;
18
- use syntax:: symbol:: Symbol ;
19
17
20
18
use error:: { EvalError , EvalResult } ;
21
19
use lvalue:: { Global , GlobalId , Lvalue , LvalueExtra } ;
@@ -43,9 +41,6 @@ pub struct EvalContext<'a, 'tcx: 'a> {
43
41
/// This prevents infinite loops and huge computations from freezing up const eval.
44
42
/// Remove once halting problem is solved.
45
43
pub ( crate ) steps_remaining : u64 ,
46
-
47
- /// Drop glue for arrays and slices
48
- pub ( crate ) seq_drop_glue : & ' tcx mir:: Mir < ' tcx > ,
49
44
}
50
45
51
46
/// A stack frame.
@@ -127,188 +122,13 @@ impl Default for ResourceLimits {
127
122
128
123
impl < ' a , ' tcx > EvalContext < ' a , ' tcx > {
129
124
pub fn new ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , limits : ResourceLimits ) -> Self {
130
- // Register array drop glue code
131
- let source_info = mir:: SourceInfo {
132
- span : DUMMY_SP ,
133
- scope : mir:: ARGUMENT_VISIBILITY_SCOPE
134
- } ;
135
- // i = 0; len = Len(*a0); goto head;
136
- let start_block = mir:: BasicBlockData {
137
- statements : vec ! [
138
- mir:: Statement {
139
- source_info,
140
- kind: mir:: StatementKind :: Assign (
141
- mir:: Lvalue :: Local ( mir:: Local :: new( 2 ) ) ,
142
- mir:: Rvalue :: Use ( mir:: Operand :: Constant ( Box :: new( mir:: Constant {
143
- span: DUMMY_SP ,
144
- ty: tcx. types. usize ,
145
- literal: mir:: Literal :: Value {
146
- value: ConstVal :: Integral ( ConstInt :: Usize ( ConstUsize :: new( 0 , tcx. sess. target. uint_type) . unwrap( ) ) ) ,
147
- } ,
148
- } ) ) )
149
- )
150
- } ,
151
- mir:: Statement {
152
- source_info,
153
- kind: mir:: StatementKind :: Assign (
154
- mir:: Lvalue :: Local ( mir:: Local :: new( 3 ) ) ,
155
- mir:: Rvalue :: Len ( mir:: Lvalue :: Projection ( Box :: new( mir:: LvalueProjection {
156
- base: mir:: Lvalue :: Local ( mir:: Local :: new( 1 ) ) ,
157
- elem: mir:: ProjectionElem :: Deref ,
158
- } ) ) ) ,
159
- )
160
- } ,
161
- ] ,
162
- terminator : Some ( mir:: Terminator {
163
- source_info : source_info,
164
- kind : mir:: TerminatorKind :: Goto { target : mir:: BasicBlock :: new ( 1 ) } ,
165
- } ) ,
166
- is_cleanup : false
167
- } ;
168
- // head: done = i == len; switch done { 1 => ret, 0 => loop }
169
- let head = mir:: BasicBlockData {
170
- statements : vec ! [
171
- mir:: Statement {
172
- source_info,
173
- kind: mir:: StatementKind :: Assign (
174
- mir:: Lvalue :: Local ( mir:: Local :: new( 4 ) ) ,
175
- mir:: Rvalue :: BinaryOp (
176
- mir:: BinOp :: Eq ,
177
- mir:: Operand :: Consume ( mir:: Lvalue :: Local ( mir:: Local :: new( 2 ) ) ) ,
178
- mir:: Operand :: Consume ( mir:: Lvalue :: Local ( mir:: Local :: new( 3 ) ) ) ,
179
- )
180
- )
181
- } ,
182
- ] ,
183
- terminator : Some ( mir:: Terminator {
184
- source_info : source_info,
185
- kind : mir:: TerminatorKind :: SwitchInt {
186
- targets : vec ! [
187
- mir:: BasicBlock :: new( 2 ) ,
188
- mir:: BasicBlock :: new( 4 ) ,
189
- ] ,
190
- discr : mir:: Operand :: Consume ( mir:: Lvalue :: Local ( mir:: Local :: new ( 4 ) ) ) ,
191
- switch_ty : tcx. types . bool ,
192
- values : vec ! [ ConstInt :: U8 ( 0 ) ] . into ( ) ,
193
- } ,
194
- } ) ,
195
- is_cleanup : false
196
- } ;
197
- // loop: drop (*a0)[i]; goto inc;
198
- let loop_ = mir:: BasicBlockData {
199
- statements : Vec :: new ( ) ,
200
- terminator : Some ( mir:: Terminator {
201
- source_info : source_info,
202
- kind : mir:: TerminatorKind :: Drop {
203
- target : mir:: BasicBlock :: new ( 3 ) ,
204
- unwind : None ,
205
- location : mir:: Lvalue :: Projection ( Box :: new (
206
- mir:: LvalueProjection {
207
- base : mir:: Lvalue :: Projection ( Box :: new (
208
- mir:: LvalueProjection {
209
- base : mir:: Lvalue :: Local ( mir:: Local :: new ( 1 ) ) ,
210
- elem : mir:: ProjectionElem :: Deref ,
211
- }
212
- ) ) ,
213
- elem : mir:: ProjectionElem :: Index ( mir:: Operand :: Consume ( mir:: Lvalue :: Local ( mir:: Local :: new ( 2 ) ) ) ) ,
214
- }
215
- ) ) ,
216
- } ,
217
- } ) ,
218
- is_cleanup : false
219
- } ;
220
- // inc: i++; goto head;
221
- let inc = mir:: BasicBlockData {
222
- statements : vec ! [
223
- mir:: Statement {
224
- source_info,
225
- kind: mir:: StatementKind :: Assign (
226
- mir:: Lvalue :: Local ( mir:: Local :: new( 2 ) ) ,
227
- mir:: Rvalue :: BinaryOp (
228
- mir:: BinOp :: Add ,
229
- mir:: Operand :: Consume ( mir:: Lvalue :: Local ( mir:: Local :: new( 2 ) ) ) ,
230
- mir:: Operand :: Constant ( Box :: new( mir:: Constant {
231
- span: DUMMY_SP ,
232
- ty: tcx. types. usize ,
233
- literal: mir:: Literal :: Value {
234
- value: ConstVal :: Integral ( ConstInt :: Usize ( ConstUsize :: new( 1 , tcx. sess. target. uint_type) . unwrap( ) ) ) ,
235
- } ,
236
- } ) ) ,
237
- )
238
- )
239
- } ,
240
- ] ,
241
- terminator : Some ( mir:: Terminator {
242
- source_info : source_info,
243
- kind : mir:: TerminatorKind :: Goto { target : mir:: BasicBlock :: new ( 1 ) } ,
244
- } ) ,
245
- is_cleanup : false
246
- } ;
247
- // ret: return;
248
- let ret = mir:: BasicBlockData {
249
- statements : Vec :: new ( ) ,
250
- terminator : Some ( mir:: Terminator {
251
- source_info : source_info,
252
- kind : mir:: TerminatorKind :: Return ,
253
- } ) ,
254
- is_cleanup : false
255
- } ;
256
- let locals = vec ! [
257
- mir:: LocalDecl {
258
- mutability: mir:: Mutability :: Mut ,
259
- ty: tcx. mk_nil( ) ,
260
- name: None ,
261
- source_info,
262
- is_user_variable: false ,
263
- } ,
264
- mir:: LocalDecl {
265
- mutability: mir:: Mutability :: Mut ,
266
- ty: tcx. mk_mut_ptr( tcx. mk_slice( tcx. mk_param( 0 , Symbol :: intern( "T" ) ) ) ) ,
267
- name: None ,
268
- source_info,
269
- is_user_variable: false ,
270
- } ,
271
- mir:: LocalDecl {
272
- mutability: mir:: Mutability :: Mut ,
273
- ty: tcx. types. usize ,
274
- name: None ,
275
- source_info,
276
- is_user_variable: false ,
277
- } ,
278
- mir:: LocalDecl {
279
- mutability: mir:: Mutability :: Mut ,
280
- ty: tcx. types. usize ,
281
- name: None ,
282
- source_info,
283
- is_user_variable: false ,
284
- } ,
285
- mir:: LocalDecl {
286
- mutability: mir:: Mutability :: Mut ,
287
- ty: tcx. types. bool ,
288
- name: None ,
289
- source_info,
290
- is_user_variable: false ,
291
- } ,
292
- ] ;
293
- let seq_drop_glue = mir:: Mir :: new (
294
- vec ! [ start_block, head, loop_, inc, ret] . into_iter ( ) . collect ( ) ,
295
- Vec :: new ( ) . into_iter ( ) . collect ( ) , // vis scopes
296
- Vec :: new ( ) . into_iter ( ) . collect ( ) , // promoted
297
- tcx. mk_nil ( ) , // return type
298
- locals. into_iter ( ) . collect ( ) ,
299
- 1 , // arg_count
300
- Vec :: new ( ) , // upvars
301
- DUMMY_SP ,
302
- ) ;
303
- let seq_drop_glue = tcx. alloc_mir ( seq_drop_glue) ;
304
125
EvalContext {
305
126
tcx,
306
127
memory : Memory :: new ( & tcx. data_layout , limits. memory_size ) ,
307
128
globals : HashMap :: new ( ) ,
308
129
stack : Vec :: new ( ) ,
309
130
stack_limit : limits. stack_limit ,
310
131
steps_remaining : limits. step_limit ,
311
- seq_drop_glue : seq_drop_glue,
312
132
}
313
133
}
314
134
@@ -823,8 +643,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
823
643
self . write_primval ( dest, PrimVal :: Ptr ( ptr) , dest_ty) ?;
824
644
}
825
645
826
- NullaryOp ( mir:: NullOp :: SizeOf , _ty) => {
827
- unimplemented ! ( )
646
+ NullaryOp ( mir:: NullOp :: SizeOf , ty) => {
647
+ let size = self . type_size ( ty) ?. expect ( "SizeOf nullary MIR operator called for unsized type" ) ;
648
+ self . write_primval ( dest, PrimVal :: from_u128 ( size as u128 ) , dest_ty) ?;
828
649
}
829
650
830
651
Cast ( kind, ref operand, cast_ty) => {
@@ -1020,6 +841,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1020
841
}
1021
842
}
1022
843
844
+ pub ( super ) fn pointer_offset ( & self , ptr : Pointer , pointee_ty : Ty < ' tcx > , offset : i64 ) -> EvalResult < ' tcx , Pointer > {
845
+ // FIXME: assuming here that type size is < i64::max_value()
846
+ let pointee_size = self . type_size ( pointee_ty) ?. expect ( "cannot offset a pointer to an unsized type" ) as i64 ;
847
+ // FIXME: Check overflow, out-of-bounds
848
+ Ok ( ptr. signed_offset ( offset * pointee_size) )
849
+ }
850
+
1023
851
pub ( super ) fn eval_operand_to_primval ( & mut self , op : & mir:: Operand < ' tcx > ) -> EvalResult < ' tcx , PrimVal > {
1024
852
let value = self . eval_operand ( op) ?;
1025
853
let ty = self . operand_ty ( op) ;
0 commit comments