Skip to content

Commit 1f346fd

Browse files
committed
BorrowUsedHere|Later
1 parent 724f4c2 commit 1f346fd

File tree

3 files changed

+145
-18
lines changed

3 files changed

+145
-18
lines changed

compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc_span::symbol::{kw, Symbol};
1616
use rustc_span::{sym, DesugaringKind, Span};
1717

1818
use crate::region_infer::BlameConstraint;
19+
use crate::session_diagnostics::{BorrowUsedHere, BorrowUsedLater};
1920
use crate::{
2021
borrow_set::BorrowData, nll::ConstraintDescription, region_infer::Cause, MirBorrowckCtxt,
2122
WriteKind,
@@ -67,34 +68,56 @@ impl<'tcx> BorrowExplanation<'tcx> {
6768
) {
6869
match *self {
6970
BorrowExplanation::UsedLater(later_use_kind, var_or_use_span, path_span) => {
70-
let message = match later_use_kind {
71-
LaterUseKind::TraitCapture => "captured here by trait object",
72-
LaterUseKind::ClosureCapture => "captured here by closure",
73-
LaterUseKind::Call => "used by call",
74-
LaterUseKind::FakeLetRead => "stored here",
75-
LaterUseKind::Other => "used here",
76-
};
7771
// We can use `var_or_use_span` if either `path_span` is not present, or both spans are the same
7872
if path_span.map(|path_span| path_span == var_or_use_span).unwrap_or(true) {
7973
if borrow_span.map(|sp| !sp.overlaps(var_or_use_span)).unwrap_or(true) {
80-
err.span_label(
81-
var_or_use_span,
82-
format!("{}borrow later {}", borrow_desc, message),
83-
);
74+
let sub_err = match later_use_kind {
75+
LaterUseKind::TraitCapture => {
76+
BorrowUsedLater::TraitCapture { borrow_desc, span: var_or_use_span }
77+
}
78+
LaterUseKind::ClosureCapture => BorrowUsedLater::ClosureCapture {
79+
borrow_desc,
80+
span: var_or_use_span,
81+
},
82+
LaterUseKind::Call => {
83+
BorrowUsedLater::Call { borrow_desc, span: var_or_use_span }
84+
}
85+
LaterUseKind::FakeLetRead => {
86+
BorrowUsedLater::FakeLetRead { borrow_desc, span: var_or_use_span }
87+
}
88+
LaterUseKind::Other => {
89+
BorrowUsedLater::Other { borrow_desc, span: var_or_use_span }
90+
}
91+
};
92+
err.subdiagnostic(sub_err);
8493
}
8594
} else {
8695
// path_span must be `Some` as otherwise the if condition is true
8796
let path_span = path_span.unwrap();
8897
// path_span is only present in the case of closure capture
8998
assert!(matches!(later_use_kind, LaterUseKind::ClosureCapture));
9099
if !borrow_span.map_or(false, |sp| sp.overlaps(var_or_use_span)) {
91-
let path_label = "used here by closure";
92-
let capture_kind_label = message;
93-
err.span_label(
94-
var_or_use_span,
95-
format!("{}borrow later {}", borrow_desc, capture_kind_label),
96-
);
97-
err.span_label(path_span, path_label);
100+
let sub_err = match later_use_kind {
101+
LaterUseKind::TraitCapture => {
102+
BorrowUsedLater::TraitCapture { borrow_desc, span: var_or_use_span }
103+
}
104+
LaterUseKind::ClosureCapture => BorrowUsedLater::ClosureCapture {
105+
borrow_desc,
106+
span: var_or_use_span,
107+
},
108+
LaterUseKind::Call => {
109+
BorrowUsedLater::Call { borrow_desc, span: var_or_use_span }
110+
}
111+
LaterUseKind::FakeLetRead => {
112+
BorrowUsedLater::FakeLetRead { borrow_desc, span: var_or_use_span }
113+
}
114+
LaterUseKind::Other => {
115+
BorrowUsedLater::Other { borrow_desc, span: var_or_use_span }
116+
}
117+
};
118+
err.subdiagnostic(sub_err);
119+
let sub_label = BorrowUsedHere::ByClosure { path_span };
120+
err.subdiagnostic(sub_label);
98121
}
99122
}
100123
}

compiler/rustc_borrowck/src/session_diagnostics.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,4 +174,51 @@ pub(crate) enum AddMoveErr {
174174
},
175175
#[note(borrowck::moved_var_cannot_copy)]
176176
MovedNotCopy {},
177+
//explain_borrow.rs
178+
179+
#[derive(SessionSubdiagnostic)]
180+
pub(crate) enum BorrowUsedHere {
181+
#[label(borrowck::used_here_by_closure)]
182+
ByClosure {
183+
#[primary_span]
184+
path_span: Span,
185+
},
186+
}
187+
188+
#[derive(SessionSubdiagnostic)]
189+
pub(crate) enum BorrowUsedLater<'a> {
190+
#[label(borrowck::borrow_later_captured_by_trait_object)]
191+
TraitCapture {
192+
borrow_desc: &'a str,
193+
#[primary_span]
194+
span: Span,
195+
},
196+
197+
#[label(borrowck::borrow_later_captured_by_closure)]
198+
ClosureCapture {
199+
borrow_desc: &'a str,
200+
#[primary_span]
201+
span: Span,
202+
},
203+
204+
#[label(borrowck::borrow_later_used_by_call)]
205+
Call {
206+
borrow_desc: &'a str,
207+
#[primary_span]
208+
span: Span,
209+
},
210+
211+
#[label(borrowck::borrow_later_stored_here)]
212+
FakeLetRead {
213+
borrow_desc: &'a str,
214+
#[primary_span]
215+
span: Span,
216+
},
217+
218+
#[label(borrowck::borrow_later_used_here)]
219+
Other {
220+
borrow_desc: &'a str,
221+
#[primary_span]
222+
span: Span,
223+
},
177224
}

compiler/rustc_error_messages/locales/en-US/borrowck.ftl

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,60 @@ borrowck_and_data_moved_here = ...and here
6666
6767
borrowck_moved_var_cannot_copy =
6868
move occurs because these variables have types that don't implement the `Copy` trait
69+
70+
borrowck_borrow_later_captured_by_trait_object =
71+
{$borrow_desc}borrow later captured here by trait object
72+
73+
borrowck_borrow_later_captured_by_closure =
74+
{$borrow_desc}borrow later captured here by closure
75+
76+
borrowck_borrow_later_used_by_call =
77+
{$borrow_desc}borrow later used by call
78+
79+
borrowck_borrow_later_stored_here =
80+
{$borrow_desc}borrow later stored here
81+
82+
borrowck_borrow_later_used_here =
83+
{$borrow_desc}borrow later used here
84+
85+
borrowck_used_here_by_closure =
86+
used here by closure
87+
88+
borrowck_trait_capture_borrow_in_later_iteration_loop =
89+
{$borrow_desc}borrow later borrow captured here by trait object, in later iteration of loop
90+
91+
borrowck_closure_capture_borrow_in_later_iteration_loop =
92+
{$borrow_desc}borrow later borrow captured here by closure, in later iteration of loop
93+
94+
borrowck_call_used_borrow_in_later_iteration_loop =
95+
{$borrow_desc}borrow later borrow used by call, in later iteration of loop
96+
97+
borrowck_used_borrow_in_later_iteration_loop =
98+
{$borrow_desc}borrow later borrow used here, in later iteration of loop
99+
100+
borrowck_drop_local_might_cause_borrow =
101+
{$borrow_desc}borrow might be used here, when `{$local_name}` is dropped and runs the {$dtor_name} for {$type_name}
102+
103+
borrowck_var_dropped_in_wrong_order =
104+
values in a scope are dropped in the opposite order they are defined
105+
106+
borrowck_temporary_access_to_borrow =
107+
a temporary with access to the {$borrow_desc}borrow is created here ...
108+
109+
borrowck_drop_temporary_might_cause_borrow = ... and the {$borrow_desc}borrow might be used here, when that temporary is dropped and runs the {$dtor_name} for {$type_name}
110+
111+
borrowck_consider_add_semicolon =
112+
consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
113+
114+
borrowck_consider_forcing_temporary_drop_sooner =
115+
the temporary is part of an expression at the end of a block;
116+
consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
117+
118+
borrowck_perhaps_save_in_new_local_to_drop =
119+
for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block
120+
121+
borrowck_outlive_constraint_need_borrow_for =
122+
{$category}requires that `{$desc}` is borrowed for `{$region_name}`
123+
124+
borrowck_outlive_constraint_need_borrow_lasts =
125+
{$category}requires that `{$borrow_desc}` lasts for `{$region_name}`

0 commit comments

Comments
 (0)