Skip to content

Commit fd8099f

Browse files
committed
Auto merge of #44882 - mikhail-m1:master, r=pnkfelix
add notes to report_conflicting_borrow MIR borrowck part of #44596
2 parents eabef06 + c68b10f commit fd8099f

File tree

4 files changed

+150
-136
lines changed

4 files changed

+150
-136
lines changed

src/librustc_borrowck/borrowck/check_loans.rs

+18-91
Original file line numberDiff line numberDiff line change
@@ -470,102 +470,29 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
470470
old_loan.kill_scope.span(self.tcx(), &self.bccx.region_scope_tree).end_point();
471471

472472
let mut err = match (new_loan.kind, old_loan.kind) {
473-
(ty::MutBorrow, ty::MutBorrow) => {
474-
let mut err = self.bccx.cannot_mutably_borrow_multiply(
475-
new_loan.span, &nl, &new_loan_msg, Origin::Ast);
476-
477-
if new_loan.span == old_loan.span {
478-
// Both borrows are happening in the same place
479-
// Meaning the borrow is occurring in a loop
480-
err.span_label(
481-
new_loan.span,
482-
format!("mutable borrow starts here in previous \
483-
iteration of loop{}", new_loan_msg));
484-
err.span_label(
485-
previous_end_span,
486-
"mutable borrow ends here");
487-
err
488-
} else {
489-
err.span_label(
490-
old_loan.span,
491-
format!("first mutable borrow occurs here{}", old_loan_msg));
492-
err.span_label(
493-
new_loan.span,
494-
format!("second mutable borrow occurs here{}", new_loan_msg));
495-
err.span_label(
496-
previous_end_span,
497-
"first borrow ends here");
498-
err
499-
}
500-
}
501-
502-
(ty::UniqueImmBorrow, ty::UniqueImmBorrow) => {
503-
let mut err = self.bccx.cannot_uniquely_borrow_by_two_closures(
504-
new_loan.span, &nl, Origin::Ast);
505-
err.span_label(
506-
old_loan.span,
507-
"first closure is constructed here");
508-
err.span_label(
509-
new_loan.span,
510-
"second closure is constructed here");
511-
err.span_label(
512-
previous_end_span,
513-
"borrow from first closure ends here");
514-
err
515-
}
516-
517-
(ty::UniqueImmBorrow, _) => {
518-
let mut err = self.bccx.cannot_uniquely_borrow_by_one_closure(
519-
new_loan.span, &nl, &ol_pronoun, &old_loan_msg, Origin::Ast);
520-
err.span_label(
521-
new_loan.span,
522-
format!("closure construction occurs here{}", new_loan_msg));
523-
err.span_label(
524-
old_loan.span,
525-
format!("borrow occurs here{}", old_loan_msg));
526-
err.span_label(
527-
previous_end_span,
528-
"borrow ends here");
529-
err
530-
}
531-
473+
(ty::MutBorrow, ty::MutBorrow) =>
474+
self.bccx.cannot_mutably_borrow_multiply(
475+
new_loan.span, &nl, &new_loan_msg, old_loan.span, &old_loan_msg,
476+
previous_end_span, Origin::Ast),
477+
(ty::UniqueImmBorrow, ty::UniqueImmBorrow) =>
478+
self.bccx.cannot_uniquely_borrow_by_two_closures(
479+
new_loan.span, &nl, old_loan.span, previous_end_span, Origin::Ast),
480+
(ty::UniqueImmBorrow, _) =>
481+
self.bccx.cannot_uniquely_borrow_by_one_closure(
482+
new_loan.span, &nl, &new_loan_msg,
483+
old_loan.span, &ol_pronoun, &old_loan_msg, previous_end_span, Origin::Ast),
532484
(_, ty::UniqueImmBorrow) => {
533485
let new_loan_str = &new_loan.kind.to_user_str();
534-
let mut err = self.bccx.cannot_reborrow_already_uniquely_borrowed(
535-
new_loan.span, &nl, &new_loan_msg, new_loan_str, Origin::Ast);
536-
err.span_label(
537-
new_loan.span,
538-
format!("borrow occurs here{}", new_loan_msg));
539-
err.span_label(
540-
old_loan.span,
541-
format!("closure construction occurs here{}", old_loan_msg));
542-
err.span_label(
543-
previous_end_span,
544-
"borrow from closure ends here");
545-
err
486+
self.bccx.cannot_reborrow_already_uniquely_borrowed(
487+
new_loan.span, &nl, &new_loan_msg, new_loan_str,
488+
old_loan.span, &old_loan_msg, previous_end_span, Origin::Ast)
546489
}
547-
548-
(..) => {
549-
let mut err = self.bccx.cannot_reborrow_already_borrowed(
490+
(..) =>
491+
self.bccx.cannot_reborrow_already_borrowed(
550492
new_loan.span,
551493
&nl, &new_loan_msg, &new_loan.kind.to_user_str(),
552-
&ol_pronoun, &old_loan.kind.to_user_str(), &old_loan_msg, Origin::Ast);
553-
err.span_label(
554-
new_loan.span,
555-
format!("{} borrow occurs here{}",
556-
new_loan.kind.to_user_str(),
557-
new_loan_msg));
558-
err.span_label(
559-
old_loan.span,
560-
format!("{} borrow occurs here{}",
561-
old_loan.kind.to_user_str(),
562-
old_loan_msg));
563-
err.span_label(
564-
previous_end_span,
565-
format!("{} borrow ends here",
566-
old_loan.kind.to_user_str()));
567-
err
568-
}
494+
old_loan.span, &ol_pronoun, &old_loan.kind.to_user_str(), &old_loan_msg,
495+
previous_end_span, Origin::Ast)
569496
};
570497

571498
match new_loan.cause {

src/librustc_mir/borrow_check.rs

+34-27
Original file line numberDiff line numberDiff line change
@@ -396,28 +396,34 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
396396
ReadKind::Copy =>
397397
this.report_use_while_mutably_borrowed(
398398
context, lvalue_span, borrow),
399-
ReadKind::Borrow(bk) =>
399+
ReadKind::Borrow(bk) => {
400+
let end_issued_loan_span =
401+
flow_state.borrows.base_results.operator().region_span(
402+
&borrow.region).end_point();
400403
this.report_conflicting_borrow(
401-
context, lvalue_span,
402-
common_prefix,
403-
(lvalue_span.0, bk), (&borrow.lvalue, borrow.kind)),
404+
context, common_prefix, lvalue_span, bk,
405+
&borrow, end_issued_loan_span)
406+
}
404407
}
405408
Control::Break
406409
}
407410
(Write(kind), _) => {
408411
match kind {
409-
WriteKind::MutableBorrow(bk) =>
412+
WriteKind::MutableBorrow(bk) => {
413+
let end_issued_loan_span =
414+
flow_state.borrows.base_results.operator().region_span(
415+
&borrow.region).end_point();
410416
this.report_conflicting_borrow(
411-
context, lvalue_span,
412-
common_prefix,
413-
(lvalue_span.0, bk), (&borrow.lvalue, borrow.kind)),
417+
context, common_prefix, lvalue_span, bk,
418+
&borrow, end_issued_loan_span)
419+
}
414420
WriteKind::StorageDead |
415421
WriteKind::Mutate =>
416422
this.report_illegal_mutation_of_borrowed(
417423
context, lvalue_span, borrow),
418424
WriteKind::Move =>
419425
this.report_move_out_while_borrowed(
420-
context, lvalue_span, borrow),
426+
context, lvalue_span, &borrow),
421427
}
422428
Control::Break
423429
}
@@ -966,48 +972,49 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
966972

