Skip to content

Commit 9d14411

Browse files
Allow rustc_peek to take arguments by value
1 parent 3594ff1 commit 9d14411

File tree

1 file changed

+36
-12
lines changed

1 file changed

+36
-12
lines changed

src/librustc_mir/transform/rustc_peek.rs

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use syntax::ast;
33
use syntax::symbol::sym;
44
use syntax_pos::Span;
55

6-
use rustc::ty::{self, TyCtxt};
6+
use rustc::ty::{self, TyCtxt, Ty};
77
use rustc::hir::def_id::DefId;
88
use rustc::mir::{self, Body, Location, Local};
99
use rustc_data_structures::bit_set::BitSet;
@@ -114,15 +114,20 @@ pub fn sanity_check_via_rustc_peek<'tcx, O>(
114114
.expect("call to rustc_peek should be preceded by \
115115
assignment to temporary holding its argument");
116116

117-
if let mir::Rvalue::Ref(_, mir::BorrowKind::Shared, peeking_at_place) = peek_rval {
118-
let loc = Location { block: bb, statement_index };
119-
let flow_state = dataflow::state_for_location(loc, results.operator(), results, body);
117+
match (call.kind, peek_rval) {
118+
| (PeekCallKind::ByRef, mir::Rvalue::Ref(_, _, peek_at))
119+
| (PeekCallKind::ByVal, mir::Rvalue::Use(mir::Operand::Move(peek_at)))
120+
| (PeekCallKind::ByVal, mir::Rvalue::Use(mir::Operand::Copy(peek_at)))
121+
=> {
122+
let loc = Location { block: bb, statement_index };
123+
results.peek_at(tcx, body, peek_at, loc, call);
124+
}
120125

121-
results.operator().peek_at(tcx, peeking_at_place, &flow_state, call);
122-
} else {
123-
let msg = "rustc_peek: argument expression \
124-
must be immediate borrow of form `&expr`";
125-
tcx.sess.span_err(call.span, msg);
126+
_ => {
127+
let msg = "rustc_peek: argument expression \
128+
must be either `place` or `&place`";
129+
tcx.sess.span_err(call.span, msg);
130+
}
126131
}
127132
}
128133
}
@@ -144,9 +149,26 @@ fn value_assigned_to_local<'a, 'tcx>(
144149
None
145150
}
146151

152+
#[derive(Clone, Copy, Debug)]
153+
enum PeekCallKind {
154+
ByVal,
155+
ByRef,
156+
}
157+
158+
impl PeekCallKind {
159+
fn from_arg_ty(arg: Ty<'_>) -> Self {
160+
if let ty::Ref(_, _, _) = arg.sty {
161+
PeekCallKind::ByRef
162+
} else {
163+
PeekCallKind::ByVal
164+
}
165+
}
166+
}
167+
147168
#[derive(Clone, Copy, Debug)]
148169
pub struct PeekCall {
149170
arg: Local,
171+
kind: PeekCallKind,
150172
span: Span,
151173
}
152174

@@ -159,14 +181,15 @@ impl PeekCall {
159181
if let mir::TerminatorKind::Call { func: mir::Operand::Constant(func), args, .. } =
160182
&terminator.kind
161183
{
162-
if let ty::FnDef(def_id, _) = func.ty.sty {
163-
let abi = tcx.fn_sig(def_id).abi();
184+
if let ty::FnDef(def_id, substs) = func.ty.sty {
185+
let sig = tcx.fn_sig(def_id);
164186
let name = tcx.item_name(def_id);
165-
if abi != Abi::RustIntrinsic || name != sym::rustc_peek {
187+
if sig.abi() != Abi::RustIntrinsic || name != sym::rustc_peek {
166188
return None;
167189
}
168190

169191
assert_eq!(args.len(), 1);
192+
let kind = PeekCallKind::from_arg_ty(substs.type_at(0));
170193
let arg = match args[0] {
171194
| mir::Operand::Copy(mir::Place::Base(mir::PlaceBase::Local(local)))
172195
| mir::Operand::Move(mir::Place::Base(mir::PlaceBase::Local(local)))
@@ -181,6 +204,7 @@ impl PeekCall {
181204

182205
return Some(PeekCall {
183206
arg,
207+
kind,
184208
span,
185209
});
186210
}

0 commit comments

Comments
 (0)