diff options
| author | Arthur Lafrance <lafrancearthur@gmail.com> | 2023-09-25 00:15:00 -0700 |
|---|---|---|
| committer | Arthur Lafrance <lafrancearthur@gmail.com> | 2023-10-16 19:47:33 -0700 |
| commit | f77dea89e183b638841d42d4d7bea48058a98e76 (patch) | |
| tree | 18bc71a5132be3dc008d7b45af46d2664db28dff | |
| parent | 8769e02d0b17e18e0a52b521a82da4bcae2e6385 (diff) | |
basic lint v2 implemented
| -rw-r--r-- | compiler/rustc_lint/messages.ftl | 2 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/internal.rs | 45 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/lib.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/lints.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/span_use_eq_ctxt.rs | 38 | ||||
| -rw-r--r-- | compiler/rustc_span/src/span_encoding.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 2 | ||||
| -rw-r--r-- | tests/ui-fulldeps/internal-lints/span_use_eq_ctxt.rs | 13 |
8 files changed, 69 insertions, 43 deletions
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 197fe6552d7..261451e530e 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -494,6 +494,8 @@ lint_renamed_lint = lint `{$name}` has been renamed to `{$replace}` lint_requested_level = requested on the command line with `{$level} {$lint_name}` +lint_span_use_eq_ctxt = use `eq_ctxt()` not `ctxt() == ctxt()` + lint_supertrait_as_deref_target = `{$t}` implements `Deref` with supertrait `{$target_principal}` as target .label = target type is set here diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index fc2d3d0a254..c2aa768e945 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -3,14 +3,14 @@ use crate::lints::{ BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand, NonExistentDocKeyword, - QueryInstability, TyQualified, TykindDiag, TykindKind, UntranslatableDiag, + QueryInstability, SpanUseEqCtxtDiag, TyQualified, TykindDiag, TykindKind, UntranslatableDiag, UntranslatableDiagnosticTrivial, }; use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; use rustc_ast as ast; use rustc_hir::def::Res; use rustc_hir::{def_id::DefId, Expr, ExprKind, GenericArg, PatKind, Path, PathSegment, QPath}; -use rustc_hir::{HirId, Impl, Item, ItemKind, Node, Pat, Ty, TyKind}; +use rustc_hir::{BinOp, BinOpKind, HirId, Impl, Item, ItemKind, Node, Pat, Ty, TyKind}; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::hygiene::{ExpnKind, MacroKind}; @@ -537,3 +537,44 @@ impl LateLintPass<'_> for BadOptAccess { } } } + +// some things i'm not sure about: +// * is Warn the right level? +// * the way i verify that the right method is being called (path + diag item check) + +declare_tool_lint! { + pub rustc::SPAN_USE_EQ_CTXT, + Warn, // is this the right level? + "Use of `==` with `Span::ctxt` rather than `Span::eq_ctxt`", + report_in_external_macro: true +} + +declare_lint_pass!(SpanUseEqCtxt => [SPAN_USE_EQ_CTXT]); + +impl<'tcx> LateLintPass<'tcx> for SpanUseEqCtxt { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) { + if let ExprKind::Binary(BinOp { node: BinOpKind::Eq, .. }, lhs, rhs) = expr.kind { + if is_span_ctxt_call(cx, lhs) && is_span_ctxt_call(cx, rhs) { + cx.emit_spanned_lint( + SPAN_USE_EQ_CTXT, + expr.span, + SpanUseEqCtxtDiag { msg: "fail" }, + ); + } + } + } +} + +fn is_span_ctxt_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { + match &expr.kind { + ExprKind::MethodCall(path, receiver, _, _) => { + path.ident.name.as_str() == "ctxt" + && cx + .typeck_results() + .type_dependent_def_id(receiver.hir_id) + .is_some_and(|did| cx.tcx.is_diagnostic_item(sym::Span, did)) + } + + _ => false, + } +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index ca1f620b7c7..d61c59af1e0 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -83,7 +83,6 @@ mod passes; mod ptr_nulls; mod redundant_semicolon; mod reference_casting; -mod span_use_eq_ctxt; mod traits; mod types; mod unused; @@ -532,6 +531,8 @@ fn register_internals(store: &mut LintStore) { store.register_late_mod_pass(|_| Box::new(BadOptAccess)); store.register_lints(&PassByValue::get_lints()); store.register_late_mod_pass(|_| Box::new(PassByValue)); + store.register_lints(&SpanUseEqCtxt::get_lints()); + store.register_late_mod_pass(|_| Box::new(SpanUseEqCtxt)); // FIXME(davidtwco): deliberately do not include `UNTRANSLATABLE_DIAGNOSTIC` and // `DIAGNOSTIC_OUTSIDE_OF_IMPL` here because `-Wrustc::internal` is provided to every crate and // 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) { LintId::of(USAGE_OF_QUALIFIED_TY), LintId::of(EXISTING_DOC_KEYWORD), LintId::of(BAD_OPT_ACCESS), + LintId::of(SPAN_USE_EQ_CTXT), ], ); } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 594ef97b3ff..a02bee506df 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -901,6 +901,12 @@ pub struct QueryInstability { } #[derive(LintDiagnostic)] +#[diag(lint_span_use_eq_ctxt)] +pub struct SpanUseEqCtxtDiag<'a> { + pub msg: &'a str, +} + +#[derive(LintDiagnostic)] #[diag(lint_tykind_kind)] pub struct TykindKind { #[suggestion(code = "ty", applicability = "maybe-incorrect")] diff --git a/compiler/rustc_lint/src/span_use_eq_ctxt.rs b/compiler/rustc_lint/src/span_use_eq_ctxt.rs deleted file mode 100644 index 19fea01bf4f..00000000000 --- a/compiler/rustc_lint/src/span_use_eq_ctxt.rs +++ /dev/null @@ -1,38 +0,0 @@ -use crate::{LateContext, LateLintPass}; -use rustc_hir::{BinOp, BinOpKind, Expr, ExprKind}; -use rustc_span::sym; - -declare_lint! { - pub SPAN_USE_EQ_CTXT, - Warn, // is this the right level? - "Use of `==` with `Span::ctxt` rather than `Span::eq_ctxt`" -} - -declare_lint_pass!(SpanUseEqCtxt => [SPAN_USE_EQ_CTXT]); - -impl<'tcx> LateLintPass<'tcx> for SpanUseEqCtxt { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) { - if let ExprKind::Binary(BinOp { node: BinOpKind::Eq, .. }, lhs, rhs) = expr.kind { - if is_span_ctxt_call(cx, lhs) && is_span_ctxt_call(cx, rhs) { - todo!(); // emit lint - } - } - } -} - -fn is_span_ctxt_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - match &expr.kind { - ExprKind::MethodCall(..) => { - // i gave a method a diagnostic item -- FIXME: switch to a diagnostic - // item for the Span type and check: - // * method call path == "ctxt" - // * receiver type matches Span diag item - // also FIXME(todo) remove old SpanCtxt diagnostic item - cx.typeck_results() - .type_dependent_def_id(expr.hir_id) - .is_some_and(|did| cx.tcx.is_diagnostic_item(sym::SpanCtxt, did)) - } - - _ => false, - } -} diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs index 69ad11e23f0..7c7f8448c97 100644 --- a/compiler/rustc_span/src/span_encoding.rs +++ b/compiler/rustc_span/src/span_encoding.rs @@ -75,6 +75,7 @@ use rustc_data_structures::fx::FxIndexSet; /// the dependency to the parent definition's span. This is performed /// using the callback `SPAN_TRACK` to access the query engine. /// +#[cfg_attr(not(test), rustc_diagnostic_item = "Span")] #[derive(Clone, Copy, Eq, PartialEq, Hash)] #[rustc_pass_by_value] pub struct Span { @@ -212,7 +213,6 @@ impl Span { /// This function is used as a fast path when decoding the full `SpanData` is not necessary. /// It's a cut-down version of `data_untracked`. - #[rustc_diagnostic_item = "SpanCtxt"] #[inline] pub fn ctxt(self) -> SyntaxContext { if self.len_with_tag_or_marker != BASE_LEN_INTERNED_MARKER { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index be8c65862dc..9598b2d0310 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -303,7 +303,7 @@ symbols! { SliceIndex, SliceIter, Some, - SpanCtxt, + Span, String, StructuralEq, StructuralPartialEq, diff --git a/tests/ui-fulldeps/internal-lints/span_use_eq_ctxt.rs b/tests/ui-fulldeps/internal-lints/span_use_eq_ctxt.rs new file mode 100644 index 00000000000..5b4c59a2e8a --- /dev/null +++ b/tests/ui-fulldeps/internal-lints/span_use_eq_ctxt.rs @@ -0,0 +1,13 @@ +// compile-flags: -Z unstable-options + +#![feature(rustc_private)] +#![deny(rustc::span_use_eq_ctxt)] + +extern crate rustc_span; +use rustc_span::Span; + +pub fn f(s: Span, t: Span) -> bool { + s.ctxt() == t.ctxt() //~ ERROR use of span ctxt +} + +fn main() {} |
