Skip to content

Commit 00c7a3f

Browse files
committed
Refactored and tidied up report function
1 parent baf68d3 commit 00c7a3f

File tree

1 file changed

+92
-53
lines changed

1 file changed

+92
-53
lines changed

src/librustc_mir/borrow_check/error_reporting.rs

Lines changed: 92 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@
99
// except according to those terms.
1010

1111
use syntax_pos::Span;
12+
use rustc::middle::region::ScopeTree;
1213
use rustc::mir::{BorrowKind, Field, Local, Location, Operand};
1314
use rustc::mir::{Place, ProjectionElem, Rvalue, StatementKind};
1415
use rustc::ty::{self, RegionKind};
1516
use rustc_data_structures::indexed_vec::Idx;
1617

18+
use std::rc::Rc;
19+
1720
use super::{MirBorrowckCtxt, Context};
1821
use super::{InitializationRequiringAction, PrefixSet};
1922
use dataflow::{BorrowData, Borrows, FlowAtLocation, MovingOutStatements};
@@ -354,64 +357,100 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
354357
_ => drop_span,
355358
};
356359

357-
match &self.describe_place(&borrow.place) {
358-
Some(description) => {
359-
match borrow.region {
360-
RegionKind::ReScope(_) => {
361-
let mut err = self.tcx.path_does_not_live_long_enough(
362-
drop_span, &format!("`{}`", description), Origin::Mir);
363-
err.span_label(borrow_span, "borrow occurs here");
364-
err.span_label(drop_span,
365-
format!("`{}` dropped here while still borrowed",
366-
description));
367-
if let Some(end) = end_span {
368-
err.span_label(end, "borrowed value needs to live until here");
369-
}
370-
err.emit();
371-
},
372-
_ => {
373-
let mut err = self.tcx.path_does_not_live_long_enough(
374-
borrow_span, &format!("`{}`", description), Origin::Mir);
375-
err.span_label(borrow_span, "does not live long enough");
376-
err.span_label(drop_span, "borrowed value only lives until here");
377-
self.tcx.note_and_explain_region(scope_tree, &mut err,
378-
"borrowed value must be valid for ",
379-
borrow.region, "...");
380-
err.emit();
381-
}
382-
}
360+
match (borrow.region, &self.describe_place(&borrow.place)) {
361+
(RegionKind::ReScope(_), Some(name)) => {
362+
self.report_scoped_local_value_does_not_live_long_enough(
363+
name, &scope_tree, &borrow, drop_span, borrow_span, proper_span, end_span);
383364
},
384-
None => {
385-
match borrow.region {
386-
RegionKind::ReEarlyBound(_) | RegionKind::ReFree(_) => {
387-
let mut err = self.tcx.path_does_not_live_long_enough(proper_span,
388-
"borrowed value",
389-
Origin::Mir);
390-
err.span_label(proper_span, "does not live long enough");
391-
err.span_label(drop_span, "temporary value only lives until here");
392-
self.tcx.note_and_explain_region(scope_tree, &mut err,
393-
"borrowed value must be valid for ",
394-
borrow.region, "...");
395-
err.emit();
396-
},
397-
_ => {
398-
let mut err = self.tcx.path_does_not_live_long_enough(drop_span,
399-
"borrowed value",
400-
Origin::Mir);
401-
err.span_label(proper_span, "temporary value created here");
402-
err.span_label(drop_span,
403-
"temporary value dropped here while still borrowed");
404-
err.note("consider using a `let` binding to increase its lifetime");
405-
if let Some(end) = end_span {
406-
err.span_label(end, "temporary value needs to live until here");
407-
}
408-
err.emit();
409-
},
410-
}
365+
(RegionKind::ReScope(_), None) => {
366+
self.report_scoped_temporary_value_does_not_live_long_enough(
367+
&scope_tree, &borrow, drop_span, borrow_span, proper_span, end_span);
368+
},
369+
(RegionKind::ReEarlyBound(_), Some(name)) |
370+
(RegionKind::ReFree(_), Some(name)) |
371+
(RegionKind::ReStatic, Some(name)) |
372+
(RegionKind::ReEmpty, Some(name)) |
373+
(RegionKind::ReVar(_), Some(name)) => {
374+
self.report_unscoped_local_value_does_not_live_long_enough(
375+
name, &scope_tree, &borrow, drop_span, borrow_span, proper_span, end_span);
376+
},
377+
(RegionKind::ReEarlyBound(_), None) |
378+
(RegionKind::ReFree(_), None) |
379+
(RegionKind::ReStatic, None) |
380+
(RegionKind::ReEmpty, None) |
381+
(RegionKind::ReVar(_), None) => {
382+
self.report_unscoped_temporary_value_does_not_live_long_enough(
383+
&scope_tree, &borrow, drop_span, borrow_span, proper_span, end_span);
384+
},
385+
(RegionKind::ReLateBound(_, _), _) |
386+
(RegionKind::ReSkolemized(_, _), _) |
387+
(RegionKind::ReErased, _) => {
388+
span_bug!(drop_span, "region does not make sense in this context");
411389
},
412390
}
413391
}
414392

393+
fn report_scoped_local_value_does_not_live_long_enough(
394+
&mut self, name: &String, _scope_tree: &Rc<ScopeTree>, _borrow: &BorrowData<'tcx>,
395+
drop_span: Span, borrow_span: Span, _proper_span: Span, end_span: Option<Span>
396+
) {
397+
let mut err = self.tcx.path_does_not_live_long_enough(drop_span,
398+
&format!("`{}`", name),
399+
Origin::Mir);
400+
err.span_label(borrow_span, "borrow occurs here");
401+
err.span_label(drop_span, format!("`{}` dropped here while still borrowed", name));
402+
if let Some(end) = end_span {
403+
err.span_label(end, "borrowed value needs to live until here");
404+
}
405+
err.emit();
406+
}
407+
408+
fn report_scoped_temporary_value_does_not_live_long_enough(
409+
&mut self, _scope_tree: &Rc<ScopeTree>, _borrow: &BorrowData<'tcx>,
410+
drop_span: Span, borrow_span: Span, proper_span: Span, end_span: Option<Span>
411+
) {
412+
let mut err = self.tcx.path_does_not_live_long_enough(borrow_span,
413+
"borrowed value",
414+
Origin::Mir);
415+
err.span_label(proper_span, "temporary value created here");
416+
err.span_label(drop_span, "temporary value dropped here while still borrowed");
417+
err.note("consider using a `let` binding to increase its lifetime");
418+
if let Some(end) = end_span {
419+
err.span_label(end, "temporary value needs to live until here");
420+
}
421+
err.emit();
422+
}
423+
424+
fn report_unscoped_local_value_does_not_live_long_enough(
425+
&mut self, name: &String, scope_tree: &Rc<ScopeTree>, borrow: &BorrowData<'tcx>,
426+
drop_span: Span, borrow_span: Span, _proper_span: Span, _end_span: Option<Span>
427+
) {
428+
let mut err = self.tcx.path_does_not_live_long_enough(borrow_span,
429+
&format!("`{}`", name),
430+
Origin::Mir);
431+
err.span_label(borrow_span, "does not live long enough");
432+
err.span_label(drop_span, "borrowed value only lives until here");
433+
self.tcx.note_and_explain_region(scope_tree, &mut err,
434+
"borrowed value must be valid for ",
435+
borrow.region, "...");
436+
err.emit();
437+
}
438+
439+
fn report_unscoped_temporary_value_does_not_live_long_enough(
440+
&mut self, scope_tree: &Rc<ScopeTree>, borrow: &BorrowData<'tcx>,
441+
drop_span: Span, _borrow_span: Span, proper_span: Span, _end_span: Option<Span>
442+
) {
443+
let mut err = self.tcx.path_does_not_live_long_enough(proper_span,
444+
"borrowed value",
445+
Origin::Mir);
446+
err.span_label(proper_span, "does not live long enough");
447+
err.span_label(drop_span, "temporary value only lives until here");
448+
self.tcx.note_and_explain_region(scope_tree, &mut err,
449+
"borrowed value must be valid for ",
450+
borrow.region, "...");
451+
err.emit();
452+
}
453+
415454
pub(super) fn report_illegal_mutation_of_borrowed(
416455
&mut self,
417456
_: Context,

0 commit comments

Comments
 (0)