Skip to content

Commit 877d339

Browse files
committed
BorrowUsedHere|Later
1 parent 6a3897f commit 877d339

File tree

3 files changed

+147
-18
lines changed

3 files changed

+147
-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: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,52 @@ pub(crate) enum RequireStaticErr {
157157
multi_span: MultiSpan,
158158
},
159159
}
160+
161+
//explain_borrow.rs
162+
163+
#[derive(SessionSubdiagnostic)]
164+
pub(crate) enum BorrowUsedHere {
165+
#[label(borrowck::used_here_by_closure)]
166+
ByClosure {
167+
#[primary_span]
168+
path_span: Span,
169+
},
170+
}
171+
172+
#[derive(SessionSubdiagnostic)]
173+
pub(crate) enum BorrowUsedLater<'a> {
174+
#[label(borrowck::borrow_later_captured_by_trait_object)]
175+
TraitCapture {
176+
borrow_desc: &'a str,
177+
#[primary_span]
178+
span: Span,
179+
},
180+
181+
#[label(borrowck::borrow_later_captured_by_closure)]
182+
ClosureCapture {
183+
borrow_desc: &'a str,
184+
#[primary_span]
185+
span: Span,
186+
},
187+
188+
#[label(borrowck::borrow_later_used_by_call)]
189+
Call {
190+
borrow_desc: &'a str,
191+
#[primary_span]
192+
span: Span,
193+
},
194+
195+
#[label(borrowck::borrow_later_stored_here)]
196+
FakeLetRead {
197+
borrow_desc: &'a str,
198+
#[primary_span]
199+
span: Span,
200+
},
201+
202+
#[label(borrowck::borrow_later_used_here)]
203+
Other {
204+
borrow_desc: &'a str,
205+
#[primary_span]
206+
span: Span,
207+
},
208+
}

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,60 @@ borrowck_returned_lifetime_short =
5858
5959
borrowck_used_impl_require_static =
6060
the used `impl` has a `'static` requirement
61+
62+
borrowck_borrow_later_captured_by_trait_object =
63+
{$borrow_desc}borrow later captured here by trait object
64+
65+
borrowck_borrow_later_captured_by_closure =
66+
{$borrow_desc}borrow later captured here by closure
67+
68+
borrowck_borrow_later_used_by_call =
69+
{$borrow_desc}borrow later used by call
70+
71+
borrowck_borrow_later_stored_here =
72+
{$borrow_desc}borrow later stored here
73+
74+
borrowck_borrow_later_used_here =
75+
{$borrow_desc}borrow later used here
76+
77+
borrowck_used_here_by_closure =
78+
used here by closure
79+
80+
borrowck_trait_capture_borrow_in_later_iteration_loop =
81+
{$borrow_desc}borrow later borrow captured here by trait object, in later iteration of loop
82+
83+
borrowck_closure_capture_borrow_in_later_iteration_loop =
84+
{$borrow_desc}borrow later borrow captured here by closure, in later iteration of loop
85+
86+
borrowck_call_used_borrow_in_later_iteration_loop =
87+
{$borrow_desc}borrow later borrow used by call, in later iteration of loop
88+
89+
borrowck_used_borrow_in_later_iteration_loop =
90+
{$borrow_desc}borrow later borrow used here, in later iteration of loop
91+
92+
borrowck_drop_local_might_cause_borrow =
93+
{$borrow_desc}borrow might be used here, when `{$local_name}` is dropped and runs the {$dtor_name} for {$type_name}
94+
95+
borrowck_var_dropped_in_wrong_order =
96+
values in a scope are dropped in the opposite order they are defined
97+
98+
borrowck_temporary_access_to_borrow =
99+
a temporary with access to the {$borrow_desc}borrow is created here ...
100+
101+
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}
102+
103+
borrowck_consider_add_semicolon =
104+
consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
105+
106+
borrowck_consider_forcing_temporary_drop_sooner =
107+
the temporary is part of an expression at the end of a block;
108+
consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
109+
110+
borrowck_perhaps_save_in_new_local_to_drop =
111+
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
112+
113+
borrowck_outlive_constraint_need_borrow_for =
114+
{$category}requires that `{$desc}` is borrowed for `{$region_name}`
115+
116+
borrowck_outlive_constraint_need_borrow_lasts =
117+
{$category}requires that `{$borrow_desc}` lasts for `{$region_name}`

0 commit comments

Comments
 (0)