mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Rollup merge of #138964 - compiler-errors:usage-of-interner, r=lcnr
Implement lint against using Interner and InferCtxtLike in random compiler crates Often `Interner` defines similar methods to `TyCtxt` (but often simplified due to the simpler API surface of the type system layer for the new solver), which people will either unintentionally or intentionally import and use. Let's discourage that. r? lcnr
This commit is contained in:
commit
cb39217d44
@ -799,6 +799,9 @@ lint_tykind_kind = usage of `ty::TyKind::<kind>`
|
|||||||
lint_type_ir_inherent_usage = do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
|
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
|
.note = the method or struct you're looking for is likely defined somewhere else downstream in the compiler
|
||||||
|
|
||||||
|
lint_type_ir_trait_usage = do not use `rustc_type_ir::Interner` or `rustc_type_ir::InferCtxtLike` 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
|
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}`
|
.label = argument has type `{$arg_ty}`
|
||||||
.suggestion = use `std::mem::ManuallyDrop::into_inner` to get the inner value
|
.suggestion = use `std::mem::ManuallyDrop::into_inner` to get the inner value
|
||||||
|
@ -1,24 +1,21 @@
|
|||||||
//! Some lints that are only useful in the compiler or crates that use compiler internals, such as
|
//! Some lints that are only useful in the compiler or crates that use compiler internals, such as
|
||||||
//! Clippy.
|
//! Clippy.
|
||||||
|
|
||||||
use rustc_ast as ast;
|
use rustc_hir::HirId;
|
||||||
use rustc_hir::def::Res;
|
use rustc_hir::def::Res;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::{
|
|
||||||
AmbigArg, BinOp, BinOpKind, Expr, ExprKind, GenericArg, HirId, Impl, Item, ItemKind, Node, Pat,
|
|
||||||
PatExpr, PatExprKind, PatKind, Path, PathSegment, QPath, Ty, TyKind,
|
|
||||||
};
|
|
||||||
use rustc_middle::ty::{self, GenericArgsRef, Ty as MiddleTy};
|
use rustc_middle::ty::{self, GenericArgsRef, Ty as MiddleTy};
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
use rustc_span::hygiene::{ExpnKind, MacroKind};
|
use rustc_span::hygiene::{ExpnKind, MacroKind};
|
||||||
use rustc_span::{Span, sym};
|
use rustc_span::{Span, sym};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
use {rustc_ast as ast, rustc_hir as hir};
|
||||||
|
|
||||||
use crate::lints::{
|
use crate::lints::{
|
||||||
BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand,
|
BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand,
|
||||||
NonGlobImportTypeIrInherent, QueryInstability, QueryUntracked, SpanUseEqCtxtDiag,
|
NonGlobImportTypeIrInherent, QueryInstability, QueryUntracked, SpanUseEqCtxtDiag,
|
||||||
SymbolInternStringLiteralDiag, TyQualified, TykindDiag, TykindKind, TypeIrInherentUsage,
|
SymbolInternStringLiteralDiag, TyQualified, TykindDiag, TykindKind, TypeIrInherentUsage,
|
||||||
UntranslatableDiag,
|
TypeIrTraitUsage, UntranslatableDiag,
|
||||||
};
|
};
|
||||||
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
||||||
|
|
||||||
@ -37,9 +34,12 @@ declare_tool_lint! {
|
|||||||
declare_lint_pass!(DefaultHashTypes => [DEFAULT_HASH_TYPES]);
|
declare_lint_pass!(DefaultHashTypes => [DEFAULT_HASH_TYPES]);
|
||||||
|
|
||||||
impl LateLintPass<'_> for DefaultHashTypes {
|
impl LateLintPass<'_> for DefaultHashTypes {
|
||||||
fn check_path(&mut self, cx: &LateContext<'_>, path: &Path<'_>, hir_id: HirId) {
|
fn check_path(&mut self, cx: &LateContext<'_>, path: &hir::Path<'_>, hir_id: HirId) {
|
||||||
let Res::Def(rustc_hir::def::DefKind::Struct, def_id) = path.res else { return };
|
let Res::Def(rustc_hir::def::DefKind::Struct, def_id) = path.res else { return };
|
||||||
if matches!(cx.tcx.hir_node(hir_id), Node::Item(Item { kind: ItemKind::Use(..), .. })) {
|
if matches!(
|
||||||
|
cx.tcx.hir_node(hir_id),
|
||||||
|
hir::Node::Item(hir::Item { kind: hir::ItemKind::Use(..), .. })
|
||||||
|
) {
|
||||||
// Don't lint imports, only actual usages.
|
// Don't lint imports, only actual usages.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -60,10 +60,10 @@ impl LateLintPass<'_> for DefaultHashTypes {
|
|||||||
/// get the `DefId` and `GenericArgsRef` of the function.
|
/// get the `DefId` and `GenericArgsRef` of the function.
|
||||||
fn typeck_results_of_method_fn<'tcx>(
|
fn typeck_results_of_method_fn<'tcx>(
|
||||||
cx: &LateContext<'tcx>,
|
cx: &LateContext<'tcx>,
|
||||||
expr: &Expr<'_>,
|
expr: &hir::Expr<'_>,
|
||||||
) -> Option<(Span, DefId, ty::GenericArgsRef<'tcx>)> {
|
) -> Option<(Span, DefId, ty::GenericArgsRef<'tcx>)> {
|
||||||
match expr.kind {
|
match expr.kind {
|
||||||
ExprKind::MethodCall(segment, ..)
|
hir::ExprKind::MethodCall(segment, ..)
|
||||||
if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) =>
|
if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) =>
|
||||||
{
|
{
|
||||||
Some((segment.ident.span, def_id, cx.typeck_results().node_args(expr.hir_id)))
|
Some((segment.ident.span, def_id, cx.typeck_results().node_args(expr.hir_id)))
|
||||||
@ -102,7 +102,7 @@ declare_tool_lint! {
|
|||||||
declare_lint_pass!(QueryStability => [POTENTIAL_QUERY_INSTABILITY, UNTRACKED_QUERY_INFORMATION]);
|
declare_lint_pass!(QueryStability => [POTENTIAL_QUERY_INSTABILITY, UNTRACKED_QUERY_INFORMATION]);
|
||||||
|
|
||||||
impl LateLintPass<'_> for QueryStability {
|
impl LateLintPass<'_> for QueryStability {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) {
|
||||||
let Some((span, def_id, args)) = typeck_results_of_method_fn(cx, expr) else { return };
|
let Some((span, def_id, args)) = typeck_results_of_method_fn(cx, expr) else { return };
|
||||||
if let Ok(Some(instance)) = ty::Instance::try_resolve(cx.tcx, cx.typing_env(), def_id, args)
|
if let Ok(Some(instance)) = ty::Instance::try_resolve(cx.tcx, cx.typing_env(), def_id, args)
|
||||||
{
|
{
|
||||||
@ -164,21 +164,25 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx Ty<'tcx, AmbigArg>) {
|
fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx, hir::AmbigArg>) {
|
||||||
match &ty.kind {
|
match &ty.kind {
|
||||||
TyKind::Path(QPath::Resolved(_, path)) => {
|
hir::TyKind::Path(hir::QPath::Resolved(_, path)) => {
|
||||||
if lint_ty_kind_usage(cx, &path.res) {
|
if lint_ty_kind_usage(cx, &path.res) {
|
||||||
let span = match cx.tcx.parent_hir_node(ty.hir_id) {
|
let span = match cx.tcx.parent_hir_node(ty.hir_id) {
|
||||||
Node::PatExpr(PatExpr { kind: PatExprKind::Path(qpath), .. })
|
hir::Node::PatExpr(hir::PatExpr {
|
||||||
| Node::Pat(Pat {
|
kind: hir::PatExprKind::Path(qpath),
|
||||||
kind: PatKind::TupleStruct(qpath, ..) | PatKind::Struct(qpath, ..),
|
|
||||||
..
|
..
|
||||||
})
|
})
|
||||||
| Node::Expr(
|
| hir::Node::Pat(hir::Pat {
|
||||||
Expr { kind: ExprKind::Path(qpath), .. }
|
kind:
|
||||||
| &Expr { kind: ExprKind::Struct(qpath, ..), .. },
|
hir::PatKind::TupleStruct(qpath, ..) | hir::PatKind::Struct(qpath, ..),
|
||||||
|
..
|
||||||
|
})
|
||||||
|
| hir::Node::Expr(
|
||||||
|
hir::Expr { kind: hir::ExprKind::Path(qpath), .. }
|
||||||
|
| &hir::Expr { kind: hir::ExprKind::Struct(qpath, ..), .. },
|
||||||
) => {
|
) => {
|
||||||
if let QPath::TypeRelative(qpath_ty, ..) = qpath
|
if let hir::QPath::TypeRelative(qpath_ty, ..) = qpath
|
||||||
&& qpath_ty.hir_id == ty.hir_id
|
&& qpath_ty.hir_id == ty.hir_id
|
||||||
{
|
{
|
||||||
Some(path.span)
|
Some(path.span)
|
||||||
@ -223,7 +227,7 @@ fn lint_ty_kind_usage(cx: &LateContext<'_>, res: &Res) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, path: &Path<'_>) -> Option<String> {
|
fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, path: &hir::Path<'_>) -> Option<String> {
|
||||||
match &path.res {
|
match &path.res {
|
||||||
Res::Def(_, def_id) => {
|
Res::Def(_, def_id) => {
|
||||||
if let Some(name @ (sym::Ty | sym::TyCtxt)) = cx.tcx.get_diagnostic_name(*def_id) {
|
if let Some(name @ (sym::Ty | sym::TyCtxt)) = cx.tcx.get_diagnostic_name(*def_id) {
|
||||||
@ -244,13 +248,17 @@ fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, path: &Path<'_>) -> Option<String> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_args(segment: &PathSegment<'_>) -> String {
|
fn gen_args(segment: &hir::PathSegment<'_>) -> String {
|
||||||
if let Some(args) = &segment.args {
|
if let Some(args) = &segment.args {
|
||||||
let lifetimes = args
|
let lifetimes = args
|
||||||
.args
|
.args
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|arg| {
|
.filter_map(|arg| {
|
||||||
if let GenericArg::Lifetime(lt) = arg { Some(lt.ident.to_string()) } else { None }
|
if let hir::GenericArg::Lifetime(lt) = arg {
|
||||||
|
Some(lt.ident.to_string())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
@ -272,7 +280,7 @@ declare_tool_lint! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
declare_tool_lint! {
|
declare_tool_lint! {
|
||||||
/// The `usage_of_type_ir_inherent` lint detects usage `rustc_type_ir::inherent`.
|
/// The `usage_of_type_ir_inherent` lint detects usage of `rustc_type_ir::inherent`.
|
||||||
///
|
///
|
||||||
/// This module should only be used within the trait solver.
|
/// This module should only be used within the trait solver.
|
||||||
pub rustc::USAGE_OF_TYPE_IR_INHERENT,
|
pub rustc::USAGE_OF_TYPE_IR_INHERENT,
|
||||||
@ -281,10 +289,43 @@ declare_tool_lint! {
|
|||||||
report_in_external_macro: true
|
report_in_external_macro: true
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint_pass!(TypeIr => [NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT, USAGE_OF_TYPE_IR_INHERENT]);
|
declare_tool_lint! {
|
||||||
|
/// The `usage_of_type_ir_traits` lint detects usage of `rustc_type_ir::Interner`,
|
||||||
|
/// or `rustc_infer::InferCtxtLike`.
|
||||||
|
///
|
||||||
|
/// Methods of this trait should only be used within the type system abstraction layer,
|
||||||
|
/// and in the generic next trait solver implementation. Look for an analogously named
|
||||||
|
/// method on `TyCtxt` or `InferCtxt` (respectively).
|
||||||
|
pub rustc::USAGE_OF_TYPE_IR_TRAITS,
|
||||||
|
Allow,
|
||||||
|
"usage `rustc_type_ir`-specific abstraction traits 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]);
|
||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for TypeIr {
|
impl<'tcx> LateLintPass<'tcx> for TypeIr {
|
||||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
|
||||||
|
let res_def_id = match expr.kind {
|
||||||
|
hir::ExprKind::Path(hir::QPath::Resolved(_, path)) => path.res.opt_def_id(),
|
||||||
|
hir::ExprKind::Path(hir::QPath::TypeRelative(..)) | hir::ExprKind::MethodCall(..) => {
|
||||||
|
cx.typeck_results().type_dependent_def_id(expr.hir_id)
|
||||||
|
}
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
let Some(res_def_id) = res_def_id else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if let Some(assoc_item) = cx.tcx.opt_associated_item(res_def_id)
|
||||||
|
&& let Some(trait_def_id) = assoc_item.trait_container(cx.tcx)
|
||||||
|
&& (cx.tcx.is_diagnostic_item(sym::type_ir_interner, trait_def_id)
|
||||||
|
| cx.tcx.is_diagnostic_item(sym::type_ir_infer_ctxt_like, trait_def_id))
|
||||||
|
{
|
||||||
|
cx.emit_span_lint(USAGE_OF_TYPE_IR_TRAITS, expr.span, TypeIrTraitUsage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
||||||
let rustc_hir::ItemKind::Use(path, kind) = item.kind else { return };
|
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 is_mod_inherent = |def_id| cx.tcx.is_diagnostic_item(sym::type_ir_inherent, def_id);
|
||||||
@ -394,15 +435,15 @@ declare_tool_lint! {
|
|||||||
declare_lint_pass!(Diagnostics => [UNTRANSLATABLE_DIAGNOSTIC, DIAGNOSTIC_OUTSIDE_OF_IMPL]);
|
declare_lint_pass!(Diagnostics => [UNTRANSLATABLE_DIAGNOSTIC, DIAGNOSTIC_OUTSIDE_OF_IMPL]);
|
||||||
|
|
||||||
impl LateLintPass<'_> for Diagnostics {
|
impl LateLintPass<'_> for Diagnostics {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) {
|
||||||
let collect_args_tys_and_spans = |args: &[Expr<'_>], reserve_one_extra: bool| {
|
let collect_args_tys_and_spans = |args: &[hir::Expr<'_>], reserve_one_extra: bool| {
|
||||||
let mut result = Vec::with_capacity(args.len() + usize::from(reserve_one_extra));
|
let mut result = Vec::with_capacity(args.len() + usize::from(reserve_one_extra));
|
||||||
result.extend(args.iter().map(|arg| (cx.typeck_results().expr_ty(arg), arg.span)));
|
result.extend(args.iter().map(|arg| (cx.typeck_results().expr_ty(arg), arg.span)));
|
||||||
result
|
result
|
||||||
};
|
};
|
||||||
// Only check function calls and method calls.
|
// Only check function calls and method calls.
|
||||||
let (span, def_id, fn_gen_args, arg_tys_and_spans) = match expr.kind {
|
let (span, def_id, fn_gen_args, arg_tys_and_spans) = match expr.kind {
|
||||||
ExprKind::Call(callee, args) => {
|
hir::ExprKind::Call(callee, args) => {
|
||||||
match cx.typeck_results().node_type(callee.hir_id).kind() {
|
match cx.typeck_results().node_type(callee.hir_id).kind() {
|
||||||
&ty::FnDef(def_id, fn_gen_args) => {
|
&ty::FnDef(def_id, fn_gen_args) => {
|
||||||
(callee.span, def_id, fn_gen_args, collect_args_tys_and_spans(args, false))
|
(callee.span, def_id, fn_gen_args, collect_args_tys_and_spans(args, false))
|
||||||
@ -410,7 +451,7 @@ impl LateLintPass<'_> for Diagnostics {
|
|||||||
_ => return, // occurs for fns passed as args
|
_ => return, // occurs for fns passed as args
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::MethodCall(_segment, _recv, args, _span) => {
|
hir::ExprKind::MethodCall(_segment, _recv, args, _span) => {
|
||||||
let Some((span, def_id, fn_gen_args)) = typeck_results_of_method_fn(cx, expr)
|
let Some((span, def_id, fn_gen_args)) = typeck_results_of_method_fn(cx, expr)
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
@ -514,8 +555,8 @@ impl Diagnostics {
|
|||||||
let mut is_inside_appropriate_impl = false;
|
let mut is_inside_appropriate_impl = false;
|
||||||
for (_hir_id, parent) in cx.tcx.hir_parent_iter(current_id) {
|
for (_hir_id, parent) in cx.tcx.hir_parent_iter(current_id) {
|
||||||
debug!(?parent);
|
debug!(?parent);
|
||||||
if let Node::Item(Item { kind: ItemKind::Impl(impl_), .. }) = parent
|
if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) = parent
|
||||||
&& let Impl { of_trait: Some(of_trait), .. } = impl_
|
&& let hir::Impl { of_trait: Some(of_trait), .. } = impl_
|
||||||
&& let Some(def_id) = of_trait.trait_def_id()
|
&& let Some(def_id) = of_trait.trait_def_id()
|
||||||
&& let Some(name) = cx.tcx.get_diagnostic_name(def_id)
|
&& let Some(name) = cx.tcx.get_diagnostic_name(def_id)
|
||||||
&& matches!(name, sym::Diagnostic | sym::Subdiagnostic | sym::LintDiagnostic)
|
&& matches!(name, sym::Diagnostic | sym::Subdiagnostic | sym::LintDiagnostic)
|
||||||
@ -543,8 +584,8 @@ declare_tool_lint! {
|
|||||||
declare_lint_pass!(BadOptAccess => [BAD_OPT_ACCESS]);
|
declare_lint_pass!(BadOptAccess => [BAD_OPT_ACCESS]);
|
||||||
|
|
||||||
impl LateLintPass<'_> for BadOptAccess {
|
impl LateLintPass<'_> for BadOptAccess {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) {
|
||||||
let ExprKind::Field(base, target) = expr.kind else { return };
|
let hir::ExprKind::Field(base, target) = expr.kind else { return };
|
||||||
let Some(adt_def) = cx.typeck_results().expr_ty(base).ty_adt_def() else { return };
|
let Some(adt_def) = cx.typeck_results().expr_ty(base).ty_adt_def() else { return };
|
||||||
// Skip types without `#[rustc_lint_opt_ty]` - only so that the rest of the lint can be
|
// Skip types without `#[rustc_lint_opt_ty]` - only so that the rest of the lint can be
|
||||||
// avoided.
|
// avoided.
|
||||||
@ -581,9 +622,12 @@ declare_tool_lint! {
|
|||||||
declare_lint_pass!(SpanUseEqCtxt => [SPAN_USE_EQ_CTXT]);
|
declare_lint_pass!(SpanUseEqCtxt => [SPAN_USE_EQ_CTXT]);
|
||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for SpanUseEqCtxt {
|
impl<'tcx> LateLintPass<'tcx> for SpanUseEqCtxt {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &hir::Expr<'_>) {
|
||||||
if let ExprKind::Binary(BinOp { node: BinOpKind::Eq | BinOpKind::Ne, .. }, lhs, rhs) =
|
if let hir::ExprKind::Binary(
|
||||||
expr.kind
|
hir::BinOp { node: hir::BinOpKind::Eq | hir::BinOpKind::Ne, .. },
|
||||||
|
lhs,
|
||||||
|
rhs,
|
||||||
|
) = expr.kind
|
||||||
{
|
{
|
||||||
if is_span_ctxt_call(cx, lhs) && is_span_ctxt_call(cx, rhs) {
|
if is_span_ctxt_call(cx, lhs) && is_span_ctxt_call(cx, rhs) {
|
||||||
cx.emit_span_lint(SPAN_USE_EQ_CTXT, expr.span, SpanUseEqCtxtDiag);
|
cx.emit_span_lint(SPAN_USE_EQ_CTXT, expr.span, SpanUseEqCtxtDiag);
|
||||||
@ -592,9 +636,9 @@ impl<'tcx> LateLintPass<'tcx> for SpanUseEqCtxt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_span_ctxt_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
fn is_span_ctxt_call(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
|
||||||
match &expr.kind {
|
match &expr.kind {
|
||||||
ExprKind::MethodCall(..) => cx
|
hir::ExprKind::MethodCall(..) => cx
|
||||||
.typeck_results()
|
.typeck_results()
|
||||||
.type_dependent_def_id(expr.hir_id)
|
.type_dependent_def_id(expr.hir_id)
|
||||||
.is_some_and(|call_did| cx.tcx.is_diagnostic_item(sym::SpanCtxt, call_did)),
|
.is_some_and(|call_did| cx.tcx.is_diagnostic_item(sym::SpanCtxt, call_did)),
|
||||||
@ -617,11 +661,11 @@ declare_lint_pass!(SymbolInternStringLiteral => [SYMBOL_INTERN_STRING_LITERAL]);
|
|||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for SymbolInternStringLiteral {
|
impl<'tcx> LateLintPass<'tcx> for SymbolInternStringLiteral {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
|
||||||
if let ExprKind::Call(path, [arg]) = expr.kind
|
if let hir::ExprKind::Call(path, [arg]) = expr.kind
|
||||||
&& let ExprKind::Path(ref qpath) = path.kind
|
&& let hir::ExprKind::Path(ref qpath) = path.kind
|
||||||
&& let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
|
&& let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
|
||||||
&& cx.tcx.is_diagnostic_item(sym::SymbolIntern, def_id)
|
&& cx.tcx.is_diagnostic_item(sym::SymbolIntern, def_id)
|
||||||
&& let ExprKind::Lit(kind) = arg.kind
|
&& let hir::ExprKind::Lit(kind) = arg.kind
|
||||||
&& let rustc_ast::LitKind::Str(_, _) = kind.node
|
&& let rustc_ast::LitKind::Str(_, _) = kind.node
|
||||||
{
|
{
|
||||||
cx.emit_span_lint(
|
cx.emit_span_lint(
|
||||||
|
@ -645,6 +645,7 @@ fn register_internals(store: &mut LintStore) {
|
|||||||
LintId::of(USAGE_OF_QUALIFIED_TY),
|
LintId::of(USAGE_OF_QUALIFIED_TY),
|
||||||
LintId::of(NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT),
|
LintId::of(NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT),
|
||||||
LintId::of(USAGE_OF_TYPE_IR_INHERENT),
|
LintId::of(USAGE_OF_TYPE_IR_INHERENT),
|
||||||
|
LintId::of(USAGE_OF_TYPE_IR_TRAITS),
|
||||||
LintId::of(BAD_OPT_ACCESS),
|
LintId::of(BAD_OPT_ACCESS),
|
||||||
LintId::of(SPAN_USE_EQ_CTXT),
|
LintId::of(SPAN_USE_EQ_CTXT),
|
||||||
],
|
],
|
||||||
|
@ -943,6 +943,11 @@ pub(crate) struct TyQualified {
|
|||||||
#[note]
|
#[note]
|
||||||
pub(crate) struct TypeIrInherentUsage;
|
pub(crate) struct TypeIrInherentUsage;
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(lint_type_ir_trait_usage)]
|
||||||
|
#[note]
|
||||||
|
pub(crate) struct TypeIrTraitUsage;
|
||||||
|
|
||||||
#[derive(LintDiagnostic)]
|
#[derive(LintDiagnostic)]
|
||||||
#[diag(lint_non_glob_import_type_ir_inherent)]
|
#[diag(lint_non_glob_import_type_ir_inherent)]
|
||||||
pub(crate) struct NonGlobImportTypeIrInherent {
|
pub(crate) struct NonGlobImportTypeIrInherent {
|
||||||
|
@ -225,8 +225,8 @@ use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion};
|
|||||||
use rustc_middle::ty::layout::ValidityRequirement;
|
use rustc_middle::ty::layout::ValidityRequirement;
|
||||||
use rustc_middle::ty::print::{shrunk_instance_name, with_no_trimmed_paths};
|
use rustc_middle::ty::print::{shrunk_instance_name, with_no_trimmed_paths};
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, GenericArgs, GenericParamDefKind, Instance, InstanceKind, Interner, Ty, TyCtxt,
|
self, GenericArgs, GenericParamDefKind, Instance, InstanceKind, Ty, TyCtxt, TypeFoldable,
|
||||||
TypeFoldable, TypeVisitableExt, VtblEntry,
|
TypeVisitableExt, VtblEntry,
|
||||||
};
|
};
|
||||||
use rustc_middle::util::Providers;
|
use rustc_middle::util::Providers;
|
||||||
use rustc_middle::{bug, span_bug};
|
use rustc_middle::{bug, span_bug};
|
||||||
@ -967,7 +967,7 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) ->
|
|||||||
{
|
{
|
||||||
// `#[rustc_force_inline]` items should never be codegened. This should be caught by
|
// `#[rustc_force_inline]` items should never be codegened. This should be caught by
|
||||||
// the MIR validator.
|
// the MIR validator.
|
||||||
tcx.delay_bug("attempt to codegen `#[rustc_force_inline]` item");
|
tcx.dcx().delayed_bug("attempt to codegen `#[rustc_force_inline]` item");
|
||||||
}
|
}
|
||||||
|
|
||||||
if def_id.is_local() {
|
if def_id.is_local() {
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
// tidy-alphabetical-start
|
// tidy-alphabetical-start
|
||||||
#![allow(rustc::usage_of_type_ir_inherent)]
|
#![allow(rustc::usage_of_type_ir_inherent)]
|
||||||
|
#![cfg_attr(not(bootstrap), allow(rustc::usage_of_type_ir_traits))]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
pub mod canonicalizer;
|
pub mod canonicalizer;
|
||||||
|
@ -2118,7 +2118,9 @@ symbols! {
|
|||||||
type_changing_struct_update,
|
type_changing_struct_update,
|
||||||
type_const,
|
type_const,
|
||||||
type_id,
|
type_id,
|
||||||
|
type_ir_infer_ctxt_like,
|
||||||
type_ir_inherent,
|
type_ir_inherent,
|
||||||
|
type_ir_interner,
|
||||||
type_length_limit,
|
type_length_limit,
|
||||||
type_macros,
|
type_macros,
|
||||||
type_name,
|
type_name,
|
||||||
|
@ -16,7 +16,7 @@ use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError};
|
|||||||
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
|
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
|
||||||
use rustc_middle::ty::{self, Ty, TypeVisitableExt, TypingMode};
|
use rustc_middle::ty::{self, Ty, TypeVisitableExt, TypingMode};
|
||||||
use rustc_middle::{bug, span_bug};
|
use rustc_middle::{bug, span_bug};
|
||||||
use rustc_type_ir::{Interner, elaborate};
|
use rustc_type_ir::elaborate;
|
||||||
use tracing::{debug, instrument, trace};
|
use tracing::{debug, instrument, trace};
|
||||||
|
|
||||||
use super::SelectionCandidate::*;
|
use super::SelectionCandidate::*;
|
||||||
@ -802,7 +802,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
| ty::UnsafeBinder(_) => {
|
| ty::UnsafeBinder(_) => {
|
||||||
// Only consider auto impls of unsafe traits when there are
|
// Only consider auto impls of unsafe traits when there are
|
||||||
// no unsafe fields.
|
// no unsafe fields.
|
||||||
if self.tcx().trait_is_unsafe(def_id) && self_ty.has_unsafe_fields() {
|
if self.tcx().trait_def(def_id).safety.is_unsafe()
|
||||||
|
&& self_ty.has_unsafe_fields()
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +102,7 @@ impl<I: Interner> TypingMode<I> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "type_ir_infer_ctxt_like")]
|
||||||
pub trait InferCtxtLike: Sized {
|
pub trait InferCtxtLike: Sized {
|
||||||
type Interner: Interner;
|
type Interner: Interner;
|
||||||
fn cx(&self) -> Self::Interner;
|
fn cx(&self) -> Self::Interner;
|
||||||
|
@ -15,6 +15,7 @@ use crate::solve::{CanonicalInput, ExternalConstraintsData, PredefinedOpaquesDat
|
|||||||
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
|
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
|
||||||
use crate::{self as ty, search_graph};
|
use crate::{self as ty, search_graph};
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "type_ir_interner")]
|
||||||
pub trait Interner:
|
pub trait Interner:
|
||||||
Sized
|
Sized
|
||||||
+ Copy
|
+ Copy
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
feature(associated_type_defaults, never_type, rustc_attrs, negative_impls)
|
feature(associated_type_defaults, never_type, rustc_attrs, negative_impls)
|
||||||
)]
|
)]
|
||||||
#![cfg_attr(feature = "nightly", allow(internal_features))]
|
#![cfg_attr(feature = "nightly", allow(internal_features))]
|
||||||
|
#![cfg_attr(not(bootstrap), allow(rustc::usage_of_type_ir_traits))]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
extern crate self as rustc_type_ir;
|
extern crate self as rustc_type_ir;
|
||||||
|
16
tests/ui-fulldeps/internal-lints/import-of-type-ir-traits.rs
Normal file
16
tests/ui-fulldeps/internal-lints/import-of-type-ir-traits.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
//@ compile-flags: -Z unstable-options
|
||||||
|
//@ ignore-stage1
|
||||||
|
|
||||||
|
#![feature(rustc_private)]
|
||||||
|
#![deny(rustc::usage_of_type_ir_traits)]
|
||||||
|
|
||||||
|
extern crate rustc_type_ir;
|
||||||
|
|
||||||
|
use rustc_type_ir::Interner;
|
||||||
|
|
||||||
|
fn foo<I: Interner>(cx: I, did: I::DefId) {
|
||||||
|
let _ = cx.trait_is_unsafe(did);
|
||||||
|
//~^ ERROR do not use `rustc_type_ir::Interner` or `rustc_type_ir::InferCtxtLike` unless you're inside of the trait solver
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,15 @@
|
|||||||
|
error: do not use `rustc_type_ir::Interner` or `rustc_type_ir::InferCtxtLike` unless you're inside of the trait solver
|
||||||
|
--> $DIR/import-of-type-ir-traits.rs:12:13
|
||||||
|
|
|
||||||
|
LL | let _ = cx.trait_is_unsafe(did);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= 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-traits.rs:5:9
|
||||||
|
|
|
||||||
|
LL | #![deny(rustc::usage_of_type_ir_traits)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
Loading…
Reference in New Issue
Block a user