@@ -190,13 +190,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
190190 if !ty. is_scalar ( ) {
191191 if let Some ( range) = range {
192192 place = unpack ! (
193- block = self . subslice (
193+ block = self . subslice_sized_range (
194194 block,
195195 place,
196196 place_ty. ty,
197- test. span,
198197 ty. sequence_element_type( tcx) ,
199198 range,
199+ test. span,
200200 )
201201 ) ;
202202 }
@@ -311,34 +311,63 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
311311 }
312312 }
313313
314- fn offset (
314+ fn intrinsic_offset (
315315 & mut self ,
316316 block : BasicBlock ,
317- ptr : Place < ' tcx > ,
318- offset : Place < ' tcx > ,
317+ ptr : Operand < ' tcx > ,
318+ offset : Operand < ' tcx > ,
319319 span : Span ,
320320 ) -> BlockAnd < Place < ' tcx > > {
321321 let tcx = self . tcx ;
322- let ptr_ty = ptr . ty ( & self . local_decls , tcx ) . ty ;
323- let offset_ty = offset . ty ( & self . local_decls , tcx) . ty ;
324-
322+ let source_info = self . source_info ( span ) ;
323+ let ptr_ty = ptr . ty ( & self . local_decls , tcx) ;
324+ let pointee_ty = ptr_ty . pointee ( ) ;
325325 let func = Operand :: function_handle (
326326 tcx,
327327 tcx. require_lang_item ( LangItem :: Offset , Some ( span) ) ,
328- [ ptr_ty . into ( ) , offset_ty . into ( ) ] ,
328+ [ pointee_ty . into ( ) ] ,
329329 span,
330330 ) ;
331331
332332 let out = self . temp ( ptr_ty, span) ;
333333 let next_block = self . cfg . start_new_block ( ) ;
334+ self . cfg . terminate ( block, source_info, TerminatorKind :: Call {
335+ func,
336+ args : [ Spanned { node : ptr, span } , Spanned { node : offset, span } ] . into ( ) ,
337+ destination : out,
338+ target : Some ( next_block) ,
339+ unwind : UnwindAction :: Continue ,
340+ call_source : CallSource :: Misc ,
341+ fn_span : span,
342+ } ) ;
343+
344+ next_block. and ( out)
345+ }
346+
347+ fn intrinsic_aggregate_raw_ptr (
348+ & mut self ,
349+ block : BasicBlock ,
350+ ptr : Operand < ' tcx > ,
351+ data : Operand < ' tcx > ,
352+ span : Span ,
353+ ) -> BlockAnd < Place < ' tcx > > {
354+ let tcx = self . tcx ;
355+ let source_info = self . source_info ( span) ;
356+ let ptr_ty = ptr. ty ( & self . local_decls , tcx) ;
357+ let pointee_ty = ptr_ty. pointee ( ) ;
358+ let func = Operand :: function_handle (
359+ tcx,
360+ tcx. require_lang_item ( LangItem :: AggregateRawPtr , Some ( span) ) ,
361+ [ pointee_ty. into ( ) ] ,
362+ span,
363+ ) ;
334364
335- self . cfg . terminate ( block, self . source_info ( span) , TerminatorKind :: Call {
365+ let aggregate_ptr_ty = Ty :: new_ptr ( tcx, Ty :: new_slice ( tcx, pointee_ty) , Mutability :: Not ) ;
366+ let out = self . temp ( aggregate_ptr_ty, span) ;
367+ let next_block = self . cfg . start_new_block ( ) ;
368+ self . cfg . terminate ( block, source_info, TerminatorKind :: Call {
336369 func,
337- args : [ Spanned { node : Operand :: Copy ( ptr) , span } , Spanned {
338- node : Operand :: Copy ( offset) ,
339- span,
340- } ]
341- . into ( ) ,
370+ args : [ Spanned { node : ptr, span } , Spanned { node : data, span } ] . into ( ) ,
342371 destination : out,
343372 target : Some ( next_block) ,
344373 unwind : UnwindAction :: Continue ,
@@ -349,42 +378,38 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
349378 next_block. and ( out)
350379 }
351380
352- fn subslice (
381+ fn subslice_sized_range (
353382 & mut self ,
354383 mut block : BasicBlock ,
355384 input : Place < ' tcx > ,
356385 input_ty : Ty < ' tcx > ,
357- span : Span ,
358386 elem_ty : Ty < ' tcx > ,
359387 range : Range ,
388+ span : Span ,
360389 ) -> BlockAnd < Place < ' tcx > > {
361390 let tcx = self . tcx ;
362391 let source_info = self . source_info ( span) ;
363392
364393 let ( ptr_offset, slice_len) = {
365394 if !range. from_end {
366- let start = self . push_usize ( block , source_info , range. start ) ;
367- let len = self . push_usize ( block , source_info , range. len ( ) ) ;
395+ let start = self . literal_operand ( span , Const :: from_usize ( tcx , range. start ) ) ;
396+ let len = Const :: from_usize ( tcx , range. len ( ) ) ;
368397 ( start, len)
369398 } else {
370399 let source_len = self . temp ( tcx. types . usize , span) ;
371400 self . cfg . push_assign ( block, source_info, source_len, Rvalue :: Len ( input) ) ;
372-
373401 let start = self . temp ( tcx. types . usize , span) ;
374- let from_end = self . push_usize ( block , source_info , range. start ) ;
402+ let neg_offset = self . literal_operand ( span , Const :: from_usize ( tcx , range. start ) ) ;
375403
376404 self . cfg . push_assign (
377405 block,
378406 source_info,
379407 start,
380- Rvalue :: BinaryOp (
381- BinOp :: Sub ,
382- Box :: new ( ( Operand :: Copy ( source_len) , Operand :: Copy ( from_end) ) ) ,
383- ) ,
408+ Rvalue :: BinaryOp ( BinOp :: Sub , Box :: new ( ( Operand :: Copy ( source_len) , neg_offset) ) ) ,
384409 ) ;
385- let len = self . push_usize ( block, source_info, range. len ( ) ) ;
386410
387- ( start, len)
411+ let len = Const :: from_usize ( tcx, range. len ( ) ) ;
412+ ( Operand :: Copy ( start) , len)
388413 }
389414 } ;
390415
@@ -397,7 +422,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
397422 ) ;
398423
399424 let elem_ptr_ty = Ty :: new_ptr ( tcx, elem_ty, Mutability :: Not ) ;
400- let slice_ptr_ty = Ty :: new_ptr ( tcx, Ty :: new_slice ( tcx, elem_ty) , Mutability :: Not ) ;
401425
402426 let temp_elem_ptr = self . temp ( elem_ptr_ty, span) ;
403427 self . cfg . push_assign (
@@ -407,35 +431,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
407431 Rvalue :: Cast ( CastKind :: PtrToPtr , Operand :: Copy ( temp_source_ptr) , elem_ptr_ty) ,
408432 ) ;
409433
410- let updated_ptr = unpack ! ( block = self . offset( block, temp_elem_ptr, ptr_offset, span) ) ;
411-
412- let aggregate_raw_ptr = Operand :: function_handle (
413- tcx,
414- tcx. require_lang_item ( LangItem :: AggregateRawPtr , Some ( span) ) ,
415- [ slice_ptr_ty. into ( ) , elem_ptr_ty. into ( ) , tcx. types . usize . into ( ) ] ,
416- span,
434+ let updated_ptr = unpack ! (
435+ block = self . intrinsic_offset( block, Operand :: Copy ( temp_elem_ptr) , ptr_offset, span)
417436 ) ;
437+ let slice_len = self . literal_operand ( span, slice_len) ;
418438
419- let subslice_ptr = self . temp ( slice_ptr_ty, span) ;
420-
421- let next_block = self . cfg . start_new_block ( ) ;
422-
423- self . cfg . terminate ( block, source_info, TerminatorKind :: Call {
424- func : aggregate_raw_ptr,
425- args : [ Spanned { node : Operand :: Move ( updated_ptr) , span } , Spanned {
426- node : Operand :: Move ( slice_len) ,
427- span,
428- } ]
429- . into ( ) ,
430- destination : subslice_ptr,
431- target : Some ( next_block) ,
432- unwind : UnwindAction :: Continue ,
433- call_source : CallSource :: Misc ,
434- fn_span : source_info. span ,
435- } ) ;
439+ let subslice_ptr = unpack ! (
440+ block = self . intrinsic_aggregate_raw_ptr(
441+ block,
442+ Operand :: Copy ( updated_ptr) ,
443+ slice_len,
444+ span
445+ )
446+ ) ;
447+ let out = PlaceBuilder :: from ( subslice_ptr) . project ( PlaceElem :: Deref ) . to_place ( self ) ;
436448
437- let subslice = PlaceBuilder :: from ( subslice_ptr) . deref ( ) . to_place ( self ) ;
438- next_block. and ( subslice)
449+ block. and ( out)
439450 }
440451
441452 /// Perform `let temp = <ty as Deref>::deref(&place)`.
0 commit comments