Skip to content

Commit

Permalink
E0596 & E0594 diagnose migration
Browse files Browse the repository at this point in the history
  • Loading branch information
AndyJado committed Oct 13, 2023
1 parent f99472f commit 639f4d9
Show file tree
Hide file tree
Showing 5 changed files with 566 additions and 94 deletions.
106 changes: 104 additions & 2 deletions compiler/rustc_borrowck/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -382,8 +382,11 @@ borrowck_require_mutable_binding =
*[mutation] possible mutation of `{$upvar}`
}

borrowck_cannot_act =
cannot {$act}
borrowck_cannot_assign =
cannot assign

borrowck_cannot_borrow_mut =
cannot borrow as mutable

borrowck_expects_fnmut_not_fn =
change this to accept `FnMut` instead of `Fn`
Expand Down Expand Up @@ -582,3 +585,102 @@ borrowck_cannot_reassign_immutable_arg =

borrowck_cannot_reassign_immutable_var =
cannot assign twice to immutable variable {$place}

borrowck_modify_ty_methods_help =
to modify a `{$ty}`, use `.get_mut()`, `.insert()` or the entry API

borrowck_upvar_need_mut_due_to_borrow =
calling `{$place}` requires mutable binding due to mutable borrow of `{$upvar}`

borrowck_upvar_need_mut_due_to_mutation =
calling `{$place}` requires mutable binding due to possible mutation of `{$upvar}`

borrowck_mut_borrow_place_declared_immute =
cannot borrow {$any_place} as mutable, as it is not declared as mutable

borrowck_mut_borrow_symbol_declared_immute =
cannot borrow {$any_place} as mutable, as `{$name}` is not declared as mutable

borrowck_mut_borrow_place_in_pattern_guard_immute =
cannot borrow {$path} as mutable, as it is immutable for the pattern guard

borrowck_mut_borrow_place_static =
cannot borrow immutable static item {$path} as mutable

borrowck_mut_borrow_symbol_static =
cannot borrow {$path} as mutable, as `{$static_name}` is an immutable static item

borrowck_mut_borrow_self_in_fn =
cannot borrow {$path} as mutable, as it is a captured variable in a `Fn` closure

borrowck_mut_borrow_upvar_in_fn =
cannot borrow {$path} as mutable, as `Fn` closures cannot mutate their captured variables

borrowck_mut_borrow_self_behind_const_pointer =
cannot borrow {$place} as mutable, as it is behind a `*const` pointer

borrowck_mut_borrow_self_behind_ref =
cannot borrow {$place} as mutable, as it is behind a `&` reference

borrowck_mut_borrow_self_behind_deref =
cannot borrow {$place} as mutable, as it is behind {$name}

borrowck_mut_borrow_self_behind_index =
cannot borrow {$place} as mutable, as it is behind an index of {$name}

borrowck_mut_borrow_data_behind_const_pointer =
cannot borrow data in a `*const` pointer as mutable

borrowck_mut_borrow_data_behind_ref =
cannot borrow data in a `&` reference as mutable

borrowck_mut_borrow_data_behind_deref =
cannot borrow data in {$name} as mutable

borrowck_mut_borrow_data_behind_index =
cannot borrow data in an index of {$name} as mutable

borrowck_assign_place_declared_immute =
cannot assign to {$any_place}, as it is not declared as mutable

borrowck_assign_symbol_declared_immute =
cannot assign to {$any_place}, as `{$name}` is not declared as mutable

borrowck_assign_place_in_pattern_guard_immute =
cannot assign to {$path}, as it is immutable for the pattern guard

borrowck_assign_place_static =
cannot assign to immutable static item {$path}

borrowck_assign_symbol_static =
cannot assign to {$path}, as `{$static_name}` is an immutable static item

borrowck_assign_place_in_fn =
cannot assign to {$path}, as it is a captured variable in a `Fn` closure

borrowck_assign_upvar_in_fn =
cannot assign to {$path}, as `Fn` closures cannot mutate their captured variables

borrowck_assign_place_behind_const_pointer =
cannot assign to {$place}, which is behind a `*const` pointer

borrowck_assign_place_behind_ref =
cannot assign to {$place}, which is behind a `&` reference

borrowck_assign_place_behind_deref =
cannot assign to {$place}, which is behind {$name}

borrowck_assign_place_behind_index =
cannot assign to {$place}, which is behind an index of {$ty}

borrowck_assign_data_behind_const_pointer =
cannot assign to data in a `*const` pointer

borrowck_assign_data_behind_ref =
cannot assign to data in a `&` reference

borrowck_assign_data_behind_deref =
cannot assign to data in {$name}

