diff options
Diffstat (limited to 'compiler/rustc_borrowck')
3 files changed, 30 insertions, 19 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 79973ab170c..db8268c8e2e 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -13,7 +13,7 @@ use rustc_middle::mir::{ use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::{self, RegionVid, TyCtxt}; use rustc_span::symbol::Symbol; -use rustc_span::Span; +use rustc_span::{sym, DesugaringKind, Span}; use crate::region_infer::BlameConstraint; use crate::{ @@ -135,7 +135,16 @@ impl BorrowExplanation { should_note_order, } => { let local_decl = &body.local_decls[dropped_local]; - let (dtor_desc, type_desc) = match local_decl.ty.kind() { + let mut ty = local_decl.ty; + if local_decl.source_info.span.desugaring_kind() == Some(DesugaringKind::ForLoop) { + if let ty::Adt(adt, substs) = local_decl.ty.kind() { + if tcx.is_diagnostic_item(sym::Option, adt.did) { + // in for loop desugaring, only look at the `Some(..)` inner type + ty = substs.type_at(0); + } + } + } + let (dtor_desc, type_desc) = match ty.kind() { // If type is an ADT that implements Drop, then // simplify output by reporting just the ADT name. ty::Adt(adt, _substs) if adt.has_dtor(tcx) && !adt.is_box() => { diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index a4df277a7b0..79623e26eb7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -13,11 +13,7 @@ use rustc_middle::mir::{ use rustc_middle::ty::print::Print; use rustc_middle::ty::{self, DefIdTree, Instance, Ty, TyCtxt}; use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult}; -use rustc_span::{ - hygiene::{DesugaringKind, ForLoopLoc}, - symbol::sym, - Span, -}; +use rustc_span::{hygiene::DesugaringKind, symbol::sym, Span}; use rustc_target::abi::VariantIdx; use super::borrow_set::BorrowData; @@ -955,10 +951,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let kind = kind.unwrap_or_else(|| { // This isn't a 'special' use of `self` debug!("move_spans: method_did={:?}, fn_call_span={:?}", method_did, fn_call_span); - let implicit_into_iter = matches!( - fn_call_span.desugaring_kind(), - Some(DesugaringKind::ForLoop(ForLoopLoc::IntoIter)) - ); + let implicit_into_iter = Some(method_did) == tcx.lang_items().into_iter_fn() + && fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop); let parent_self_ty = parent .filter(|did| tcx.def_kind(*did) == rustc_hir::def::DefKind::Impl) .and_then(|did| match tcx.type_of(did).kind() { diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index d5ff4c6766f..46e2a99a0d0 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -445,15 +445,23 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { }, ))) => { // check if the RHS is from desugaring - let locations = self.body.find_assignments(local); - let opt_assignment_rhs_span = locations - .first() - .map(|&location| self.body.source_info(location).span); - let opt_desugaring_kind = - opt_assignment_rhs_span.and_then(|span| span.desugaring_kind()); - match opt_desugaring_kind { + let opt_assignment_rhs_span = + self.body.find_assignments(local).first().map(|&location| { + let stmt = &self.body[location.block].statements + [location.statement_index]; + match stmt.kind { + mir::StatementKind::Assign(box ( + _, + mir::Rvalue::Use(mir::Operand::Copy(place)), + )) => { + self.body.local_decls[place.local].source_info.span + } + _ => self.body.source_info(location).span, + } + }); + match opt_assignment_rhs_span.and_then(|s| s.desugaring_kind()) { // on for loops, RHS points to the iterator part - Some(DesugaringKind::ForLoop(_)) => { + Some(DesugaringKind::ForLoop) => { self.suggest_similar_mut_method_for_for_loop(&mut err); Some(( false, |
