@@ -368,16 +368,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
368368 // Some intrinsics are handled here because they desperately want to avoid introducing
369369 // unnecessary copies.
370370 ExprKind :: Call { ty, fun, ref args, .. }
371- if let ty:: FnDef ( def_id, generic_args ) = ty. kind ( )
371+ if let ty:: FnDef ( def_id, _generic_args ) = ty. kind ( )
372372 && let Some ( intrinsic) = this. tcx . intrinsic ( def_id)
373- && matches ! ( intrinsic. name, sym:: write_via_move | sym:: init_box_via_move) =>
373+ && matches ! (
374+ intrinsic. name,
375+ sym:: write_via_move
376+ | sym:: write_via_move_for_vec_unsafe
377+ | sym:: init_box_via_move
378+ ) =>
374379 {
375380 // We still have to evaluate the callee expression as normal (but we don't care
376381 // about its result).
377382 let _fun = unpack ! ( block = this. as_local_operand( block, fun) ) ;
378383
379384 match intrinsic. name {
380- sym:: write_via_move => {
385+ sym:: write_via_move | sym :: write_via_move_for_vec_unsafe => {
381386 // `write_via_move(ptr, val)` becomes `*ptr = val` but without any dropping.
382387
383388 // The destination must have unit type (so we don't actually have to store anything
@@ -395,80 +400,59 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
395400 let ptr_deref = ptr. project_deeper ( & [ ProjectionElem :: Deref ] , this. tcx ) ;
396401 this. expr_into_dest ( ptr_deref, block, val)
397402 }
398- sym:: init_box_via_move => {
399- // `write_via_move(b, val)` becomes
400- // ```
401- // *transmute::<_, *mut T>(b) = val;
402- // transmute::<_, Box<T>>(b)
403- // ```
404- let t = generic_args. type_at ( 0 ) ;
405- let [ b, val] = * * args else {
406- span_bug ! ( expr_span, "invalid init_box_via_move call" )
407- } ;
408- let Some ( b) = unpack ! ( block = this. as_local_operand( block, b) ) . place ( )
409- else {
410- span_bug ! ( expr_span, "invalid init_box_via_move call" )
411- } ;
412- // Project to the pointer inside `b`. We have to keep `b` in scope to ensure
413- // it gets dropped. After the first projection we can transmute which is
414- // easier.
415- let ty:: Adt ( box_adt_def, box_adt_args) =
416- b. ty ( & this. local_decls , this. tcx ) . ty . kind ( )
417- else {
418- span_bug ! ( expr_span, "invalid init_box_via_move call" )
419- } ;
420- let unique_field =
421- this. tcx . adt_def ( box_adt_def. did ( ) ) . non_enum_variant ( ) . fields
422- [ rustc_abi:: FieldIdx :: ZERO ]
423- . did ;
424- let Some ( unique_def) =
425- this. tcx . type_of ( unique_field) . instantiate_identity ( ) . ty_adt_def ( )
426- else {
427- span_bug ! (
428- this. tcx. def_span( unique_field) ,
429- "expected Box to contain Unique"
430- )
431- } ;
432- let unique_ty =
433- Ty :: new_adt ( this. tcx , unique_def, this. tcx . mk_args ( & [ box_adt_args[ 0 ] ] ) ) ;
434- let b_field = b. project_deeper (
435- & [ ProjectionElem :: Field ( rustc_abi:: FieldIdx :: ZERO , unique_ty) ] ,
436- this. tcx ,
437- ) ;
438- // `ptr` is `b` transmuted to `*mut T`.
439- let ptr_ty = Ty :: new_mut_ptr ( this. tcx , t) ;
440- let ptr = this. local_decls . push ( LocalDecl :: new ( ptr_ty, expr_span) ) ;
441- this. cfg . push (
442- block,
443- Statement :: new ( source_info, StatementKind :: StorageLive ( ptr) ) ,
444- ) ;
445- // Make sure `StorageDead` gets emitted.
446- this. schedule_drop_storage_and_value ( expr_span, this. local_scope ( ) , ptr) ;
447- this. cfg . push_assign (
448- block,
449- source_info,
450- Place :: from ( ptr) ,
451- // Needs to be a `Copy` so that `b` still gets dropped if `val` panics.
452- Rvalue :: Cast ( CastKind :: Transmute , Operand :: Copy ( b_field) , ptr_ty) ,
453- ) ;
454- // Store `val` into `ptr`.
455- let ptr_deref =
456- Place :: from ( ptr) . project_deeper ( & [ ProjectionElem :: Deref ] , this. tcx ) ;
457- unpack ! ( block = this. expr_into_dest( ptr_deref, block, val) ) ;
458- // Return `ptr` transmuted to `Box<T>`.
459- this. cfg . push_assign (
460- block,
461- source_info,
462- destination,
463- Rvalue :: Cast (
464- CastKind :: Transmute ,
465- // Move from `b` so that does not get dropped any more.
466- Operand :: Move ( b) ,
467- Ty :: new_box ( this. tcx , t) ,
468- ) ,
469- ) ;
470- block. unit ( )
471- }
403+ // sym::init_box_via_move => {
404+ // use rustc_abi::FieldIdx;
405+ // // `init_box_via_move(b, val)` becomes
406+ // // ```
407+ // // *(b.0.0.0) = val;
408+ // // ```
409+ // let [b, val] = **args else {
410+ // span_bug!(expr_span, "invalid init_box_via_move call")
411+ // };
412+ // let Some(b) = unpack!(block = this.as_local_operand(block, b)).place()
413+ // else {
414+ // span_bug!(expr_span, "invalid init_box_via_move call")
415+ // };
416+ // // Project to the pointer inside `b`. First we need to get the types of all
417+ // // the fields we are projecting through.
418+ // let field_ty = |adt: &ty::AdtDef<'tcx>, idx: FieldIdx| {
419+ // let field = adt.non_enum_variant().fields[idx].did;
420+ // this.tcx.type_of(field).instantiate_identity()
421+ // };
422+ // let ty::Adt(box_adt, box_adt_args) =
423+ // b.ty(&this.local_decls, this.tcx).ty.kind()
424+ // else {
425+ // span_bug!(expr_span, "invalid init_box_via_move call")
426+ // };
427+ // // The `<T>` shared by Box, Unique, NonNull.
428+ // let ty_arg = this.tcx.mk_args(&[box_adt_args[0]]);
429+ // let ty::Adt(unique_adt, _args) = field_ty(box_adt, FieldIdx::Zero).kind()
430+ // else {
431+ // span_bug!(expr_span, "invalid init_box_via_move call")
432+ // };
433+ // let unique_ty = Ty::new_adt(this.tcx, unique_def, ty_arg);
434+ // let ty::Adt(nonnull_adt, _args) =
435+ // field_ty(unique_adt, FieldIdx::Zero).kind()
436+ // else {
437+ // span_bug!(expr_span, "invalid init_box_via_move call")
438+ // };
439+ // let nonnull_ty = Ty::new_adt(this.tcx, nonnull_adt, ty_arg);
440+ // // Then we can construct the projection.
441+ // let b_ptr_deref = b.project_deeper(
442+ // &[
443+ // ProjectionElem::Field(FieldIdx::ZERO, unique_ty),
444+ // ProjectionElem::Field(FieldIdx::ZERO, nonnull_ty),
445+ // ProjectionElem::Field(
446+ // FieldIdx::ZERO,
447+ // Ty::new_mut_ptr(tcx, ty_arg.type_at(0)),
448+ // ),
449+ // ProjectionElem::Deref,
450+ // ],
451+ // this.tcx,
452+ // );
453+ // // Store `val` into `b_ptr`.
454+ // this.expr_into_dest(b_ptr_deref, block, val)
455+ // }
472456 _ => rustc_middle:: bug!( ) ,
473457 }
474458 }
0 commit comments