Skip to content

Commit 3ff3116

Browse files
committed
make Return terminators "use" the RETURN_PLACE
1 parent 9a34822 commit 3ff3116

File tree

3 files changed

+78
-4
lines changed

3 files changed

+78
-4
lines changed

src/librustc/mir/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,10 @@ impl<'tcx> Mir<'tcx> {
193193
Location { block, statement_index: num_statements }
194194
}
195195

196+
pub fn visitable(&self, location: Location) -> &dyn MirVisitable<'tcx> {
197+
self.basic_blocks[location.block].visitable(location.statement_index)
198+
}
199+
196200
#[inline]
197201
pub fn predecessors(&self) -> ReadGuard<IndexVec<BasicBlock, Vec<BasicBlock>>> {
198202
self.cache.predecessors(self)

src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs

+62-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ use borrow_check::nll::region_infer::{Cause, RegionInferenceContext};
1212
use borrow_check::{Context, MirBorrowckCtxt};
1313
use borrow_check::borrow_set::BorrowData;
1414
use rustc::mir::visit::{MirVisitable, PlaceContext, Visitor};
15-
use rustc::mir::{Local, Location, Mir};
15+
use rustc::mir::{BasicBlock, Local, Location, Mir, Statement, Terminator, TerminatorKind};
16+
use rustc::mir::RETURN_PLACE;
1617
use rustc_data_structures::fx::FxHashSet;
1718
use rustc_errors::DiagnosticBuilder;
1819
use util::liveness::{self, DefUse, LivenessMode};
@@ -38,9 +39,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
3839
Cause::LiveVar(local, location) => {
3940
match find_regular_use(mir, regioncx, borrow, location, local) {
4041
Some(p) => {
41-
err.span_label(
42-
mir.source_info(p).span,
43-
format!("borrow later used here"),
42+
mir.visitable(p).apply(
43+
p,
44+
&mut LaterUsedReporter { err, mir },
4445
);
4546
}
4647

@@ -232,4 +233,61 @@ impl<'tcx> Visitor<'tcx> for DefUseVisitor {
232233
}
233234
}
234235
}
236+
237+
fn visit_terminator(
238+
&mut self,
239+
block: BasicBlock,
240+
terminator: &Terminator<'tcx>,
241+
location: Location,
242+
) {
243+
if let TerminatorKind::Return = terminator.kind {
244+
if self.local == RETURN_PLACE {
245+
self.used = true;
246+
}
247+
}
248+
self.super_terminator(block, terminator, location);
249+
}
250+
}
251+
252+
struct LaterUsedReporter<'cx, 'diag: 'cx, 'tcx: 'cx> {
253+
err: &'cx mut DiagnosticBuilder<'diag>,
254+
mir: &'cx Mir<'tcx>,
255+
}
256+
257+
impl<'cx, 'diag, 'tcx> LaterUsedReporter<'cx, 'diag, 'tcx> {
258+
fn base_report(&mut self, location: Location) {
259+
self.err.span_label(
260+
self.mir.source_info(location).span,
261+
format!("borrow later used here"),
262+
);
263+
}
264+
}
265+
266+
impl<'cx, 'diag, 'tcx> Visitor<'tcx> for LaterUsedReporter<'cx, 'diag, 'tcx> {
267+
fn visit_statement(
268+
&mut self,
269+
_block: BasicBlock,
270+
_statement: &Statement<'tcx>,
271+
location: Location
272+
) {
273+
self.base_report(location);
274+
}
275+
276+
fn visit_terminator(
277+
&mut self,
278+
_block: BasicBlock,
279+
terminator: &Terminator<'tcx>,
280+
location: Location,
281+
) {
282+
match terminator.kind {
283+
TerminatorKind::Return => {
284+
// If the last use is the `Return` terminator
285+
// then for now we don't add any label, as it's
286+
// not clear what to say that is helpful.
287+
}
288+
_ => {
289+
self.base_report(location);
290+
}
291+
}
292+
}
235293
}

src/librustc_mir/util/liveness.rs

+12
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,18 @@ impl<'tcx> Visitor<'tcx> for DefsUsesVisitor {
355355
None => {}
356356
}
357357
}
358+
359+
fn visit_terminator(
360+
&mut self,
361+
block: BasicBlock,
362+
terminator: &Terminator<'tcx>,
363+
location: Location,
364+
) {
365+
if let TerminatorKind::Return = terminator.kind {
366+
self.defs_uses.add_use(RETURN_PLACE);
367+
}
368+
self.super_terminator(block, terminator, location);
369+
}
358370
}
359371

360372
fn block<'tcx>(mode: LivenessMode, b: &BasicBlockData<'tcx>, locals: usize) -> DefsUses {

0 commit comments

Comments
 (0)