1
Fork 0

Rollup merge of #89895 - camsteffen:for-loop-head-span, r=davidtwco

Don't mark for loop iter expression as desugared

We typically don't mark spans of lowered things as desugared. This helps Clippy rightly discern when code is (not) from expansion. This was discovered by ``@flip1995`` at https://github.com/rust-lang/rust-clippy/pull/7789#issuecomment-939289501.
This commit is contained in:
Yuki Okushi 2021-10-22 19:42:45 +09:00 committed by GitHub
commit 91fb223f59
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 65 additions and 74 deletions

View file

@ -11,7 +11,6 @@ use rustc_middle::mir::{
};
use rustc_middle::ty::{self, suggest_constraining_type_param, Ty};
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
use rustc_span::source_map::DesugaringKind;
use rustc_span::symbol::sym;
use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
use rustc_trait_selection::infer::InferCtxtExt;
@ -247,6 +246,36 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
place_name, partially_str, loop_message
),
);
let sess = self.infcx.tcx.sess;
let ty = used_place.ty(self.body, self.infcx.tcx).ty;
// If we have a `&mut` ref, we need to reborrow.
if let ty::Ref(_, _, hir::Mutability::Mut) = ty.kind() {
// If we are in a loop this will be suggested later.
if !is_loop_move {
err.span_suggestion_verbose(
move_span.shrink_to_lo(),
&format!(
"consider creating a fresh reborrow of {} here",
self.describe_place(moved_place.as_ref())
.map(|n| format!("`{}`", n))
.unwrap_or_else(
|| "the mutable reference".to_string()
),
),
"&mut *".to_string(),
Applicability::MachineApplicable,
);
}
} else if let Ok(snippet) =
sess.source_map().span_to_snippet(move_span)
{
err.span_suggestion(
move_span,
"consider borrowing to avoid moving into the for loop",
format!("&{}", snippet),
Applicability::MaybeIncorrect,
);
}
} else {
err.span_label(
fn_call_span,
@ -315,35 +344,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
in_pattern = true;
}
}
if let Some(DesugaringKind::ForLoop(_)) = move_span.desugaring_kind() {
let sess = self.infcx.tcx.sess;
let ty = used_place.ty(self.body, self.infcx.tcx).ty;
// If we have a `&mut` ref, we need to reborrow.
if let ty::Ref(_, _, hir::Mutability::Mut) = ty.kind() {
// If we are in a loop this will be suggested later.
if !is_loop_move {
err.span_suggestion_verbose(
move_span.shrink_to_lo(),
&format!(
"consider creating a fresh reborrow of {} here",
self.describe_place(moved_place.as_ref())
.map(|n| format!("`{}`", n))
.unwrap_or_else(|| "the mutable reference".to_string()),
),
"&mut *".to_string(),
Applicability::MachineApplicable,
);
}
} else if let Ok(snippet) = sess.source_map().span_to_snippet(move_span) {
err.span_suggestion(
move_span,
"consider borrowing to avoid moving into the for loop",
format!("&{}", snippet),
Applicability::MaybeIncorrect,
);
}
}
}
use_spans.var_span_label_path_only(

View file

@ -5,11 +5,10 @@ use rustc_middle::ty;
use rustc_mir_dataflow::move_paths::{
IllegalMoveOrigin, IllegalMoveOriginKind, LookupResult, MoveError, MovePathIndex,
};
use rustc_span::source_map::DesugaringKind;
use rustc_span::{sym, Span, DUMMY_SP};
use rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions;
use crate::diagnostics::UseSpans;
use crate::diagnostics::{FnSelfUseKind, UseSpans};
use crate::prefixes::PrefixSet;
use crate::MirBorrowckCtxt;
@ -400,19 +399,21 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
| ty::Opaque(def_id, _) => def_id,
_ => return err,
};
let is_option = self.infcx.tcx.is_diagnostic_item(sym::Option, def_id);
let is_result = self.infcx.tcx.is_diagnostic_item(sym::Result, def_id);
if (is_option || is_result) && use_spans.map_or(true, |v| !v.for_closure()) {
let diag_name = self.infcx.tcx.get_diagnostic_name(def_id);
if matches!(diag_name, Some(sym::Option | sym::Result))
&& use_spans.map_or(true, |v| !v.for_closure())
{
err.span_suggestion_verbose(
span.shrink_to_hi(),
&format!(
"consider borrowing the `{}`'s content",
if is_option { "Option" } else { "Result" }
),
&format!("consider borrowing the `{}`'s content", diag_name.unwrap()),
".as_ref()".to_string(),
Applicability::MaybeIncorrect,
);
} else if matches!(span.desugaring_kind(), Some(DesugaringKind::ForLoop(_))) {
} else if let Some(UseSpans::FnSelfUse {
kind: FnSelfUseKind::Normal { implicit_into_iter: true, .. },
..
}) = use_spans
{
let suggest = match self.infcx.tcx.get_diagnostic_item(sym::IntoIterator) {
Some(def_id) => self.infcx.tcx.infer_ctxt().enter(|infcx| {
type_known_to_meet_bound_modulo_regions(