Skip to content

Commit

Permalink
rustc: use ReifyShim for reifying Virtual call instances.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb committed Nov 3, 2019
1 parent b5f38f0 commit b30866f
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 26 deletions.
34 changes: 21 additions & 13 deletions src/librustc/ty/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,22 @@ 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_*`
/// `DefId` is `FnTrait::call_*`
FnPtrShim(DefId, Ty<'tcx>),

/// `<Trait as Trait>::fn`
/// `<dyn Trait as Trait>::fn`
Virtual(DefId, usize),

/// `<[mut closure] as FnOnce>::call_once`
Expand Down Expand Up @@ -193,7 +198,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)
Expand Down Expand Up @@ -308,20 +313,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
})
}

Expand Down
16 changes: 7 additions & 9 deletions src/librustc_mir/monomorphize/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -743,23 +743,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(..) |
Expand Down
11 changes: 7 additions & 4 deletions src/librustc_mir/shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
}
Expand Down

0 comments on commit b30866f

Please sign in to comment.