1
1
#![ feature( rustc_private) ]
2
2
3
+ extern crate rustc_ast_pretty;
3
4
extern crate rustc_driver;
4
5
extern crate rustc_error_codes;
5
6
extern crate rustc_errors;
@@ -9,84 +10,78 @@ extern crate rustc_interface;
9
10
extern crate rustc_session;
10
11
extern crate rustc_span;
11
12
12
- use std:: { path, process, str, sync:: Arc } ;
13
+ use std:: io;
14
+ use std:: path:: Path ;
15
+ use std:: str;
16
+ use std:: sync:: Arc ;
13
17
18
+ use rustc_ast_pretty:: pprust:: item_to_string;
19
+ use rustc_data_structures:: sync:: Lrc ;
20
+ use rustc_driver:: Compilation ;
14
21
use rustc_errors:: registry;
15
- use rustc_hash:: FxHashMap ;
16
22
use rustc_session:: config;
17
23
24
+ struct MyFileLoader ;
25
+
26
+ impl rustc_span:: source_map:: FileLoader for MyFileLoader {
27
+ fn file_exists ( & self , path : & Path ) -> bool {
28
+ path == "main.rs"
29
+ }
30
+
31
+ fn read_file ( & self , path : & Path ) -> io:: Result < String > {
32
+ if path == "main.rs" {
33
+ Ok ( r#"
18
34
fn main() {
19
- let out = process:: Command :: new ( "rustc" )
20
- . arg ( "--print=sysroot" )
21
- . current_dir ( "." )
22
- . output ( )
23
- . unwrap ( ) ;
24
- let sysroot = str:: from_utf8 ( & out. stdout ) . unwrap ( ) . trim ( ) ;
25
- let config = rustc_interface:: Config {
26
- // Command line options
27
- opts : config:: Options {
28
- maybe_sysroot : Some ( path:: PathBuf :: from ( sysroot) ) ,
29
- ..config:: Options :: default ( )
30
- } ,
31
- // cfg! configuration in addition to the default ones
32
- crate_cfg : Vec :: new ( ) , // FxHashSet<(String, Option<String>)>
33
- crate_check_cfg : Vec :: new ( ) , // CheckCfg
34
- input : config:: Input :: Str {
35
- name : rustc_span:: FileName :: Custom ( "main.rs" . into ( ) ) ,
36
- input : r#"
37
- static HELLO: &str = "Hello, world!";
38
- fn main() {
39
- println!("{HELLO}");
35
+ let message = "Hello, World!";
36
+ println!("{message}");
40
37
}
41
38
"#
42
- . into ( ) ,
43
- } ,
44
- output_dir : None , // Option<PathBuf>
45
- output_file : None , // Option<PathBuf>
46
- file_loader : None , // Option<Box<dyn FileLoader + Send + Sync>>
47
- locale_resources : rustc_driver:: DEFAULT_LOCALE_RESOURCES ,
48
- lint_caps : FxHashMap :: default ( ) , // FxHashMap<lint::LintId, lint::Level>
49
- // This is a callback from the driver that is called when [`ParseSess`] is created.
50
- psess_created : None , //Option<Box<dyn FnOnce(&mut ParseSess) + Send>>
51
- // This is a callback from the driver that is called when we're registering lints;
52
- // it is called during plugin registration when we have the LintStore in a non-shared state.
53
- //
54
- // Note that if you find a Some here you probably want to call that function in the new
55
- // function being registered.
56
- register_lints : None , // Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>>
57
- // This is a callback from the driver that is called just after we have populated
58
- // the list of queries.
59
- //
60
- // The second parameter is local providers and the third parameter is external providers.
61
- override_queries : None , // Option<fn(&Session, &mut ty::query::Providers<'_>, &mut ty::query::Providers<'_>)>
62
- // Registry of diagnostics codes.
63
- registry : registry:: Registry :: new ( rustc_errors:: codes:: DIAGNOSTICS ) ,
64
- make_codegen_backend : None ,
65
- expanded_args : Vec :: new ( ) ,
66
- ice_file : None ,
67
- hash_untracked_state : None ,
68
- using_internal_features : Arc :: default ( ) ,
69
- } ;
70
- rustc_interface:: run_compiler ( config, |compiler| {
71
- compiler. enter ( |queries| {
72
- // Parse the program and print the syntax tree.
73
- let parse = queries. parse ( ) . unwrap ( ) . get_mut ( ) . clone ( ) ;
74
- println ! ( "{parse:?}" ) ;
75
- // Analyze the program and inspect the types of definitions.
76
- queries. global_ctxt ( ) . unwrap ( ) . enter ( |tcx| {
77
- for id in tcx. hir ( ) . items ( ) {
78
- let hir = tcx. hir ( ) ;
79
- let item = hir. item ( id) ;
80
- match item. kind {
81
- rustc_hir:: ItemKind :: Static ( _, _, _) | rustc_hir:: ItemKind :: Fn ( _, _, _) => {
82
- let name = item. ident ;
83
- let ty = tcx. type_of ( item. hir_id ( ) . owner . def_id ) ;
84
- println ! ( "{name:?}:\t {ty:?}" )
85
- }
86
- _ => ( ) ,
87
- }
39
+ . to_string ( ) )
40
+ } else {
41
+ Err ( io:: Error :: other ( "oops" ) )
42
+ }
43
+ }
44
+
45
+ fn read_binary_file ( & self , path : & Path ) -> io:: Result < Lrc < [ u8 ] > > {
46
+ Err ( io:: Error :: other ( "oops" ) )
47
+ }
48
+ }
49
+
50
+ struct MyCallbacks ;
51
+
52
+ impl rustc_driver:: Callbacks for MyCallbacks {
53
+ fn after_crate_root_parsing (
54
+ _compiler : & rustc_interface:: Compiler ,
55
+ krate : & rustc_ast:: Crate ,
56
+ ) -> Compilation {
57
+ for item in krate. items {
58
+ println ! ( "{}" , item_to_string( & item) ) ;
59
+ }
60
+
61
+ Compilation :: Continue
62
+ }
63
+
64
+ fn after_analysis ( _compiler : & rustc_interface:: Compiler , tcx : TyCtxt < ' _ > ) -> Compilation {
65
+ // Analyze the program and inspect the types of definitions.
66
+ for id in tcx. hir ( ) . items ( ) {
67
+ let hir = tcx. hir ( ) ;
68
+ let item = hir. item ( id) ;
69
+ match item. kind {
70
+ rustc_hir:: ItemKind :: Static ( _, _, _) | rustc_hir:: ItemKind :: Fn ( _, _, _) => {
71
+ let name = item. ident ;
72
+ let ty = tcx. type_of ( item. hir_id ( ) . owner . def_id ) ;
73
+ println ! ( "{name:?}:\t {ty:?}" )
88
74
}
89
- } )
90
- } ) ;
91
- } ) ;
75
+ _ => ( ) ,
76
+ }
77
+ }
78
+
79
+ Compilation :: Stop
80
+ }
81
+ }
82
+
83
+ fn main ( ) {
84
+ RunCompiler :: new ( & [ "main.rs" . to_string ( ) ] , MyCallbacks )
85
+ . set_file_loader ( Some ( Box :: new ( MyFileLoader ) ) )
86
+ . run ( ) ;
92
87
}
0 commit comments