Skip to content

Commit 19d8527

Browse files
eddybanp
authored andcommittedJan 19, 2020
rustc_mir: don't require a self argument for ReifyShim.
1 parent 0ee9221 commit 19d8527

File tree

1 file changed

+53
-27
lines changed

1 file changed

+53
-27
lines changed
 

‎src/librustc_mir/shim.rs

+53-27
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,13 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
3131

3232
let mut result = match instance {
3333
ty::InstanceDef::Item(..) => bug!("item {:?} passed to make_shim", instance),
34-
ty::InstanceDef::VtableShim(def_id) => {
35-
build_call_shim(tcx, instance, Adjustment::DerefMove, CallKind::Direct(def_id), None)
36-
}
34+
ty::InstanceDef::VtableShim(def_id) => build_call_shim(
35+
tcx,
36+
instance,
37+
Some(Adjustment::DerefMove),
38+
CallKind::Direct(def_id),
39+
None,
40+
),
3741
ty::InstanceDef::FnPtrShim(def_id, ty) => {
3842
let trait_ = tcx.trait_of_item(def_id).unwrap();
3943
let adjustment = match tcx.lang_items().fn_trait_kind(trait_) {
@@ -50,15 +54,15 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
5054
let sig = tcx.erase_late_bound_regions(&ty.fn_sig(tcx));
5155
let arg_tys = sig.inputs();
5256

53-
build_call_shim(tcx, instance, adjustment, CallKind::Indirect, Some(arg_tys))
57+
build_call_shim(tcx, instance, Some(adjustment), CallKind::Indirect, Some(arg_tys))
5458
}
5559
// We are generating a call back to our def-id, which the
5660
// codegen backend knows to turn to an actual call, be it
5761
// a virtual call, or a direct call to a function for which
5862
// indirect calls must be codegen'd differently than direct ones
5963
// (such as `#[track_caller]`).
6064
ty::InstanceDef::ReifyShim(def_id) => {
61-
build_call_shim(tcx, instance, Adjustment::Identity, CallKind::Direct(def_id), None)
65+
build_call_shim(tcx, instance, None, CallKind::Direct(def_id), None)
6266
}
6367
ty::InstanceDef::ClosureOnceShim { call_once: _ } => {
6468
let fn_mut = tcx.lang_items().fn_mut_trait().unwrap();
@@ -68,7 +72,13 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
6872
.unwrap()
6973
.def_id;
7074

71-
build_call_shim(tcx, instance, Adjustment::RefMut, CallKind::Direct(call_mut), None)
75+
build_call_shim(
76+
tcx,
77+
instance,
78+
Some(Adjustment::RefMut),
79+
CallKind::Direct(call_mut),
80+
None,
81+
)
7282
}
7383
ty::InstanceDef::DropGlue(def_id, ty) => build_drop_shim(tcx, def_id, ty),
7484
ty::InstanceDef::CloneShim(def_id, ty) => {
@@ -648,7 +658,7 @@ impl CloneShimBuilder<'tcx> {
648658
fn build_call_shim<'tcx>(
649659
tcx: TyCtxt<'tcx>,
650660
instance: ty::InstanceDef<'tcx>,
651-
rcvr_adjustment: Adjustment,
661+
rcvr_adjustment: Option<Adjustment>,
652662
call_kind: CallKind,
653663
untuple_args: Option<&[Ty<'tcx>]>,
654664
) -> BodyAndCache<'tcx> {
@@ -680,14 +690,16 @@ fn build_call_shim<'tcx>(
680690
let mut local_decls = local_decls_for_sig(&sig, span);
681691
let source_info = SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE };
682692

683-
let rcvr_arg = Local::new(1 + 0);
684-
let rcvr_l = Place::from(rcvr_arg);
693+
let rcvr_place = || {
694+
assert!(rcvr_adjustment.is_some());
695+
Place::from(Local::new(1 + 0))
696+
};
685697
let mut statements = vec![];
686698

687-
let rcvr = match rcvr_adjustment {
688-
Adjustment::Identity => Operand::Move(rcvr_l),
689-
Adjustment::Deref => Operand::Copy(tcx.mk_place_deref(rcvr_l)),
690-
Adjustment::DerefMove => Operand::Move(tcx.mk_place_deref(rcvr_l)),
699+
let rcvr = rcvr_adjustment.map(|rcvr_adjustment| match rcvr_adjustment {
700+
Adjustment::Identity => Operand::Move(rcvr_place()),
701+
Adjustment::Deref => Operand::Copy(tcx.mk_place_deref(rcvr_place())),
702+
Adjustment::DerefMove => Operand::Move(tcx.mk_place_deref(rcvr_place())),
691703
Adjustment::RefMut => {
692704
// let rcvr = &mut rcvr;
693705
let ref_rcvr = local_decls.push(temp_decl(
@@ -703,15 +715,15 @@ fn build_call_shim<'tcx>(
703715
source_info,
704716
kind: StatementKind::Assign(box (
705717
Place::from(ref_rcvr),
706-
Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind, rcvr_l),
718+
Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind, rcvr_place()),
707719
)),
708720
});
709721
Operand::Move(Place::from(ref_rcvr))
710722
}
711-
};
723+
});
712724