borrowck_assign_data_behind_index =
cannot assign to data in an index of {$name}
157 changes: 149 additions & 8 deletions compiler/rustc_borrowck/src/borrowck_errors.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
// #![deny(rustc::untranslatable_diagnostic)]
// #![deny(rustc::diagnostic_outside_of_impl)]

use rustc_errors::{
struct_span_err, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, ErrorGuaranteed, MultiSpan,
};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::Span;

use crate::session_diagnostics::{
AssignBorrowErr, BorrowAcrossDestructor, BorrowAcrossGeneratorYield, InteriorDropMoveErr,
PathShortLive, UseMutBorrowErr,
use crate::{
diagnostics::PlaceAndReason,
session_diagnostics::{
AssignBorrowErr, AssignErr, BorrowAcrossDestructor, BorrowAcrossGeneratorYield,
InteriorDropMoveErr, MutBorrowErr, PathShortLive, UseMutBorrowErr,
},
};

impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
Expand Down Expand Up @@ -215,9 +221,77 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
pub(crate) fn cannot_assign(
&self,
span: Span,
desc: &str,
path_and_reason: PlaceAndReason<'_>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
struct_span_err!(self, span, E0594, "cannot assign to {}", desc)
let diag = match path_and_reason {
PlaceAndReason::DeclaredImmute(place, name) => {
if let Some(name) = name {
AssignErr::SymbolDeclaredImmute { span, any_place: place, name }
} else {
AssignErr::PlaceDeclaredImmute { span, any_place: place }
}
}
PlaceAndReason::InPatternGuard(place) => {
AssignErr::PatternGuardImmute { span, path: place }
}
PlaceAndReason::StaticItem(place, name) => {
if let Some(name) = name {
AssignErr::SymbolStatic { span, path: place, static_name: name }
} else {
AssignErr::PlaceStatic { span, path: place }
}
}
PlaceAndReason::UpvarCaptured(place) => AssignErr::UpvarInFn { span, path: place },
PlaceAndReason::SelfCaptured(place) => AssignErr::CapturedInFn { span, path: place },
PlaceAndReason::BehindPointer(place, pointer_ty, name) => {
if let Some(place) = place {
match pointer_ty {
crate::diagnostics::BorrowedContentSource::DerefRawPointer => {
AssignErr::PlaceBehindRawPointer { span, place }
}
crate::diagnostics::BorrowedContentSource::DerefMutableRef => {
unreachable!()
}
crate::diagnostics::BorrowedContentSource::DerefSharedRef => {
AssignErr::PlaceBehindSharedRef { span, place }
}
crate::diagnostics::BorrowedContentSource::OverloadedDeref(_) => {
AssignErr::PlaceBehindDeref {
span,
place,
name: name.unwrap_or_default(),
}
}
crate::diagnostics::BorrowedContentSource::OverloadedIndex(_) => {
AssignErr::PlaceBehindIndex {
span,
place,
name: name.unwrap_or_default(),
}
}
}
} else {
match pointer_ty {
crate::diagnostics::BorrowedContentSource::DerefRawPointer => {
AssignErr::DataBehindRawPointer { span }
}
crate::diagnostics::BorrowedContentSource::DerefMutableRef => {
unreachable!()
}
crate::diagnostics::BorrowedContentSource::DerefSharedRef => {
AssignErr::DataBehindSharedRef { span }
}
crate::diagnostics::BorrowedContentSource::OverloadedDeref(_) => {
AssignErr::DataBehindDeref { span, name: name.unwrap_or_default() }
}
crate::diagnostics::BorrowedContentSource::OverloadedIndex(_) => {
AssignErr::DataBehindIndex { span, name: name.unwrap_or_default() }
}
}
}
}
};
self.infcx.tcx.sess.create_err(diag)
}

pub(crate) fn cannot_move_out_of(
Expand Down Expand Up @@ -285,10 +359,77 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
pub(crate) fn cannot_borrow_path_as_mutable_because(
&self,
span: Span,
path: &str,
reason: &str,
path_and_reason: PlaceAndReason<'_>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
struct_span_err!(self, span, E0596, "cannot borrow {} as mutable{}", path, reason,)
let diag = match path_and_reason {
PlaceAndReason::DeclaredImmute(place, name) => {
if let Some(name) = name {
MutBorrowErr::SymbolDeclaredImmute { span, any_place: place, name }
} else {
MutBorrowErr::PlaceDeclaredImmute { span, any_place: place }
}
}
PlaceAndReason::InPatternGuard(place) => {
MutBorrowErr::PatternGuardImmute { span, path: place }
}
PlaceAndReason::StaticItem(place, name) => {
if let Some(name) = name {
MutBorrowErr::SymbolStatic { span, path: place, static_name: name }
} else {
MutBorrowErr::PlaceStatic { span, path: place }
}
}
PlaceAndReason::UpvarCaptured(place) => MutBorrowErr::UpvarInFn { span, path: place },
PlaceAndReason::SelfCaptured(place) => MutBorrowErr::CapturedInFn { span, path: place },
PlaceAndReason::BehindPointer(place, pointer_ty, name) => {
if let Some(place) = place {
match pointer_ty {
crate::diagnostics::BorrowedContentSource::DerefRawPointer => {
MutBorrowErr::SelfBehindRawPointer { span, place }
}
crate::diagnostics::BorrowedContentSource::DerefMutableRef => {
unreachable!()
}
crate::diagnostics::BorrowedContentSource::DerefSharedRef => {
MutBorrowErr::SelfBehindSharedRef { span, place }
}
crate::diagnostics::BorrowedContentSource::OverloadedDeref(_) => {
MutBorrowErr::SelfBehindDeref {
span,
place,
name: name.unwrap_or_default(),
}
}
crate::diagnostics::BorrowedContentSource::OverloadedIndex(_) => {
MutBorrowErr::SelfBehindIndex {
span,
place,
name: name.unwrap_or_default(),
}
}
}
} else {
match pointer_ty {
crate::diagnostics::BorrowedContentSource::DerefRawPointer => {
MutBorrowErr::DataBehindRawPointer { span }
}
crate::diagnostics::BorrowedContentSource::DerefMutableRef => {
unreachable!()
}
crate::diagnostics::BorrowedContentSource::DerefSharedRef => {
MutBorrowErr::DataBehindSharedRef { span }
}
crate::diagnostics::BorrowedContentSource::OverloadedDeref(_) => {
MutBorrowErr::DataBehindDeref { span, name: name.unwrap_or_default() }
}
crate::diagnostics::BorrowedContentSource::OverloadedIndex(_) => {
MutBorrowErr::DataBehindIndex { span, name: name.unwrap_or_default() }
}
}
}
}
};
self.infcx.tcx.sess.create_err(diag)
}

pub(crate) fn cannot_mutate_in_immutable_section(
Expand Down
16 changes: 9 additions & 7 deletions compiler/rustc_borrowck/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ mod mutability_errors;
mod region_errors;

pub(crate) use bound_region_errors::{ToUniverseInfo, UniverseInfo};
pub(crate) use mutability_errors::AccessKind;
pub(crate) use mutability_errors::{AccessKind, PlaceAndReason};
pub(crate) use outlives_suggestion::OutlivesSuggestionBuilder;
pub(crate) use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors};
pub(crate) use region_name::{RegionName, RegionNameSource};
Expand Down Expand Up @@ -678,6 +678,7 @@ impl UseSpans<'_> {
}
}

