|
3 | 3 |
|
4 | 4 | use crate::lints::{
|
5 | 5 | BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand, NonExistentDocKeyword,
|
6 |
| - QueryInstability, TyQualified, TykindDiag, TykindKind, UntranslatableDiag, |
| 6 | + QueryInstability, SpanUseEqCtxtDiag, TyQualified, TykindDiag, TykindKind, UntranslatableDiag, |
7 | 7 | UntranslatableDiagnosticTrivial,
|
8 | 8 | };
|
9 | 9 | use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
10 | 10 | use rustc_ast as ast;
|
11 | 11 | use rustc_hir::def::Res;
|
12 | 12 | use rustc_hir::{def_id::DefId, Expr, ExprKind, GenericArg, PatKind, Path, PathSegment, QPath};
|
13 |
| -use rustc_hir::{HirId, Impl, Item, ItemKind, Node, Pat, Ty, TyKind}; |
| 13 | +use rustc_hir::{BinOp, BinOpKind, HirId, Impl, Item, ItemKind, Node, Pat, Ty, TyKind}; |
14 | 14 | use rustc_middle::ty;
|
15 | 15 | use rustc_session::{declare_lint_pass, declare_tool_lint};
|
16 | 16 | use rustc_span::hygiene::{ExpnKind, MacroKind};
|
@@ -537,3 +537,33 @@ impl LateLintPass<'_> for BadOptAccess {
|
537 | 537 | }
|
538 | 538 | }
|
539 | 539 | }
|
| 540 | + |
| 541 | +declare_tool_lint! { |
| 542 | + pub rustc::SPAN_USE_EQ_CTXT, |
| 543 | + Allow, |
| 544 | + "forbid uses of `==` with `Span::ctxt`, suggest `Span::eq_ctxt` instead", |
| 545 | + report_in_external_macro: true |
| 546 | +} |
| 547 | + |
| 548 | +declare_lint_pass!(SpanUseEqCtxt => [SPAN_USE_EQ_CTXT]); |
| 549 | + |
| 550 | +impl<'tcx> LateLintPass<'tcx> for SpanUseEqCtxt { |
| 551 | + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) { |
| 552 | + if let ExprKind::Binary(BinOp { node: BinOpKind::Eq, .. }, lhs, rhs) = expr.kind { |
| 553 | + if is_span_ctxt_call(cx, lhs) && is_span_ctxt_call(cx, rhs) { |
| 554 | + cx.emit_spanned_lint(SPAN_USE_EQ_CTXT, expr.span, SpanUseEqCtxtDiag); |
| 555 | + } |
| 556 | + } |
| 557 | + } |
| 558 | +} |
| 559 | + |
| 560 | +fn is_span_ctxt_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { |
| 561 | + match &expr.kind { |
| 562 | + ExprKind::MethodCall(..) => cx |
| 563 | + .typeck_results() |
| 564 | + .type_dependent_def_id(expr.hir_id) |
| 565 | + .is_some_and(|call_did| cx.tcx.is_diagnostic_item(sym::SpanCtxt, call_did)), |
| 566 | + |
| 567 | + _ => false, |
| 568 | + } |
| 569 | +} |
0 commit comments