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 /compiler/rustc_lint | |
| parent | 8769e02d0b17e18e0a52b521a82da4bcae2e6385 (diff) | |
| download | rust-f77dea89e183b638841d42d4d7bea48058a98e76.tar.gz rust-f77dea89e183b638841d42d4d7bea48058a98e76.zip | |
basic lint v2 implemented
Diffstat (limited to 'compiler/rustc_lint')
| -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 |
5 files changed, 54 insertions, 41 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, - } -} |
