Skip to content

Commit 810bb8f

Browse files
committed
Auto merge of rust-lang#119501 - cjgillot:clone-shim, r=<try>
Only generate a single shim for clone of copy types. r? `@ghost`
2 parents e51e98d + 7539a4e commit 810bb8f

File tree

16 files changed

+618
-29
lines changed

16 files changed

+618
-29
lines changed

compiler/rustc_const_eval/src/interpret/terminator.rs

+1
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
544544
| ty::InstanceDef::FnPtrShim(..)
545545
| ty::InstanceDef::DropGlue(..)
546546
| ty::InstanceDef::CloneShim(..)
547+
| ty::InstanceDef::CloneCopyShim(..)
547548
| ty::InstanceDef::FnPtrAddrShim(..)
548549
| ty::InstanceDef::ThreadLocalShim(..)
549550
| ty::InstanceDef::Item(_) => {

compiler/rustc_middle/src/mir/mono.rs

+1
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ impl<'tcx> CodegenUnit<'tcx> {
404404
| InstanceDef::ClosureOnceShim { .. }
405405
| InstanceDef::DropGlue(..)
406406
| InstanceDef::CloneShim(..)
407+
| InstanceDef::CloneCopyShim(..)
407408
| InstanceDef::ThreadLocalShim(..)
408409
| InstanceDef::FnPtrAddrShim(..) => None,
409410
}

compiler/rustc_middle/src/mir/visit.rs

+1
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ macro_rules! make_mir_visitor {
344344
ty::InstanceDef::ReifyShim(_def_id) |
345345
ty::InstanceDef::Virtual(_def_id, _) |
346346
ty::InstanceDef::ThreadLocalShim(_def_id) |
347+
ty::InstanceDef::CloneCopyShim(_def_id) |
347348
ty::InstanceDef::ClosureOnceShim { call_once: _def_id, track_caller: _ } |
348349
ty::InstanceDef::DropGlue(_def_id, None) => {}
349350

compiler/rustc_middle/src/ty/instance.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,13 @@ pub enum InstanceDef<'tcx> {
9797
/// glue.
9898
DropGlue(DefId, Option<Ty<'tcx>>),
9999

100+
/// Compiler-generated `<T as Clone>::clone` implementation where T is `Copy`.
101+
///
102+
/// The `DefId` is for `Clone::clone`.
103+
CloneCopyShim(DefId),
104+
100105
/// Compiler-generated `<T as Clone>::clone` implementation.
101106
///
102-
/// For all types that automatically implement `Copy`, a trivial `Clone` impl is provided too.
103107
/// Additionally, arrays, tuples, and closures get a `Clone` shim even if they aren't `Copy`.
104108
///
105109
/// The `DefId` is for `Clone::clone`, the `Ty` is the type `T` with the builtin `Clone` impl.
@@ -168,6 +172,7 @@ impl<'tcx> InstanceDef<'tcx> {
168172
| InstanceDef::ClosureOnceShim { call_once: def_id, track_caller: _ }
169173
| InstanceDef::DropGlue(def_id, _)
170174
| InstanceDef::CloneShim(def_id, _)
175+
| InstanceDef::CloneCopyShim(def_id)
171176
| InstanceDef::FnPtrAddrShim(def_id, _) => def_id,
172177
}
173178
}
@@ -187,6 +192,7 @@ impl<'tcx> InstanceDef<'tcx> {
187192
| InstanceDef::ClosureOnceShim { .. }
188193
| InstanceDef::DropGlue(..)
189194
| InstanceDef::CloneShim(..)
195+
| InstanceDef::CloneCopyShim(..)
190196
| InstanceDef::FnPtrAddrShim(..) => None,
191197
}
192198
}
@@ -280,6 +286,7 @@ impl<'tcx> InstanceDef<'tcx> {
280286
| InstanceDef::FnPtrShim(..)
281287
| InstanceDef::DropGlue(_, Some(_)) => false,
282288
InstanceDef::ClosureOnceShim { .. }
289+
| InstanceDef::CloneCopyShim(..)
283290
| InstanceDef::DropGlue(..)
284291
| InstanceDef::Item(_)
285292
| InstanceDef::Intrinsic(..)
@@ -316,6 +323,7 @@ fn fmt_instance(
316323
InstanceDef::DropGlue(_, None) => write!(f, " - shim(None)"),
317324
InstanceDef::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({ty}))"),
318325
InstanceDef::CloneShim(_, ty) => write!(f, " - shim({ty})"),
326+
InstanceDef::CloneCopyShim(_) => write!(f, " - shim(<Copy>)"),
319327
InstanceDef::FnPtrAddrShim(_, ty) => write!(f, " - shim({ty})"),
320328
}
321329
}

