Skip to content

Commit be33ad8

Browse files
committed
fix types in shim building
1 parent c594330 commit be33ad8

File tree

2 files changed

+24
-8
lines changed

2 files changed

+24
-8
lines changed

compiler/rustc_mir_transform/src/shim.rs

+23-7
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,15 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
3232
let mut result = match instance {
3333
ty::InstanceDef::Item(..) => bug!("item {:?} passed to make_shim", instance),
3434
ty::InstanceDef::VTableShim(def_id) => {
35-
build_call_shim(tcx, instance, Some(Adjustment::Deref), CallKind::Direct(def_id))
35+
let adjustment = Adjustment::Deref { source: DerefSource::MutPtr };
36+
build_call_shim(tcx, instance, Some(adjustment), CallKind::Direct(def_id))
3637
}
3738
ty::InstanceDef::FnPtrShim(def_id, ty) => {
3839
let trait_ = tcx.trait_of_item(def_id).unwrap();
3940
let adjustment = match tcx.fn_trait_kind_from_def_id(trait_) {
4041
Some(ty::ClosureKind::FnOnce) => Adjustment::Identity,
41-
Some(ty::ClosureKind::FnMut | ty::ClosureKind::Fn) => Adjustment::Deref,
42+
Some(ty::ClosureKind::Fn) => Adjustment::Deref { source: DerefSource::ImmRef },
43+
Some(ty::ClosureKind::FnMut) => Adjustment::Deref { source: DerefSource::MutRef },
4244
None => bug!("fn pointer {:?} is not an fn", ty),
4345
};
4446

@@ -107,16 +109,26 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
107109
result
108110
}
109111

112+
#[derive(Copy, Clone, Debug, PartialEq)]
113+
enum DerefSource {
114+
/// `fn shim(&self) { inner(*self )}`.
115+
ImmRef,
116+
/// `fn shim(&mut self) { inner(*self )}`.
117+
MutRef,
118+
/// `fn shim(*mut self) { inner(*self )}`.
119+
MutPtr,
120+
}
121+
110122
#[derive(Copy, Clone, Debug, PartialEq)]
111123
enum Adjustment {
112124
/// Pass the receiver as-is.
113125
Identity,
114126

115-
/// We get passed `&[mut] self` and call the target with `*self`.
127+
/// We get passed a reference or a raw pointer to `self` and call the target with `*self`.
116128
///
117129
/// This either copies `self` (if `Self: Copy`, eg. for function items), or moves out of it
118130
/// (for `VTableShim`, which effectively is passed `&own Self`).
119-
Deref,
131+
Deref { source: DerefSource },
120132

121133
/// We get passed `self: Self` and call the target with `&mut self`.
122134
///
@@ -667,8 +679,12 @@ fn build_call_shim<'tcx>(
667679
let self_arg = &mut inputs_and_output[0];
668680
*self_arg = match rcvr_adjustment.unwrap() {
669681
Adjustment::Identity => fnty,
670-
Adjustment::Deref => tcx.mk_imm_ptr(fnty),
671-
Adjustment::RefMut => tcx.mk_mut_ptr(fnty),
682+
Adjustment::Deref { source } => match source {
683+
DerefSource::ImmRef => tcx.mk_imm_ref(tcx.lifetimes.re_erased, fnty),
684+
DerefSource::MutRef => tcx.mk_mut_ref(tcx.lifetimes.re_erased, fnty),
685+
DerefSource::MutPtr => tcx.mk_mut_ptr(fnty),
686+
},
687+
Adjustment::RefMut => bug!("`RefMut` is never used with indirect calls: {instance:?}"),
672688
};
673689
sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
674690
}
@@ -699,7 +715,7 @@ fn build_call_shim<'tcx>(
699715

700716
let rcvr = rcvr_adjustment.map(|rcvr_adjustment| match rcvr_adjustment {
701717
Adjustment::Identity => Operand::Move(rcvr_place()),
702-
Adjustment::Deref => Operand::Move(tcx.mk_place_deref(rcvr_place())),
718+
Adjustment::Deref { source: _ } => Operand::Move(tcx.mk_place_deref(rcvr_place())),
703719
Adjustment::RefMut => {
704720
// let rcvr = &mut rcvr;
705721
let ref_rcvr = local_decls.push(

tests/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// MIR for `std::ops::Fn::call` before AddMovesForPackedDrops
22

3-
fn std::ops::Fn::call(_1: *const fn(), _2: ()) -> <fn() as FnOnce<()>>::Output {
3+
fn std::ops::Fn::call(_1: &fn(), _2: ()) -> <fn() as FnOnce<()>>::Output {
44
let mut _0: <fn() as std::ops::FnOnce<()>>::Output;
55

66
bb0: {

0 commit comments

Comments
 (0)