Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert two rustc_middle::lint functions to Span methods. #136422

Merged
merged 1 commit into from
Feb 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions compiler/rustc_hir_typeck/src/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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(_))
Expand Down
10 changes: 4 additions & 6 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -2265,7 +2264,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() {
Expand Down Expand Up @@ -2593,14 +2592,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)
};
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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;
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_lint/src/early/diagnostics/check_cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_lint/src/non_fmt_panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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('"'));
Expand Down Expand Up @@ -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((
Expand Down
40 changes: 3 additions & 37 deletions compiler/rustc_middle/src/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -201,7 +200,7 @@ impl LintExpectation {
}
}

pub fn explain_lint_level_source(
fn explain_lint_level_source(
lint: &'static Lint,
level: Level,
src: LintLevelSource,
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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,
}
}
32 changes: 32 additions & 0 deletions compiler/rustc_span/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/book/src/development/adding_lints.md
Original file line number Diff line number Diff line change
Expand Up @@ -788,7 +788,7 @@ don't hesitate to ask on [Zulip] or in the issue/PR.
[`snippet`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/source/fn.snippet.html
[let-chains]: https://github.com/rust-lang/rust/pull/94927
[from_expansion]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html#method.from_expansion
[in_external_macro]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/lint/fn.in_external_macro.html
[in_external_macro]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html#method.in_external_macro
[span]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html
[applicability]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/enum.Applicability.html
[rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ functions to deal with macros:
> context. And so just using `span.from_expansion()` is often good enough.


- `in_external_macro(span)`: detect if the given span is from a macro defined in
- `span.in_external_macro(sm)`: detect if the given span is from a macro defined in
a foreign crate. If you want the lint to work with macro-generated code, this
is the next line of defense to avoid macros not defined in the current crate.
It doesn't make sense to lint code that the coder can't change.
Expand All @@ -227,15 +227,13 @@ functions to deal with macros:
crates

```rust
use rustc_middle::lint::in_external_macro;

use a_crate_with_macros::foo;

// `foo` is defined in `a_crate_with_macros`
foo!("bar");

// if we lint the `match` of `foo` call and test its span
assert_eq!(in_external_macro(cx.sess(), match_span), true);
assert_eq!(match_span.in_external_macro(cx.sess().source_map()), true);
```

- `span.ctxt()`: the span's context represents whether it is from expansion, and
Expand Down
6 changes: 3 additions & 3 deletions src/tools/clippy/book/src/development/macro_expansions.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ assert_ne!(x_is_some_span.ctxt(), x_unwrap_span.ctxt());

### The `in_external_macro` function

`rustc_middle::lint` provides a function ([`in_external_macro`]) that can
`Span` provides a method ([`in_external_macro`]) that can
detect if the given span is from a macro defined in a foreign crate.

Therefore, if we really want a new lint to work with macro-generated code,
Expand All @@ -144,7 +144,7 @@ Also assume that we get the corresponding variable `foo_span` for the
results in `true` (note that `cx` can be `EarlyContext` or `LateContext`):

```rust
if in_external_macro(cx.sess(), foo_span) {
if foo_span.in_external_macro(cx.sess().source_map()) {
// We should ignore macro from a foreign crate.
return;
}
Expand All @@ -153,6 +153,6 @@ if in_external_macro(cx.sess(), foo_span) {
[`ctxt`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.ctxt
[expansion]: https://rustc-dev-guide.rust-lang.org/macro-expansion.html#expansion-and-ast-integration
[`from_expansion`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.from_expansion
[`in_external_macro`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_middle/lint/fn.in_external_macro.html
[`in_external_macro`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.in_external_macro
[Span]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html
[SyntaxContext]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/hygiene/struct.SyntaxContext.html
5 changes: 2 additions & 3 deletions src/tools/clippy/clippy_lints/src/almost_complete_range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use clippy_utils::source::{trim_span, walk_span_to_context};
use rustc_ast::ast::{Expr, ExprKind, LitKind, Pat, PatKind, RangeEnd, RangeLimits};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;

declare_clippy_lint! {
Expand Down Expand Up @@ -45,7 +44,7 @@ impl EarlyLintPass for AlmostCompleteRange {
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &Expr) {
if let ExprKind::Range(Some(start), Some(end), RangeLimits::HalfOpen) = &e.kind
&& is_incomplete_range(start, end)
&& !in_external_macro(cx.sess(), e.span)
&& !e.span.in_external_macro(cx.sess().source_map())
{
span_lint_and_then(
cx,
Expand Down Expand Up @@ -74,7 +73,7 @@ impl EarlyLintPass for AlmostCompleteRange {
if let PatKind::Range(Some(start), Some(end), kind) = &p.kind
&& matches!(kind.node, RangeEnd::Excluded)
&& is_incomplete_range(start, end)
&& !in_external_macro(cx.sess(), p.span)
&& !p.span.in_external_macro(cx.sess().source_map())
{
span_lint_and_then(
cx,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use rustc_hir::{
Variant, VariantData,
};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;

declare_clippy_lint! {
Expand Down Expand Up @@ -248,7 +247,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
ItemKind::Enum(enum_def, _generics) if self.enable_ordering_for_enum => {
let mut cur_v: Option<&Variant<'_>> = None;
for variant in enum_def.variants {
if in_external_macro(cx.sess(), variant.span) {
if variant.span.in_external_macro(cx.sess().source_map()) {
continue;
}

Expand All @@ -263,7 +262,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
ItemKind::Struct(VariantData::Struct { fields, .. }, _generics) if self.enable_ordering_for_struct => {
let mut cur_f: Option<&FieldDef<'_>> = None;
for field in *fields {
if in_external_macro(cx.sess(), field.span) {
if field.span.in_external_macro(cx.sess().source_map()) {
continue;
}

Expand All @@ -281,7 +280,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
let mut cur_t: Option<&TraitItemRef> = None;

for item in *item_ref {
if in_external_macro(cx.sess(), item.span) {
if item.span.in_external_macro(cx.sess().source_map()) {
continue;
}

Expand All @@ -304,7 +303,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
let mut cur_t: Option<&ImplItemRef> = None;

for item in trait_impl.items {
if in_external_macro(cx.sess(), item.span) {
if item.span.in_external_macro(cx.sess().source_map()) {
continue;
}

Expand Down Expand Up @@ -348,7 +347,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
// as no sorting by source map/line of code has to be applied.
//
for item in items {
if in_external_macro(cx.sess(), item.span) {
if item.span.in_external_macro(cx.sess().source_map()) {
continue;
}

Expand Down
Loading
Loading