mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-24 15:54:15 +00:00
Improve check_ref suggestions in macros.
This commit is contained in:
parent
716394d658
commit
80828f26bb
@ -8,6 +8,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::{is_range_literal, Node};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty::adjustment::AllowTwoPhase;
|
||||
use rustc_middle::ty::{self, AssocItem, Ty, TypeAndMut};
|
||||
use rustc_span::symbol::sym;
|
||||
@ -412,14 +413,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
checked_ty: Ty<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
) -> Option<(Span, &'static str, String, Applicability)> {
|
||||
let sm = self.sess().source_map();
|
||||
let sess = self.sess();
|
||||
let sp = expr.span;
|
||||
if sm.is_imported(sp) {
|
||||
// Ignore if span is from within a macro #41858, #58298. We previously used the macro
|
||||
// call span, but that breaks down when the type error comes from multiple calls down.
|
||||
|
||||
// If the span is from an external macro, there's no suggestion we can make.
|
||||
if in_external_macro(sess, sp) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let sm = sess.source_map();
|
||||
|
||||
let replace_prefix = |s: &str, old: &str, new: &str| {
|
||||
s.strip_prefix(old).map(|stripped| new.to_string() + stripped)
|
||||
};
|
||||
@ -427,10 +430,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let is_struct_pat_shorthand_field =
|
||||
self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, sp);
|
||||
|
||||
// If the span is from a macro, then it's hard to extract the text
|
||||
// and make a good suggestion, so don't bother.
|
||||
let is_macro = sp.from_expansion() && sp.desugaring_kind().is_none();
|
||||
|
||||
// `ExprKind::DropTemps` is semantically irrelevant for these suggestions.
|
||||
let expr = expr.peel_drop_temps();
|
||||
|
||||
@ -570,10 +569,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, ref expr),
|
||||
_,
|
||||
&ty::Ref(_, checked, _),
|
||||
) if {
|
||||
self.infcx.can_sub(self.param_env, checked, &expected).is_ok() && !is_macro
|
||||
} =>
|
||||
{
|
||||
) if self.infcx.can_sub(self.param_env, checked, &expected).is_ok() => {
|
||||
// We have `&T`, check if what was expected was `T`. If so,
|
||||
// we may want to suggest removing a `&`.
|
||||
if sm.is_imported(expr.span) {
|
||||
@ -589,13 +585,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
return None;
|
||||
}
|
||||
if let Ok(code) = sm.span_to_snippet(expr.span) {
|
||||
return Some((
|
||||
sp,
|
||||
"consider removing the borrow",
|
||||
code,
|
||||
Applicability::MachineApplicable,
|
||||
));
|
||||
if sp.contains(expr.span) {
|
||||
if let Ok(code) = sm.span_to_snippet(expr.span) {
|
||||
return Some((
|
||||
sp,
|
||||
"consider removing the borrow",
|
||||
code,
|
||||
Applicability::MachineApplicable,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
(
|
||||
@ -643,7 +641,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
_ if sp == expr.span && !is_macro => {
|
||||
_ if sp == expr.span => {
|
||||
if let Some(steps) = self.deref_steps(checked_ty, expected) {
|
||||
let expr = expr.peel_blocks();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user