713725
let (callee, mut args) = match call_kind {
714-
CallKind::Indirect => (rcvr, vec![]),
726+
CallKind::Indirect => (rcvr.unwrap(), vec![]),
715727
CallKind::Direct(def_id) => {
716728
let ty = tcx.type_of(def_id);
717729
(
@@ -720,21 +732,35 @@ fn build_call_shim<'tcx>(
720732
user_ty: None,
721733
literal: ty::Const::zero_sized(tcx, ty),
722734
}),
723-
vec![rcvr],
735+
rcvr.into_iter().collect::<Vec<_>>(),
724736
)
725737
}
726738
};
727739

740+
let mut arg_range = 0..sig.inputs().len();
741+
742+
// Take the `self` ("receiver") argument out of the range (it's adjusted above).
743+
if rcvr_adjustment.is_some() {
744+
arg_range.start += 1;
745+
}
746+
747+
// Take the last argument, if we need to untuple it (handled below).
748+
if untuple_args.is_some() {
749+
arg_range.end -= 1;
750+
}
751+
752+
// Pass all of the non-special arguments directly.
753+
args.extend(arg_range.map(|i| Operand::Move(Place::from(Local::new(1 + i)))));
754+
755+
// Untuple the last argument, if we have to.
728756
if let Some(untuple_args) = untuple_args {
757+
let tuple_arg = Local::new(1 + (sig.inputs().len() - 1));
729758
args.extend(untuple_args.iter().enumerate().map(|(i, ity)| {
730-
let arg_place = Place::from(Local::new(1 + 1));
731-
Operand::Move(tcx.mk_place_field(arg_place, Field::new(i), *ity))
759+
Operand::Move(tcx.mk_place_field(Place::from(tuple_arg), Field::new(i), *ity))
732760
}));
733-
} else {
734-
args.extend((1..sig.inputs().len()).map(|i| Operand::Move(Place::from(Local::new(1 + i)))));
735761
}
736762

737-
let n_blocks = if let Adjustment::RefMut = rcvr_adjustment { 5 } else { 2 };
763+
let n_blocks = if let Some(Adjustment::RefMut) = rcvr_adjustment { 5 } else { 2 };
738764
let mut blocks = IndexVec::with_capacity(n_blocks);
739765
let block = |blocks: &mut IndexVec<_, _>, statements, kind, is_cleanup| {
740766
blocks.push(BasicBlockData {
@@ -752,7 +778,7 @@ fn build_call_shim<'tcx>(
752778
func: callee,
753779
args,
754780
destination: Some((Place::return_place(), BasicBlock::new(1))),
755-
cleanup: if let Adjustment::RefMut = rcvr_adjustment {
781+
cleanup: if let Some(Adjustment::RefMut) = rcvr_adjustment {
756782
Some(BasicBlock::new(3))
757783
} else {
758784
None
@@ -762,13 +788,13 @@ fn build_call_shim<'tcx>(
762788
false,
763789
);
764790

765-
if let Adjustment::RefMut = rcvr_adjustment {
791+
if let Some(Adjustment::RefMut) = rcvr_adjustment {
766792
// BB #1 - drop for Self
767793
block(
768794
&mut blocks,
769795
vec![],
770796
TerminatorKind::Drop {
771-
location: Place::from(rcvr_arg),
797+
location: rcvr_place(),
772798
target: BasicBlock::new(2),
773799
unwind: None,
774800
},
@@ -777,13 +803,13 @@ fn build_call_shim<'tcx>(
777803
}
778804
// BB #1/#2 - return
779805
block(&mut blocks, vec![], TerminatorKind::Return, false);
780-
if let Adjustment::RefMut = rcvr_adjustment {
806+
if let Some(Adjustment::RefMut) = rcvr_adjustment {
781807
// BB #3 - drop if closure panics
782808
block(
783809
&mut blocks,
784810
vec![],
785811
TerminatorKind::Drop {
786-
location: Place::from(rcvr_arg),
812+
location: rcvr_place(),
787813
target: BasicBlock::new(4),
788814
unwind: None,
789815
},

0 commit comments

Comments
 (0)
Please sign in to comment.