about summary refs log tree commit diff
path: root/compiler/rustc_lint
diff options
context:
space:
mode:
authorRomain Perier <romain.perier@gmail.com>2025-05-25 15:15:49 +0200
committerRomain Perier <romain.perier@gmail.com>2025-06-18 16:01:41 +0200
commita1a3bef6f0d5f5f45f0296133d7af745dc89d7bb (patch)
treeec68e7afb6fc2ba1b3353835ecdc205fd82e1449 /compiler/rustc_lint
parent6f935a044d1ddeb6160494a6320d008d7c311aef (diff)
downloadrust-a1a3bef6f0d5f5f45f0296133d7af745dc89d7bb.tar.gz
rust-a1a3bef6f0d5f5f45f0296133d7af745dc89d7bb.zip
Implement lint against direct uses of rustc_type_ir in compiler crates
This commit adds a lint to prevent the use of rustc_type_ir in random
compiler crates, except for type system internals traits, which are
explicitly allowed. Moreover, this fixes diagnostic_items() to include
the CRATE_OWNER_ID, otherwise rustc_diagnostic_item attribute is ignored
on the crate root.
Diffstat (limited to 'compiler/rustc_lint')
-rw-r--r--compiler/rustc_lint/messages.ftl3
-rw-r--r--compiler/rustc_lint/src/internal.rs31
-rw-r--r--compiler/rustc_lint/src/lib.rs1
-rw-r--r--compiler/rustc_lint/src/lints.rs5
4 files changed, 37 insertions, 3 deletions
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index f92f8307808..8d9f2385b71 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -812,6 +812,9 @@ lint_tykind = usage of `ty::TyKind`
 lint_tykind_kind = usage of `ty::TyKind::<kind>`
     .suggestion = try using `ty::<kind>` directly
 
+lint_type_ir_direct_use = do not use `rustc_type_ir` unless you are implementing type system internals
+    .note = use `rustc_middle::ty` instead
+
 lint_type_ir_inherent_usage = do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
     .note = the method or struct you're looking for is likely defined somewhere else downstream in the compiler
 
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index 1805a674d68..d8fc46aa9ab 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -14,8 +14,8 @@ use {rustc_ast as ast, rustc_hir as hir};
 use crate::lints::{
     BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand,
     NonGlobImportTypeIrInherent, QueryInstability, QueryUntracked, SpanUseEqCtxtDiag,
-    SymbolInternStringLiteralDiag, TyQualified, TykindDiag, TykindKind, TypeIrInherentUsage,
-    TypeIrTraitUsage, UntranslatableDiag,
+    SymbolInternStringLiteralDiag, TyQualified, TykindDiag, TykindKind, TypeIrDirectUse,
+    TypeIrInherentUsage, TypeIrTraitUsage, UntranslatableDiag,
 };
 use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
 
@@ -301,8 +301,18 @@ declare_tool_lint! {
     "usage `rustc_type_ir`-specific abstraction traits outside of trait system",
     report_in_external_macro: true
 }
+declare_tool_lint! {
+    /// The `direct_use_of_rustc_type_ir` lint detects usage of `rustc_type_ir`.
+    ///
+    /// This module should only be used within the trait solver and some desirable
+    /// crates like rustc_middle.
+    pub rustc::DIRECT_USE_OF_RUSTC_TYPE_IR,
+    Allow,
+    "usage `rustc_type_ir` abstraction outside of trait system",
+    report_in_external_macro: true
+}
 
-declare_lint_pass!(TypeIr => [NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT, USAGE_OF_TYPE_IR_INHERENT, USAGE_OF_TYPE_IR_TRAITS]);
+declare_lint_pass!(TypeIr => [DIRECT_USE_OF_RUSTC_TYPE_IR, NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT, USAGE_OF_TYPE_IR_INHERENT, USAGE_OF_TYPE_IR_TRAITS]);
 
 impl<'tcx> LateLintPass<'tcx> for TypeIr {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
@@ -372,6 +382,21 @@ impl<'tcx> LateLintPass<'tcx> for TypeIr {
             NonGlobImportTypeIrInherent { suggestion: lo.eq_ctxt(hi).then(|| lo.to(hi)), snippet },
         );
     }
+
+    fn check_path(
+        &mut self,
+        cx: &LateContext<'tcx>,
+        path: &rustc_hir::Path<'tcx>,
+        _: rustc_hir::HirId,
+    ) {
+        if let Some(seg) = path.segments.iter().find(|seg| {
+            seg.res
+                .opt_def_id()
+                .is_some_and(|def_id| cx.tcx.is_diagnostic_item(sym::type_ir, def_id))
+        }) {
+            cx.emit_span_lint(DIRECT_USE_OF_RUSTC_TYPE_IR, seg.ident.span, TypeIrDirectUse);
+        }
+    }
 }
 
 declare_tool_lint! {
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 9a1490d3eea..20568f35a47 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -668,6 +668,7 @@ fn register_internals(store: &mut LintStore) {
             LintId::of(USAGE_OF_TYPE_IR_TRAITS),
             LintId::of(BAD_OPT_ACCESS),
             LintId::of(SPAN_USE_EQ_CTXT),
+            LintId::of(DIRECT_USE_OF_RUSTC_TYPE_IR),
         ],
     );
 }
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index ae65cefda77..abdf8e3853b 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -970,6 +970,11 @@ pub(crate) struct TypeIrInherentUsage;
 pub(crate) struct TypeIrTraitUsage;
 
 #[derive(LintDiagnostic)]
+#[diag(lint_type_ir_direct_use)]
+#[note]
+pub(crate) struct TypeIrDirectUse;
+
+#[derive(LintDiagnostic)]
 #[diag(lint_non_glob_import_type_ir_inherent)]
 pub(crate) struct NonGlobImportTypeIrInherent {
     #[suggestion(code = "{snippet}", applicability = "maybe-incorrect")]