Skip to content

Commit f77dea8

Browse files
committed
basic lint v2 implemented
1 parent 8769e02 commit f77dea8

File tree

8 files changed

+69
-43
lines changed

8 files changed

+69
-43
lines changed

compiler/rustc_lint/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,8 @@ lint_renamed_lint = lint `{$name}` has been renamed to `{$replace}`
494494
495495
lint_requested_level = requested on the command line with `{$level} {$lint_name}`
496496
497+
lint_span_use_eq_ctxt = use `eq_ctxt()` not `ctxt() == ctxt()`
498+
497499
lint_supertrait_as_deref_target = `{$t}` implements `Deref` with supertrait `{$target_principal}` as target
498500
.label = target type is set here
499501

compiler/rustc_lint/src/internal.rs

+43-2
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
44
use crate::lints::{
55
BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand, NonExistentDocKeyword,
6-
QueryInstability, TyQualified, TykindDiag, TykindKind, UntranslatableDiag,
6+
QueryInstability, SpanUseEqCtxtDiag, TyQualified, TykindDiag, TykindKind, UntranslatableDiag,
77
UntranslatableDiagnosticTrivial,
88
};
99
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
1010
use rustc_ast as ast;
1111
use rustc_hir::def::Res;
1212
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};
1414
use rustc_middle::ty;
1515
use rustc_session::{declare_lint_pass, declare_tool_lint};
1616
use rustc_span::hygiene::{ExpnKind, MacroKind};
@@ -537,3 +537,44 @@ impl LateLintPass<'_> for BadOptAccess {
537537
}
538538
}
539539
}
540+
541+
// some things i'm not sure about:
542+
// * is Warn the right level?
543+
// * the way i verify that the right method is being called (path + diag item check)
544+
545+
declare_tool_lint! {
546+
pub rustc::SPAN_USE_EQ_CTXT,
547+
Warn, // is this the right level?
548+
"Use of `==` with `Span::ctxt` rather than `Span::eq_ctxt`",
549+
report_in_external_macro: true
550+
}
551+
552+
declare_lint_pass!(SpanUseEqCtxt => [SPAN_USE_EQ_CTXT]);
553+
554+
impl<'tcx> LateLintPass<'tcx> for SpanUseEqCtxt {
555+
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
556+
if let ExprKind::Binary(BinOp { node: BinOpKind::Eq, .. }, lhs, rhs) = expr.kind {
557+
if is_span_ctxt_call(cx, lhs) && is_span_ctxt_call(cx, rhs) {
558+
cx.emit_spanned_lint(
559+
SPAN_USE_EQ_CTXT,
560+
expr.span,
561+
SpanUseEqCtxtDiag { msg: "fail" },
562+
);
563+
}
564+
}
565+
}
566+
}
567+
568+
fn is_span_ctxt_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
569+
match &expr.kind {
570+
ExprKind::MethodCall(path, receiver, _, _) => {
571+
path.ident.name.as_str() == "ctxt"
572+
&& cx
573+
.typeck_results()
574+
.type_dependent_def_id(receiver.hir_id)
575+
.is_some_and(|did| cx.tcx.is_diagnostic_item(sym::Span, did))
576+
}
577+
578+
_ => false,
579+
}
580+
}

compiler/rustc_lint/src/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ mod passes;
8383
mod ptr_nulls;
8484
mod redundant_semicolon;
8585
mod reference_casting;
86-
mod span_use_eq_ctxt;
8786
mod traits;
8887
mod types;
8988
mod unused;
@@ -532,6 +531,8 @@ fn register_internals(store: &mut LintStore) {
532531
store.register_late_mod_pass(|_| Box::new(BadOptAccess));
533532
store.register_lints(&PassByValue::get_lints());
534533
store.register_late_mod_pass(|_| Box::new(PassByValue));
534+
store.register_lints(&SpanUseEqCtxt::get_lints());
535+
store.register_late_mod_pass(|_| Box::new(SpanUseEqCtxt));
535536
// FIXME(davidtwco): deliberately do not include `UNTRANSLATABLE_DIAGNOSTIC` and
536537
// `DIAGNOSTIC_OUTSIDE_OF_IMPL` here because `-Wrustc::internal` is provided to every crate and
537538
// these lints will trigger all of the time - change this once migration to diagnostic structs
@@ -549,6 +550,7 @@ fn register_internals(store: &mut LintStore) {
549550
LintId::of(USAGE_OF_QUALIFIED_TY),
550551
LintId::of(EXISTING_DOC_KEYWORD),
551552
LintId::of(BAD_OPT_ACCESS),
553+
LintId::of(SPAN_USE_EQ_CTXT),
552554
],
553555
);
554556
}

compiler/rustc_lint/src/lints.rs

+6
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,12 @@ pub struct QueryInstability {
900900
pub query: Symbol,
901901
}
902902

903+
#[derive(LintDiagnostic)]
904+
#[diag(lint_span_use_eq_ctxt)]
905+
pub struct SpanUseEqCtxtDiag<'a> {
906+
pub msg: &'a str,
907+
}
908+
903909
#[derive(LintDiagnostic)]
904910
#[diag(lint_tykind_kind)]
905911
pub struct TykindKind {

compiler/rustc_lint/src/span_use_eq_ctxt.rs

-38
This file was deleted.

compiler/rustc_span/src/span_encoding.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ use rustc_data_structures::fx::FxIndexSet;
7575
/// the dependency to the parent definition's span. This is performed
7676
/// using the callback `SPAN_TRACK` to access the query engine.
7777
///
78+
#[cfg_attr(not(test), rustc_diagnostic_item = "Span")]
7879
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
7980
#[rustc_pass_by_value]
8081
pub struct Span {
@@ -212,7 +213,6 @@ impl Span {
212213

213214
/// This function is used as a fast path when decoding the full `SpanData` is not necessary.
214215
/// It's a cut-down version of `data_untracked`.
215-
#[rustc_diagnostic_item = "SpanCtxt"]
216216
#[inline]
217217
pub fn ctxt(self) -> SyntaxContext {
218218
if self.len_with_tag_or_marker != BASE_LEN_INTERNED_MARKER {

compiler/rustc_span/src/symbol.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ symbols! {
303303
SliceIndex,
304304
SliceIter,
305305
Some,
306-
SpanCtxt,
306+
Span,
307307
String,
308308
StructuralEq,
309309
StructuralPartialEq,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// compile-flags: -Z unstable-options
2+
3+
#![feature(rustc_private)]
4+
#![deny(rustc::span_use_eq_ctxt)]
5+
6+
extern crate rustc_span;
7+
use rustc_span::Span;
8+
9+
pub fn f(s: Span, t: Span) -> bool {
10+
s.ctxt() == t.ctxt() //~ ERROR use of span ctxt
11+
}
12+
13+
fn main() {}

0 commit comments

Comments
 (0)