11//! Some lints that are only useful in the compiler or crates that use compiler internals, such as
22//! Clippy.
33
4- use rustc_ast as ast ;
4+ use rustc_hir :: HirId ;
55use rustc_hir:: def:: Res ;
66use rustc_hir:: def_id:: DefId ;
7- use rustc_hir:: {
8- AmbigArg , BinOp , BinOpKind , Expr , ExprKind , GenericArg , HirId , Impl , Item , ItemKind , Node , Pat ,
9- PatExpr , PatExprKind , PatKind , Path , PathSegment , QPath , Ty , TyKind ,
10- } ;
117use rustc_middle:: ty:: { self , GenericArgsRef , Ty as MiddleTy } ;
128use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
139use rustc_span:: hygiene:: { ExpnKind , MacroKind } ;
1410use rustc_span:: { Span , sym} ;
1511use tracing:: debug;
12+ use { rustc_ast as ast, rustc_hir as hir} ;
1613
1714use crate :: lints:: {
1815 BadOptAccessDiag , DefaultHashTypesDiag , DiagOutOfImpl , LintPassByHand ,
1916 NonGlobImportTypeIrInherent , QueryInstability , QueryUntracked , SpanUseEqCtxtDiag ,
2017 SymbolInternStringLiteralDiag , TyQualified , TykindDiag , TykindKind , TypeIrInherentUsage ,
21- UntranslatableDiag ,
18+ TypeIrTraitUsage , UntranslatableDiag ,
2219} ;
2320use crate :: { EarlyContext , EarlyLintPass , LateContext , LateLintPass , LintContext } ;
2421
@@ -37,9 +34,12 @@ declare_tool_lint! {
3734declare_lint_pass ! ( DefaultHashTypes => [ DEFAULT_HASH_TYPES ] ) ;
3835
3936impl LateLintPass < ' _ > for DefaultHashTypes {
40- fn check_path ( & mut self , cx : & LateContext < ' _ > , path : & Path < ' _ > , hir_id : HirId ) {
37+ fn check_path ( & mut self , cx : & LateContext < ' _ > , path : & hir :: Path < ' _ > , hir_id : HirId ) {
4138 let Res :: Def ( rustc_hir:: def:: DefKind :: Struct , def_id) = path. res else { return } ;
42- if matches ! ( cx. tcx. hir_node( hir_id) , Node :: Item ( Item { kind: ItemKind :: Use ( ..) , .. } ) ) {
39+ if matches ! (
40+ cx. tcx. hir_node( hir_id) ,
41+ hir:: Node :: Item ( hir:: Item { kind: hir:: ItemKind :: Use ( ..) , .. } )
42+ ) {
4343 // Don't lint imports, only actual usages.
4444 return ;
4545 }
@@ -60,10 +60,10 @@ impl LateLintPass<'_> for DefaultHashTypes {
6060/// get the `DefId` and `GenericArgsRef` of the function.
6161fn typeck_results_of_method_fn < ' tcx > (
6262 cx : & LateContext < ' tcx > ,
63- expr : & Expr < ' _ > ,
63+ expr : & hir :: Expr < ' _ > ,
6464) -> Option < ( Span , DefId , ty:: GenericArgsRef < ' tcx > ) > {
6565 match expr. kind {
66- ExprKind :: MethodCall ( segment, ..)
66+ hir :: ExprKind :: MethodCall ( segment, ..)
6767 if let Some ( def_id) = cx. typeck_results ( ) . type_dependent_def_id ( expr. hir_id ) =>
6868 {
6969 Some ( ( segment. ident . span , def_id, cx. typeck_results ( ) . node_args ( expr. hir_id ) ) )
@@ -102,7 +102,7 @@ declare_tool_lint! {
102102declare_lint_pass ! ( QueryStability => [ POTENTIAL_QUERY_INSTABILITY , UNTRACKED_QUERY_INFORMATION ] ) ;
103103
104104impl LateLintPass < ' _ > for QueryStability {
105- fn check_expr ( & mut self , cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) {
105+ fn check_expr ( & mut self , cx : & LateContext < ' _ > , expr : & hir :: Expr < ' _ > ) {
106106 let Some ( ( span, def_id, args) ) = typeck_results_of_method_fn ( cx, expr) else { return } ;
107107 if let Ok ( Some ( instance) ) = ty:: Instance :: try_resolve ( cx. tcx , cx. typing_env ( ) , def_id, args)
108108 {
@@ -164,21 +164,25 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
164164 }
165165 }
166166
167- fn check_ty ( & mut self , cx : & LateContext < ' _ > , ty : & ' tcx Ty < ' tcx , AmbigArg > ) {
167+ fn check_ty ( & mut self , cx : & LateContext < ' _ > , ty : & ' tcx hir :: Ty < ' tcx , hir :: AmbigArg > ) {
168168 match & ty. kind {
169- TyKind :: Path ( QPath :: Resolved ( _, path) ) => {
169+ hir :: TyKind :: Path ( hir :: QPath :: Resolved ( _, path) ) => {
170170 if lint_ty_kind_usage ( cx, & path. res ) {
171171 let span = match cx. tcx . parent_hir_node ( ty. hir_id ) {
172- Node :: PatExpr ( PatExpr { kind : PatExprKind :: Path ( qpath) , .. } )
173- | Node :: Pat ( Pat {
174- kind : PatKind :: TupleStruct ( qpath, ..) | PatKind :: Struct ( qpath, ..) ,
172+ hir:: Node :: PatExpr ( hir:: PatExpr {
173+ kind : hir:: PatExprKind :: Path ( qpath) ,
174+ ..
175+ } )
176+ | hir:: Node :: Pat ( hir:: Pat {
177+ kind :
178+ hir:: PatKind :: TupleStruct ( qpath, ..) | hir:: PatKind :: Struct ( qpath, ..) ,
175179 ..
176180 } )
177- | Node :: Expr (
178- Expr { kind : ExprKind :: Path ( qpath) , .. }
179- | & Expr { kind : ExprKind :: Struct ( qpath, ..) , .. } ,
181+ | hir :: Node :: Expr (
182+ hir :: Expr { kind : hir :: ExprKind :: Path ( qpath) , .. }
183+ | & hir :: Expr { kind : hir :: ExprKind :: Struct ( qpath, ..) , .. } ,
180184 ) => {
181- if let QPath :: TypeRelative ( qpath_ty, ..) = qpath
185+ if let hir :: QPath :: TypeRelative ( qpath_ty, ..) = qpath
182186 && qpath_ty. hir_id == ty. hir_id
183187 {
184188 Some ( path. span )
@@ -223,7 +227,7 @@ fn lint_ty_kind_usage(cx: &LateContext<'_>, res: &Res) -> bool {
223227 }
224228}
225229
226- fn is_ty_or_ty_ctxt ( cx : & LateContext < ' _ > , path : & Path < ' _ > ) -> Option < String > {
230+ fn is_ty_or_ty_ctxt ( cx : & LateContext < ' _ > , path : & hir :: Path < ' _ > ) -> Option < String > {
227231 match & path. res {
228232 Res :: Def ( _, def_id) => {
229233 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> {
244248 None
245249}
246250
247- fn gen_args ( segment : & PathSegment < ' _ > ) -> String {
251+ fn gen_args ( segment : & hir :: PathSegment < ' _ > ) -> String {
248252 if let Some ( args) = & segment. args {
249253 let lifetimes = args
250254 . args
251255 . iter ( )
252256 . filter_map ( |arg| {
253- if let GenericArg :: Lifetime ( lt) = arg { Some ( lt. ident . to_string ( ) ) } else { None }
257+ if let hir:: GenericArg :: Lifetime ( lt) = arg {
258+ Some ( lt. ident . to_string ( ) )
259+ } else {
260+ None
261+ }
254262 } )
255263 . collect :: < Vec < _ > > ( ) ;
256264
@@ -272,7 +280,7 @@ declare_tool_lint! {
272280}
273281
274282declare_tool_lint ! {
275- /// 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`.
276284 ///
277285 /// This module should only be used within the trait solver.
278286 pub rustc:: USAGE_OF_TYPE_IR_INHERENT ,
@@ -281,10 +289,43 @@ declare_tool_lint! {
281289 report_in_external_macro: true
282290}
283291
284- 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 ] ) ;
285306
286307impl < ' tcx > LateLintPass < ' tcx > for TypeIr {
287- fn check_item ( & mut self , cx : & LateContext < ' tcx > , item : & ' tcx Item < ' tcx > ) {
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+
328+ fn check_item ( & mut self , cx : & LateContext < ' tcx > , item : & ' tcx hir:: Item < ' tcx > ) {
288329 let rustc_hir:: ItemKind :: Use ( path, kind) = item. kind else { return } ;
289330
290331 let is_mod_inherent = |def_id| cx. tcx . is_diagnostic_item ( sym:: type_ir_inherent, def_id) ;
@@ -394,23 +435,23 @@ declare_tool_lint! {
394435declare_lint_pass ! ( Diagnostics => [ UNTRANSLATABLE_DIAGNOSTIC , DIAGNOSTIC_OUTSIDE_OF_IMPL ] ) ;
395436
396437impl LateLintPass < ' _ > for Diagnostics {
397- fn check_expr ( & mut self , cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) {
398- let collect_args_tys_and_spans = |args : & [ Expr < ' _ > ] , reserve_one_extra : bool | {
438+ fn check_expr ( & mut self , cx : & LateContext < ' _ > , expr : & hir :: Expr < ' _ > ) {
439+ let collect_args_tys_and_spans = |args : & [ hir :: Expr < ' _ > ] , reserve_one_extra : bool | {
399440 let mut result = Vec :: with_capacity ( args. len ( ) + usize:: from ( reserve_one_extra) ) ;
400441 result. extend ( args. iter ( ) . map ( |arg| ( cx. typeck_results ( ) . expr_ty ( arg) , arg. span ) ) ) ;
401442 result
402443 } ;
403444 // Only check function calls and method calls.
404445 let ( span, def_id, fn_gen_args, arg_tys_and_spans) = match expr. kind {
405- ExprKind :: Call ( callee, args) => {
446+ hir :: ExprKind :: Call ( callee, args) => {
406447 match cx. typeck_results ( ) . node_type ( callee. hir_id ) . kind ( ) {
407448 & ty:: FnDef ( def_id, fn_gen_args) => {
408449 ( callee. span , def_id, fn_gen_args, collect_args_tys_and_spans ( args, false ) )
409450 }
410451 _ => return , // occurs for fns passed as args
411452 }
412453 }
413- ExprKind :: MethodCall ( _segment, _recv, args, _span) => {
454+ hir :: ExprKind :: MethodCall ( _segment, _recv, args, _span) => {
414455 let Some ( ( span, def_id, fn_gen_args) ) = typeck_results_of_method_fn ( cx, expr)
415456 else {
416457 return ;
@@ -514,8 +555,8 @@ impl Diagnostics {
514555 let mut is_inside_appropriate_impl = false ;
515556 for ( _hir_id, parent) in cx. tcx . hir_parent_iter ( current_id) {
516557 debug ! ( ?parent) ;
517- if let Node :: Item ( Item { kind : ItemKind :: Impl ( impl_) , .. } ) = parent
518- && let Impl { of_trait : Some ( of_trait) , .. } = impl_
558+ if let hir :: Node :: Item ( hir :: Item { kind : hir :: ItemKind :: Impl ( impl_) , .. } ) = parent
559+ && let hir :: Impl { of_trait : Some ( of_trait) , .. } = impl_
519560 && let Some ( def_id) = of_trait. trait_def_id ( )
520561 && let Some ( name) = cx. tcx . get_diagnostic_name ( def_id)
521562 && matches ! ( name, sym:: Diagnostic | sym:: Subdiagnostic | sym:: LintDiagnostic )
@@ -543,8 +584,8 @@ declare_tool_lint! {
543584declare_lint_pass ! ( BadOptAccess => [ BAD_OPT_ACCESS ] ) ;
544585
545586impl LateLintPass < ' _ > for BadOptAccess {
546- fn check_expr ( & mut self , cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) {
547- let ExprKind :: Field ( base, target) = expr. kind else { return } ;
587+ fn check_expr ( & mut self , cx : & LateContext < ' _ > , expr : & hir :: Expr < ' _ > ) {
588+ let hir :: ExprKind :: Field ( base, target) = expr. kind else { return } ;
548589 let Some ( adt_def) = cx. typeck_results ( ) . expr_ty ( base) . ty_adt_def ( ) else { return } ;
549590 // Skip types without `#[rustc_lint_opt_ty]` - only so that the rest of the lint can be
550591 // avoided.
@@ -581,9 +622,12 @@ declare_tool_lint! {
581622declare_lint_pass ! ( SpanUseEqCtxt => [ SPAN_USE_EQ_CTXT ] ) ;
582623
583624impl < ' tcx > LateLintPass < ' tcx > for SpanUseEqCtxt {
584- fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & Expr < ' _ > ) {
585- if let ExprKind :: Binary ( BinOp { node : BinOpKind :: Eq | BinOpKind :: Ne , .. } , lhs, rhs) =
586- expr. kind
625+ fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & hir:: Expr < ' _ > ) {
626+ if let hir:: ExprKind :: Binary (
627+ hir:: BinOp { node : hir:: BinOpKind :: Eq | hir:: BinOpKind :: Ne , .. } ,
628+ lhs,
629+ rhs,
630+ ) = expr. kind
587631 {
588632 if is_span_ctxt_call ( cx, lhs) && is_span_ctxt_call ( cx, rhs) {
589633 cx. emit_span_lint ( SPAN_USE_EQ_CTXT , expr. span , SpanUseEqCtxtDiag ) ;
@@ -592,9 +636,9 @@ impl<'tcx> LateLintPass<'tcx> for SpanUseEqCtxt {
592636 }
593637}
594638
595- fn is_span_ctxt_call ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) -> bool {
639+ fn is_span_ctxt_call ( cx : & LateContext < ' _ > , expr : & hir :: Expr < ' _ > ) -> bool {
596640 match & expr. kind {
597- ExprKind :: MethodCall ( ..) => cx
641+ hir :: ExprKind :: MethodCall ( ..) => cx
598642 . typeck_results ( )
599643 . type_dependent_def_id ( expr. hir_id )
600644 . 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]);
617661
618662impl < ' tcx > LateLintPass < ' tcx > for SymbolInternStringLiteral {
619663 fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx rustc_hir:: Expr < ' tcx > ) {
620- if let ExprKind :: Call ( path, [ arg] ) = expr. kind
621- && let ExprKind :: Path ( ref qpath) = path. kind
664+ if let hir :: ExprKind :: Call ( path, [ arg] ) = expr. kind
665+ && let hir :: ExprKind :: Path ( ref qpath) = path. kind
622666 && let Some ( def_id) = cx. qpath_res ( qpath, path. hir_id ) . opt_def_id ( )
623667 && cx. tcx . is_diagnostic_item ( sym:: SymbolIntern , def_id)
624- && let ExprKind :: Lit ( kind) = arg. kind
668+ && let hir :: ExprKind :: Lit ( kind) = arg. kind
625669 && let rustc_ast:: LitKind :: Str ( _, _) = kind. node
626670 {
627671 cx. emit_span_lint (
0 commit comments