Skip to content

Commit 2b637ef

Browse files
committed
rustc_mir: don't hardcode InstanceDef::VtableShim behavior to Adjustment::DerefMove.
1 parent c4f5696 commit 2b637ef

File tree

1 file changed

+24
-18
lines changed

1 file changed

+24
-18
lines changed

src/librustc_mir/shim.rs

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
3535
ty::InstanceDef::VtableShim(def_id) => {
3636
build_call_shim(
3737
tcx,
38-
def_id,
38+
instance,
3939
Adjustment::DerefMove,
4040
CallKind::Direct(def_id),
4141
None,
@@ -60,7 +60,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
6060

6161
build_call_shim(
6262
tcx,
63-
def_id,
63+
instance,
6464
adjustment,
6565
CallKind::Indirect,
6666
Some(arg_tys)
@@ -74,13 +74,13 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
7474
ty::InstanceDef::ReifyShim(def_id) => {
7575
build_call_shim(
7676
tcx,
77-
def_id,
77+
instance,
7878
Adjustment::Identity,
7979
CallKind::Direct(def_id),
8080
None
8181
)
8282
}
83-
ty::InstanceDef::ClosureOnceShim { call_once } => {
83+
ty::InstanceDef::ClosureOnceShim { call_once: _ } => {
8484
let fn_mut = tcx.lang_items().fn_mut_trait().unwrap();
8585
let call_mut = tcx
8686
.associated_items(fn_mut)
@@ -89,7 +89,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
8989

9090
build_call_shim(
9191
tcx,
92-
call_once,
92+
instance,
9393
Adjustment::RefMut,
9494
CallKind::Direct(call_mut),
9595
None
@@ -689,25 +689,38 @@ impl CloneShimBuilder<'tcx> {
689689
}
690690
}
691691

692-
/// Builds a "call" shim for `def_id`. The shim calls the
692+
/// Builds a "call" shim for `instance`. The shim calls the
693693
/// function specified by `call_kind`, first adjusting its first
694694
/// argument according to `rcvr_adjustment`.
695695
///
696696
/// If `untuple_args` is a vec of types, the second argument of the
697697
/// function will be untupled as these types.
698698
fn build_call_shim<'tcx>(
699699
tcx: TyCtxt<'tcx>,
700-
def_id: DefId,
700+
instance: ty::InstanceDef<'tcx>,
701701
rcvr_adjustment: Adjustment,
702702
call_kind: CallKind,
703703
untuple_args: Option<&[Ty<'tcx>]>,
704704
) -> Body<'tcx> {
705-
debug!("build_call_shim(def_id={:?}, rcvr_adjustment={:?}, \
705+
debug!("build_call_shim(instance={:?}, rcvr_adjustment={:?}, \
706706
call_kind={:?}, untuple_args={:?})",
707-
def_id, rcvr_adjustment, call_kind, untuple_args);
707+
instance, rcvr_adjustment, call_kind, untuple_args);
708708

709+
let def_id = instance.def_id();
709710
let sig = tcx.fn_sig(def_id);
710-
let sig = tcx.erase_late_bound_regions(&sig);
711+
let mut sig = tcx.erase_late_bound_regions(&sig);
712+
713+
// FIXME(eddyb) avoid having this snippet both here and in
714+
// `Instance::fn_sig` (introduce `InstanceDef::fn_sig`?).
715+
if let ty::InstanceDef::VtableShim(..) = instance {
716+
// Modify fn(self, ...) to fn(self: *mut Self, ...)
717+
let mut inputs_and_output = sig.inputs_and_output.to_vec();
718+
let self_arg = &mut inputs_and_output[0];
719+
debug_assert!(tcx.generics_of(def_id).has_self && *self_arg == tcx.types.self_param);
720+
*self_arg = tcx.mk_mut_ptr(*self_arg);
721+
sig.inputs_and_output = tcx.intern_type_list(&inputs_and_output);
722+
}
723+
711724
let span = tcx.def_span(def_id);
712725

713726
debug!("build_call_shim: sig={:?}", sig);
@@ -722,14 +735,7 @@ fn build_call_shim<'tcx>(
722735
let rcvr = match rcvr_adjustment {
723736
Adjustment::Identity => Operand::Move(rcvr_l),
724737
Adjustment::Deref => Operand::Copy(tcx.mk_place_deref(rcvr_l)),
725-
Adjustment::DerefMove => {
726-
// fn(Self, ...) -> fn(*mut Self, ...)
727-
let arg_ty = local_decls[rcvr_arg].ty;
728-
debug_assert!(tcx.generics_of(def_id).has_self && arg_ty == tcx.types.self_param);
729-
local_decls[rcvr_arg].ty = tcx.mk_mut_ptr(arg_ty);
730-
731-
Operand::Move(tcx.mk_place_deref(rcvr_l))
732-
}
738+
Adjustment::DerefMove => Operand::Move(tcx.mk_place_deref(rcvr_l)),
733739
Adjustment::RefMut => {
734740
// let rcvr = &mut rcvr;
735741
let ref_rcvr = local_decls.push(temp_decl(

0 commit comments

Comments
 (0)