@@ -6,115 +6,72 @@ extern crate rustc_metadata;
66extern crate rustc_driver;
77extern crate rustc_errors;
88extern crate rustc_codegen_utils;
9+ extern crate rustc_interface;
910extern crate syntax;
1011
11- use std:: path:: { PathBuf , Path } ;
12+ use std:: path:: Path ;
1213use std:: io:: Write ;
1314use std:: sync:: { Mutex , Arc } ;
1415use std:: io;
1516
1617
17- use rustc:: session:: Session ;
18- use rustc_metadata:: cstore:: CStore ;
19- use rustc_driver:: { Compilation , CompilerCalls , RustcDefaultCalls } ;
20- use rustc_driver:: driver:: { CompileState , CompileController } ;
21- use rustc:: session:: config:: { self , Input , ErrorOutputType } ;
18+ use rustc_interface:: interface;
2219use rustc:: hir:: { self , itemlikevisit} ;
23- use rustc_codegen_utils:: codegen_backend:: CodegenBackend ;
2420use rustc:: ty:: TyCtxt ;
25- use syntax:: ast;
2621use rustc:: hir:: def_id:: LOCAL_CRATE ;
2722
2823use miri:: MiriConfig ;
2924
3025struct MiriCompilerCalls {
31- default : Box < RustcDefaultCalls > ,
3226 /// whether we are building for the host
3327 host_target : bool ,
3428}
3529
36- impl < ' a > CompilerCalls < ' a > for MiriCompilerCalls {
37- fn early_callback (
38- & mut self ,
39- matches : & getopts:: Matches ,
40- sopts : & config:: Options ,
41- cfg : & ast:: CrateConfig ,
42- descriptions : & rustc_errors:: registry:: Registry ,
43- output : ErrorOutputType
44- ) -> Compilation {
45- self . default . early_callback ( matches, sopts, cfg, descriptions, output)
46- }
47- fn no_input (
48- & mut self ,
49- matches : & getopts:: Matches ,
50- sopts : & config:: Options ,
51- cfg : & ast:: CrateConfig ,
52- odir : & Option < PathBuf > ,
53- ofile : & Option < PathBuf > ,
54- descriptions : & rustc_errors:: registry:: Registry
55- ) -> Option < ( Input , Option < PathBuf > ) > {
56- self . default . no_input ( matches, sopts, cfg, odir, ofile, descriptions)
57- }
58- fn late_callback (
59- & mut self ,
60- trans : & CodegenBackend ,
61- matches : & getopts:: Matches ,
62- sess : & Session ,
63- cstore : & CStore ,
64- input : & Input ,
65- odir : & Option < PathBuf > ,
66- ofile : & Option < PathBuf > ,
67- ) -> Compilation {
68- self . default . late_callback ( trans, matches, sess, cstore, input, odir, ofile)
69- }
70- fn build_controller ( self : Box < Self > , sess : & Session , matches : & getopts:: Matches ) -> CompileController < ' a > {
71- let this = * self ;
72- let mut control = this. default . build_controller ( sess, matches) ;
73- control. after_hir_lowering . callback = Box :: new ( after_hir_lowering) ;
74- control. after_analysis . callback = Box :: new ( after_analysis) ;
75- if !this. host_target {
76- // only fully compile targets on the host
77- control. after_analysis . stop = Compilation :: Stop ;
78- }
79- control
80- }
81- }
82-
83- fn after_hir_lowering ( state : & mut CompileState ) {
84- let attr = ( String :: from ( "miri" ) , syntax:: feature_gate:: AttributeType :: Whitelisted ) ;
85- state. session . plugin_attributes . borrow_mut ( ) . push ( attr) ;
86- }
30+ impl rustc_driver:: Callbacks for MiriCompilerCalls {
31+ fn after_parsing ( & mut self , compiler : & interface:: Compiler ) -> bool {
32+ let attr = (
33+ String :: from ( "miri" ) ,
34+ syntax:: feature_gate:: AttributeType :: Whitelisted ,
35+ ) ;
36+ compiler. session ( ) . plugin_attributes . borrow_mut ( ) . push ( attr) ;
8737
88- fn after_analysis < ' a , ' tcx > ( state : & mut CompileState < ' a , ' tcx > ) {
89- state. session . abort_if_errors ( ) ;
90-
91- let tcx = state. tcx . unwrap ( ) ;
38+ // Continue execution
39+ true
40+ }
9241
93- if std:: env:: args ( ) . any ( |arg| arg == "--test" ) {
94- struct Visitor < ' a , ' tcx : ' a > ( TyCtxt < ' a , ' tcx , ' tcx > , & ' a CompileState < ' a , ' tcx > ) ;
95- impl < ' a , ' tcx : ' a , ' hir > itemlikevisit:: ItemLikeVisitor < ' hir > for Visitor < ' a , ' tcx > {
96- fn visit_item ( & mut self , i : & ' hir hir:: Item ) {
97- if let hir:: ItemKind :: Fn ( .., body_id) = i. node {
98- if i. attrs . iter ( ) . any ( |attr| attr. name ( ) == "test" ) {
99- let config = MiriConfig { validate : true , args : vec ! [ ] } ;
100- let did = self . 0 . hir ( ) . body_owner_def_id ( body_id) ;
101- println ! ( "running test: {}" , self . 0 . def_path_debug_str( did) ) ;
102- miri:: eval_main ( self . 0 , did, config) ;
103- self . 1 . session . abort_if_errors ( ) ;
42+ fn after_analysis ( & mut self , compiler : & interface:: Compiler ) -> bool {
43+ compiler. session ( ) . abort_if_errors ( ) ;
44+ compiler. global_ctxt ( ) . unwrap ( ) . peek_mut ( ) . enter ( |tcx| {
45+ if std:: env:: args ( ) . any ( |arg| arg == "--test" ) {
46+ struct Visitor < ' a , ' tcx : ' a > ( TyCtxt < ' a , ' tcx , ' tcx > ) ;
47+ impl < ' a , ' tcx : ' a , ' hir > itemlikevisit:: ItemLikeVisitor < ' hir > for Visitor < ' a , ' tcx > {
48+ fn visit_item ( & mut self , i : & ' hir hir:: Item ) {
49+ if let hir:: ItemKind :: Fn ( .., body_id) = i. node {
50+ if i. attrs . iter ( ) . any ( |attr| attr. name ( ) == "test" ) {
51+ let config = MiriConfig { validate : true , args : vec ! [ ] } ;
52+ let did = self . 0 . hir ( ) . body_owner_def_id ( body_id) ;
53+ println ! ( "running test: {}" , self . 0 . def_path_debug_str( did) ) ;
54+ miri:: eval_main ( self . 0 , did, config) ;
55+ self . 0 . sess . abort_if_errors ( ) ;
56+ }
57+ }
10458 }
59+ fn visit_trait_item ( & mut self , _trait_item : & ' hir hir:: TraitItem ) { }
60+ fn visit_impl_item ( & mut self , _impl_item : & ' hir hir:: ImplItem ) { }
10561 }
62+ tcx. hir ( ) . krate ( ) . visit_all_item_likes ( & mut Visitor ( tcx) ) ;
63+ } else if let Some ( ( entry_def_id, _) ) = tcx. entry_fn ( LOCAL_CRATE ) {
64+ let config = MiriConfig { validate : true , args : vec ! [ ] } ;
65+ miri:: eval_main ( tcx, entry_def_id, config) ;
66+
67+ compiler. session ( ) . abort_if_errors ( ) ;
68+ } else {
69+ println ! ( "no main function found, assuming auxiliary build" ) ;
10670 }
107- fn visit_trait_item ( & mut self , _trait_item : & ' hir hir:: TraitItem ) { }
108- fn visit_impl_item ( & mut self , _impl_item : & ' hir hir:: ImplItem ) { }
109- }
110- state. hir_crate . unwrap ( ) . visit_all_item_likes ( & mut Visitor ( tcx, state) ) ;
111- } else if let Some ( ( entry_def_id, _) ) = tcx. entry_fn ( LOCAL_CRATE ) {
112- let config = MiriConfig { validate : true , args : vec ! [ ] } ;
113- miri:: eval_main ( tcx, entry_def_id, config) ;
71+ } ) ;
11472
115- state. session . abort_if_errors ( ) ;
116- } else {
117- println ! ( "no main function found, assuming auxiliary build" ) ;
73+ // Continue execution on host target
74+ self . host_target
11875 }
11976}
12077
@@ -185,10 +142,7 @@ fn main() {
185142 let buf = BufWriter :: default ( ) ;
186143 let output = buf. clone ( ) ;
187144 let result = std:: panic:: catch_unwind ( || {
188- rustc_driver:: run_compiler ( & args, Box :: new ( MiriCompilerCalls {
189- default : Box :: new ( RustcDefaultCalls ) ,
190- host_target,
191- } ) , None , Some ( Box :: new ( buf) ) ) ;
145+ let _ = rustc_driver:: run_compiler ( & args, & mut MiriCompilerCalls { host_target } , None , Some ( Box :: new ( buf) ) ) ;
192146 } ) ;
193147
194148 match result {
0 commit comments