about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeón Orell Valerian Liehr <me@fmease.dev>2024-07-17 12:35:50 +0200
committerLeón Orell Valerian Liehr <me@fmease.dev>2024-07-18 13:03:26 +0200
commit2507301de0814406175fdb0bbe9da40a348b1f30 (patch)
treef6c57b331c56a817c7ad835f9d52843d3c832f05
parent44fb8575dee0c1f2d454962ae78b09817a0f32b1 (diff)
downloadrust-2507301de0814406175fdb0bbe9da40a348b1f30.tar.gz
rust-2507301de0814406175fdb0bbe9da40a348b1f30.zip
Add internal lint for detecting non-glob imports of `rustc_type_ir::inherent`
-rw-r--r--compiler/rustc_lint/messages.ftl3
-rw-r--r--compiler/rustc_lint/src/internal.rs46
-rw-r--r--compiler/rustc_lint/src/lib.rs3
-rw-r--r--compiler/rustc_lint/src/lints.rs8
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_type_ir/src/effects.rs2
-rw-r--r--compiler/rustc_type_ir/src/lib.rs1
-rw-r--r--tests/ui-fulldeps/internal-lints/non_glob_import_of_type_ir_inherent.rs38
-rw-r--r--tests/ui-fulldeps/internal-lints/non_glob_import_of_type_ir_inherent.stderr68
9 files changed, 168 insertions, 2 deletions
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index de04d882f51..79d52914381 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -556,6 +556,9 @@ lint_non_fmt_panic_unused =
     }
     .add_fmt_suggestion = or add a "{"{"}{"}"}" format string to use the message literally
 
+lint_non_glob_import_type_ir_inherent = non-glob import of `rustc_type_ir::inherent`
+    .suggestion = try using a glob import instead
+
 lint_non_local_definitions_cargo_update = the {$macro_kind} `{$macro_name}` may come from an old version of the `{$crate_name}` crate, try updating your dependency with `cargo update -p {$crate_name}`
 
 lint_non_local_definitions_deprecation = this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index 772cc2ff8b9..e15eb90f827 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -3,7 +3,8 @@
 
 use crate::lints::{
     BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand, NonExistentDocKeyword,
-    QueryInstability, SpanUseEqCtxtDiag, TyQualified, TykindDiag, TykindKind, UntranslatableDiag,
+    NonGlobImportTypeIrInherent, QueryInstability, SpanUseEqCtxtDiag, TyQualified, TykindDiag,
+    TykindKind, UntranslatableDiag,
 };
 use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
 use rustc_ast as ast;