967973
fn report_conflicting_borrow(&mut self,
968974
_context: Context,
969-
(lvalue, span): (&Lvalue, Span),
970975
common_prefix: &Lvalue,
971-
loan1: (&Lvalue, BorrowKind),
972-
loan2: (&Lvalue, BorrowKind)) {
976+
(lvalue, span): (&Lvalue, Span),
977+
gen_borrow_kind: BorrowKind,
978+
issued_borrow: &BorrowData,
979+
end_issued_loan_span: Span) {
973980
use self::prefixes::IsPrefixOf;
974981

975-
let (loan1_lvalue, loan1_kind) = loan1;
976-
let (loan2_lvalue, loan2_kind) = loan2;
982+
assert!(common_prefix.is_prefix_of(lvalue));
983+
assert!(common_prefix.is_prefix_of(&issued_borrow.lvalue));
977984

978-
assert!(common_prefix.is_prefix_of(loan1_lvalue));
979-
assert!(common_prefix.is_prefix_of(loan2_lvalue));
985+
let issued_span = self.retrieve_borrow_span(issued_borrow);
980986

981987
// FIXME: supply non-"" `opt_via` when appropriate
982-
let mut err = match (loan1_kind, "immutable", "mutable",
983-
loan2_kind, "immutable", "mutable") {
988+
let mut err = match (gen_borrow_kind, "immutable", "mutable",
989+
issued_borrow.kind, "immutable", "mutable") {
984990
(BorrowKind::Shared, lft, _, BorrowKind::Mut, _, rgt) |
985991
(BorrowKind::Mut, _, lft, BorrowKind::Shared, rgt, _) =>
986992
self.tcx.cannot_reborrow_already_borrowed(
987-
span, &self.describe_lvalue(lvalue),
988-
"", lft, "it", rgt, "", Origin::Mir),
993+
span, &self.describe_lvalue(lvalue), "", lft, issued_span,
994+
"it", rgt, "", end_issued_loan_span, Origin::Mir),
989995

990996
(BorrowKind::Mut, _, _, BorrowKind::Mut, _, _) =>
991997
self.tcx.cannot_mutably_borrow_multiply(
992-
span, &self.describe_lvalue(lvalue), "", Origin::Mir),
998+
span, &self.describe_lvalue(lvalue), "", issued_span,
999+
"", end_issued_loan_span, Origin::Mir),
9931000

9941001
(BorrowKind::Unique, _, _, BorrowKind::Unique, _, _) =>
9951002
self.tcx.cannot_uniquely_borrow_by_two_closures(
996-
span, &self.describe_lvalue(lvalue), Origin::Mir),
1003+
span, &self.describe_lvalue(lvalue), issued_span,
1004+
end_issued_loan_span, Origin::Mir),
9971005

