@@ -6,6 +6,7 @@ use crate::ty::{self, SubstsRef, Ty, TyCtxt, TypeFoldable};
66use rustc_hir:: def:: Namespace ;
77use rustc_hir:: def_id:: { CrateNum , DefId } ;
88use rustc_macros:: HashStable ;
9+ use rustc_span:: sym;
910use rustc_target:: spec:: abi:: Abi ;
1011
1112use std:: fmt;
@@ -40,6 +41,11 @@ pub enum InstanceDef<'tcx> {
4041
4142 /// `<fn() as FnTrait>::call_*`
4243 /// `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.
4349 FnPtrShim ( DefId , Ty < ' tcx > ) ,
4450
4551 /// `<dyn Trait as Trait>::fn`, "direct calls" of which are implicitly
@@ -55,9 +61,19 @@ pub enum InstanceDef<'tcx> {
5561 } ,
5662
5763 /// `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.
5869 DropGlue ( DefId , Option < Ty < ' tcx > > ) ,
5970
6071 ///`<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.
6177 CloneShim ( DefId , Ty < ' tcx > ) ,
6278}
6379
@@ -282,21 +298,28 @@ impl<'tcx> Instance<'tcx> {
282298 debug ! ( " => intrinsic" ) ;
283299 ty:: InstanceDef :: Intrinsic ( def_id)
284300 }
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 ;
294310 }
311+
312+ debug ! ( " => nontrivial drop glue" ) ;
313+ ty:: InstanceDef :: DropGlue ( def_id, Some ( ty) )
295314 } else {
296- debug ! ( " => free item " ) ;
297- ty:: InstanceDef :: Item ( def_id)
315+ debug ! ( " => trivial drop glue " ) ;
316+ ty:: InstanceDef :: DropGlue ( def_id, None )
298317 }
299318 }
319+ _ => {
320+ debug ! ( " => free item" ) ;
321+ ty:: InstanceDef :: Item ( def_id)
322+ }
300323 } ;
301324 Some ( Instance { def : def, substs : substs } )
302325 } ;
@@ -457,20 +480,44 @@ fn resolve_associated_item<'tcx>(
457480 trait_closure_kind,
458481 ) )
459482 }
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+ }
464494 traits:: VtableObject ( ref data) => {
465495 let index = traits:: get_vtable_index_of_object_method ( tcx, data, def_id) ;
466496 Some ( Instance { def : ty:: InstanceDef :: Virtual ( def_id, index) , substs : rcvr_substs } )
467497 }
468498 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+ }
474521 } else {
475522 None
476523 }
0 commit comments