1
1
use std:: borrow:: { Borrow , Cow } ;
2
2
use std:: fmt;
3
3
use std:: hash:: Hash ;
4
- use std:: ops:: ControlFlow ;
5
4
6
5
use rustc_ast:: Mutability ;
7
6
use rustc_data_structures:: fx:: { FxHashMap , FxIndexMap , IndexEntry } ;
8
7
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
9
8
use rustc_hir:: { self as hir, CRATE_HIR_ID , LangItem } ;
10
9
use rustc_middle:: mir:: AssertMessage ;
11
10
use rustc_middle:: query:: TyCtxtAt ;
12
- use rustc_middle:: ty:: layout:: { FnAbiOf , TyAndLayout } ;
11
+ use rustc_middle:: ty:: layout:: TyAndLayout ;
13
12
use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
14
13
use rustc_middle:: { bug, mir} ;
15
14
use rustc_span:: Span ;
@@ -23,9 +22,9 @@ use crate::errors::{LongRunning, LongRunningWarn};
23
22
use crate :: fluent_generated as fluent;
24
23
use crate :: interpret:: {
25
24
self , AllocId , AllocRange , ConstAllocation , CtfeProvenance , FnArg , Frame , GlobalAlloc , ImmTy ,
26
- InterpCx , InterpResult , MPlaceTy , OpTy , Pointer , PointerArithmetic , RangeSet , Scalar ,
27
- StackPopCleanup , compile_time_machine , interp_ok, throw_exhaust, throw_inval, throw_ub,
28
- throw_ub_custom , throw_unsup , throw_unsup_format,
25
+ InterpCx , InterpResult , MPlaceTy , OpTy , Pointer , RangeSet , Scalar , compile_time_machine ,
26
+ interp_ok, throw_exhaust, throw_inval, throw_ub, throw_ub_custom , throw_unsup ,
27
+ throw_unsup_format,
29
28
} ;
30
29
31
30
/// When hitting this many interpreted terminators we emit a deny by default lint
@@ -227,8 +226,8 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
227
226
& mut self ,
228
227
instance : ty:: Instance < ' tcx > ,
229
228
args : & [ FnArg < ' tcx > ] ,
230
- dest : & MPlaceTy < ' tcx > ,
231
- ret : Option < mir:: BasicBlock > ,
229
+ _dest : & MPlaceTy < ' tcx > ,
230
+ _ret : Option < mir:: BasicBlock > ,
232
231
) -> InterpResult < ' tcx , Option < ty:: Instance < ' tcx > > > {
233
232
let def_id = instance. def_id ( ) ;
234
233
@@ -260,85 +259,10 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
260
259
) ;
261
260
262
261
return interp_ok ( Some ( new_instance) ) ;
263
- } else if self . tcx . is_lang_item ( def_id, LangItem :: AlignOffset ) {
264
- let args = self . copy_fn_args ( args) ;
265
- // For align_offset, we replace the function call if the pointer has no address.
266
- match self . align_offset ( instance, & args, dest, ret) ? {
267
- ControlFlow :: Continue ( ( ) ) => return interp_ok ( Some ( instance) ) ,
268
- ControlFlow :: Break ( ( ) ) => return interp_ok ( None ) ,
269
- }
270
262
}
271
263
interp_ok ( Some ( instance) )
272
264
}
273
265
274
- /// `align_offset(ptr, target_align)` needs special handling in const eval, because the pointer
275
- /// may not have an address.
276
- ///
277
- /// If `ptr` does have a known address, then we return `Continue(())` and the function call should
278
- /// proceed as normal.
279
- ///
280
- /// If `ptr` doesn't have an address, but its underlying allocation's alignment is at most
281
- /// `target_align`, then we call the function again with an dummy address relative to the
282
- /// allocation.
283
- ///
284
- /// If `ptr` doesn't have an address and `target_align` is stricter than the underlying
285
- /// allocation's alignment, then we return `usize::MAX` immediately.
286
- fn align_offset (
287
- & mut self ,
288
- instance : ty:: Instance < ' tcx > ,
289
- args : & [ OpTy < ' tcx > ] ,
290
- dest : & MPlaceTy < ' tcx > ,
291
- ret : Option < mir:: BasicBlock > ,
292
- ) -> InterpResult < ' tcx , ControlFlow < ( ) > > {
293
- assert_eq ! ( args. len( ) , 2 ) ;
294
-
295
- let ptr = self . read_pointer ( & args[ 0 ] ) ?;
296
- let target_align = self . read_scalar ( & args[ 1 ] ) ?. to_target_usize ( self ) ?;
297
-
298
- if !target_align. is_power_of_two ( ) {
299
- throw_ub_custom ! (
300
- fluent:: const_eval_align_offset_invalid_align,
301
- target_align = target_align,
302
- ) ;
303
- }
304
-
305
- match self . ptr_try_get_alloc_id ( ptr, 0 ) {
306
- Ok ( ( alloc_id, offset, _extra) ) => {
307
- let ( _size, alloc_align, _kind) = self . get_alloc_info ( alloc_id) ;
308
-
309
- if target_align <= alloc_align. bytes ( ) {
310
- // Extract the address relative to the allocation base that is definitely
311
- // sufficiently aligned and call `align_offset` again.
312
- let addr = ImmTy :: from_uint ( offset. bytes ( ) , args[ 0 ] . layout ) . into ( ) ;
313
- let align = ImmTy :: from_uint ( target_align, args[ 1 ] . layout ) . into ( ) ;
314
- let fn_abi = self . fn_abi_of_instance ( instance, ty:: List :: empty ( ) ) ?;
315
-
316
- // Push the stack frame with our own adjusted arguments.
317
- self . init_stack_frame (
318
- instance,
319
- self . load_mir ( instance. def , None ) ?,
320
- fn_abi,
321
- & [ FnArg :: Copy ( addr) , FnArg :: Copy ( align) ] ,
322
- /* with_caller_location = */ false ,
323
- dest,
324
- StackPopCleanup :: Goto { ret, unwind : mir:: UnwindAction :: Unreachable } ,
325
- ) ?;
326
- interp_ok ( ControlFlow :: Break ( ( ) ) )
327
- } else {
328
- // Not alignable in const, return `usize::MAX`.
329
- let usize_max = Scalar :: from_target_usize ( self . target_usize_max ( ) , self ) ;
330
- self . write_scalar ( usize_max, dest) ?;
331
- self . return_to_block ( ret) ?;
332
- interp_ok ( ControlFlow :: Break ( ( ) ) )
333
- }
334
- }
335
- Err ( _addr) => {
336
- // The pointer has an address, continue with function call.
337
- interp_ok ( ControlFlow :: Continue ( ( ) ) )
338
- }
339
- }
340
- }
341
-
342
266
/// See documentation on the `ptr_guaranteed_cmp` intrinsic.
343
267
fn guaranteed_cmp ( & mut self , a : Scalar , b : Scalar ) -> InterpResult < ' tcx , u8 > {
344
268
interp_ok ( match ( a, b) {
0 commit comments