@@ -69,11 +69,13 @@ use rustc_hir::def::{DefKind, Res};
69
69
use rustc_hir:: def_id:: DefId ;
70
70
use rustc_hir:: hir_id:: { HirIdMap , HirIdSet } ;
71
71
use rustc_hir:: intravisit:: { self , walk_expr, ErasedMap , FnKind , NestedVisitorMap , Visitor } ;
72
+ use rustc_hir:: itemlikevisit:: ItemLikeVisitor ;
72
73
use rustc_hir:: LangItem :: { OptionNone , ResultErr , ResultOk } ;
73
74
use rustc_hir:: {
74
- def, Arm , BindingAnnotation , Block , Body , Constness , Destination , Expr , ExprKind , FnDecl , GenericArgs , HirId , Impl ,
75
- ImplItem , ImplItemKind , IsAsync , Item , ItemKind , LangItem , Local , MatchSource , Mutability , Node , Param , Pat ,
76
- PatKind , Path , PathSegment , PrimTy , QPath , Stmt , StmtKind , TraitItem , TraitItemKind , TraitRef , TyKind , UnOp ,
75
+ def, Arm , BindingAnnotation , Block , Body , Constness , Destination , Expr , ExprKind , FnDecl , ForeignItem , GenericArgs ,
76
+ HirId , Impl , ImplItem , ImplItemKind , IsAsync , Item , ItemKind , LangItem , Local , MatchSource , Mutability , Node ,
77
+ Param , Pat , PatKind , Path , PathSegment , PrimTy , QPath , Stmt , StmtKind , TraitItem , TraitItemKind , TraitRef , TyKind ,
78
+ UnOp ,
77
79
} ;
78
80
use rustc_lint:: { LateContext , Level , Lint , LintContext } ;
79
81
use rustc_middle:: hir:: exports:: Export ;
@@ -2064,16 +2066,57 @@ pub fn is_hir_ty_cfg_dependant(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool {
2064
2066
false
2065
2067
}
2066
2068
2067
- /// Checks whether item either has `test` attribute applied, or
2068
- /// is a module with `test` in its name.
2069
- pub fn is_test_module_or_function ( tcx : TyCtxt < ' _ > , item : & Item < ' _ > ) -> bool {
2070
- if let Some ( def_id) = tcx. hir ( ) . opt_local_def_id ( item. hir_id ( ) ) {
2071
- if tcx. has_attr ( def_id. to_def_id ( ) , sym:: test) {
2072
- return true ;
2069
+ struct VisitConstTestStruct {
2070
+ names : Vec < Symbol > ,
2071
+ found : bool ,
2072
+ }
2073
+ impl < ' hir > ItemLikeVisitor < ' hir > for VisitConstTestStruct {
2074
+ fn visit_item ( & mut self , item : & Item < ' _ > ) {
2075
+ if let ItemKind :: Const ( ty, _body) = item. kind {
2076
+ if let TyKind :: Path ( QPath :: Resolved ( _, path) ) = ty. kind {
2077
+ // We could also check for the type name `test::TestDescAndFn`
2078
+ // and the `#[rustc_test_marker]` attribute?
2079
+ if let Res :: Def ( DefKind :: Struct , _) = path. res {
2080
+ if self . names . contains ( & item. ident . name ) {
2081
+ self . found = true ;
2082
+ }
2083
+ }
2084
+ }
2073
2085
}
2074
2086
}
2087
+ fn visit_trait_item ( & mut self , _: & TraitItem < ' _ > ) { }
2088
+ fn visit_impl_item ( & mut self , _: & ImplItem < ' _ > ) { }
2089
+ fn visit_foreign_item ( & mut self , _: & ForeignItem < ' _ > ) { }
2090
+ }
2091
+
2092
+ /// Checks if the function containing the given `HirId` is a `#[test]` function
2093
+ pub fn is_in_test_function ( tcx : TyCtxt < ' _ > , id : hir:: HirId ) -> bool {
2094
+ let names: Vec < _ > = tcx
2095
+ . hir ( )
2096
+ . parent_iter ( id)
2097
+ // Since you can nest functions we need to collect all until we leave
2098
+ // function scope
2099
+ . filter_map ( |( _id, node) | {
2100
+ if let Node :: Item ( item) = node {
2101
+ if let ItemKind :: Fn ( _, _, _) = item. kind {
2102
+ return Some ( item. ident . name ) ;
2103
+ }
2104
+ }
2105
+ None
2106
+ } )
2107
+ . collect ( ) ;
2108
+ let parent_mod = tcx. parent_module ( id) ;
2109
+ let mut vis = VisitConstTestStruct { names, found : false } ;
2110
+ tcx. hir ( ) . visit_item_likes_in_module ( parent_mod, & mut vis) ;
2111
+ vis. found
2112
+ }
2075
2113
2076
- matches ! ( item. kind, ItemKind :: Mod ( ..) ) && item. ident . name . as_str ( ) . split ( '_' ) . any ( |a| a == "test" || a == "tests" )
2114
+ /// Checks whether item either has `test` attribute appelied, or
2115
+ /// is a module with `test` in its name.
2116
+ pub fn is_test_module_or_function ( tcx : TyCtxt < ' _ > , item : & Item < ' _ > ) -> bool {
2117
+ is_in_test_function ( tcx, item. hir_id ( ) )
2118
+ || matches ! ( item. kind, ItemKind :: Mod ( ..) )
2119
+ && item. ident . name . as_str ( ) . split ( '_' ) . any ( |a| a == "test" || a == "tests" )
2077
2120
}
2078
2121
2079
2122
macro_rules! op_utils {
0 commit comments