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.
This commit is contained in:
parent
6f935a044d
commit
a1a3bef6f0
13 changed files with 111 additions and 5 deletions
|
|
@ -7,6 +7,7 @@
|
|||
#![allow(internal_features)]
|
||||
#![allow(rustc::diagnostic_outside_of_impl)]
|
||||
#![allow(rustc::untranslatable_diagnostic)]
|
||||
#![cfg_attr(not(bootstrap), allow(rustc::direct_use_of_rustc_type_ir))]
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||
#![doc(rust_logo)]
|
||||
#![feature(array_windows)]
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#![allow(internal_features)]
|
||||
#![allow(rustc::diagnostic_outside_of_impl)]
|
||||
#![allow(rustc::untranslatable_diagnostic)]
|
||||
#![cfg_attr(not(bootstrap), allow(rustc::direct_use_of_rustc_type_ir))]
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||
#![doc(rust_logo)]
|
||||
#![feature(assert_matches)]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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! {
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -969,6 +969,11 @@ pub(crate) struct TypeIrInherentUsage;
|
|||
#[note]
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#![allow(internal_features)]
|
||||
#![allow(rustc::diagnostic_outside_of_impl)]
|
||||
#![allow(rustc::untranslatable_diagnostic)]
|
||||
#![cfg_attr(not(bootstrap), allow(rustc::direct_use_of_rustc_type_ir))]
|
||||
#![cfg_attr(not(bootstrap), feature(sized_hierarchy))]
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||
#![doc(rust_logo)]
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
// tidy-alphabetical-start
|
||||
#![allow(rustc::usage_of_type_ir_inherent)]
|
||||
#![allow(rustc::usage_of_type_ir_traits)]
|
||||
#![cfg_attr(not(bootstrap), allow(rustc::direct_use_of_rustc_type_ir))]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
pub mod canonicalizer;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
//! * Compiler internal types like `Ty` and `TyCtxt`
|
||||
|
||||
use rustc_hir::diagnostic_items::DiagnosticItems;
|
||||
use rustc_hir::{Attribute, OwnerId};
|
||||
use rustc_hir::{Attribute, CRATE_OWNER_ID, OwnerId};
|
||||
use rustc_middle::query::{LocalCrate, Providers};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::def_id::{DefId, LOCAL_CRATE};
|
||||
|
|
@ -67,7 +67,7 @@ fn diagnostic_items(tcx: TyCtxt<'_>, _: LocalCrate) -> DiagnosticItems {
|
|||
|
||||
// Collect diagnostic items in this crate.
|
||||
let crate_items = tcx.hir_crate_items(());
|
||||
for id in crate_items.owners() {
|
||||
for id in crate_items.owners().chain(std::iter::once(CRATE_OWNER_ID)) {
|
||||
observe_item(tcx, &mut diagnostic_items, id);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2183,6 +2183,7 @@ symbols! {
|
|||
type_changing_struct_update,
|
||||
type_const,
|
||||
type_id,
|
||||
type_ir,
|
||||
type_ir_infer_ctxt_like,
|
||||
type_ir_inherent,
|
||||
type_ir_interner,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#![cfg_attr(feature = "nightly", rustc_diagnostic_item = "type_ir")]
|
||||
// tidy-alphabetical-start
|
||||
#![allow(rustc::usage_of_ty_tykind)]
|
||||
#![allow(rustc::usage_of_type_ir_inherent)]
|
||||
|
|
@ -7,6 +8,7 @@
|
|||
feature(associated_type_defaults, never_type, rustc_attrs, negative_impls)
|
||||
)]
|
||||
#![cfg_attr(feature = "nightly", allow(internal_features))]
|
||||
#![cfg_attr(not(bootstrap), allow(rustc::direct_use_of_rustc_type_ir))]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
extern crate self as rustc_type_ir;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
//@ compile-flags: -Z unstable-options
|
||||
//@ ignore-stage1
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![deny(rustc::direct_use_of_rustc_type_ir)]
|
||||
|
||||
extern crate rustc_middle;
|
||||
extern crate rustc_type_ir;
|
||||
|
||||
use rustc_middle::ty::*; // OK, we have to accept rustc_middle::ty::*
|
||||
|
||||
// We have to deny direct import of type_ir
|
||||
use rustc_type_ir::*;
|
||||
//~^ ERROR: do not use `rustc_type_ir` unless you are implementing type system internals
|
||||
|
||||
// We have to deny direct types usages which resolves to type_ir
|
||||
fn foo<I: rustc_type_ir::Interner>(cx: I, did: I::DefId) {
|
||||
//~^ ERROR: do not use `rustc_type_ir` unless you are implementing type system internals
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = rustc_type_ir::InferConst::Fresh(42);
|
||||
//~^ ERROR: do not use `rustc_type_ir` unless you are implementing type system internals
|
||||
let _: rustc_type_ir::InferConst;
|
||||
//~^ ERROR: do not use `rustc_type_ir` unless you are implementing type system internals
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
error: do not use `rustc_type_ir` unless you are implementing type system internals
|
||||
--> $DIR/direct-use-of-rustc-type-ir.rs:13:5
|
||||
|
|
||||
LL | use rustc_type_ir::*;
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: use `rustc_middle::ty` instead
|
||||
note: the lint level is defined here
|
||||
--> $DIR/direct-use-of-rustc-type-ir.rs:5:9
|
||||
|
|
||||
LL | #![deny(rustc::direct_use_of_rustc_type_ir)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: do not use `rustc_type_ir` unless you are implementing type system internals
|
||||
--> $DIR/direct-use-of-rustc-type-ir.rs:17:11
|
||||
|
|
||||
LL | fn foo<I: rustc_type_ir::Interner>(cx: I, did: I::DefId) {
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: use `rustc_middle::ty` instead
|
||||
|
||||
error: do not use `rustc_type_ir` unless you are implementing type system internals
|
||||
--> $DIR/direct-use-of-rustc-type-ir.rs:22:13
|
||||
|
|
||||
LL | let _ = rustc_type_ir::InferConst::Fresh(42);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: use `rustc_middle::ty` instead
|
||||
|
||||
error: do not use `rustc_type_ir` unless you are implementing type system internals
|
||||
--> $DIR/direct-use-of-rustc-type-ir.rs:24:12
|
||||
|
|
||||
LL | let _: rustc_type_ir::InferConst;
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: use `rustc_middle::ty` instead
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue