|
3 | 3 |
|
4 | 4 | use crate::lints::{ |
5 | 5 | BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand, NonExistentDocKeyword, |
6 | | - QueryInstability, TyQualified, TykindDiag, TykindKind, UntranslatableDiag, |
7 | | - UntranslatableDiagnosticTrivial, |
| 6 | + QueryInstability, TyCompareOperatorUsed, TyQualified, TykindDiag, TykindKind, |
| 7 | + UntranslatableDiag, UntranslatableDiagnosticTrivial, |
8 | 8 | }; |
9 | 9 | use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; |
10 | 10 | use rustc_ast as ast; |
| 11 | +use rustc_hir as hir; |
11 | 12 | use rustc_hir::def::Res; |
12 | 13 | use rustc_hir::{def_id::DefId, Expr, ExprKind, GenericArg, PatKind, Path, PathSegment, QPath}; |
13 | 14 | use rustc_hir::{HirId, Impl, Item, ItemKind, Node, Pat, Ty, TyKind}; |
@@ -127,12 +128,7 @@ declare_lint_pass!(TyTyKind => [ |
127 | 128 | ]); |
128 | 129 |
|
129 | 130 | impl<'tcx> LateLintPass<'tcx> for TyTyKind { |
130 | | - fn check_path( |
131 | | - &mut self, |
132 | | - cx: &LateContext<'tcx>, |
133 | | - path: &rustc_hir::Path<'tcx>, |
134 | | - _: rustc_hir::HirId, |
135 | | - ) { |
| 131 | + fn check_path(&mut self, cx: &LateContext<'tcx>, path: &hir::Path<'tcx>, _: hir::HirId) { |
136 | 132 | if let Some(segment) = path.segments.iter().nth_back(1) |
137 | 133 | && lint_ty_kind_usage(cx, &segment.res) |
138 | 134 | { |
@@ -269,6 +265,37 @@ fn gen_args(segment: &PathSegment<'_>) -> String { |
269 | 265 | String::new() |
270 | 266 | } |
271 | 267 |
|
| 268 | +declare_tool_lint! { |
| 269 | + pub rustc::TY_COMPARE_OPERATOR, |
| 270 | + Allow, |
| 271 | + "using the a comparison operator on `Ty`" |
| 272 | +} |
| 273 | + |
| 274 | +declare_lint_pass!(TyCompareOperator => [TY_COMPARE_OPERATOR]); |
| 275 | + |
| 276 | +impl<'tcx> LateLintPass<'tcx> for TyCompareOperator { |
| 277 | + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { |
| 278 | + use hir::BinOpKind::*; |
| 279 | + |
| 280 | + if let hir::ExprKind::Binary( |
| 281 | + hir::BinOp { node:Eq | Ne | Gt | Lt | Le | Ge, span}, |
| 282 | + lhs, |
| 283 | + rhs |
| 284 | + ) = expr.kind |
| 285 | + && let ty::Adt(lhs_def, _) = cx.typeck_results().node_type(lhs.hir_id).peel_refs().kind() |
| 286 | + && let ty::Adt(rhs_def, _) = cx.typeck_results().node_type(rhs.hir_id).peel_refs().kind() |
| 287 | + && cx.tcx.is_diagnostic_item(sym::Ty, lhs_def.did()) |
| 288 | + && cx.tcx.is_diagnostic_item(sym::Ty, rhs_def.did()) |
| 289 | + { |
| 290 | + cx.emit_spanned_lint( |
| 291 | + TY_COMPARE_OPERATOR, |
| 292 | + span, |
| 293 | + TyCompareOperatorUsed, |
| 294 | + ) |
| 295 | + } |
| 296 | + } |
| 297 | +} |
| 298 | + |
272 | 299 | declare_tool_lint! { |
273 | 300 | /// The `lint_pass_impl_without_macro` detects manual implementations of a lint |
274 | 301 | /// pass, without using [`declare_lint_pass`] or [`impl_lint_pass`]. |
@@ -318,7 +345,7 @@ fn is_doc_keyword(s: Symbol) -> bool { |
318 | 345 | } |
319 | 346 |
|
320 | 347 | impl<'tcx> LateLintPass<'tcx> for ExistingDocKeyword { |
321 | | - fn check_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::Item<'_>) { |
| 348 | + fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) { |
322 | 349 | for attr in cx.tcx.hir().attrs(item.hir_id()) { |
323 | 350 | if !attr.has_name(sym::doc) { |
324 | 351 | continue; |
|
0 commit comments