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
0 commit comments