@@ -264,6 +265,49 @@ fn gen_args(segment: &PathSegment<'_>) -> String {
 }
 
 declare_tool_lint! {
+    /// The `non_glob_import_of_type_ir_inherent_item` lint detects
+    /// non-glob imports of module `rustc_type_ir::inherent`.
+    pub rustc::NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT,
+    Allow,
+    "non-glob import of `rustc_type_ir::inherent`",
+    report_in_external_macro: true
+}
+
+declare_lint_pass!(TypeIr => [NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT]);
+
+impl<'tcx> LateLintPass<'tcx> for TypeIr {
+    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
+        let rustc_hir::ItemKind::Use(path, kind) = item.kind else { return };
+
+        let is_mod_inherent = |def_id| cx.tcx.is_diagnostic_item(sym::type_ir_inherent, def_id);
+        let (lo, hi, snippet) = match path.segments {
+            [.., penultimate, segment]
+                if penultimate.res.opt_def_id().is_some_and(is_mod_inherent) =>
+            {
+                (segment.ident.span, item.ident.span, "*")
+            }
+            [.., segment]
+                if path.res.iter().flat_map(Res::opt_def_id).any(is_mod_inherent)
+                    && let rustc_hir::UseKind::Single = kind =>
+            {
+                let (lo, snippet) =
+                    match cx.tcx.sess.source_map().span_to_snippet(path.span).as_deref() {
+                        Ok("self") => (path.span, "*"),
+                        _ => (segment.ident.span.shrink_to_hi(), "::*"),
+                    };
+                (lo, if segment.ident == item.ident { lo } else { item.ident.span }, snippet)
+            }
+            _ => return,
+        };
+        cx.emit_span_lint(
+            NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT,
+            path.span,
+            NonGlobImportTypeIrInherent { suggestion: lo.eq_ctxt(hi).then(|| lo.to(hi)), snippet },
+        );
+    }
+}
+
+declare_tool_lint! {
     /// The `lint_pass_impl_without_macro` detects manual implementations of a lint
     /// pass, without using [`declare_lint_pass`] or [`impl_lint_pass`].
     pub rustc::LINT_PASS_IMPL_WITHOUT_MACRO,
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 8be8996e4c8..68f66ca5c0d 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -573,6 +573,8 @@ fn register_internals(store: &mut LintStore) {
     store.register_late_mod_pass(|_| Box::new(ExistingDocKeyword));
     store.register_lints(&TyTyKind::get_lints());
     store.register_late_mod_pass(|_| Box::new(TyTyKind));
+    store.register_lints(&TypeIr::get_lints());
+    store.register_late_mod_pass(|_| Box::new(TypeIr));
     store.register_lints(&Diagnostics::get_lints());
     store.register_late_mod_pass(|_| Box::new(Diagnostics));
     store.register_lints(&BadOptAccess::get_lints());
@@ -596,6 +598,7 @@ fn register_internals(store: &mut LintStore) {
             LintId::of(PASS_BY_VALUE),
             LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO),
             LintId::of(USAGE_OF_QUALIFIED_TY),
+            LintId::of(NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT),
             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 308bb73f4ce..ac5511faf19 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -927,6 +927,14 @@ pub struct TyQualified {
 }
 
 #[derive(LintDiagnostic)]
+#[diag(lint_non_glob_import_type_ir_inherent)]
+pub struct NonGlobImportTypeIrInherent {
+    #[suggestion(code = "{snippet}", applicability = "maybe-incorrect")]
+    pub suggestion: Option<Span>,
+    pub snippet: &'static str,
+}
+
+#[derive(LintDiagnostic)]
 #[diag(lint_lintpass_by_hand)]
 #[help]
 pub struct LintPassByHand;
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 2fe7c951793..b64efadb261 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1926,6 +1926,7 @@ symbols! {
         type_ascription,
         type_changing_struct_update,
         type_id,
+        type_ir_inherent,
         type_length_limit,
         type_macros,
         type_name,
diff --git a/compiler/rustc_type_ir/src/effects.rs b/compiler/rustc_type_ir/src/effects.rs
index f7942f2f982..0f28355c4b8 100644
--- a/compiler/rustc_type_ir/src/effects.rs
+++ b/compiler/rustc_type_ir/src/effects.rs
@@ -1,4 +1,4 @@
-use crate::inherent::{AdtDef, IntoKind, Ty};
+use crate::inherent::*;
 use crate::lang_items::TraitSolverLangItem::{EffectsMaybe, EffectsNoRuntime, EffectsRuntime};
 use crate::Interner;
 
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index 37ee66fa222..80e970a23a9 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -24,6 +24,7 @@ pub mod elaborate;
 pub mod error;
 pub mod fast_reject;
 pub mod fold;
+#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "type_ir_inherent")]
 pub mod inherent;
 pub mod ir_print;
 pub mod lang_items;
diff --git a/tests/ui-fulldeps/internal-lints/non_glob_import_of_type_ir_inherent.rs b/tests/ui-fulldeps/internal-lints/non_glob_import_of_type_ir_inherent.rs
new file mode 100644
index 00000000000..33e10a00713
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/non_glob_import_of_type_ir_inherent.rs
@@ -0,0 +1,38 @@
+//@ compile-flags: -Z unstable-options
+//@ ignore-stage1 (can be removed after beta bump, #[cfg(bootstrap)])
+#![feature(rustc_private)]
+#![deny(rustc::non_glob_import_of_type_ir_inherent)]
+
+extern crate rustc_type_ir;
+
+mod ok {
+    use rustc_type_ir::inherent::*; // OK
+    use rustc_type_ir::inherent::{}; // OK
+    use rustc_type_ir::inherent::{*}; // OK
+
+    fn usage<T: rustc_type_ir::inherent::SliceLike>() {} // OK
+}
+
+mod direct {
+    use rustc_type_ir::inherent::Predicate; //~ ERROR non-glob import of `rustc_type_ir::inherent`
+    use rustc_type_ir::inherent::{AdtDef, Ty};
+    //~^ ERROR non-glob import of `rustc_type_ir::inherent`
+    //~| ERROR non-glob import of `rustc_type_ir::inherent`
+    use rustc_type_ir::inherent::ParamEnv as _; //~ ERROR non-glob import of `rustc_type_ir::inherent`
+}
+
+mod indirect0 {
+    use rustc_type_ir::inherent; //~ ERROR non-glob import of `rustc_type_ir::inherent`
+    use rustc_type_ir::inherent as inh; //~ ERROR non-glob import of `rustc_type_ir::inherent`
+    use rustc_type_ir::{inherent as _}; //~ ERROR non-glob import of `rustc_type_ir::inherent`
+
+    fn usage0<T: inherent::SliceLike>() {}
+    fn usage1<T: inh::SliceLike>() {}
+}
+
+mod indirect1 {
+    use rustc_type_ir::inherent::{self}; //~ ERROR non-glob import of `rustc_type_ir::inherent`
+    use rustc_type_ir::inherent::{self as innate}; //~ ERROR non-glob import of `rustc_type_ir::inherent`
+}
+
+fn main() {}
diff --git a/tests/ui-fulldeps/internal-lints/non_glob_import_of_type_ir_inherent.stderr b/tests/ui-fulldeps/internal-lints/non_glob_import_of_type_ir_inherent.stderr
new file mode 100644
index 00000000000..84e3867c95b
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/non_glob_import_of_type_ir_inherent.stderr
@@ -0,0 +1,68 @@
+error: non-glob import of `rustc_type_ir::inherent`
+  --> $DIR/non_glob_import_of_type_ir_inherent.rs:17:9
+   |
+LL |     use rustc_type_ir::inherent::Predicate;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^---------
+   |                                  |
+   |                                  help: try using a glob import instead: `*`
+   |
+note: the lint level is defined here
+  --> $DIR/non_glob_import_of_type_ir_inherent.rs:4:9
+   |
+LL | #![deny(rustc::non_glob_import_of_type_ir_inherent)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: non-glob import of `rustc_type_ir::inherent`
+  --> $DIR/non_glob_import_of_type_ir_inherent.rs:18:35
+   |
+LL |     use rustc_type_ir::inherent::{AdtDef, Ty};
+   |                                   ^^^^^^ help: try using a glob import instead: `*`
+
+error: non-glob import of `rustc_type_ir::inherent`
+  --> $DIR/non_glob_import_of_type_ir_inherent.rs:18:43
+   |
+LL |     use rustc_type_ir::inherent::{AdtDef, Ty};
+   |                                           ^^ help: try using a glob import instead: `*`
+
+error: non-glob import of `rustc_type_ir::inherent`
+  --> $DIR/non_glob_import_of_type_ir_inherent.rs:21:9
+   |
+LL |     use rustc_type_ir::inherent::ParamEnv as _;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^-------------
+   |                                  |
+   |                                  help: try using a glob import instead: `*`
+
+error: non-glob import of `rustc_type_ir::inherent`
+  --> $DIR/non_glob_import_of_type_ir_inherent.rs:25:9
+   |
+LL |     use rustc_type_ir::inherent;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^- help: try using a glob import instead: `::*`
+
+error: non-glob import of `rustc_type_ir::inherent`
+  --> $DIR/non_glob_import_of_type_ir_inherent.rs:26:9
+   |
+LL |     use rustc_type_ir::inherent as inh;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^------- help: try using a glob import instead: `::*`
+
+error: non-glob import of `rustc_type_ir::inherent`
+  --> $DIR/non_glob_import_of_type_ir_inherent.rs:27:25
+   |
+LL |     use rustc_type_ir::{inherent as _};
+   |                         ^^^^^^^^----- help: try using a glob import instead: `::*`
+
+error: non-glob import of `rustc_type_ir::inherent`
+  --> $DIR/non_glob_import_of_type_ir_inherent.rs:34:35
+   |
+LL |     use rustc_type_ir::inherent::{self};
+   |                                   ^^^^ help: try using a glob import instead: `*`
+
+error: non-glob import of `rustc_type_ir::inherent`
+  --> $DIR/non_glob_import_of_type_ir_inherent.rs:35:35
+   |
+LL |     use rustc_type_ir::inherent::{self as innate};
+   |                                   ^^^^----------
+   |                                   |
+   |                                   help: try using a glob import instead: `*`
+
+error: aborting due to 9 previous errors
+