@@ -6,6 +6,7 @@ use crate::ty::{self, SubstsRef, Ty, TyCtxt, TypeFoldable};
6
6
use rustc_hir:: def:: Namespace ;
7
7
use rustc_hir:: def_id:: { CrateNum , DefId } ;
8
8
use rustc_macros:: HashStable ;
9
+ use rustc_span:: sym;
9
10
use rustc_target:: spec:: abi:: Abi ;
10
11
11
12
use std:: fmt;
@@ -40,6 +41,11 @@ pub enum InstanceDef<'tcx> {
40
41
41
42
/// `<fn() as FnTrait>::call_*`
42
43
/// `DefId` is `FnTrait::call_*`.
44
+ ///
45
+ /// NB: the (`fn` pointer) type must be monomorphic for MIR shims to work.
46
+ // FIXME(eddyb) support generating shims for a "shallow type",
47
+ // e.g. `fn(_, _) -> _` instead of requiring a fully monomorphic
48
+ // `fn(Foo, Bar) -> Baz` etc.
43
49
FnPtrShim ( DefId , Ty < ' tcx > ) ,
44
50
45
51
/// `<dyn Trait as Trait>::fn`, "direct calls" of which are implicitly
@@ -55,9 +61,19 @@ pub enum InstanceDef<'tcx> {
55
61
} ,
56
62
57
63
/// `drop_in_place::<T>; None` for empty drop glue.
64
+ ///
65
+ /// NB: the type must be monomorphic for MIR shims to work.
66
+ // FIXME(eddyb) support generating shims for a "shallow type",
67
+ // e.g. `Foo<_>` or `[_]` instead of requiring a fully monomorphic
68
+ // `Foo<Bar>` or `[String]` etc.
58
69
DropGlue ( DefId , Option < Ty < ' tcx > > ) ,
59
70
60
71
///`<T as Clone>::clone` shim.
72
+ ///
73
+ /// NB: the type must be monomorphic for MIR shims to work.
74
+ // FIXME(eddyb) support generating shims for a "shallow type",
75
+ // e.g. `Foo<_>` or `[_]` instead of requiring a fully monomorphic
76
+ // `Foo<Bar>` or `[String]` etc.
61
77
CloneShim ( DefId , Ty < ' tcx > ) ,
62
78
}
63
79
@@ -282,21 +298,28 @@ impl<'tcx> Instance<'tcx> {
282
298
debug ! ( " => intrinsic" ) ;
283
299
ty:: InstanceDef :: Intrinsic ( def_id)
284
300
}
285
- _ => {
286
- if Some ( def_id) == tcx. lang_items ( ) . drop_in_place_fn ( ) {
287
- let ty = substs . type_at ( 0 ) ;
288
- if ty . needs_drop ( tcx , ty :: ParamEnv :: reveal_all ( ) ) {
289
- debug ! ( " => nontrivial drop glue" ) ;
290
- ty :: InstanceDef :: DropGlue ( def_id , Some ( ty ) )
291
- } else {
292
- debug ! ( " => trivial drop glue" ) ;
293
- ty :: InstanceDef :: DropGlue ( def_id , None )
301
+ ty :: FnDef ( def_id , substs )
302
+ if Some ( def_id) == tcx. lang_items ( ) . drop_in_place_fn ( ) =>
303
+ {
304
+ let ty = substs . type_at ( 0 ) ;
305
+
306
+ if ty . needs_drop ( tcx , param_env ) {
307
+ // `DropGlue` requires a monomorphic aka concrete type.
308
+ if ty . needs_subst ( ) {
309
+ return None ;
294
310
}
311
+
312
+ debug ! ( " => nontrivial drop glue" ) ;
313
+ ty:: InstanceDef :: DropGlue ( def_id, Some ( ty) )
295
314
} else {
296
- debug ! ( " => free item " ) ;
297
- ty:: InstanceDef :: Item ( def_id)
315
+ debug ! ( " => trivial drop glue " ) ;
316
+ ty:: InstanceDef :: DropGlue ( def_id, None )
298
317
}
299
318
}
319
+ _ => {
320
+ debug ! ( " => free item" ) ;
321
+ ty:: InstanceDef :: Item ( def_id)
322
+ }
300
323
} ;
301
324
Some ( Instance { def : def, substs : substs } )
302
325
} ;
@@ -457,20 +480,44 @@ fn resolve_associated_item<'tcx>(
457
480
trait_closure_kind,
458
481
) )
459
482
}
460
- traits:: VtableFnPointer ( ref data) => Some ( Instance {
461
- def : ty:: InstanceDef :: FnPtrShim ( trait_item. def_id , data. fn_ty ) ,
462
- substs : rcvr_substs,
463
- } ) ,
483
+ traits:: VtableFnPointer ( ref data) => {
484
+ // `FnPtrShim` requires a monomorphic aka concrete type.
485
+ if data. fn_ty . needs_subst ( ) {
486
+ return None ;
487
+ }
488
+
489
+ Some ( Instance {
490
+ def : ty:: InstanceDef :: FnPtrShim ( trait_item. def_id , data. fn_ty ) ,
491
+ substs : rcvr_substs,
492
+ } )
493
+ }
464
494
traits:: VtableObject ( ref data) => {
465
495
let index = traits:: get_vtable_index_of_object_method ( tcx, data, def_id) ;
466
496
Some ( Instance { def : ty:: InstanceDef :: Virtual ( def_id, index) , substs : rcvr_substs } )
467
497
}
468
498
traits:: VtableBuiltin ( ..) => {
469
- if tcx. lang_items ( ) . clone_trait ( ) . is_some ( ) {
470
- Some ( Instance {
471
- def : ty:: InstanceDef :: CloneShim ( def_id, trait_ref. self_ty ( ) ) ,
472
- substs : rcvr_substs,
473
- } )
499
+ if Some ( trait_ref. def_id ) == tcx. lang_items ( ) . clone_trait ( ) {
500
+ // FIXME(eddyb) use lang items for methods instead of names.
501
+ let name = tcx. item_name ( def_id) ;
502
+ if name == sym:: clone {
503
+ let self_ty = trait_ref. self_ty ( ) ;
504
+
505
+ // `CloneShim` requires a monomorphic aka concrete type.
506
+ if self_ty. needs_subst ( ) {
507
+ return None ;
508
+ }
509
+
510
+ Some ( Instance {
511
+ def : ty:: InstanceDef :: CloneShim ( def_id, self_ty) ,
512
+ substs : rcvr_substs,
513
+ } )
514
+ } else {
515
+ assert_eq ! ( name, sym:: clone_from) ;
516
+
517
+ // Use the default `fn clone_from` from `trait Clone`.
518
+ let substs = tcx. erase_regions ( & rcvr_substs) ;
519
+ Some ( ty:: Instance :: new ( def_id, substs) )
520
+ }
474
521
} else {
475
522
None
476
523
}
0 commit comments