diff options
| author | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2019-10-29 20:56:21 +0200 |
|---|---|---|
| committer | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2019-12-03 15:41:56 +0200 |
| commit | 39e50e2f289a58a46f46044d8e9d296b9e7ac7e6 (patch) | |
| tree | 0d38df30866d8949cc5d84a3a466abad6ee28284 | |
| parent | 4b68afe257603a61aa2eb8b8eaa394c5e7a246fe (diff) | |
| download | rust-39e50e2f289a58a46f46044d8e9d296b9e7ac7e6.tar.gz rust-39e50e2f289a58a46f46044d8e9d296b9e7ac7e6.zip | |
rustc: use ReifyShim for reifying Virtual call instances.
| -rw-r--r-- | src/librustc/ty/instance.rs | 32 | ||||
| -rw-r--r-- | src/librustc_mir/monomorphize/collector.rs | 16 | ||||
| -rw-r--r-- | src/librustc_mir/shim.rs | 11 |
3 files changed, 34 insertions, 25 deletions
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 856be6f3c77..06fc168bd57 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -29,10 +29,15 @@ pub enum InstanceDef<'tcx> { /// `fn()` pointer where the function itself cannot be turned into a pointer. /// - /// One example in the compiler today is functions annotated with `#[track_caller]`, which - /// must have their implicit caller location argument populated for a call. Because this is a - /// required part of the function's ABI but can't be tracked as a property of the function - /// pointer, we create a single "caller location" at the site where the function is reified. + /// One example is `<dyn Trait as Trait>::fn`, where the shim contains + /// a virtual call, which codegen supports only via a direct call to the + /// `<dyn Trait as Trait>::fn` instance (an `InstanceDef::Virtual`). + /// + /// Another example is functions annotated with `#[track_caller]`, which + /// must have their implicit caller location argument populated for a call. + /// Because this is a required part of the function's ABI but can't be tracked + /// as a property of the function pointer, we use a single "caller location" + /// (the definition of the function itself). ReifyShim(DefId), /// `<fn() as FnTrait>::call_*` @@ -194,7 +199,7 @@ impl<'tcx> fmt::Display for Instance<'tcx> { write!(f, " - intrinsic") } InstanceDef::Virtual(_, num) => { - write!(f, " - shim(#{})", num) + write!(f, " - virtual#{}", num) } InstanceDef::FnPtrShim(_, ty) => { write!(f, " - shim({:?})", ty) @@ -309,20 +314,23 @@ impl<'tcx> Instance<'tcx> { substs: SubstsRef<'tcx>, ) -> Option<Instance<'tcx>> { debug!("resolve(def_id={:?}, substs={:?})", def_id, substs); - Instance::resolve(tcx, param_env, def_id, substs).map(|resolved| { + Instance::resolve(tcx, param_env, def_id, substs).map(|mut resolved| { let has_track_caller = |def| tcx.codegen_fn_attrs(def).flags .contains(CodegenFnAttrFlags::TRACK_CALLER); match resolved.def { InstanceDef::Item(def_id) if has_track_caller(def_id) => { debug!(" => fn pointer created for function with #[track_caller]"); - Instance { - def: InstanceDef::ReifyShim(def_id), - substs, - } - }, - _ => resolved, + resolved.def = InstanceDef::ReifyShim(def_id); + } + InstanceDef::Virtual(def_id, _) => { + debug!(" => fn pointer created for virtual call"); + resolved.def = InstanceDef::ReifyShim(def_id); + } + _ => {} } + + resolved }) } diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 4fe53cf35e5..93a76712b28 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -741,23 +741,21 @@ fn visit_instance_use<'tcx>( } match instance.def { - ty::InstanceDef::Intrinsic(def_id) => { + ty::InstanceDef::Virtual(..) | + ty::InstanceDef::Intrinsic(_) => { if !is_direct_call { - bug!("intrinsic {:?} being reified", def_id); + bug!("{:?} being reified", instance); } } - ty::InstanceDef::VtableShim(..) | - ty::InstanceDef::ReifyShim(..) | - ty::InstanceDef::Virtual(..) | ty::InstanceDef::DropGlue(_, None) => { - // Don't need to emit shim if we are calling directly. + // Don't need to emit noop drop glue if we are calling directly. if !is_direct_call { output.push(create_fn_mono_item(instance)); } } - ty::InstanceDef::DropGlue(_, Some(_)) => { - output.push(create_fn_mono_item(instance)); - } + ty::InstanceDef::DropGlue(_, Some(_)) | + ty::InstanceDef::VtableShim(..) | + ty::InstanceDef::ReifyShim(..) | ty::InstanceDef::ClosureOnceShim { .. } | ty::InstanceDef::Item(..) | ty::InstanceDef::FnPtrShim(..) | diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index fc606db98be..5b208dd8587 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -67,10 +67,10 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx ) } // We are generating a call back to our def-id, which the - // codegen backend knows to turn to an actual virtual call. - ty::InstanceDef::Virtual(def_id, _) | - // ...or we are generating a direct call to a function for which indirect calls must be - // codegen'd differently than direct ones (example: #[track_caller]) + // codegen backend knows to turn to an actual call, be it + // a virtual call, or a direct call to a function for which + // indirect calls must be codegen'd differently than direct ones + // (such as `#[track_caller]`). ty::InstanceDef::ReifyShim(def_id) => { build_call_shim( tcx, @@ -109,6 +109,9 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx bug!("builtin clone shim {:?} not supported", instance) } } + ty::InstanceDef::Virtual(..) => { + bug!("InstanceDef::Virtual ({:?}) is for direct calls only", instance) + } ty::InstanceDef::Intrinsic(_) => { bug!("creating shims from intrinsics ({:?}) is unsupported", instance) } |
