Skip to content

Commit 6d721f1

Browse files
committed
E0596 & E0594 diagnose migration
1 parent 84b168f commit 6d721f1

File tree

5 files changed

+568
-95
lines changed

5 files changed

+568
-95
lines changed

compiler/rustc_borrowck/messages.ftl

+104-2
Original file line numberDiff line numberDiff line change
@@ -389,8 +389,11 @@ borrowck_require_mutable_binding =
389389
*[mutation] possible mutation of `{$upvar}`
390390
}
391391

392-
borrowck_cannot_act =
393-
cannot {$act}
392+
borrowck_cannot_assign =
393+
cannot assign
394+
395+
borrowck_cannot_borrow_mut =
396+
cannot borrow as mutable
394397

395398
borrowck_expects_fnmut_not_fn =
396399
change this to accept `FnMut` instead of `Fn`
@@ -589,3 +592,102 @@ borrowck_cannot_reassign_immutable_arg =
589592

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

compiler/rustc_borrowck/src/borrowck_errors.rs

+149-8
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

+9-7
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ mod mutability_errors;
4545
mod region_errors;
4646

4747
pub(crate) use bound_region_errors::{ToUniverseInfo, UniverseInfo};
48-
pub(crate) use mutability_errors::AccessKind;
48+
pub(crate) use mutability_errors::{AccessKind, PlaceAndReason};
4949
pub(crate) use outlives_suggestion::OutlivesSuggestionBuilder;
5050
pub(crate) use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors};
5151
pub(crate) use region_name::{RegionName, RegionNameSource};
@@ -670,6 +670,7 @@ impl UseSpans<'_> {
670670
}
671671
}
672672

673+
#[derive(Clone, Copy, Debug)]
673674
pub(super) enum BorrowedContentSource<'tcx> {
674675
DerefRawPointer,
675676
DerefMutableRef,
@@ -707,21 +708,22 @@ impl<'tcx> BorrowedContentSource<'tcx> {
707708
}
708709
}
709710

710-
pub(super) fn describe_for_immutable_place(&self, tcx: TyCtxt<'_>) -> String {
711+
// ready to remove
712+
pub(super) fn describe_for_immutable_place(&self, tcx: TyCtxt<'_>) -> Option<String> {
711713
match *self {
712-
BorrowedContentSource::DerefRawPointer => "a `*const` pointer".to_string(),
713-
BorrowedContentSource::DerefSharedRef => "a `&` reference".to_string(),
714+
BorrowedContentSource::DerefRawPointer => None,
715+
BorrowedContentSource::DerefSharedRef => None,
714716
BorrowedContentSource::DerefMutableRef => {
715717
bug!("describe_for_immutable_place: DerefMutableRef isn't immutable")
716718
}
717719
BorrowedContentSource::OverloadedDeref(ty) => ty
718720
.ty_adt_def()
719721
.and_then(|adt| match tcx.get_diagnostic_name(adt.did())? {
720-
name @ (sym::Rc | sym::Arc) => Some(format!("an `{name}`")),
722+
name @ (sym::Rc | sym::Arc) => Some(Some(format!("an `{name}`"))),
721723
_ => None,
722724
})
723-
.unwrap_or_else(|| format!("dereference of `{ty}`")),
724-
BorrowedContentSource::OverloadedIndex(ty) => format!("an index of `{ty}`"),
725+
.unwrap_or_else(|| Some(format!("dereference of `{ty}`"))),
726+
BorrowedContentSource::OverloadedIndex(ty) => Some(format!("`{ty}`")),
725727
}
726728
}
727729

0 commit comments

Comments
 (0)