Skip to content

Commit 39e50e2

Browse files
committed
rustc: use ReifyShim for reifying Virtual call instances.
1 parent 4b68afe commit 39e50e2

File tree

3 files changed

+34
-25
lines changed

3 files changed

+34
-25
lines changed

src/librustc/ty/instance.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,15 @@ pub enum InstanceDef<'tcx> {
2929

3030
/// `fn()` pointer where the function itself cannot be turned into a pointer.
3131
///
32-
/// One example in the compiler today is functions annotated with `#[track_caller]`, which
33-
/// must have their implicit caller location argument populated for a call. Because this is a
34-
/// required part of the function's ABI but can't be tracked as a property of the function
35-
/// pointer, we create a single "caller location" at the site where the function is reified.
32+
/// One example is `<dyn Trait as Trait>::fn`, where the shim contains
33+
/// a virtual call, which codegen supports only via a direct call to the
34+
/// `<dyn Trait as Trait>::fn` instance (an `InstanceDef::Virtual`).
35+
///
36+
/// Another example is functions annotated with `#[track_caller]`, which
37+
/// must have their implicit caller location argument populated for a call.
38+
/// Because this is a required part of the function's ABI but can't be tracked
39+
/// as a property of the function pointer, we use a single "caller location"
40+
/// (the definition of the function itself).
3641
ReifyShim(DefId),
3742

3843
/// `<fn() as FnTrait>::call_*`
@@ -194,7 +199,7 @@ impl<'tcx> fmt::Display for Instance<'tcx> {
194199
write!(f, " - intrinsic")
195200
}
196201
InstanceDef::Virtual(_, num) => {
197-
write!(f, " - shim(#{})", num)
202+
write!(f, " - virtual#{}", num)
198203
}
199204
InstanceDef::FnPtrShim(_, ty) => {
200205
write!(f, " - shim({:?})", ty)
@@ -309,20 +314,23 @@ impl<'tcx> Instance<'tcx> {
309314
substs: SubstsRef<'tcx>,
310315
) -> Option<Instance<'tcx>> {
311316
debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
312-
Instance::resolve(tcx, param_env, def_id, substs).map(|resolved| {
317+
Instance::resolve(tcx, param_env, def_id, substs).map(|mut resolved| {
313318
let has_track_caller = |def| tcx.codegen_fn_attrs(def).flags
314319
.contains(CodegenFnAttrFlags::TRACK_CALLER);
315320

316321
match resolved.def {
317322
InstanceDef::Item(def_id) if has_track_caller(def_id) => {
318323
debug!(" => fn pointer created for function with #[track_caller]");
319-
Instance {
320-
def: InstanceDef::ReifyShim(def_id),
321-
substs,
322-
}
323-
},
324-
_ => resolved,
324+
resolved.def = InstanceDef::ReifyShim(def_id);
325+
}
326+
InstanceDef::Virtual(def_id, _) => {
327+
debug!(" => fn pointer created for virtual call");
328+
resolved.def = InstanceDef::ReifyShim(def_id);
329+
}
330+
_ => {}
325331
}
332+
333+
resolved
326334
})
327335
}
328336

src/librustc_mir/monomorphize/collector.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -741,23 +741,21 @@ fn visit_instance_use<'tcx>(
741741
}
742742

743743
match instance.def {
744-
ty::InstanceDef::Intrinsic(def_id) => {
744+
ty::InstanceDef::Virtual(..) |
745+
ty::InstanceDef::Intrinsic(_) => {
745746
if !is_direct_call {
746-
bug!("intrinsic {:?} being reified", def_id);
747+
bug!("{:?} being reified", instance);
747748
}
748749
}
749-
ty::InstanceDef::VtableShim(..) |
750-
ty::InstanceDef::ReifyShim(..) |
751-
ty::InstanceDef::Virtual(..) |
752750
ty::InstanceDef::DropGlue(_, None) => {
753-
// Don't need to emit shim if we are calling directly.
751+
// Don't need to emit noop drop glue if we are calling directly.
754752
if !is_direct_call {
755753
output.push(create_fn_mono_item(instance));
756754
}
757755
}
758-
ty::InstanceDef::DropGlue(_, Some(_)) => {
759-
output.push(create_fn_mono_item(instance));
760-
}
756+
ty::InstanceDef::DropGlue(_, Some(_)) |
757+
ty::InstanceDef::VtableShim(..) |
758+
ty::InstanceDef::ReifyShim(..) |
761759
ty::InstanceDef::ClosureOnceShim { .. } |
762760
ty::InstanceDef::Item(..) |
763761
ty::InstanceDef::FnPtrShim(..) |

src/librustc_mir/shim.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
6767
)
6868
}
6969
// We are generating a call back to our def-id, which the
70-
// codegen backend knows to turn to an actual virtual call.
71-
ty::InstanceDef::Virtual(def_id, _) |
72-
// ...or we are generating a direct call to a function for which indirect calls must be
73-
// codegen'd differently than direct ones (example: #[track_caller])
70+
// codegen backend knows to turn to an actual call, be it
71+
// a virtual call, or a direct call to a function for which
72+
// indirect calls must be codegen'd differently than direct ones
73+
// (such as `#[track_caller]`).
7474
ty::InstanceDef::ReifyShim(def_id) => {
7575
build_call_shim(
7676
tcx,
@@ -109,6 +109,9 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
109109
bug!("builtin clone shim {:?} not supported", instance)
110110
}
111111
}
112+
ty::InstanceDef::Virtual(..) => {
113+
bug!("InstanceDef::Virtual ({:?}) is for direct calls only", instance)
114+
}
112115
ty::InstanceDef::Intrinsic(_) => {
113116
bug!("creating shims from intrinsics ({:?}) is unsupported", instance)
114117
}

0 commit comments

Comments
 (0)