diff options
Diffstat (limited to 'compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs')
-rw-r--r-- | compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs | 116 |
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() |