From 8769e02d0b17e18e0a52b521a82da4bcae2e6385 Mon Sep 17 00:00:00 2001 From: Arthur Lafrance Date: Sat, 23 Sep 2023 23:50:47 -0700 Subject: [PATCH 1/5] implement the basics of the lint static analysis --- compiler/rustc_lint/src/lib.rs | 1 + compiler/rustc_lint/src/span_use_eq_ctxt.rs | 38 +++++++++++++++++++++ compiler/rustc_span/src/span_encoding.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + 4 files changed, 41 insertions(+) create mode 100644 compiler/rustc_lint/src/span_use_eq_ctxt.rs diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index b9e455e6c2a3d..ca1f620b7c762 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -83,6 +83,7 @@ mod passes; mod ptr_nulls; mod redundant_semicolon; mod reference_casting; +mod span_use_eq_ctxt; mod traits; mod types; mod unused; diff --git a/compiler/rustc_lint/src/span_use_eq_ctxt.rs b/compiler/rustc_lint/src/span_use_eq_ctxt.rs new file mode 100644 index 0000000000000..19fea01bf4f75 --- /dev/null +++ b/compiler/rustc_lint/src/span_use_eq_ctxt.rs @@ -0,0 +1,38 @@ +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 bfc9e125362ca..69ad11e23f02a 100644 --- a/compiler/rustc_span/src/span_encoding.rs +++ b/compiler/rustc_span/src/span_encoding.rs @@ -212,6 +212,7 @@ 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 ea261923c6541..be8c65862dc2e 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -303,6 +303,7 @@ symbols! { SliceIndex, SliceIter, Some, + SpanCtxt, String, StructuralEq, StructuralPartialEq, From f77dea89e183b638841d42d4d7bea48058a98e76 Mon Sep 17 00:00:00 2001 From: Arthur Lafrance Date: Mon, 25 Sep 2023 00:15:00 -0700 Subject: [PATCH 2/5] basic lint v2 implemented --- compiler/rustc_lint/messages.ftl | 2 + compiler/rustc_lint/src/internal.rs | 45 ++++++++++++++++++- compiler/rustc_lint/src/lib.rs | 4 +- compiler/rustc_lint/src/lints.rs | 6 +++ compiler/rustc_lint/src/span_use_eq_ctxt.rs | 38 ---------------- compiler/rustc_span/src/span_encoding.rs | 2 +- compiler/rustc_span/src/symbol.rs | 2 +- .../internal-lints/span_use_eq_ctxt.rs | 13 ++++++ 8 files changed, 69 insertions(+), 43 deletions(-) delete mode 100644 compiler/rustc_lint/src/span_use_eq_ctxt.rs create mode 100644 tests/ui-fulldeps/internal-lints/span_use_eq_ctxt.rs diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 197fe6552d796..261451e530e68 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 fc2d3d0a25446..c2aa768e94578 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 ca1f620b7c762..d61c59af1e05f 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 594ef97b3ffb5..a02bee506dfae 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -900,6 +900,12 @@ pub struct QueryInstability { pub query: Symbol, } +#[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 { 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 19fea01bf4f75..0000000000000 --- 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 69ad11e23f02a..7c7f8448c9789 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 be8c65862dc2e..9598b2d0310a2 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 0000000000000..5b4c59a2e8a0b --- /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() {} From 5895102c4dab67e7962bd76e1204bcf0fab467c5 Mon Sep 17 00:00:00 2001 From: Arthur Lafrance Date: Mon, 16 Oct 2023 01:05:11 -0700 Subject: [PATCH 3/5] debug Span::ctxt() call detection --- compiler/rustc_hir_typeck/src/callee.rs | 2 +- compiler/rustc_lint/messages.ftl | 2 +- compiler/rustc_lint/src/internal.rs | 23 +++++-------------- compiler/rustc_lint/src/lints.rs | 4 +--- .../rustc_mir_transform/src/coverage/spans.rs | 2 +- compiler/rustc_span/src/span_encoding.rs | 2 +- compiler/rustc_span/src/symbol.rs | 2 +- .../internal-lints/span_use_eq_ctxt.rs | 6 ++--- .../internal-lints/span_use_eq_ctxt.stderr | 14 +++++++++++ 9 files changed, 29 insertions(+), 28 deletions(-) create mode 100644 tests/ui-fulldeps/internal-lints/span_use_eq_ctxt.stderr diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 512d73fc10368..1c23ccd157940 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -650,7 +650,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .sess .source_map() .is_multiline(call_expr.span.with_lo(callee_expr.span.hi())) - && call_expr.span.ctxt() == callee_expr.span.ctxt(); + && call_expr.span.eq_ctxt(callee_expr.span); if call_is_multiline { err.span_suggestion( callee_expr.span.shrink_to_hi(), diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 261451e530e68..4c4d2933bf4f4 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -494,7 +494,7 @@ 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_span_use_eq_ctxt = use `.eq_ctxt()` instead of `.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 c2aa768e94578..34f241e8c8d21 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -538,13 +538,9 @@ 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? + Allow, "Use of `==` with `Span::ctxt` rather than `Span::eq_ctxt`", report_in_external_macro: true } @@ -555,11 +551,7 @@ 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" }, - ); + cx.emit_spanned_lint(SPAN_USE_EQ_CTXT, expr.span, SpanUseEqCtxtDiag); } } } @@ -567,13 +559,10 @@ impl<'tcx> LateLintPass<'tcx> for SpanUseEqCtxt { 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)) - } + ExprKind::MethodCall(..) => cx + .typeck_results() + .type_dependent_def_id(expr.hir_id) + .is_some_and(|call_did| cx.tcx.is_diagnostic_item(sym::SpanCtxt, call_did)), _ => false, } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index a02bee506dfae..4eaf8bbf5ded2 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -902,9 +902,7 @@ pub struct QueryInstability { #[derive(LintDiagnostic)] #[diag(lint_span_use_eq_ctxt)] -pub struct SpanUseEqCtxtDiag<'a> { - pub msg: &'a str, -} +pub struct SpanUseEqCtxtDiag; #[derive(LintDiagnostic)] #[diag(lint_tykind_kind)] diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index 1d1be8f249274..f1a0f762041c7 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -404,7 +404,7 @@ impl<'a> CoverageSpansGenerator<'a> { let Some(visible_macro) = curr.visible_macro(self.body_span) else { return }; if let Some(prev) = &self.some_prev - && prev.expn_span.ctxt() == curr.expn_span.ctxt() + && prev.expn_span.eq_ctxt(curr.expn_span) { return; } diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs index 7c7f8448c9789..f7d17a267d693 100644 --- a/compiler/rustc_span/src/span_encoding.rs +++ b/compiler/rustc_span/src/span_encoding.rs @@ -75,7 +75,6 @@ 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 { @@ -213,6 +212,7 @@ 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`. + #[cfg_attr(not(test), 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 9598b2d0310a2..be8c65862dc2e 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -303,7 +303,7 @@ symbols! { SliceIndex, SliceIter, Some, - Span, + SpanCtxt, 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 index 5b4c59a2e8a0b..39980ee7c672c 100644 --- a/tests/ui-fulldeps/internal-lints/span_use_eq_ctxt.rs +++ b/tests/ui-fulldeps/internal-lints/span_use_eq_ctxt.rs @@ -1,13 +1,13 @@ +// Test the `rustc::span_use_eq_ctxt` internal lint // compile-flags: -Z unstable-options #![feature(rustc_private)] #![deny(rustc::span_use_eq_ctxt)] +#![crate_type = "lib"] 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 + s.ctxt() == t.ctxt() //~ ERROR use `.eq_ctxt()` instead of `.ctxt() == .ctxt()` } - -fn main() {} diff --git a/tests/ui-fulldeps/internal-lints/span_use_eq_ctxt.stderr b/tests/ui-fulldeps/internal-lints/span_use_eq_ctxt.stderr new file mode 100644 index 0000000000000..b33f621254541 --- /dev/null +++ b/tests/ui-fulldeps/internal-lints/span_use_eq_ctxt.stderr @@ -0,0 +1,14 @@ +error: use `.eq_ctxt()` instead of `.ctxt() == .ctxt()` + --> $DIR/span_use_eq_ctxt.rs:12:5 + | +LL | s.ctxt() == t.ctxt() + | ^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/span_use_eq_ctxt.rs:5:9 + | +LL | #![deny(rustc::span_use_eq_ctxt)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + From 52ad8199d502cdce296a2145cad2650795a2f3f6 Mon Sep 17 00:00:00 2001 From: Arthur Lafrance Date: Mon, 16 Oct 2023 01:17:52 -0700 Subject: [PATCH 4/5] tweak pass description and fix lint fail post-rebase --- compiler/rustc_lint/src/internal.rs | 2 +- compiler/rustc_passes/src/loops.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 34f241e8c8d21..2d86129c480c6 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -541,7 +541,7 @@ impl LateLintPass<'_> for BadOptAccess { declare_tool_lint! { pub rustc::SPAN_USE_EQ_CTXT, Allow, - "Use of `==` with `Span::ctxt` rather than `Span::eq_ctxt`", + "forbid uses of `==` with `Span::ctxt`, suggest `Span::eq_ctxt` instead", report_in_external_macro: true } diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs index 4590ab9e4f579..25e131d7477fd 100644 --- a/compiler/rustc_passes/src/loops.rs +++ b/compiler/rustc_passes/src/loops.rs @@ -231,7 +231,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> { AsyncClosure(closure_span) => { self.sess.emit_err(BreakInsideAsyncBlock { span, closure_span, name }); } - UnlabeledBlock(block_span) if is_break && block_span.ctxt() == break_span.ctxt() => { + UnlabeledBlock(block_span) if is_break && block_span.eq_ctxt(break_span) => { let suggestion = Some(OutsideLoopSuggestion { block_span, break_span }); self.sess.emit_err(OutsideLoop { span, name, is_break, suggestion }); } From e89d4d4871d7ecd5f59136638250bca419628baa Mon Sep 17 00:00:00 2001 From: Arthur Lafrance Date: Mon, 16 Oct 2023 13:52:50 -0700 Subject: [PATCH 5/5] fix lint failures in clippy --- src/tools/clippy/clippy_lints/src/dereference.rs | 2 +- src/tools/clippy/clippy_lints/src/entry.rs | 2 +- src/tools/clippy/clippy_lints/src/formatting.rs | 2 +- src/tools/clippy/clippy_lints/src/let_with_type_underscore.rs | 2 +- src/tools/clippy/clippy_lints/src/manual_let_else.rs | 2 +- .../clippy/clippy_lints/src/matches/collapsible_match.rs | 2 +- src/tools/clippy/clippy_lints/src/matches/manual_utils.rs | 4 ++-- src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs | 2 +- src/tools/clippy/clippy_lints/src/needless_question_mark.rs | 2 +- .../clippy/clippy_lints/src/non_octal_unix_permissions.rs | 4 ++-- src/tools/clippy/clippy_lints/src/redundant_async_block.rs | 2 +- src/tools/clippy/clippy_lints/src/reference.rs | 2 +- .../clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs | 2 +- src/tools/clippy/clippy_utils/src/macros.rs | 2 +- 14 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 14877385646a0..5134cf66050c9 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -701,7 +701,7 @@ fn deref_method_same_type<'tcx>(result_ty: Ty<'tcx>, arg_ty: Ty<'tcx>) -> bool { fn in_postfix_position<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> bool { if let Some(parent) = get_parent_expr(cx, e) - && parent.span.ctxt() == e.span.ctxt() + && parent.span.eq_ctxt(e.span) { match parent.kind { ExprKind::Call(child, _) | ExprKind::MethodCall(_, child, _, _) | ExprKind::Index(child, _, _) diff --git a/src/tools/clippy/clippy_lints/src/entry.rs b/src/tools/clippy/clippy_lints/src/entry.rs index 6197b5b19eb4c..70a467dde6136 100644 --- a/src/tools/clippy/clippy_lints/src/entry.rs +++ b/src/tools/clippy/clippy_lints/src/entry.rs @@ -241,7 +241,7 @@ fn try_parse_contains<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Optio }, ], _, - ) if key_span.ctxt() == expr.span.ctxt() => { + ) if key_span.eq_ctxt(expr.span) => { let id = cx.typeck_results().type_dependent_def_id(expr.hir_id)?; let expr = ContainsExpr { negated, diff --git a/src/tools/clippy/clippy_lints/src/formatting.rs b/src/tools/clippy/clippy_lints/src/formatting.rs index d03480c21084c..4ebf0e9667dfe 100644 --- a/src/tools/clippy/clippy_lints/src/formatting.rs +++ b/src/tools/clippy/clippy_lints/src/formatting.rs @@ -274,7 +274,7 @@ fn check_array(cx: &EarlyContext<'_>, expr: &Expr) { for element in array { if_chain! { if let ExprKind::Binary(ref op, ref lhs, _) = element.kind; - if has_unary_equivalent(op.node) && lhs.span.ctxt() == op.span.ctxt(); + if has_unary_equivalent(op.node) && lhs.span.eq_ctxt(op.span); let space_span = lhs.span.between(op.span); if let Some(space_snippet) = snippet_opt(cx, space_span); let lint_span = lhs.span.with_lo(lhs.span.hi()); diff --git a/src/tools/clippy/clippy_lints/src/let_with_type_underscore.rs b/src/tools/clippy/clippy_lints/src/let_with_type_underscore.rs index 4e9d77ea156af..79d728a021c3c 100644 --- a/src/tools/clippy/clippy_lints/src/let_with_type_underscore.rs +++ b/src/tools/clippy/clippy_lints/src/let_with_type_underscore.rs @@ -31,7 +31,7 @@ impl LateLintPass<'_> for UnderscoreTyped { if !in_external_macro(cx.tcx.sess, local.span); if let Some(ty) = local.ty; // Ensure that it has a type defined if let TyKind::Infer = &ty.kind; // that type is '_' - if local.span.ctxt() == ty.span.ctxt(); + if local.span.eq_ctxt(ty.span); then { // NOTE: Using `is_from_proc_macro` on `init` will require that it's initialized, // this doesn't. Alternatively, `WithSearchPat` can be implemented for `Ty` diff --git a/src/tools/clippy/clippy_lints/src/manual_let_else.rs b/src/tools/clippy/clippy_lints/src/manual_let_else.rs index 2117308cd4009..86bbdb4ea1993 100644 --- a/src/tools/clippy/clippy_lints/src/manual_let_else.rs +++ b/src/tools/clippy/clippy_lints/src/manual_let_else.rs @@ -59,7 +59,7 @@ impl<'tcx> QuestionMark { let Some(init) = local.init && local.els.is_none() && local.ty.is_none() && - init.span.ctxt() == stmt.span.ctxt() && + init.span.eq_ctxt(stmt.span) && let Some(if_let_or_match) = IfLetOrMatch::parse(cx, init) { match if_let_or_match { diff --git a/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs b/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs index 33a052c41a38a..29b935fb61a8a 100644 --- a/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs @@ -57,7 +57,7 @@ fn check_arm<'tcx>( } }, }; - if outer_pat.span.ctxt() == inner_scrutinee.span.ctxt(); + if outer_pat.span.eq_ctxt(inner_scrutinee.span); // match expression must be a local binding // match { .. } if let Some(binding_id) = path_to_local(peel_ref_operators(cx, inner_scrutinee)); diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs index 6b611f567ae28..781ee138c76f7 100644 --- a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs +++ b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs @@ -119,7 +119,7 @@ where // it's being passed by value. let scrutinee = peel_hir_expr_refs(scrutinee).0; let (scrutinee_str, _) = snippet_with_context(cx, scrutinee.span, expr_ctxt, "..", &mut app); - let scrutinee_str = if scrutinee.span.ctxt() == expr.span.ctxt() && scrutinee.precedence().order() < PREC_POSTFIX { + let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence().order() < PREC_POSTFIX { format!("({scrutinee_str})") } else { scrutinee_str.into() @@ -130,7 +130,7 @@ where if_chain! { if !some_expr.needs_unsafe_block; if let Some(func) = can_pass_as_func(cx, id, some_expr.expr); - if func.span.ctxt() == some_expr.expr.span.ctxt(); + if func.span.eq_ctxt(some_expr.expr.span); then { snippet_with_applicability(cx, func.span, "..", &mut app).into_owned() } else { diff --git a/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs index 5464e455dea40..e70a1bc98799c 100644 --- a/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs +++ b/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs @@ -56,7 +56,7 @@ pub(super) fn check<'tcx>( // lint, with note if neither arg is > 1 line and both map() and // unwrap_or_else() have the same span let multiline = map_snippet.lines().count() > 1 || unwrap_snippet.lines().count() > 1; - let same_span = map_arg.span.ctxt() == unwrap_arg.span.ctxt(); + let same_span = map_arg.span.eq_ctxt(unwrap_arg.span); if same_span && !multiline { let var_snippet = snippet(cx, recv.span, ".."); span_lint_and_sugg( diff --git a/src/tools/clippy/clippy_lints/src/needless_question_mark.rs b/src/tools/clippy/clippy_lints/src/needless_question_mark.rs index 7b0f7eaf1f063..0e834fb3ac768 100644 --- a/src/tools/clippy/clippy_lints/src/needless_question_mark.rs +++ b/src/tools/clippy/clippy_lints/src/needless_question_mark.rs @@ -125,7 +125,7 @@ fn check(cx: &LateContext<'_>, expr: &Expr<'_>) { if let ExprKind::Match(inner_expr_with_q, _, MatchSource::TryDesugar(_)) = &arg.kind; if let ExprKind::Call(called, [inner_expr]) = &inner_expr_with_q.kind; if let ExprKind::Path(QPath::LangItem(LangItem::TryTraitBranch, ..)) = &called.kind; - if expr.span.ctxt() == inner_expr.span.ctxt(); + if expr.span.eq_ctxt(inner_expr.span); let expr_ty = cx.typeck_results().expr_ty(expr); let inner_ty = cx.typeck_results().expr_ty(inner_expr); if expr_ty == inner_ty; diff --git a/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs b/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs index d47728f190ab9..e94e458996601 100644 --- a/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs +++ b/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs @@ -51,7 +51,7 @@ impl<'tcx> LateLintPass<'tcx> for NonOctalUnixPermissions { || (path.ident.name == sym!(set_mode) && cx.tcx.is_diagnostic_item(sym::FsPermissions, adt.did())); if let ExprKind::Lit(_) = param.kind; - if param.span.ctxt() == expr.span.ctxt(); + if param.span.eq_ctxt(expr.span); then { let Some(snip) = snippet_opt(cx, param.span) else { @@ -70,7 +70,7 @@ impl<'tcx> LateLintPass<'tcx> for NonOctalUnixPermissions { if let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id(); if match_def_path(cx, def_id, &paths::PERMISSIONS_FROM_MODE); if let ExprKind::Lit(_) = param.kind; - if param.span.ctxt() == expr.span.ctxt(); + if param.span.eq_ctxt(expr.span); if let Some(snip) = snippet_opt(cx, param.span); if !snip.starts_with("0o"); then { diff --git a/src/tools/clippy/clippy_lints/src/redundant_async_block.rs b/src/tools/clippy/clippy_lints/src/redundant_async_block.rs index 534b2762ba769..8193057a6eb27 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_async_block.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_async_block.rs @@ -48,7 +48,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantAsyncBlock { let Some(body_expr) = desugar_async_block(cx, expr) && let Some(expr) = desugar_await(peel_blocks(body_expr)) && // The await prefix must not come from a macro as its content could change in the future. - expr.span.ctxt() == body_expr.span.ctxt() && + expr.span.eq_ctxt(body_expr.span) && // An async block does not have immediate side-effects from a `.await` point-of-view. (!expr.can_have_side_effects() || desugar_async_block(cx, expr).is_some()) && let Some(shortened_span) = walk_span_to_context(expr.span, span.ctxt()) diff --git a/src/tools/clippy/clippy_lints/src/reference.rs b/src/tools/clippy/clippy_lints/src/reference.rs index db870ec4c5b6d..12da29f11089c 100644 --- a/src/tools/clippy/clippy_lints/src/reference.rs +++ b/src/tools/clippy/clippy_lints/src/reference.rs @@ -50,7 +50,7 @@ impl EarlyLintPass for DerefAddrOf { if_chain! { if let ExprKind::Unary(UnOp::Deref, ref deref_target) = e.kind; if let ExprKind::AddrOf(_, ref mutability, ref addrof_target) = without_parens(deref_target).kind; - if deref_target.span.ctxt() == e.span.ctxt(); + if deref_target.span.eq_ctxt(e.span); if !addrof_target.span.from_expansion(); then { let mut applicability = Applicability::MachineApplicable; diff --git a/src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs b/src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs index 8e156b8829b9c..39cd289b67ad3 100644 --- a/src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs +++ b/src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs @@ -33,7 +33,7 @@ impl LateLintPass<'_> for ConfusingXorAndPow { if !in_external_macro(cx.sess(), expr.span) && let ExprKind::Binary(op, left, right) = &expr.kind && op.node == BinOpKind::BitXor - && left.span.ctxt() == right.span.ctxt() + && left.span.eq_ctxt(right.span) && let ExprKind::Lit(lit_left) = &left.kind && let ExprKind::Lit(lit_right) = &right.kind && matches!(lit_right.node, LitKind::Int(..) | LitKind::Float(..)) diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs index eaf590f6ad77d..46ce4ffdce5d4 100644 --- a/src/tools/clippy/clippy_utils/src/macros.rs +++ b/src/tools/clippy/clippy_utils/src/macros.rs @@ -245,7 +245,7 @@ impl<'a> PanicExpn<'a> { return None; }; let result = match name { - "panic" if arg.span.ctxt() == expr.span.ctxt() => Self::Empty, + "panic" if arg.span.eq_ctxt(expr.span) => Self::Empty, "panic" | "panic_str" => Self::Str(arg), "panic_display" | "panic_cold_display" => { let ExprKind::AddrOf(_, _, e) = &arg.kind else {