summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs')
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs116
1 files changed, 51 insertions, 65 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 328ac880d..9d9040096 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -7,11 +7,12 @@ use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::{
hir::place::PlaceBase,
- mir::{self, BindingForm, ClearCrossCrate, Local, LocalDecl, LocalInfo, LocalKind, Location},
+ mir::{self, BindingForm, Local, LocalDecl, LocalInfo, LocalKind, Location},
};
use rustc_span::source_map::DesugaringKind;
use rustc_span::symbol::{kw, Symbol};
use rustc_span::{sym, BytePos, Span};
+use rustc_target::abi::FieldIdx;
use crate::diagnostics::BorrowedContentSource;
use crate::MirBorrowckCtxt;
@@ -105,8 +106,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
reason = String::new();
} else {
item_msg = access_place_desc;
- let local_info = &self.body.local_decls[local].local_info;
- if let Some(box LocalInfo::StaticRef { def_id, .. }) = *local_info {
+ let local_info = self.body.local_decls[local].local_info();
+ if let LocalInfo::StaticRef { def_id, .. } = *local_info {
let static_name = &self.infcx.tcx.item_name(def_id);
reason = format!(", as `{static_name}` is an immutable static item");
} else {
@@ -120,9 +121,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
&& !self.upvars.is_empty()
{
item_msg = access_place_desc;
- debug_assert!(
- self.body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty.is_region_ptr()
- );
+ debug_assert!(self.body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty.is_ref());
debug_assert!(is_closure_or_generator(
Place::ty_from(
the_place_err.local,
@@ -305,15 +304,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
..
}) = &self.body[location.block].statements.get(location.statement_index)
{
- match decl.local_info {
- Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
- mir::VarBindingForm {
- binding_mode: ty::BindingMode::BindByValue(Mutability::Not),
- opt_ty_info: Some(sp),
- opt_match_place: _,
- pat_span: _,
- },
- )))) => {
+ match *decl.local_info() {
+ LocalInfo::User(BindingForm::Var(mir::VarBindingForm {
+ binding_mode: ty::BindingMode::BindByValue(Mutability::Not),
+ opt_ty_info: Some(sp),
+ opt_match_place: _,
+ pat_span: _,
+ })) => {
if suggest {
err.span_note(sp, "the binding is already a mutable borrow");
}
@@ -346,10 +343,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}
} else if decl.mutability.is_not() {
if matches!(
- decl.local_info,
- Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf(
- hir::ImplicitSelfKind::MutRef
- ),)))
+ decl.local_info(),
+ LocalInfo::User(BindingForm::ImplicitSelf(hir::ImplicitSelfKind::MutRef))
) {
err.note(
"as `Self` may be unsized, this call attempts to take `&mut &mut self`",
@@ -474,30 +469,23 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
{
let local_decl = &self.body.local_decls[local];
- let (pointer_sigil, pointer_desc) = if local_decl.ty.is_region_ptr() {
- ("&", "reference")
- } else {
- ("*const", "pointer")
- };
+ let (pointer_sigil, pointer_desc) =
+ if local_decl.ty.is_ref() { ("&", "reference") } else { ("*const", "pointer") };
match self.local_names[local] {
Some(name) if !local_decl.from_compiler_desugaring() => {
- let label = match local_decl.local_info.as_deref().unwrap() {
- LocalInfo::User(ClearCrossCrate::Set(
- mir::BindingForm::ImplicitSelf(_),
- )) => {
+ let label = match *local_decl.local_info() {
+ LocalInfo::User(mir::BindingForm::ImplicitSelf(_)) => {
let (span, suggestion) =
suggest_ampmut_self(self.infcx.tcx, local_decl);
Some((true, span, suggestion))
}
- LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::Var(
- mir::VarBindingForm {
- binding_mode: ty::BindingMode::BindByValue(_),
- opt_ty_info,
- ..
- },
- ))) => {
+ LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
+ binding_mode: ty::BindingMode::BindByValue(_),
+ opt_ty_info,
+ ..
+ })) => {
// check if the RHS is from desugaring
let opt_assignment_rhs_span =
self.body.find_assignments(local).first().map(|&location| {
@@ -534,16 +522,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
self.infcx.tcx,
local_decl,
opt_assignment_rhs_span,
- *opt_ty_info,
+ opt_ty_info,
)
} else {
- match local_decl.local_info.as_deref() {
- Some(LocalInfo::User(ClearCrossCrate::Set(
- mir::BindingForm::Var(mir::VarBindingForm {
- opt_ty_info: None,
- ..
- }),
- ))) => {
+ match local_decl.local_info() {
+ LocalInfo::User(mir::BindingForm::Var(
+ mir::VarBindingForm {
+ opt_ty_info: None, ..
+ },
+ )) => {
let (span, sugg) = suggest_ampmut_self(
self.infcx.tcx,
local_decl,
@@ -555,7 +542,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
self.infcx.tcx,
local_decl,
opt_assignment_rhs_span,
- *opt_ty_info,
+ opt_ty_info,
),
}
};
@@ -564,21 +551,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}
}
- LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::Var(
- mir::VarBindingForm {
- binding_mode: ty::BindingMode::BindByReference(_),
- ..
- },
- ))) => {
+ LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
+ binding_mode: ty::BindingMode::BindByReference(_),
+ ..
+ })) => {
let pattern_span = local_decl.source_info.span;
suggest_ref_mut(self.infcx.tcx, pattern_span)
.map(|replacement| (true, pattern_span, replacement))
}
- LocalInfo::User(ClearCrossCrate::Clear) => {
- bug!("saw cleared local state")
- }
-
_ => unreachable!(),
};
@@ -828,7 +809,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let Some(hir::Node::Item(item)) = node else { return; };
let hir::ItemKind::Fn(.., body_id) = item.kind else { return; };
let body = self.infcx.tcx.hir().body(body_id);
- let mut v = V { assign_span: span, err, ty, suggested: false };
+ let mut assign_span = span;
+ // Drop desugaring is done at MIR build so it's not in the HIR
+ if let Some(DesugaringKind::Replace) = span.desugaring_kind() {
+ assign_span.remove_mark();
+ }
+
+ let mut v = V { assign_span, err, ty, suggested: false };
v.visit_body(body);
if !v.suggested {
err.help(&format!(
@@ -1145,20 +1132,19 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
pub fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<Symbol>) -> bool {
debug!("local_info: {:?}, ty.kind(): {:?}", local_decl.local_info, local_decl.ty.kind());
- match local_decl.local_info.as_deref() {
+ match *local_decl.local_info() {
// Check if mutably borrowing a mutable reference.
- Some(LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::Var(
- mir::VarBindingForm {
- binding_mode: ty::BindingMode::BindByValue(Mutability::Not), ..
- },
- )))) => matches!(local_decl.ty.kind(), ty::Ref(_, _, hir::Mutability::Mut)),
- Some(LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::ImplicitSelf(kind)))) => {
+ LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
+ binding_mode: ty::BindingMode::BindByValue(Mutability::Not),
+ ..
+ })) => matches!(local_decl.ty.kind(), ty::Ref(_, _, hir::Mutability::Mut)),
+ LocalInfo::User(mir::BindingForm::ImplicitSelf(kind)) => {
// Check if the user variable is a `&mut self` and we can therefore
// suggest removing the `&mut`.
//
// Deliberately fall into this case for all implicit self types,
// so that we don't fall in to the next case with them.
- *kind == hir::ImplicitSelfKind::MutRef
+ kind == hir::ImplicitSelfKind::MutRef
}
_ if Some(kw::SelfLower) == local_name => {
// Otherwise, check if the name is the `self` keyword - in which case
@@ -1268,7 +1254,7 @@ fn suggest_ampmut<'tcx>(
(
suggestability,
highlight_span,
- if local_decl.ty.is_region_ptr() {
+ if local_decl.ty.is_ref() {
format!("&mut {}", ty_mut.ty)
} else {
format!("*mut {}", ty_mut.ty)
@@ -1290,7 +1276,7 @@ fn is_closure_or_generator(ty: Ty<'_>) -> bool {
fn get_mut_span_in_struct_field<'tcx>(
tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>,
- field: mir::Field,
+ field: FieldIdx,
) -> Option<Span> {
// Expect our local to be a reference to a struct of some kind.
if let ty::Ref(_, ty, _) = ty.kind()