11use std:: borrow:: { Borrow , Cow } ;
22use std:: fmt;
33use std:: hash:: Hash ;
4- use std:: ops:: ControlFlow ;
54
65use rustc_ast:: Mutability ;
76use rustc_data_structures:: fx:: { FxHashMap , FxIndexMap , IndexEntry } ;
87use rustc_hir:: def_id:: { DefId , LocalDefId } ;
98use rustc_hir:: { self as hir, CRATE_HIR_ID , LangItem } ;
109use rustc_middle:: mir:: AssertMessage ;
1110use rustc_middle:: query:: TyCtxtAt ;
12- use rustc_middle:: ty:: layout:: { FnAbiOf , TyAndLayout } ;
11+ use rustc_middle:: ty:: layout:: TyAndLayout ;
1312use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
1413use rustc_middle:: { bug, mir} ;
1514use rustc_span:: Span ;
@@ -23,9 +22,9 @@ use crate::errors::{LongRunning, LongRunningWarn};
2322use crate :: fluent_generated as fluent;
2423use crate :: interpret:: {
2524 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,
2928} ;
3029
3130/// When hitting this many interpreted terminators we emit a deny by default lint
@@ -227,8 +226,8 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
227226 & mut self ,
228227 instance : ty:: Instance < ' tcx > ,
229228 args : & [ FnArg < ' tcx > ] ,
230- dest : & MPlaceTy < ' tcx > ,
231- ret : Option < mir:: BasicBlock > ,
229+ _dest : & MPlaceTy < ' tcx > ,
230+ _ret : Option < mir:: BasicBlock > ,
232231 ) -> InterpResult < ' tcx , Option < ty:: Instance < ' tcx > > > {
233232 let def_id = instance. def_id ( ) ;
234233
@@ -260,85 +259,10 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
260259 ) ;
261260
262261 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- }
270262 }
271263 interp_ok ( Some ( instance) )
272264 }
273265
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-
342266 /// See documentation on the `ptr_guaranteed_cmp` intrinsic.
343267 fn guaranteed_cmp ( & mut self , a : Scalar , b : Scalar ) -> InterpResult < ' tcx , u8 > {
344268 interp_ok ( match ( a, b) {
0 commit comments