Skip to content

Commit 639f4d9

Browse files
committed
E0596 & E0594 diagnose migration
1 parent f99472f commit 639f4d9

File tree

5 files changed

+566
-94
lines changed

5 files changed

+566
-94
lines changed

compiler/rustc_borrowck/messages.ftl

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,11 @@ borrowck_require_mutable_binding =
382382
*[mutation] possible mutation of `{$upvar}`
383383
}
384384

385-
borrowck_cannot_act =
386-
cannot {$act}
385+
borrowck_cannot_assign =
386+
cannot assign
387+
388+
borrowck_cannot_borrow_mut =
389+
cannot borrow as mutable
387390

388391
borrowck_expects_fnmut_not_fn =
389392
change this to accept `FnMut` instead of `Fn`
@@ -582,3 +585,102 @@ borrowck_cannot_reassign_immutable_arg =
582585

583586
borrowck_cannot_reassign_immutable_var =
584587
cannot assign twice to immutable variable {$place}
588+
589+
borrowck_modify_ty_methods_help =
590+
to modify a `{$ty}`, use `.get_mut()`, `.insert()` or the entry API
591+
592+
borrowck_upvar_need_mut_due_to_borrow =
593+
calling `{$place}` requires mutable binding due to mutable borrow of `{$upvar}`
594+
595+
borrowck_upvar_need_mut_due_to_mutation =
596+
calling `{$place}` requires mutable binding due to possible mutation of `{$upvar}`
597+
598+
borrowck_mut_borrow_place_declared_immute =
599+
cannot borrow {$any_place} as mutable, as it is not declared as mutable
600+
601+
borrowck_mut_borrow_symbol_declared_immute =
602+
cannot borrow {$any_place} as mutable, as `{$name}` is not declared as mutable
603+
604+
borrowck_mut_borrow_place_in_pattern_guard_immute =
605+
cannot borrow {$path} as mutable, as it is immutable for the pattern guard
606+
607+
borrowck_mut_borrow_place_static =
608+
cannot borrow immutable static item {$path} as mutable
609+
610+
borrowck_mut_borrow_symbol_static =
611+
cannot borrow {$path} as mutable, as `{$static_name}` is an immutable static item
612+
613+
borrowck_mut_borrow_self_in_fn =
614+
cannot borrow {$path} as mutable, as it is a captured variable in a `Fn` closure
615+
616+
borrowck_mut_borrow_upvar_in_fn =
617+
cannot borrow {$path} as mutable, as `Fn` closures cannot mutate their captured variables
618+
619+
borrowck_mut_borrow_self_behind_const_pointer =
620+
cannot borrow {$place} as mutable, as it is behind a `*const` pointer
621+
622+
borrowck_mut_borrow_self_behind_ref =
623+
cannot borrow {$place} as mutable, as it is behind a `&` reference
624+
625+
borrowck_mut_borrow_self_behind_deref =
626+
cannot borrow {$place} as mutable, as it is behind {$name}
627+
628+
borrowck_mut_borrow_self_behind_index =
629+
cannot borrow {$place} as mutable, as it is behind an index of {$name}
630+
631+
borrowck_mut_borrow_data_behind_const_pointer =
632+
cannot borrow data in a `*const` pointer as mutable
633+
634+
borrowck_mut_borrow_data_behind_ref =
635+
cannot borrow data in a `&` reference as mutable
636+
637+
borrowck_mut_borrow_data_behind_deref =
638+
cannot borrow data in {$name} as mutable
639+
640+
borrowck_mut_borrow_data_behind_index =
641+
cannot borrow data in an index of {$name} as mutable
642+
643+
borrowck_assign_place_declared_immute =
644+
cannot assign to {$any_place}, as it is not declared as mutable
645+
646+
borrowck_assign_symbol_declared_immute =
647+
cannot assign to {$any_place}, as `{$name}` is not declared as mutable
648+
649+
borrowck_assign_place_in_pattern_guard_immute =
650+
cannot assign to {$path}, as it is immutable for the pattern guard
651+
652+
borrowck_assign_place_static =
653+
cannot assign to immutable static item {$path}
654+
655+
borrowck_assign_symbol_static =
656+
cannot assign to {$path}, as `{$static_name}` is an immutable static item
657+
658+
borrowck_assign_place_in_fn =
659+
cannot assign to {$path}, as it is a captured variable in a `Fn` closure
660+
661+
borrowck_assign_upvar_in_fn =
662+
cannot assign to {$path}, as `Fn` closures cannot mutate their captured variables
663+
664+
borrowck_assign_place_behind_const_pointer =
665+
cannot assign to {$place}, which is behind a `*const` pointer
666+
667+
borrowck_assign_place_behind_ref =
668+
cannot assign to {$place}, which is behind a `&` reference
669+
670+
borrowck_assign_place_behind_deref =
671+
cannot assign to {$place}, which is behind {$name}
672+
673+
borrowck_assign_place_behind_index =
674+
cannot assign to {$place}, which is behind an index of {$ty}
675+
676+
borrowck_assign_data_behind_const_pointer =
677+
cannot assign to data in a `*const` pointer
678+
679+
borrowck_assign_data_behind_ref =
680+
cannot assign to data in a `&` reference
681+
682+
borrowck_assign_data_behind_deref =
683+
cannot assign to data in {$name}
684+
685+
borrowck_assign_data_behind_index =
686+
cannot assign to data in an index of {$name}

