Skip to content

Commit 8769e02

Browse files
committed
implement the basics of the lint static analysis
1 parent 39164b8 commit 8769e02

File tree

4 files changed

+41
-0
lines changed

4 files changed

+41
-0
lines changed

compiler/rustc_lint/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ mod passes;
8383
mod ptr_nulls;
8484
mod redundant_semicolon;
8585
mod reference_casting;
86+
mod span_use_eq_ctxt;
8687
mod traits;
8788
mod types;
8889
mod unused;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use crate::{LateContext, LateLintPass};
2+
use rustc_hir::{BinOp, BinOpKind, Expr, ExprKind};
3+
use rustc_span::sym;
4+
5+
declare_lint! {
6+
pub SPAN_USE_EQ_CTXT,
7+
Warn, // is this the right level?
8+
"Use of `==` with `Span::ctxt` rather than `Span::eq_ctxt`"
9+
}
10+
11+
declare_lint_pass!(SpanUseEqCtxt => [SPAN_USE_EQ_CTXT]);
12+
13+
impl<'tcx> LateLintPass<'tcx> for SpanUseEqCtxt {
14+
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
15+
if let ExprKind::Binary(BinOp { node: BinOpKind::Eq, .. }, lhs, rhs) = expr.kind {
16+
if is_span_ctxt_call(cx, lhs) && is_span_ctxt_call(cx, rhs) {
17+
todo!(); // emit lint
18+
}
19+
}
20+
}
21+
}
22+
23+
fn is_span_ctxt_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
24+
match &expr.kind {
25+
ExprKind::MethodCall(..) => {
26+
// i gave a method a diagnostic item -- FIXME: switch to a diagnostic
27+
// item for the Span type and check:
28+
// * method call path == "ctxt"
29+
// * receiver type matches Span diag item
30+
// also FIXME(todo) remove old SpanCtxt diagnostic item
31+
cx.typeck_results()
32+
.type_dependent_def_id(expr.hir_id)
33+
.is_some_and(|did| cx.tcx.is_diagnostic_item(sym::SpanCtxt, did))
34+
}
35+
36+
_ => false,
37+
}
38+
}

compiler/rustc_span/src/span_encoding.rs

+1
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ impl Span {
212212

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

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ symbols! {
303303
SliceIndex,
304304
SliceIter,
305305
Some,
306+
SpanCtxt,
306307
String,
307308
StructuralEq,
308309
StructuralPartialEq,

0 commit comments

Comments
 (0)