Skip to content

Commit 05cc555

Browse files
committed
place and reason as a IntodiagnosticArg type
1 parent e924fd8 commit 05cc555

File tree

5 files changed

+116
-94
lines changed

5 files changed

+116
-94
lines changed

compiler/rustc_borrowck/messages.ftl

+14-14
Original file line numberDiff line numberDiff line change
@@ -36,25 +36,25 @@ borrowck_assign_place_behind_ref =
3636
cannot assign to {$place}, which is behind a `&` reference
3737
3838
borrowck_assign_place_declared_immute =
39-
cannot assign to {$any_place}, as it is not declared as mutable
39+
cannot assign to {$place}, as it is not declared as mutable
4040
4141
borrowck_assign_place_in_fn =
42-
cannot assign to {$path}, as it is a captured variable in a `Fn` closure
42+
cannot assign to {$place}, as it is a captured variable in a `Fn` closure
4343
4444
borrowck_assign_place_in_pattern_guard_immute =
45-
cannot assign to {$path}, as it is immutable for the pattern guard
45+
cannot assign to {$place}, as it is immutable for the pattern guard
4646
4747
borrowck_assign_place_static =
48-
cannot assign to immutable static item {$path}
48+
cannot assign to immutable static item {$place}
4949
5050
borrowck_assign_symbol_declared_immute =
51-
cannot assign to {$any_place}, as `{$name}` is not declared as mutable
51+
cannot assign to {$place}, as `{$name}` is not declared as mutable
5252
5353
borrowck_assign_symbol_static =
54-
cannot assign to {$path}, as `{$static_name}` is an immutable static item
54+
cannot assign to {$place}, as `{$static_name}` is an immutable static item
5555
5656
borrowck_assign_upvar_in_fn =
57-
cannot assign to {$path}, as `Fn` closures cannot mutate their captured variables
57+
cannot assign to {$place}, as `Fn` closures cannot mutate their captured variables
5858
5959
borrowck_borrow_due_to_use_closure =
6060
borrow occurs due to use in closure
@@ -396,13 +396,13 @@ borrowck_mut_borrow_data_behind_ref =
396396
cannot borrow data in a `&` reference as mutable
397397
398398
borrowck_mut_borrow_place_declared_immute =
399-
cannot borrow {$any_place} as mutable, as it is not declared as mutable
399+
cannot borrow {$place} as mutable, as it is not declared as mutable
400400
401401
borrowck_mut_borrow_place_in_pattern_guard_immute =
402-
cannot borrow {$path} as mutable, as it is immutable for the pattern guard
402+
cannot borrow {$place} as mutable, as it is immutable for the pattern guard
403403
404404
borrowck_mut_borrow_place_static =
405-
cannot borrow immutable static item {$path} as mutable
405+
cannot borrow immutable static item {$place} as mutable
406406
407407
borrowck_mut_borrow_self_behind_const_pointer =
408408
cannot borrow {$place} as mutable, as it is behind a `*const` pointer
@@ -417,16 +417,16 @@ borrowck_mut_borrow_self_behind_ref =
417417
cannot borrow {$place} as mutable, as it is behind a `&` reference
418418
419419
borrowck_mut_borrow_self_in_fn =
420-
cannot borrow {$path} as mutable, as it is a captured variable in a `Fn` closure
420+
cannot borrow {$place} as mutable, as it is a captured variable in a `Fn` closure
421421
422422
borrowck_mut_borrow_symbol_declared_immute =
423-
cannot borrow {$any_place} as mutable, as `{$name}` is not declared as mutable
423+
cannot borrow {$place} as mutable, as `{$name}` is not declared as mutable
424424
425425
borrowck_mut_borrow_symbol_static =
426-
cannot borrow {$path} as mutable, as `{$static_name}` is an immutable static item
426+
cannot borrow {$place} as mutable, as `{$static_name}` is an immutable static item
427427
428428
borrowck_mut_borrow_upvar_in_fn =
429-
cannot borrow {$path} as mutable, as `Fn` closures cannot mutate their captured variables
429+
cannot borrow {$place} as mutable, as `Fn` closures cannot mutate their captured variables
430430
431431
borrowck_mutably_borrow_multiply_loop_label =
432432
{$is_place_empty ->

compiler/rustc_borrowck/src/borrowck_errors.rs

+16-18
Original file line numberDiff line numberDiff line change
@@ -226,25 +226,23 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
226226
let diag = match path_and_reason {
227227
PlaceAndReason::DeclaredImmute(place, name) => {
228228
if let Some(name) = name {
229-
AssignErr::SymbolDeclaredImmute { span, any_place: place, name }
229+
AssignErr::SymbolDeclaredImmute { span, place, name }
230230
} else {
231-
AssignErr::PlaceDeclaredImmute { span, any_place: place }
231+
AssignErr::PlaceDeclaredImmute { span, place }
232232
}
233233
}
234-
PlaceAndReason::InPatternGuard(place) => {
235-
AssignErr::PatternGuardImmute { span, path: place }
236-
}
234+
PlaceAndReason::InPatternGuard(place) => AssignErr::PatternGuardImmute { span, place },
237235
PlaceAndReason::StaticItem(place, name) => {
238236
if let Some(name) = name {
239-
AssignErr::SymbolStatic { span, path: place, static_name: name }
237+
AssignErr::SymbolStatic { span, place, static_name: name }
240238
} else {
241-
AssignErr::PlaceStatic { span, path: place }
239+
AssignErr::PlaceStatic { span, place }
242240
}
243241
}
244-
PlaceAndReason::UpvarCaptured(place) => AssignErr::UpvarInFn { span, path: place },
245-
PlaceAndReason::SelfCaptured(place) => AssignErr::CapturedInFn { span, path: place },
242+
PlaceAndReason::UpvarCaptured(place) => AssignErr::UpvarInFn { span, place },
243+
PlaceAndReason::SelfCaptured(place) => AssignErr::CapturedInFn { span, place },
246244
PlaceAndReason::BehindPointer(place, pointer_ty, name) => {
247-
if let Some(place) = place {
245+
if place.0.is_some() {
248246
match pointer_ty {
249247
crate::diagnostics::BorrowedContentSource::DerefRawPointer => {
250248
AssignErr::PlaceBehindRawPointer { span, place }
@@ -364,25 +362,25 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
364362
let diag = match path_and_reason {
365363
PlaceAndReason::DeclaredImmute(place, name) => {
366364
if let Some(name) = name {
367-
MutBorrowErr::SymbolDeclaredImmute { span, any_place: place, name }
365+
MutBorrowErr::SymbolDeclaredImmute { span, place, name }
368366
} else {
369-
MutBorrowErr::PlaceDeclaredImmute { span, any_place: place }
367+
MutBorrowErr::PlaceDeclaredImmute { span, place }
370368
}
371369
}
372370
PlaceAndReason::InPatternGuard(place) => {
373-
MutBorrowErr::PatternGuardImmute { span, path: place }
371+
MutBorrowErr::PatternGuardImmute { span, place }
374372
}
375373
PlaceAndReason::StaticItem(place, name) => {
376374
if let Some(name) = name {
377-
MutBorrowErr::SymbolStatic { span, path: place, static_name: name }
375+
MutBorrowErr::SymbolStatic { span, place, static_name: name }
378376
} else {
379-
MutBorrowErr::PlaceStatic { span, path: place }
377+
MutBorrowErr::PlaceStatic { span, place }
380378
}
381379
}
382-
PlaceAndReason::UpvarCaptured(place) => MutBorrowErr::UpvarInFn { span, path: place },
383-
PlaceAndReason::SelfCaptured(place) => MutBorrowErr::CapturedInFn { span, path: place },
380+
PlaceAndReason::UpvarCaptured(place) => MutBorrowErr::UpvarInFn { span, place },
381+
PlaceAndReason::SelfCaptured(place) => MutBorrowErr::CapturedInFn { span, place },
384382
PlaceAndReason::BehindPointer(place, pointer_ty, name) => {
385-
if let Some(place) = place {
383+
if place.0.is_some() {
386384
match pointer_ty {
387385
crate::diagnostics::BorrowedContentSource::DerefRawPointer => {
388386
MutBorrowErr::SelfBehindRawPointer { span, place }

compiler/rustc_borrowck/src/diagnostics/mod.rs

+31-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::session_diagnostics::{
55
CaptureVarKind, CaptureVarPathUseCause, OnClosureNote,
66
};
77
use itertools::Itertools;
8-
use rustc_errors::{Applicability, Diagnostic};
8+
use rustc_errors::{Applicability, Diagnostic, DiagnosticArgValue, IntoDiagnosticArg};
99
use rustc_hir as hir;
1010
use rustc_hir::def::{CtorKind, Namespace};
1111
use rustc_hir::CoroutineKind;
@@ -63,6 +63,25 @@ pub(super) struct DescribePlaceOpt {
6363

6464
pub(super) struct IncludingTupleField(pub(super) bool);
6565

66+
#[derive(Debug)]
67+
pub(super) struct DescribedPlace(pub(super) Option<String>);
68+
69+
impl IntoDiagnosticArg for DescribedPlace {
70+
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
71+
let mut desc = self.0;
72+
desc.as_mut().map(|s| {
73+
s.reserve(2);
74+
s.insert(0, '`');
75+
s.push('`');
76+
s
77+
});
78+
match desc {
79+
Some(descr) => descr.into_diagnostic_arg(),
80+
None => "value".into_diagnostic_arg(),
81+
}
82+
}
83+
}
84+
6685
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
6786
/// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure
6887
/// is moved after being invoked.
@@ -174,6 +193,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
174193
}
175194
}
176195

196+
pub(super) fn describe_place_typed(&self, place_ref: PlaceRef<'tcx>) -> DescribedPlace {
197+
DescribedPlace(self.describe_place(place_ref))
198+
}
199+
177200
/// End-user visible description of `place` if one can be found.
178201
/// If the place is a temporary for instance, `None` will be returned.
179202
pub(super) fn describe_place(&self, place_ref: PlaceRef<'tcx>) -> Option<String> {
@@ -631,7 +654,7 @@ impl UseSpans<'_> {
631654
) {
632655
if let UseSpans::ClosureUse { coroutine_kind, capture_kind_span, path_span, .. } = self {
633656
if capture_kind_span != path_span {
634-
err.subdiagnostic(match kind {
657+
let diag = match kind {
635658
Some(kd) => match kd {
636659
rustc_middle::mir::BorrowKind::Shared
637660
| rustc_middle::mir::BorrowKind::Shallow => {
@@ -643,7 +666,12 @@ impl UseSpans<'_> {
643666
}
644667
},
645668
None => CaptureVarKind::Move { kind_span: capture_kind_span },
646-
});
669+
};
670+
671+
match handler {
672+
Some(hd) => err.eager_subdiagnostic(hd, diag),
673+
None => err.subdiagnostic(diag),
674+
};
647675
};
648676
let diag = f(coroutine_kind, path_span);
649677
match handler {

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

+32-36
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ use crate::session_diagnostics::{BorrowMutUpvarLable, FnMutBumpFn, OnModifyTy};
2121
use crate::util::FindAssignments;
2222
use crate::MirBorrowckCtxt;
2323

24+
use super::DescribedPlace;
25+
2426
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
2527
pub(crate) enum AccessKind {
2628
MutableBorrow,
@@ -30,17 +32,17 @@ pub(crate) enum AccessKind {
3032
#[derive(Debug)]
3133
pub(crate) enum PlaceAndReason<'a> {
3234
// place, name
33-
DeclaredImmute(String, Option<String>),
35+
DeclaredImmute(DescribedPlace, Option<String>),
3436
// place
35-
InPatternGuard(String),
37+
InPatternGuard(DescribedPlace),
3638
// place, name
37-
StaticItem(String, Option<String>),
39+
StaticItem(DescribedPlace, Option<String>),
3840
// place
39-
UpvarCaptured(String),
41+
UpvarCaptured(DescribedPlace),
4042
// place
41-
SelfCaptured(String),
43+
SelfCaptured(DescribedPlace),
4244
// place, pointer_type, name
43-
BehindPointer(Option<String>, BorrowedContentSource<'a>, Option<String>),
45+
BehindPointer(DescribedPlace, BorrowedContentSource<'a>, Option<String>),
4446
}
4547

4648
impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
@@ -60,20 +62,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
6062
);
6163

6264
let mut err;
63-
let item_msg;
6465
let diagnostic: PlaceAndReason<'_>;
6566
let mut opt_source = None;
66-
let access_place_desc = self.describe_any_place(access_place.as_ref());
67-
debug!("report_mutability_error: access_place_desc={:?}", access_place_desc);
67+
let access_place_desc = self.describe_place_typed(access_place.as_ref());
68+
69+
let access_place_desc_dbg = self.describe_any_place(access_place.as_ref());
70+
debug!("report_mutability_error: access_place_desc={:?}", access_place_desc_dbg);
6871

6972
match the_place_err {
7073
PlaceRef { local, projection: [] } => {
71-
item_msg = access_place_desc;
72-
diagnosing = if access_place.as_local().is_some() {
73-
PlaceAndReason::DeclaredImmute(item_msg.clone(), None)
74+
diagnostic = if access_place.as_local().is_some() {
75+
PlaceAndReason::DeclaredImmute(access_place_desc, None)
7476
} else {
7577
let name = self.local_names[local].expect("immutable unnamed local");
76-
PlaceAndReason::DeclaredImmute(item_msg.clone(), Some(name.to_string()))
78+
PlaceAndReason::DeclaredImmute(access_place_desc, Some(name.to_string()))
7779
};
7880
}
7981

@@ -101,34 +103,31 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
101103
// If we deref an immutable ref then the suggestion here doesn't help.
102104
return;
103105
} else {
104-
item_msg = access_place_desc;
105106
diagnostic = if self.is_upvar_field_projection(access_place.as_ref()).is_some()
106107
{
107-
PlaceAndReason::DeclaredImmute(item_msg.clone(), None)
108+
PlaceAndReason::DeclaredImmute(access_place_desc, None)
108109
} else {
109110
let name = self.upvars[upvar_index.index()].place.to_string(self.infcx.tcx);
110-
PlaceAndReason::DeclaredImmute(item_msg.clone(), Some(name))
111+
PlaceAndReason::DeclaredImmute(access_place_desc, Some(name))
111112
}
112113
}
113114
}
114115

115116
PlaceRef { local, projection: [ProjectionElem::Deref] }
116117
if self.body.local_decls[local].is_ref_for_guard() =>
117118
{
118-
item_msg = access_place_desc;
119119
diagnostic = PlaceAndReason::InPatternGuard(access_place_desc)
120120
}
121121
PlaceRef { local, projection: [ProjectionElem::Deref] }
122122
if self.body.local_decls[local].is_ref_to_static() =>
123123
{
124-
diagnosing = if access_place.projection.len() == 1 {
125-
PlaceAndReason::StaticItem(access_place_desc.clone(), None)
124+
diagnostic = if access_place.projection.len() == 1 {
125+
PlaceAndReason::StaticItem(access_place_desc, None)
126126
} else {
127-
item_msg = access_place_desc;
128127
let local_info = self.body.local_decls[local].local_info();
129128
if let LocalInfo::StaticRef { def_id, .. } = *local_info {
130129
let static_name = &self.infcx.tcx.item_name(def_id);
131-
PlaceAndReason::StaticItem(item_msg.clone(), Some(static_name.to_string()))
130+
PlaceAndReason::StaticItem(access_place_desc, Some(static_name.to_string()))
132131
} else {
133132
bug!("is_ref_to_static return true, but not ref to static?");
134133
}
@@ -139,32 +138,29 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
139138
&& proj_base.is_empty()
140139
&& !self.upvars.is_empty()
141140
{
142-
item_msg = access_place_desc;
143141
debug_assert!(self.body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty.is_ref());
144142
debug_assert!(is_closure_or_coroutine(
145143
the_place_err.ty(self.body, self.infcx.tcx).ty
146144
));
147145

148146
diagnostic = if self.is_upvar_field_projection(access_place.as_ref()).is_some()
149147
{
150-
PlaceAndReason::SelfCaptured(item_msg.clone())
148+
PlaceAndReason::SelfCaptured(access_place_desc)
151149
} else {
152-
PlaceAndReason::UpvarCaptured(item_msg.clone())
150+
PlaceAndReason::UpvarCaptured(access_place_desc)
153151
}
154152
} else {
155-
let source = self.borrowed_content_source(PlaceRef {
153+
let ptr_source = self.borrowed_content_source(PlaceRef {
156154
local: the_place_err.local,
157155
projection: proj_base,
158156
});
159-
let diag_msg = source.describe_for_immutable_place(self.infcx.tcx);
160-
diagnosing = if let Some(desc) = self.describe_place(access_place.as_ref()) {
161-
item_msg = format!("`{desc}`");
162-
PlaceAndReason::BehindPointer(Some(item_msg.clone()), source, diag_msg)
163-
} else {
164-
PlaceAndReason::BehindPointer(None, source, diag_msg)
165-
};
166-
167-
opt_source = Some(source);
157+
let name = ptr_source.describe_for_immutable_place(self.infcx.tcx);
158+
diagnostic = PlaceAndReason::BehindPointer(
159+
self.describe_place_typed(access_place.as_ref()),
160+
ptr_source,
161+
name,
162+
);
163+
opt_source = Some(ptr_source);
168164
}
169165
}
170166

@@ -184,8 +180,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
184180
}
185181

186182
debug!(
187-
"report_mutability_error: item_msg and reason is moved to a struct due to diagnosing migration: {:?}",
188-
&diagnosing
183+
"report_mutability_error: item_msg and reason is moved to a struct due to diagnosing migration: [E0594] & [E0596], now they are typed value: {:?}",
184+
&diagnostic
189185
);
190186

191187
// `act` and `acted_on` are strings that let us abstract over

0 commit comments

Comments
 (0)