#[derive(Clone, Copy, Debug)]
pub(super) enum BorrowedContentSource<'tcx> {
DerefRawPointer,
DerefMutableRef,
Expand Down Expand Up @@ -715,21 +716,22 @@ impl<'tcx> BorrowedContentSource<'tcx> {
}
}

pub(super) fn describe_for_immutable_place(&self, tcx: TyCtxt<'_>) -> String {
// ready to remove
pub(super) fn describe_for_immutable_place(&self, tcx: TyCtxt<'_>) -> Option<String> {
match *self {
BorrowedContentSource::DerefRawPointer => "a `*const` pointer".to_string(),
BorrowedContentSource::DerefSharedRef => "a `&` reference".to_string(),
BorrowedContentSource::DerefRawPointer => None,
BorrowedContentSource::DerefSharedRef => None,
BorrowedContentSource::DerefMutableRef => {
bug!("describe_for_immutable_place: DerefMutableRef isn't immutable")
}
BorrowedContentSource::OverloadedDeref(ty) => ty
.ty_adt_def()
.and_then(|adt| match tcx.get_diagnostic_name(adt.did())? {
name @ (sym::Rc | sym::Arc) => Some(format!("an `{name}`")),
name @ (sym::Rc | sym::Arc) => Some(Some(format!("an `{name}`"))),
_ => None,
})
.unwrap_or_else(|| format!("dereference of `{ty}`")),
BorrowedContentSource::OverloadedIndex(ty) => format!("an index of `{ty}`"),
.unwrap_or_else(|| Some(format!("dereference of `{ty}`"))),
BorrowedContentSource::OverloadedIndex(ty) => Some(format!("`{ty}`")),
}
}

Expand Down
Loading

0 comments on commit 639f4d9

Please sign in to comment.