compiler/rustc_borrowck/src/borrowck_errors.rs

Lines changed: 149 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1+
// #![deny(rustc::untranslatable_diagnostic)]
2+
// #![deny(rustc::diagnostic_outside_of_impl)]
3+
14
use rustc_errors::{
25
struct_span_err, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, ErrorGuaranteed, MultiSpan,
36
};
47
use rustc_middle::ty::{self, Ty, TyCtxt};
58
use rustc_span::Span;
69

7-
use crate::session_diagnostics::{
8-
AssignBorrowErr, BorrowAcrossDestructor, BorrowAcrossGeneratorYield, InteriorDropMoveErr,
9-
PathShortLive, UseMutBorrowErr,
10+
use crate::{
11+
diagnostics::PlaceAndReason,
12+
session_diagnostics::{
13+
AssignBorrowErr, AssignErr, BorrowAcrossDestructor, BorrowAcrossGeneratorYield,
14+
InteriorDropMoveErr, MutBorrowErr, PathShortLive, UseMutBorrowErr,
15+
},
1016
};
1117

1218
impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
@@ -215,9 +221,77 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
215221
pub(crate) fn cannot_assign(
216222
&self,
217223
span: Span,
218-
desc: &str,
224+
path_and_reason: PlaceAndReason<'_>,
219225
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
220-
struct_span_err!(self, span, E0594, "cannot assign to {}", desc)
226+
let diag = match path_and_reason {
227+
PlaceAndReason::DeclaredImmute(place, name) => {
228+
if let Some(name) = name {
229+
AssignErr::SymbolDeclaredImmute { span, any_place: place, name }
230+
} else {
231+
AssignErr::PlaceDeclaredImmute { span, any_place: place }
232+
}
233+
}
234+
PlaceAndReason::InPatternGuard(place) => {
235+
AssignErr::PatternGuardImmute { span, path: place }
236+
}
237+
PlaceAndReason::StaticItem(place, name) => {
238+
if let Some(name) = name {
239+
AssignErr::SymbolStatic { span, path: place, static_name: name }
240+
} else {
241+
AssignErr::PlaceStatic { span, path: place }
242+
}
243+
}
244+
PlaceAndReason::UpvarCaptured(place) => AssignErr::UpvarInFn { span, path: place },
245+
PlaceAndReason::SelfCaptured(place) => AssignErr::CapturedInFn { span, path: place },
246+
PlaceAndReason::BehindPointer(place, pointer_ty, name) => {
247+
if let Some(place) = place {
248+
match pointer_ty {
249+
crate::diagnostics::BorrowedContentSource::DerefRawPointer => {
250+
AssignErr::PlaceBehindRawPointer { span, place }
251+
}
252+
crate::diagnostics::BorrowedContentSource::DerefMutableRef => {
253+
unreachable!()
254+
}
255+
crate::diagnostics::BorrowedContentSource::DerefSharedRef => {
256+
AssignErr::PlaceBehindSharedRef { span, place }
257+
}
258+
crate::diagnostics::BorrowedContentSource::OverloadedDeref(_) => {
259+
AssignErr::PlaceBehindDeref {
260+
span,
261+
place,
262+
name: name.unwrap_or_default(),
263+
}
264+
}
265+
crate::diagnostics::BorrowedContentSource::OverloadedIndex(_) => {
266+
AssignErr::PlaceBehindIndex {
267+
span,
268+
place,
269+
name: name.unwrap_or_default(),
270+
}
271+
}
272+
}
273+
} else {
274+
match pointer_ty {
275+
crate::diagnostics::BorrowedContentSource::DerefRawPointer => {
276+
AssignErr::DataBehindRawPointer { span }
277+
}
278+
crate::diagnostics::BorrowedContentSource::DerefMutableRef => {
279+
unreachable!()
280+
}
281+
crate::diagnostics::BorrowedContentSource::DerefSharedRef => {
282+
AssignErr::DataBehindSharedRef { span }
283+
}
284+
crate::diagnostics::BorrowedContentSource::OverloadedDeref(_) => {
285+
AssignErr::DataBehindDeref { span, name: name.unwrap_or_default() }
286+
}
287+
crate::diagnostics::BorrowedContentSource::OverloadedIndex(_) => {
288+
AssignErr::DataBehindIndex { span, name: name.unwrap_or_default() }
289+
}
290+
}
291+
}
292+
}
293+
};
294+
self.infcx.tcx.sess.create_err(diag)
221295
}
222296

223297
pub(crate) fn cannot_move_out_of(
@@ -285,10 +359,77 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
285359
pub(crate) fn cannot_borrow_path_as_mutable_because(
286360
&self,
287361
span: Span,
288-
path: &str,
289-
reason: &str,
362+
path_and_reason: PlaceAndReason<'_>,
290363
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
291-
struct_span_err!(self, span, E0596, "cannot borrow {} as mutable{}", path, reason,)
364+
let diag = match path_and_reason {
365+
PlaceAndReason::DeclaredImmute(place, name) => {
366+
if let Some(name) = name {
367+
MutBorrowErr::SymbolDeclaredImmute { span, any_place: place, name }
368+
} else {
369+
MutBorrowErr::PlaceDeclaredImmute { span, any_place: place }
370+
}
371+
}
372+
PlaceAndReason::InPatternGuard(place) => {
373+
MutBorrowErr::PatternGuardImmute { span, path: place }
374+
}
375+
PlaceAndReason::StaticItem(place, name) => {
376+
if let Some(name) = name {
377+
MutBorrowErr::SymbolStatic { span, path: place, static_name: name }
378+
} else {
379+
MutBorrowErr::PlaceStatic { span, path: place }
380+
}
381+
}
382+
PlaceAndReason::UpvarCaptured(place) => MutBorrowErr::UpvarInFn { span, path: place },
383+
PlaceAndReason::SelfCaptured(place) => MutBorrowErr::CapturedInFn { span, path: place },
384+
PlaceAndReason::BehindPointer(place, pointer_ty, name) => {
385+
if let Some(place) = place {
386+
match pointer_ty {
387+
crate::diagnostics::BorrowedContentSource::DerefRawPointer => {
388+
MutBorrowErr::SelfBehindRawPointer { span, place }
389+
}
390+
crate::diagnostics::BorrowedContentSource::DerefMutableRef => {
391+
unreachable!()
392+
}
393+
crate::diagnostics::BorrowedContentSource::DerefSharedRef => {
394+
MutBorrowErr::SelfBehindSharedRef { span, place }
395+
}
396+
crate::diagnostics::BorrowedContentSource::OverloadedDeref(_) => {
397+
MutBorrowErr::SelfBehindDeref {
398+
span,
399+
place,
400+
name: name.unwrap_or_default(),
401+
}
402+
}
403+
crate::diagnostics::BorrowedContentSource::OverloadedIndex(_) => {
404+
MutBorrowErr::SelfBehindIndex {
405+
span,
406+
place,
407+
name: name.unwrap_or_default(),
408+
}
409+
}
410+
}
411+
} else {
412+
match pointer_ty {
413+
crate::diagnostics::BorrowedContentSource::DerefRawPointer => {
414+
MutBorrowErr::DataBehindRawPointer { span }
415+
}
416+
crate::diagnostics::BorrowedContentSource::DerefMutableRef => {
417+
unreachable!()
418+
}
419+
crate::diagnostics::BorrowedContentSource::DerefSharedRef => {
420+
MutBorrowErr::DataBehindSharedRef { span }
421+
}
422+
crate::diagnostics::BorrowedContentSource::OverloadedDeref(_) => {
423+
MutBorrowErr::DataBehindDeref { span, name: name.unwrap_or_default() }
424+
}
425+
crate::diagnostics::BorrowedContentSource::OverloadedIndex(_) => {
426+
MutBorrowErr::DataBehindIndex { span, name: name.unwrap_or_default() }
427+
}
428+
}
429+
}
430+
}
431+
};
432+
self.infcx.tcx.sess.create_err(diag)
292433
}
293434

294435
pub(crate) fn cannot_mutate_in_immutable_section(

compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ mod mutability_errors;
4646
mod region_errors;
4747

4848
pub(crate) use bound_region_errors::{ToUniverseInfo, UniverseInfo};
49-
pub(crate) use mutability_errors::AccessKind;
49+
pub(crate) use mutability_errors::{AccessKind, PlaceAndReason};
5050
pub(crate) use outlives_suggestion::OutlivesSuggestionBuilder;
5151
pub(crate) use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors};
5252
pub(crate) use region_name::{RegionName, RegionNameSource};
@@ -678,6 +678,7 @@ impl UseSpans<'_> {
678678
}
679679
}
680680

