Rollup merge of #136422 - nnethercote:convert-lint-functions, r=Noratrieb
Convert two `rustc_middle::lint` functions to `Span` methods. `rustc_middle` is a huge crate and it's always good to move stuff out of it. There are lots of similar methods already on `Span`, so these two functions, `in_external_macro` and `is_from_async_await`, fit right in. The diff is big because `in_external_macro` is used a lot by clippy lints. r? ``@Noratrieb``
This commit is contained in:
commit
5bc5827636
102 changed files with 179 additions and 278 deletions
|
@ -50,7 +50,6 @@ use rustc_infer::traits::{
|
|||
IfExpressionCause, MatchExpressionArmCause, Obligation, PredicateObligation,
|
||||
PredicateObligations,
|
||||
};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::traits::BuiltinImplSource;
|
||||
use rustc_middle::ty::adjustment::{
|
||||
|
@ -1937,7 +1936,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
|||
cond_expr.span.desugaring_kind(),
|
||||
None | Some(DesugaringKind::WhileLoop)
|
||||
)
|
||||
&& !in_external_macro(fcx.tcx.sess, cond_expr.span)
|
||||
&& !cond_expr.span.in_external_macro(fcx.tcx.sess.source_map())
|
||||
&& !matches!(
|
||||
cond_expr.kind,
|
||||
hir::ExprKind::Match(.., hir::MatchSource::TryDesugar(_))
|
||||
|
|
|
@ -14,7 +14,6 @@ use rustc_hir::{
|
|||
};
|
||||
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
|
||||
use rustc_hir_analysis::suggest_impl_trait;
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::middle::stability::EvalResult;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
|
@ -770,7 +769,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// If the expression is from an external macro, then do not suggest
|
||||
// adding a semicolon, because there's nowhere to put it.
|
||||
// See issue #81943.
|
||||
&& !in_external_macro(self.tcx.sess, expression.span) =>
|
||||
&& !expression.span.in_external_macro(self.tcx.sess.source_map()) =>
|
||||
{
|
||||
if needs_block {
|
||||
err.multipart_suggestion(
|
||||
|
@ -2261,7 +2260,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
expected: Ty<'tcx>,
|
||||
expr_ty: Ty<'tcx>,
|
||||
) -> bool {
|
||||
if in_external_macro(self.tcx.sess, expr.span) {
|
||||
if expr.span.in_external_macro(self.tcx.sess.source_map()) {
|
||||
return false;
|
||||
}
|
||||
if let ty::Adt(expected_adt, args) = expected.kind() {
|
||||
|
@ -2589,14 +2588,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
)> {
|
||||
let sess = self.sess();
|
||||
let sp = expr.span;
|
||||
let sm = sess.source_map();
|
||||
|
||||
// If the span is from an external macro, there's no suggestion we can make.
|
||||
if in_external_macro(sess, sp) {
|
||||
if sp.in_external_macro(sm) {
|
||||
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)
|
||||
};
|
||||
|
|
|
@ -29,7 +29,6 @@ use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
|
|||
use rustc_hir::intravisit::FnKind as HirFnKind;
|
||||
use rustc_hir::{Body, FnDecl, GenericParamKind, PatKind, PredicateOrigin};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, Upcast, VariantDef};
|
||||
|
@ -2029,7 +2028,7 @@ impl ExplicitOutlivesRequirements {
|
|||
}
|
||||
|
||||
let span = bound.span().find_ancestor_inside(predicate_span)?;
|
||||
if in_external_macro(tcx.sess, span) {
|
||||
if span.in_external_macro(tcx.sess.source_map()) {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ pub(super) fn unexpected_cfg_name(
|
|||
};
|
||||
|
||||
let is_from_cargo = rustc_session::utils::was_invoked_from_cargo();
|
||||
let is_from_external_macro = rustc_middle::lint::in_external_macro(sess, name_span);
|
||||
let is_from_external_macro = name_span.in_external_macro(sess.source_map());
|
||||
let mut is_feature_cfg = name == sym::feature;
|
||||
|
||||
let code_sugg = if is_feature_cfg && is_from_cargo {
|
||||
|
@ -281,7 +281,7 @@ pub(super) fn unexpected_cfg_value(
|
|||
.collect();
|
||||
|
||||
let is_from_cargo = rustc_session::utils::was_invoked_from_cargo();
|
||||
let is_from_external_macro = rustc_middle::lint::in_external_macro(sess, name_span);
|
||||
let is_from_external_macro = name_span.in_external_macro(sess.source_map());
|
||||
|
||||
// Show the full list if all possible values for a given name, but don't do it
|
||||
// for names as the possibilities could be very long
|
||||
|
|
|
@ -2,7 +2,6 @@ use rustc_ast as ast;
|
|||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{self as hir, LangItem};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::{bug, ty};
|
||||
use rustc_parse_format::{ParseMode, Parser, Piece};
|
||||
use rustc_session::lint::FutureIncompatibilityReason;
|
||||
|
@ -100,7 +99,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
|
|||
|
||||
let (span, panic, symbol) = panic_call(cx, f);
|
||||
|
||||
if in_external_macro(cx.sess(), span) {
|
||||
if span.in_external_macro(cx.sess().source_map()) {
|
||||
// Nothing that can be done about it in the current crate.
|
||||
return;
|
||||
}
|
||||
|
@ -229,14 +228,15 @@ fn check_panic_str<'tcx>(
|
|||
|
||||
let (span, _, _) = panic_call(cx, f);
|
||||
|
||||
if in_external_macro(cx.sess(), span) && in_external_macro(cx.sess(), arg.span) {
|
||||
let sm = cx.sess().source_map();
|
||||
if span.in_external_macro(sm) && arg.span.in_external_macro(sm) {
|
||||
// Nothing that can be done about it in the current crate.
|
||||
return;
|
||||
}
|
||||
|
||||
let fmt_span = arg.span.source_callsite();
|
||||
|
||||
let (snippet, style) = match cx.sess().psess.source_map().span_to_snippet(fmt_span) {
|
||||
let (snippet, style) = match sm.span_to_snippet(fmt_span) {
|
||||
Ok(snippet) => {
|
||||
// Count the number of `#`s between the `r` and `"`.
|
||||
let style = snippet.strip_prefix('r').and_then(|s| s.find('"'));
|
||||
|
@ -283,7 +283,7 @@ fn check_panic_str<'tcx>(
|
|||
/// Given the span of `some_macro!(args);`, gives the span of `(` and `)`,
|
||||
/// and the type of (opening) delimiter used.
|
||||
fn find_delimiters(cx: &LateContext<'_>, span: Span) -> Option<(Span, Span, char)> {
|
||||
let snippet = cx.sess().psess.source_map().span_to_snippet(span).ok()?;
|
||||
let snippet = cx.sess().source_map().span_to_snippet(span).ok()?;
|
||||
let (open, open_ch) = snippet.char_indices().find(|&(_, c)| "([{".contains(c))?;
|
||||
let close = snippet.rfind(|c| ")]}".contains(c))?;
|
||||
Some((
|
||||
|
|
|
@ -8,8 +8,7 @@ use rustc_macros::{Decodable, Encodable, HashStable};
|
|||
use rustc_session::Session;
|
||||
use rustc_session::lint::builtin::{self, FORBIDDEN_LINT_GROUPS};
|
||||
use rustc_session::lint::{FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId};
|
||||
use rustc_span::hygiene::{ExpnKind, MacroKind};
|
||||
use rustc_span::{DUMMY_SP, DesugaringKind, Span, Symbol, kw};
|
||||
use rustc_span::{DUMMY_SP, Span, Symbol, kw};
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::ty::TyCtxt;
|
||||
|
@ -201,7 +200,7 @@ impl LintExpectation {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn explain_lint_level_source(
|
||||
fn explain_lint_level_source(
|
||||
lint: &'static Lint,
|
||||
level: Level,
|
||||
src: LintLevelSource,
|
||||
|
@ -325,7 +324,7 @@ pub fn lint_level(
|
|||
// If this code originates in a foreign macro, aka something that this crate
|
||||
// did not itself author, then it's likely that there's nothing this crate
|
||||
// can do about it. We probably want to skip the lint entirely.
|
||||
if err.span.primary_spans().iter().any(|s| in_external_macro(sess, *s)) {
|
||||
if err.span.primary_spans().iter().any(|s| s.in_external_macro(sess.source_map())) {
|
||||
// Any suggestions made here are likely to be incorrect, so anything we
|
||||
// emit shouldn't be automatically fixed by rustfix.
|
||||
err.disable_suggestions();
|
||||
|
@ -422,36 +421,3 @@ pub fn lint_level(
|
|||
}
|
||||
lint_level_impl(sess, lint, level, src, span, Box::new(decorate))
|
||||
}
|
||||
|
||||
/// Returns whether `span` originates in a foreign crate's external macro.
|
||||
///
|
||||
/// This is used to test whether a lint should not even begin to figure out whether it should
|
||||
/// be reported on the current node.
|
||||
pub fn in_external_macro(sess: &Session, span: Span) -> bool {
|
||||
let expn_data = span.ctxt().outer_expn_data();
|
||||
match expn_data.kind {
|
||||
ExpnKind::Root
|
||||
| ExpnKind::Desugaring(
|
||||
DesugaringKind::ForLoop
|
||||
| DesugaringKind::WhileLoop
|
||||
| DesugaringKind::OpaqueTy
|
||||
| DesugaringKind::Async
|
||||
| DesugaringKind::Await,
|
||||
) => false,
|
||||
ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external"
|
||||
ExpnKind::Macro(MacroKind::Bang, _) => {
|
||||
// Dummy span for the `def_site` means it's an external macro.
|
||||
expn_data.def_site.is_dummy() || sess.source_map().is_imported(expn_data.def_site)
|
||||
}
|
||||
ExpnKind::Macro { .. } => true, // definitely a plugin
|
||||
}
|
||||
}
|
||||
|
||||
/// Return whether `span` is generated by `async` or `await`.
|
||||
pub fn is_from_async_await(span: Span) -> bool {
|
||||
let expn_data = span.ctxt().outer_expn_data();
|
||||
match expn_data.kind {
|
||||
ExpnKind::Desugaring(DesugaringKind::Async | DesugaringKind::Await) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -600,11 +600,43 @@ impl Span {
|
|||
!self.is_dummy() && sm.is_span_accessible(self)
|
||||
}
|
||||
|
||||
/// Returns whether `span` originates in a foreign crate's external macro.
|
||||
///
|
||||
/// This is used to test whether a lint should not even begin to figure out whether it should
|
||||
/// be reported on the current node.
|
||||
pub fn in_external_macro(self, sm: &SourceMap) -> bool {
|
||||
let expn_data = self.ctxt().outer_expn_data();
|
||||
match expn_data.kind {
|
||||
ExpnKind::Root
|
||||
| ExpnKind::Desugaring(
|
||||
DesugaringKind::ForLoop
|
||||
| DesugaringKind::WhileLoop
|
||||
| DesugaringKind::OpaqueTy
|
||||
| DesugaringKind::Async
|
||||
| DesugaringKind::Await,
|
||||
) => false,
|
||||
ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external"
|
||||
ExpnKind::Macro(MacroKind::Bang, _) => {
|
||||
// Dummy span for the `def_site` means it's an external macro.
|
||||
expn_data.def_site.is_dummy() || sm.is_imported(expn_data.def_site)
|
||||
}
|
||||
ExpnKind::Macro { .. } => true, // definitely a plugin
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if `span` originates in a derive-macro's expansion.
|
||||
pub fn in_derive_expansion(self) -> bool {
|
||||
matches!(self.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Derive, _))
|
||||
}
|
||||
|
||||
/// Return whether `span` is generated by `async` or `await`.
|
||||
pub fn is_from_async_await(self) -> bool {
|
||||
matches!(
|
||||
self.ctxt().outer_expn_data().kind,
|
||||
ExpnKind::Desugaring(DesugaringKind::Async | DesugaringKind::Await),
|
||||
)
|
||||
}
|
||||
|
||||
/// Gate suggestions that would not be appropriate in a context the user didn't write.
|
||||
pub fn can_be_used_for_suggestions(self) -> bool {
|
||||
!self.from_expansion()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue