@@ -317,16 +317,56 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
317317 let block = |blocks : & mut IndexVec < _ , _ > , kind| {
318318 blocks. push ( BasicBlockData :: new ( Some ( Terminator { source_info, kind } ) , false ) )
319319 } ;
320- block ( & mut blocks, TerminatorKind :: Goto { target : return_block } ) ;
320+ if ty. is_some ( ) {
321+ block ( & mut blocks, TerminatorKind :: Goto { target : return_block } ) ;
322+ }
321323 block ( & mut blocks, TerminatorKind :: Return ) ;
322324
323325 let source = MirSource :: from_instance ( ty:: InstanceKind :: DropGlue ( def_id, ty) ) ;
324326 let mut body =
325327 new_body ( source, blocks, local_decls_for_sig ( & sig, span) , sig. inputs ( ) . len ( ) , span) ;
326328
329+ let Some ( ty) = ty else {
330+ return body;
331+ } ;
332+
327333 let dropee_ptr = Place :: from ( Local :: arg ( 0 ) ) ;
328334
329- if ty. is_some ( ) {
335+ if let ty:: Array ( ety, _len) = * ty. kind ( ) {
336+ // Don't write out the elaboration for each array type.
337+ // Instead, just delegate to the slice version.
338+ let slice_ty = Ty :: new_slice ( tcx, ety) ;
339+ let mut_slice_ty = Ty :: new_ref ( tcx, tcx. lifetimes . re_erased , slice_ty, ty:: Mutability :: Mut ) ;
340+ let erased_local = body. local_decls . push ( LocalDecl :: new ( mut_slice_ty, span) ) ;
341+
342+ let start = & mut body. basic_blocks_mut ( ) [ START_BLOCK ] ;
343+ start. statements . push ( Statement :: new (
344+ source_info,
345+ StatementKind :: Assign ( Box :: new ( (
346+ Place :: from ( erased_local) ,
347+ Rvalue :: Cast (
348+ CastKind :: PointerCoercion (
349+ ty:: adjustment:: PointerCoercion :: Unsize ,
350+ CoercionSource :: Implicit ,
351+ ) ,
352+ Operand :: Move ( dropee_ptr) ,
353+ mut_slice_ty,
354+ ) ,
355+ ) ) ) ,
356+ ) ) ;
357+ start. terminator = Some ( Terminator {
358+ source_info,
359+ kind : TerminatorKind :: Call {
360+ func : Operand :: function_handle ( tcx, def_id, [ ty:: GenericArg :: from ( slice_ty) ] , span) ,
361+ args : Box :: new ( [ Spanned { span, node : Operand :: Move ( Place :: from ( erased_local) ) } ] ) ,
362+ destination : Place :: from ( RETURN_PLACE ) ,
363+ target : Some ( return_block) ,
364+ unwind : UnwindAction :: Continue ,
365+ call_source : CallSource :: Misc ,
366+ fn_span : span,
367+ } ,
368+ } ) ;
369+ } else {
330370 let patch = {
331371 let typing_env = ty:: TypingEnv :: post_analysis ( tcx, def_id) ;
332372 let mut elaborator = DropShimElaborator {
0 commit comments