Auto merge of #119501 - cjgillot:clone-shim, r= · rust-lang/rust@810bb8f (original) (raw)

1

1

`use rustc_hir as hir;

`

2

2

`use rustc_hir::def_id::DefId;

`

3

3

`use rustc_hir::lang_items::LangItem;

`

``

4

`+

use rustc_index::{Idx, IndexVec};

`

4

5

`use rustc_middle::mir::*;

`

5

6

`use rustc_middle::query::Providers;

`

6

7

`use rustc_middle::ty::GenericArgs;

`

7

8

`use rustc_middle::ty::{self, CoroutineArgs, EarlyBinder, Ty, TyCtxt};

`

8

``

`-

use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};

`

9

``

-

10

``

`-

use rustc_index::{Idx, IndexVec};

`

11

``

-

``

9

`+

use rustc_span::symbol::kw;

`

12

10

`use rustc_span::Span;

`

``

11

`+

use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};

`

13

12

`use rustc_target::spec::abi::Abi;

`

14

13

``

15

14

`use std::fmt;

`

`@@ -90,7 +89,18 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'

`

90

89

`build_drop_shim(tcx, def_id, ty)

`

91

90

`}

`

92

91

` ty::InstanceDef::ThreadLocalShim(..) => build_thread_local_shim(tcx, instance),

`

93

``

`-

ty::InstanceDef::CloneShim(def_id, ty) => build_clone_shim(tcx, def_id, ty),

`

``

92

`+

ty::InstanceDef::CloneCopyShim(def_id) => {

`

``

93

`+

let self_ty = Ty::new_param(tcx, 0, kw::SelfUpper);

`

``

94

`+

let mut builder = CloneShimBuilder::new(tcx, def_id, self_ty);

`

``

95

`+

builder.copy_shim();

`

``

96

`+

let mut result = builder.into_mir(instance);

`

``

97

`` +

// Mark as runtime MIR to bypass MIR validation checking Operand::Copy.

``

``

98

`+

result.phase = MirPhase::Runtime(RuntimePhase::Initial);

`

``

99

`+

result

`

``

100

`+

}

`

``

101

`+

ty::InstanceDef::CloneShim(def_id, ty) => {

`

``

102

`+

build_clone_shim(tcx, def_id, ty).into_mir(instance)

`

``

103

`+

}

`

94

104

` ty::InstanceDef::FnPtrAddrShim(def_id, ty) => build_fn_ptr_addr_shim(tcx, def_id, ty),

`

95

105

` ty::InstanceDef::Virtual(..) => {

`

96

106

`bug!("InstanceDef::Virtual ({:?}) is for direct calls only", instance)

`

`@@ -379,19 +389,18 @@ fn build_thread_local_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'t

`

379

389

`}

`

380

390

``

381

391

`` /// Builds a Clone::clone shim for self_ty. Here, def_id is Clone::clone.

``

382

``

`-

fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Body<'tcx> {

`

383

``

`-

debug!("build_clone_shim(def_id={:?})", def_id);

`

384

``

-

385

``

`-

let param_env = tcx.param_env_reveal_all_normalized(def_id);

`

386

``

-

``

392

`+

#[instrument(level = "trace", skip(tcx))]

`

``

393

`+

fn build_clone_shim<'tcx>(

`

``

394

`+

tcx: TyCtxt<'tcx>,

`

``

395

`+

def_id: DefId,

`

``

396

`+

self_ty: Ty<'tcx>,

`

``

397

`+

) -> CloneShimBuilder<'tcx> {

`

387

398

`let mut builder = CloneShimBuilder::new(tcx, def_id, self_ty);

`

388

``

`-

let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env);

`

389

399

``

390

400

`let dest = Place::return_place();

`

391

401

`let src = tcx.mk_place_deref(Place::from(Local::new(1 + 0)));

`

392

402

``

393

403

`match self_ty.kind() {

`

394

``

`-

_ if is_copy => builder.copy_shim(),

`

395

404

` ty::Closure(_, args) => builder.tuple_like_shim(dest, src, args.as_closure().upvar_tys()),

`

396

405

` ty::Tuple(..) => builder.tuple_like_shim(dest, src, self_ty.tuple_fields()),

`

397

406

` ty::Coroutine(coroutine_def_id, args) => {

`

`@@ -401,7 +410,7 @@ fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -

`

401

410

`` _ => bug!("clone shim for {:?} which is not Copy and is not an aggregate", self_ty),

``

402

411

`};

`

403

412

``

404

``

`-

builder.into_mir()

`

``

413

`+

builder

`

405

414

`}

`

406

415

``

407

416

`struct CloneShimBuilder<'tcx> {

`

`@@ -432,11 +441,8 @@ impl<'tcx> CloneShimBuilder<'tcx> {

`

432

441

`}

`

433

442

`}

`

434

443

``

435

``

`-

fn into_mir(self) -> Body<'tcx> {

`

436

``

`-

let source = MirSource::from_instance(ty::InstanceDef::CloneShim(

`

437

``

`-

self.def_id,

`

438

``

`-

self.sig.inputs_and_output[0],

`

439

``

`-

));

`

``

444

`+

fn into_mir(self, def: ty::InstanceDef<'tcx>) -> Body<'tcx> {

`

``

445

`+

let source = MirSource::from_instance(def);

`

440

446

`new_body(source, self.blocks, self.local_decls, self.sig.inputs().len(), self.span)

`

441

447

`}

`

442

448

``