@@ -6,6 +6,7 @@ extern crate rustc_metadata;
6
6
extern crate rustc_driver;
7
7
extern crate rustc_errors;
8
8
extern crate rustc_codegen_utils;
9
+ extern crate rustc_interface;
9
10
extern crate syntax;
10
11
11
12
use std:: path:: { PathBuf , Path } ;
@@ -15,106 +16,66 @@ use std::io;
15
16
16
17
17
18
use rustc:: session:: Session ;
19
+ use rustc_interface:: interface;
18
20
use rustc_metadata:: cstore:: CStore ;
19
- use rustc_driver:: { Compilation , CompilerCalls , RustcDefaultCalls } ;
20
- use rustc_driver:: driver:: { CompileState , CompileController } ;
21
21
use rustc:: session:: config:: { self , Input , ErrorOutputType } ;
22
22
use rustc:: hir:: { self , itemlikevisit} ;
23
- use rustc_codegen_utils:: codegen_backend:: CodegenBackend ;
24
23
use rustc:: ty:: TyCtxt ;
25
24
use syntax:: ast;
26
25
use rustc:: hir:: def_id:: LOCAL_CRATE ;
27
26
28
27
use miri:: MiriConfig ;
29
28
30
29
struct MiriCompilerCalls {
31
- default : Box < RustcDefaultCalls > ,
32
30
/// whether we are building for the host
33
31
host_target : bool ,
34
32
}
35
33
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
- }
34
+ impl rustc_driver:: Callbacks for MiriCompilerCalls {
35
+ fn after_parsing ( & mut self , compiler : & interface:: Compiler < ' _ > ) -> bool {
36
+ let attr = (
37
+ String :: from ( "miri" ) ,
38
+ syntax:: feature_gate:: AttributeType :: Whitelisted ,
39
+ ) ;
40
+ compiler. session ( ) . plugin_attributes . borrow_mut ( ) . push ( attr) ;
87
41
88
- fn after_analysis < ' a , ' tcx > ( state : & mut CompileState < ' a , ' tcx > ) {
89
- state. session . abort_if_errors ( ) ;
90
-
91
- let tcx = state. tcx . unwrap ( ) ;
42
+ // Continue execution
43
+ true
44
+ }
92
45
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 ( ) ;
46
+ fn after_analysis ( & mut self , compiler : & interface:: Compiler < ' _ > ) -> bool {
47
+ compiler. session ( ) . abort_if_errors ( ) ;
48
+ compiler. global_ctxt ( ) . unwrap ( ) . peek_mut ( ) . enter ( |tcx| {
49
+ if std:: env:: args ( ) . any ( |arg| arg == "--test" ) {
50
+ struct Visitor < ' a , ' tcx : ' a > ( TyCtxt < ' a , ' tcx , ' tcx > ) ;
51
+ impl < ' a , ' tcx : ' a , ' hir > itemlikevisit:: ItemLikeVisitor < ' hir > for Visitor < ' a , ' tcx > {
52
+ fn visit_item ( & mut self , i : & ' hir hir:: Item ) {
53
+ if let hir:: ItemKind :: Fn ( .., body_id) = i. node {
54
+ if i. attrs . iter ( ) . any ( |attr| attr. name ( ) == "test" ) {
55
+ let config = MiriConfig { validate : true , args : vec ! [ ] } ;
56
+ let did = self . 0 . hir ( ) . body_owner_def_id ( body_id) ;
57
+ println ! ( "running test: {}" , self . 0 . def_path_debug_str( did) ) ;
58
+ miri:: eval_main ( self . 0 , did, config) ;
59
+ self . 0 . sess . abort_if_errors ( ) ;
60
+ }
61
+ }
104
62
}
63
+ fn visit_trait_item ( & mut self , _trait_item : & ' hir hir:: TraitItem ) { }
64
+ fn visit_impl_item ( & mut self , _impl_item : & ' hir hir:: ImplItem ) { }
105
65
}
66
+ tcx. hir ( ) . krate ( ) . visit_all_item_likes ( & mut Visitor ( tcx) ) ;
67
+ } else if let Some ( ( entry_def_id, _) ) = tcx. entry_fn ( LOCAL_CRATE ) {
68
+ let config = MiriConfig { validate : true , args : vec ! [ ] } ;
69
+ miri:: eval_main ( tcx, entry_def_id, config) ;
70
+
71
+ compiler. session ( ) . abort_if_errors ( ) ;
72
+ } else {
73
+ println ! ( "no main function found, assuming auxiliary build" ) ;
106
74
}
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) ;
75
+ } ) ;
114
76
115
- state. session . abort_if_errors ( ) ;
116
- } else {
117
- println ! ( "no main function found, assuming auxiliary build" ) ;
77
+ // Continue execution on host target
78
+ self . host_target
118
79
}
119
80
}
120
81
@@ -185,10 +146,7 @@ fn main() {
185
146
let buf = BufWriter :: default ( ) ;
186
147
let output = buf. clone ( ) ;
187
148
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) ) ) ;
149
+ rustc_driver:: run_compiler ( & args, & mut MiriCompilerCalls { host_target } , None , Some ( Box :: new ( buf) ) ) ;
192
150
} ) ;
193
151
194
152
match result {
0 commit comments