|
3 | 3 |
|
4 | 4 | use crate::lints::{
|
5 | 5 | BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand, NonExistentDocKeyword,
|
6 |
| - QueryInstability, SpanUseEqCtxtDiag, TyQualified, TykindDiag, TykindKind, UntranslatableDiag, |
| 6 | + NonGlobImportTypeIrInherent, QueryInstability, SpanUseEqCtxtDiag, TyQualified, TykindDiag, |
| 7 | + TykindKind, UntranslatableDiag, |
7 | 8 | };
|
8 | 9 | use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
9 | 10 | use rustc_ast as ast;
|
@@ -263,6 +264,49 @@ fn gen_args(segment: &PathSegment<'_>) -> String {
|
263 | 264 | String::new()
|
264 | 265 | }
|
265 | 266 |
|
| 267 | +declare_tool_lint! { |
| 268 | + /// The `non_glob_import_of_type_ir_inherent_item` lint detects |
| 269 | + /// non-glob imports of module `rustc_type_ir::inherent`. |
| 270 | + pub rustc::NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT, |
| 271 | + Allow, |
| 272 | + "non-glob import of `rustc_type_ir::inherent`", |
| 273 | + report_in_external_macro: true |
| 274 | +} |
| 275 | + |
| 276 | +declare_lint_pass!(TypeIr => [NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT]); |
| 277 | + |
| 278 | +impl<'tcx> LateLintPass<'tcx> for TypeIr { |
| 279 | + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { |
| 280 | + let rustc_hir::ItemKind::Use(path, kind) = item.kind else { return }; |
| 281 | + |
| 282 | + let is_mod_inherent = |def_id| cx.tcx.is_diagnostic_item(sym::type_ir_inherent, def_id); |
| 283 | + let (lo, hi, snippet) = match path.segments { |
| 284 | + [.., penultimate, segment] |
| 285 | + if penultimate.res.opt_def_id().is_some_and(is_mod_inherent) => |
| 286 | + { |
| 287 | + (segment.ident.span, item.ident.span, "*") |
| 288 | + } |
| 289 | + [.., segment] |
| 290 | + if path.res.iter().flat_map(Res::opt_def_id).any(is_mod_inherent) |
| 291 | + && let rustc_hir::UseKind::Single = kind => |
| 292 | + { |
| 293 | + let (lo, snippet) = |
| 294 | + match cx.tcx.sess.source_map().span_to_snippet(path.span).as_deref() { |
| 295 | + Ok("self") => (path.span, "*"), |
| 296 | + _ => (segment.ident.span.shrink_to_hi(), "::*"), |
| 297 | + }; |
| 298 | + (lo, if segment.ident == item.ident { lo } else { item.ident.span }, snippet) |
| 299 | + } |
| 300 | + _ => return, |
| 301 | + }; |
| 302 | + cx.emit_span_lint( |
| 303 | + NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT, |
| 304 | + path.span, |
| 305 | + NonGlobImportTypeIrInherent { suggestion: lo.eq_ctxt(hi).then(|| lo.to(hi)), snippet }, |
| 306 | + ); |
| 307 | + } |
| 308 | +} |
| 309 | + |
266 | 310 | declare_tool_lint! {
|
267 | 311 | /// The `lint_pass_impl_without_macro` detects manual implementations of a lint
|
268 | 312 | /// pass, without using [`declare_lint_pass`] or [`impl_lint_pass`].
|
|
0 commit comments