681+
#[derive(Clone, Copy, Debug)]
681682
pub(super) enum BorrowedContentSource<'tcx> {
682683
DerefRawPointer,
683684
DerefMutableRef,
@@ -715,21 +716,22 @@ impl<'tcx> BorrowedContentSource<'tcx> {
715716
}
716717
}
717718

718-
pub(super) fn describe_for_immutable_place(&self, tcx: TyCtxt<'_>) -> String {
719+
// ready to remove
720+
pub(super) fn describe_for_immutable_place(&self, tcx: TyCtxt<'_>) -> Option<String> {
719721
match *self {
720-
BorrowedContentSource::DerefRawPointer => "a `*const` pointer".to_string(),
721-
BorrowedContentSource::DerefSharedRef => "a `&` reference".to_string(),
722+
BorrowedContentSource::DerefRawPointer => None,
723+
BorrowedContentSource::DerefSharedRef => None,
722724
BorrowedContentSource::DerefMutableRef => {
723725
bug!("describe_for_immutable_place: DerefMutableRef isn't immutable")
724726
}
725727
BorrowedContentSource::OverloadedDeref(ty) => ty
726728
.ty_adt_def()
727729
.and_then(|adt| match tcx.get_diagnostic_name(adt.did())? {
728-
name @ (sym::Rc | sym::Arc) => Some(format!("an `{name}`")),
730+
name @ (sym::Rc | sym::Arc) => Some(Some(format!("an `{name}`"))),
729731
_ => None,
730732
})
731-
.unwrap_or_else(|| format!("dereference of `{ty}`")),
732-
BorrowedContentSource::OverloadedIndex(ty) => format!("an index of `{ty}`"),
733+
.unwrap_or_else(|| Some(format!("dereference of `{ty}`"))),
734+
BorrowedContentSource::OverloadedIndex(ty) => Some(format!("`{ty}`")),
733735
}
734736
}
735737

0 commit comments

Comments
 (0)