@@ -15,7 +15,7 @@ use crate::lints::{
1515 BadOptAccessDiag , DefaultHashTypesDiag , DiagOutOfImpl , LintPassByHand ,
1616 NonGlobImportTypeIrInherent , QueryInstability , QueryUntracked , SpanUseEqCtxtDiag ,
1717 SymbolInternStringLiteralDiag , TyQualified , TykindDiag , TykindKind , TypeIrInherentUsage ,
18- UntranslatableDiag ,
18+ TypeIrTraitUsage , UntranslatableDiag ,
1919} ;
2020use crate :: { EarlyContext , EarlyLintPass , LateContext , LateLintPass , LintContext } ;
2121
@@ -280,7 +280,7 @@ declare_tool_lint! {
280280}
281281
282282declare_tool_lint ! {
283- /// The `usage_of_type_ir_inherent` lint detects usage `rustc_type_ir::inherent`.
283+ /// The `usage_of_type_ir_inherent` lint detects usage of `rustc_type_ir::inherent`.
284284 ///
285285 /// This module should only be used within the trait solver.
286286 pub rustc:: USAGE_OF_TYPE_IR_INHERENT ,
@@ -289,9 +289,42 @@ declare_tool_lint! {
289289 report_in_external_macro: true
290290}
291291
292- declare_lint_pass ! ( TypeIr => [ NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT , USAGE_OF_TYPE_IR_INHERENT ] ) ;
292+ declare_tool_lint ! {
293+ /// The `usage_of_type_ir_traits` lint detects usage of `rustc_type_ir::Interner`,
294+ /// or `rustc_infer::InferCtxtLike`.
295+ ///
296+ /// Methods of this trait should only be used within the type system abstraction layer,
297+ /// and in the generic next trait solver implementation. Look for an analogously named
298+ /// method on `TyCtxt` or `InferCtxt` (respectively).
299+ pub rustc:: USAGE_OF_TYPE_IR_TRAITS ,
300+ Allow ,
301+ "usage `rustc_type_ir`-specific abstraction traits outside of trait system" ,
302+ report_in_external_macro: true
303+ }
304+
305+ declare_lint_pass ! ( TypeIr => [ NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT , USAGE_OF_TYPE_IR_INHERENT , USAGE_OF_TYPE_IR_TRAITS ] ) ;
293306
294307impl < ' tcx > LateLintPass < ' tcx > for TypeIr {
308+ fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx hir:: Expr < ' tcx > ) {
309+ let res_def_id = match expr. kind {
310+ hir:: ExprKind :: Path ( hir:: QPath :: Resolved ( _, path) ) => path. res . opt_def_id ( ) ,
311+ hir:: ExprKind :: Path ( hir:: QPath :: TypeRelative ( ..) ) | hir:: ExprKind :: MethodCall ( ..) => {
312+ cx. typeck_results ( ) . type_dependent_def_id ( expr. hir_id )
313+ }
314+ _ => return ,
315+ } ;
316+ let Some ( res_def_id) = res_def_id else {
317+ return ;
318+ } ;
319+ if let Some ( assoc_item) = cx. tcx . opt_associated_item ( res_def_id)
320+ && let Some ( trait_def_id) = assoc_item. trait_container ( cx. tcx )
321+ && ( cx. tcx . is_diagnostic_item ( sym:: type_ir_interner, trait_def_id)
322+ | cx. tcx . is_diagnostic_item ( sym:: type_ir_infer_ctxt_like, trait_def_id) )
323+ {
324+ cx. emit_span_lint ( USAGE_OF_TYPE_IR_TRAITS , expr. span , TypeIrTraitUsage ) ;
325+ }
326+ }
327+
295328 fn check_item ( & mut self , cx : & LateContext < ' tcx > , item : & ' tcx hir:: Item < ' tcx > ) {
296329 let rustc_hir:: ItemKind :: Use ( path, kind) = item. kind else { return } ;
297330
0 commit comments