9981006
(BorrowKind::Unique, _, _, _, _, _) =>
9991007
self.tcx.cannot_uniquely_borrow_by_one_closure(
1000-
span, &self.describe_lvalue(lvalue), "it", "", Origin::Mir),
1008+
span, &self.describe_lvalue(lvalue), "",
1009+
issued_span, "it", "", end_issued_loan_span, Origin::Mir),
10011010

10021011
(_, _, _, BorrowKind::Unique, _, _) =>
10031012
self.tcx.cannot_reborrow_already_uniquely_borrowed(
1004-
span, &self.describe_lvalue(lvalue), "it", "", Origin::Mir),
1013+
span, &self.describe_lvalue(lvalue), "it", "",
1014+
issued_span, "", end_issued_loan_span, Origin::Mir),
10051015

10061016
(BorrowKind::Shared, _, _, BorrowKind::Shared, _, _) =>
10071017
unreachable!(),
1008-
1009-
// FIXME: add span labels for first and second mutable borrows, as well as
1010-
// end point for first.
10111018
};
10121019
err.emit();
10131020
}

src/librustc_mir/dataflow/impls/borrows.rs

+25-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use rustc::mir::{self, Location, Mir};
1212
use rustc::mir::visit::Visitor;
1313
use rustc::ty::{Region, TyCtxt};
14+
use rustc::ty::RegionKind;
1415
use rustc::ty::RegionKind::ReScope;
1516
use rustc::util::nodemap::{FxHashMap, FxHashSet};
1617

@@ -21,6 +22,8 @@ use rustc_data_structures::indexed_vec::{IndexVec};
2122
use dataflow::{BitDenotation, BlockSets, DataflowOperator};
2223
pub use dataflow::indexes::BorrowIndex;
2324

25+
use syntax_pos::Span;
26+
2427
use std::fmt;
2528

2629
// `Borrows` maps each dataflow bit to an `Rvalue::Ref`, which can be
@@ -32,6 +35,7 @@ pub struct Borrows<'a, 'tcx: 'a> {
3235
borrows: IndexVec<BorrowIndex, BorrowData<'tcx>>,
3336
location_map: FxHashMap<Location, BorrowIndex>,
3437
region_map: FxHashMap<Region<'tcx>, FxHashSet<BorrowIndex>>,
38+
region_span_map: FxHashMap<RegionKind, Span>,
3539
}
3640

3741
// temporarily allow some dead fields: `kind` and `region` will be
@@ -63,18 +67,21 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
6367
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &'a Mir<'tcx>) -> Self {
6468
let mut visitor = GatherBorrows { idx_vec: IndexVec::new(),
6569
location_map: FxHashMap(),
66-
region_map: FxHashMap(), };
70+
region_map: FxHashMap(),
71+
region_span_map: FxHashMap()};
6772
visitor.visit_mir(mir);
6873
return Borrows { tcx: tcx,
6974
mir: mir,
7075
borrows: visitor.idx_vec,
7176
location_map: visitor.location_map,
72-
region_map: visitor.region_map, };
77+
region_map: visitor.region_map,
78+
region_span_map: visitor.region_span_map};
7379

7480
struct GatherBorrows<'tcx> {
7581
idx_vec: IndexVec<BorrowIndex, BorrowData<'tcx>>,
7682
location_map: FxHashMap<Location, BorrowIndex>,
7783
region_map: FxHashMap<Region<'tcx>, FxHashSet<BorrowIndex>>,
84+
region_span_map: FxHashMap<RegionKind, Span>,
7885
}
7986
impl<'tcx> Visitor<'tcx> for GatherBorrows<'tcx> {
8087
fn visit_rvalue(&mut self,
@@ -90,6 +97,16 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
9097
borrows.insert(idx);
9198
}
9299
}
100+
101+
fn visit_statement(&mut self,
102+
block: mir::BasicBlock,
103+
statement: &mir::Statement<'tcx>,
104+
location: Location) {
105+
if let mir::StatementKind::EndRegion(region_scope) = statement.kind {
106+
self.region_span_map.insert(ReScope(region_scope), statement.source_info.span);
107+
}
108+
self.super_statement(block, statement, location);
109+
}
93110
}
94111
}
95112

@@ -98,6 +115,12 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
98115
pub fn location(&self, idx: BorrowIndex) -> &Location {
99116
&self.borrows[idx].location
100117
}
118+
119+
pub fn region_span(&self, region: &Region) -> Span {
120+
let opt_span = self.region_span_map.get(region);
121+
assert!(opt_span.is_some(), "end region not found for {:?}", region);
122+
*opt_span.unwrap()
123+
}
101124
}
102125

103126
impl<'a, 'tcx> BitDenotation for Borrows<'a, 'tcx> {

0 commit comments

Comments
 (0)