compiler/rustc_middle/src/ty/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2334,6 +2334,7 @@ impl<'tcx> TyCtxt<'tcx> {
23342334
| ty::InstanceDef::ClosureOnceShim { .. }
23352335
| ty::InstanceDef::DropGlue(..)
23362336
| ty::InstanceDef::CloneShim(..)
2337+
| ty::InstanceDef::CloneCopyShim(..)
23372338
| ty::InstanceDef::ThreadLocalShim(..)
23382339
| ty::InstanceDef::FnPtrAddrShim(..) => self.mir_shims(instance),
23392340
}

compiler/rustc_mir_transform/src/inline.rs

+1
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ impl<'tcx> Inliner<'tcx> {
319319
| InstanceDef::ClosureOnceShim { .. }
320320
| InstanceDef::DropGlue(..)
321321
| InstanceDef::CloneShim(..)
322+
| InstanceDef::CloneCopyShim(..)
322323
| InstanceDef::ThreadLocalShim(..)
323324
| InstanceDef::FnPtrAddrShim(..) => return Ok(()),
324325
}

compiler/rustc_mir_transform/src/inline/cycle.rs

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>(
8888
| InstanceDef::FnPtrShim(..)
8989
| InstanceDef::ClosureOnceShim { .. }
9090
| InstanceDef::ThreadLocalShim { .. }
91+
| InstanceDef::CloneCopyShim(..)
9192
| InstanceDef::CloneShim(..) => {}
9293

9394
// This shim does not call any other functions, thus there can be no recursion.

compiler/rustc_mir_transform/src/shim.rs

+24-18
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
use rustc_hir as hir;
22
use rustc_hir::def_id::DefId;
33
use rustc_hir::lang_items::LangItem;
4+
use rustc_index::{Idx, IndexVec};
45
use rustc_middle::mir::*;
56
use rustc_middle::query::Providers;
67
use rustc_middle::ty::GenericArgs;
78
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;
1210
use rustc_span::Span;
11+
use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
1312
use rustc_target::spec::abi::Abi;
1413

1514
use std::fmt;
@@ -90,7 +89,18 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
9089
build_drop_shim(tcx, def_id, ty)
9190
}
9291
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+
}
94104
ty::InstanceDef::FnPtrAddrShim(def_id, ty) => build_fn_ptr_addr_shim(tcx, def_id, ty),
95105
ty::InstanceDef::Virtual(..) => {
96106
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
379389
}
380390

381391
/// 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> {
387398
let mut builder = CloneShimBuilder::new(tcx, def_id, self_ty);
388-
let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env);
389399

390400
let dest = Place::return_place();
391401
let src = tcx.mk_place_deref(Place::from(Local::new(1 + 0)));
392402

393403
match self_ty.kind() {
394-
_ if is_copy => builder.copy_shim(),
395404
ty::Closure(_, args) => builder.tuple_like_shim(dest, src, args.as_closure().upvar_tys()),
396405
ty::Tuple(..) => builder.tuple_like_shim(dest, src, self_ty.tuple_fields()),
397406
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>) -
401410
_ => bug!("clone shim for `{:?}` which is not `Copy` and is not an aggregate", self_ty),
402411
};
403412

404-
builder.into_mir()
413+
builder
405414
}
406415

407416
struct CloneShimBuilder<'tcx> {
@@ -432,11 +441,8 @@ impl<'tcx> CloneShimBuilder<'tcx> {
432441
}
433442
}
434443

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);
440446
new_body(source, self.blocks, self.local_decls, self.sig.inputs().len(), self.span)
441447
}
442448

compiler/rustc_monomorphize/src/collector.rs

+1
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,7 @@ fn visit_instance_use<'tcx>(
961961
| ty::InstanceDef::Item(..)
962962
| ty::InstanceDef::FnPtrShim(..)
963963
| ty::InstanceDef::CloneShim(..)
964+
| ty::InstanceDef::CloneCopyShim(..)
964965
| ty::InstanceDef::FnPtrAddrShim(..) => {
965966
output.push(create_fn_mono_item(tcx, instance, source));
966967
}

compiler/rustc_monomorphize/src/partitioning.rs

+2
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,7 @@ fn characteristic_def_id_of_mono_item<'tcx>(
624624
| ty::InstanceDef::DropGlue(..)
625625
| ty::InstanceDef::Virtual(..)
626626
| ty::InstanceDef::CloneShim(..)
627+
| ty::InstanceDef::CloneCopyShim(..)
627628
| ty::InstanceDef::ThreadLocalShim(..)
628629
| ty::InstanceDef::FnPtrAddrShim(..) => return None,
629630
};
@@ -785,6 +786,7 @@ fn mono_item_visibility<'tcx>(
785786
| InstanceDef::ClosureOnceShim { .. }
786787
| InstanceDef::DropGlue(..)
787788
| InstanceDef::CloneShim(..)
789+
| InstanceDef::CloneCopyShim(..)
788790
| InstanceDef::FnPtrAddrShim(..) => return Visibility::Hidden,
789791
};
790792

0 commit comments

Comments
 (0)