Rollup merge of #129678 - compiler-errors:type-ir-inherent, r=fmease

Deny imports of `rustc_type_ir::inherent` outside of type ir + new trait solver

We shouldn't encourage using `rustc_type_ir::inherent` outside of the new solver[^1], though this can happen by accident due to rust-analyzer, for example. See https://github.com/rust-lang/rust/pull/127537#discussion_r1733813842 for an example in practice.

r? fmease

[^1]: Unless we go the fully radical approach of always using these inherent methods everywhere in favor of inherent methods, which would be a major overhaul of the compiler, IMO. I don't really want to consider that possibility right now, tho.
This commit is contained in:
Matthias Krüger 2024-09-02 04:19:28 +02:00 committed by GitHub
commit e0039171ff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 87 additions and 2 deletions

View File

@ -783,6 +783,9 @@ lint_tykind = usage of `ty::TyKind`
lint_tykind_kind = usage of `ty::TyKind::<kind>`
.suggestion = try using `ty::<kind>` directly
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
lint_undropped_manually_drops = calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of the inner value does nothing
.label = argument has type `{$arg_ty}`
.suggestion = use `std::mem::ManuallyDrop::into_inner` to get the inner value

View File

@ -18,7 +18,7 @@ use tracing::debug;
use crate::lints::{
BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand, NonExistentDocKeyword,
NonGlobImportTypeIrInherent, QueryInstability, SpanUseEqCtxtDiag, TyQualified, TykindDiag,
TykindKind, UntranslatableDiag,
TykindKind, TypeIrInherentUsage, UntranslatableDiag,
};
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
@ -277,13 +277,39 @@ declare_tool_lint! {
report_in_external_macro: true
}
declare_lint_pass!(TypeIr => [NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT]);
declare_tool_lint! {
/// The `usage_of_type_ir_inherent` lint detects usage `rustc_type_ir::inherent`.
///
/// This module should only be used within the trait solver.
pub rustc::USAGE_OF_TYPE_IR_INHERENT,
Allow,
"usage `rustc_type_ir::inherent` 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]);
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);
// Path segments except for the final.
if let Some(seg) =
path.segments.iter().find(|seg| seg.res.opt_def_id().is_some_and(is_mod_inherent))
{
cx.emit_span_lint(USAGE_OF_TYPE_IR_INHERENT, seg.ident.span, TypeIrInherentUsage);
}
// Final path resolutions, like `use rustc_type_ir::inherent`
else if path.res.iter().any(|res| res.opt_def_id().is_some_and(is_mod_inherent)) {
cx.emit_span_lint(
USAGE_OF_TYPE_IR_INHERENT,
path.segments.last().unwrap().ident.span,
TypeIrInherentUsage,
);
}
let (lo, hi, snippet) = match path.segments {
[.., penultimate, segment]
if penultimate.res.opt_def_id().is_some_and(is_mod_inherent) =>

View File

@ -918,6 +918,11 @@ pub(crate) struct TyQualified {
pub suggestion: Span,
}
#[derive(LintDiagnostic)]
#[diag(lint_type_ir_inherent_usage)]
#[note]
pub(crate) struct TypeIrInherentUsage;
#[derive(LintDiagnostic)]
#[diag(lint_non_glob_import_type_ir_inherent)]
pub(crate) struct NonGlobImportTypeIrInherent {

View File

@ -5,6 +5,7 @@
//! So if you got to this crate from the old solver, it's totally normal.
// tidy-alphabetical-start
#![cfg_attr(not(bootstrap), allow(rustc::usage_of_type_ir_inherent))]
#![warn(unreachable_pub)]
// tidy-alphabetical-end

View File

@ -5,6 +5,7 @@
feature(associated_type_defaults, never_type, rustc_attrs, negative_impls)
)]
#![cfg_attr(feature = "nightly", allow(internal_features))]
#![cfg_attr(not(bootstrap), allow(rustc::usage_of_type_ir_inherent))]
// tidy-alphabetical-end
extern crate self as rustc_type_ir;

View File

@ -0,0 +1,18 @@
//@ compile-flags: -Z unstable-options
// #[cfg(bootstrap)]: We can stop ignoring next beta bump; afterward this ALWAYS should run.
//@ ignore-stage1
#![feature(rustc_private)]
#![deny(rustc::usage_of_type_ir_inherent)]
extern crate rustc_type_ir;
use rustc_type_ir::inherent::*;
//~^ ERROR do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
use rustc_type_ir::inherent;
//~^ ERROR do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
use rustc_type_ir::inherent::Predicate;
//~^ ERROR do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
fn main() {}

View File

@ -0,0 +1,31 @@
error: do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
--> $DIR/import-of-type-ir-inherent.rs:11:20
|
LL | use rustc_type_ir::inherent::*;
| ^^^^^^^^
|
= note: the method or struct you're looking for is likely defined somewhere else downstream in the compiler
note: the lint level is defined here
--> $DIR/import-of-type-ir-inherent.rs:7:9
|
LL | #![deny(rustc::usage_of_type_ir_inherent)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
--> $DIR/import-of-type-ir-inherent.rs:13:20
|
LL | use rustc_type_ir::inherent;
| ^^^^^^^^
|
= note: the method or struct you're looking for is likely defined somewhere else downstream in the compiler
error: do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
--> $DIR/import-of-type-ir-inherent.rs:15:20
|
LL | use rustc_type_ir::inherent::Predicate;
| ^^^^^^^^
|
= note: the method or struct you're looking for is likely defined somewhere else downstream in the compiler
error: aborting due to 3 previous errors