@@ -10,13 +10,19 @@ use crate::analysis::ast_lowering;
1010use crate :: analysis:: hir;
1111use crate :: codegen:: ast;
1212use crate :: codegen:: ast:: visit:: Visitor ;
13- use crate :: codegen:: symbols:: { DUMMY_SP , FileNameDisplayPreference , Ident , Symbol , path, sym} ;
13+ use crate :: codegen:: symbols:: { DUMMY_SP , ExpnKind , FileNameDisplayPreference , Ident , MacroKind , Symbol , path, sym} ;
14+
15+ pub enum TestKind {
16+ Test ,
17+ QuickCheck { original_def_id : hir:: LocalDefId } ,
18+ }
1419
1520pub struct Test {
1621 pub path : Vec < Ident > ,
1722 pub descriptor : Box < ast:: Item > ,
1823 pub item : Box < ast:: Item > ,
1924 pub def_id : hir:: LocalDefId ,
25+ pub kind : TestKind ,
2026 pub ignore : bool ,
2127}
2228
@@ -58,7 +64,7 @@ fn is_test_case(item: &ast::Item) -> bool {
5864 item. attrs . iter ( ) . any ( |attr| attr. has_name ( sym:: rustc_test_marker) )
5965}
6066
61- fn extract_expanded_tests ( def_res : & ast_lowering:: DefResolutions , path : & [ Ident ] , items : & [ Box < ast:: Item > ] ) -> Vec < Test > {
67+ fn extract_expanded_tests < ' tcx > ( tcx : TyCtxt < ' tcx > , def_res : & ast_lowering:: DefResolutions , path : & [ Ident ] , items : & [ Box < ast:: Item > ] ) -> Vec < Test > {
6268 let mut tests = vec ! [ ] ;
6369
6470 let mut item_iterator = items. iter ( ) ;
@@ -74,29 +80,54 @@ fn extract_expanded_tests(def_res: &ast_lowering::DefResolutions, path: &[Ident]
7480
7581 let Some ( ident) = test_case. kind . ident ( ) else { panic ! ( "encountered test case without ident" ) ; } ;
7682
83+ let mut kind = TestKind :: Test ;
84+ let expn_data = test_item. span . ctxt ( ) . outer_expn_data ( ) ;
85+ let expn_macro_crate_name = expn_data. macro_def_id . map ( |def_id| tcx. crate_name ( def_id. krate ) . as_str ( ) . to_owned ( ) ) ;
86+ match ( expn_macro_crate_name. as_deref ( ) , expn_data. kind ) {
87+ ( Some ( "quickcheck" ) , ExpnKind :: Macro ( MacroKind :: Bang , _) ) => {
88+ if let ast:: ItemKind :: Fn ( fn_item) = & test_item. kind && let Some ( body) = & fn_item. body {
89+ if let [ original_fn_item_stmt, _] = & body. stmts [ ..] && let ast:: StmtKind :: Item ( original_fn_item) = & original_fn_item_stmt. kind {
90+ let Some ( original_def_id) = def_res. node_id_to_def_id . get ( & original_fn_item. id ) . copied ( ) else { unreachable ! ( ) ; } ;
91+ kind = TestKind :: QuickCheck { original_def_id } ;
92+ }
93+ }
94+ }
95+ ( Some ( "quickcheck_macros" ) , ExpnKind :: Macro ( MacroKind :: Attr , _) ) => {
96+ if let ast:: ItemKind :: Fn ( fn_item) = & test_item. kind && let Some ( body) = & fn_item. body {
97+ if let [ original_fn_item_stmt, _] = & body. stmts [ ..] && let ast:: StmtKind :: Item ( original_fn_item) = & original_fn_item_stmt. kind {
98+ let Some ( original_def_id) = def_res. node_id_to_def_id . get ( & original_fn_item. id ) . copied ( ) else { unreachable ! ( ) ; } ;
99+ kind = TestKind :: QuickCheck { original_def_id } ;
100+ }
101+ }
102+ }
103+ _ => { }
104+ }
105+
77106 let ignore = test_item. attrs . iter ( ) . any ( |attr| attr. has_name ( sym:: ignore) ) ;
78107
79108 tests. push ( Test {
80109 path : path. iter ( ) . copied ( ) . chain ( iter:: once ( ident) ) . collect ( ) ,
81110 descriptor : test_case. to_owned ( ) ,
82111 item : test_item. to_owned ( ) ,
83112 def_id,
113+ kind,
84114 ignore,
85115 } ) ;
86116 }
87117
88118 tests
89119}
90120
91- struct TestCollector < ' op > {
121+ struct TestCollector < ' tcx , ' op > {
122+ tcx : TyCtxt < ' tcx > ,
123+ def_res : & ' op ast_lowering:: DefResolutions ,
92124 current_path : Vec < Ident > ,
93125 tests : Vec < Test > ,
94- def_res : & ' op ast_lowering:: DefResolutions ,
95126}
96127
97- impl < ' ast , ' op > ast:: visit:: Visitor < ' ast > for TestCollector < ' op > {
128+ impl < ' tcx , ' ast , ' op > ast:: visit:: Visitor < ' ast > for TestCollector < ' tcx , ' op > {
98129 fn visit_crate ( & mut self , krate : & ' ast ast:: Crate ) {
99- let mut tests = extract_expanded_tests ( self . def_res , & self . current_path , & krate. items ) ;
130+ let mut tests = extract_expanded_tests ( self . tcx , self . def_res , & self . current_path , & krate. items ) ;
100131 self . tests . append ( & mut tests) ;
101132
102133 ast:: visit:: walk_crate ( self , krate) ;
@@ -108,7 +139,7 @@ impl<'ast, 'op> ast::visit::Visitor<'ast> for TestCollector<'op> {
108139
109140 if let Some ( ident) = ident { self . current_path . push ( ident) ; }
110141
111- let mut tests = extract_expanded_tests ( self . def_res , & self . current_path , & items) ;
142+ let mut tests = extract_expanded_tests ( self . tcx , self . def_res , & self . current_path , & items) ;
112143 self . tests . append ( & mut tests) ;
113144
114145 ast:: visit:: walk_item ( self , item) ;
@@ -118,8 +149,8 @@ impl<'ast, 'op> ast::visit::Visitor<'ast> for TestCollector<'op> {
118149 }
119150}
120151
121- pub fn collect_tests ( krate : & ast:: Crate , def_res : & ast_lowering:: DefResolutions ) -> Vec < Test > {
122- let mut collector = TestCollector { current_path : vec ! [ ] , tests : vec ! [ ] , def_res } ;
152+ pub fn collect_tests < ' tcx > ( tcx : TyCtxt < ' tcx > , krate : & ast:: Crate , def_res : & ast_lowering:: DefResolutions ) -> Vec < Test > {
153+ let mut collector = TestCollector { tcx , def_res , current_path : vec ! [ ] , tests : vec ! [ ] } ;
123154 collector. visit_crate ( krate) ;
124155
125156 collector. tests
@@ -237,6 +268,7 @@ fn extract_and_mark_expanded_embedded_tests(sess: &Session, def_res: &ast_loweri
237268 descriptor,
238269 item : test_item,
239270 def_id,
271+ kind : TestKind :: Test ,
240272 ignore,
241273 } ) ;
242274
0 commit comments