| // Tested with nightly-2025-03-28 | |
| #![feature(rustc_private)] | |
| extern crate rustc_driver; | |
| extern crate rustc_error_codes; | |
| extern crate rustc_hash; | |
| extern crate rustc_hir; | |
| extern crate rustc_interface; | |
| extern crate rustc_session; | |
| extern crate rustc_span; | |
| use rustc_hash::FxHashMap; | |
| use rustc_session::config; | |
| fn main() { | |
| let config = rustc_interface::Config { | |
| // Command line options | |
| opts: config::Options::default(), | |
| // cfg! configuration in addition to the default ones | |
| crate_cfg: Vec::new(), // FxHashSet<(String, Option<String>)> | |
| crate_check_cfg: Vec::new(), // CheckCfg | |
| input: config::Input::Str { | |
| name: rustc_span::FileName::Custom("main.rs".into()), | |
| input: r#" | |
| static HELLO: &str = "Hello, world!"; | |
| fn main() { | |
| println!("{HELLO}"); | |
| } | |
| "# | |
| .into(), | |
| }, | |
| output_dir: None, // Option<PathBuf> | |
| output_file: None, // Option<PathBuf> | |
| file_loader: None, // Option<Box<dyn FileLoader + Send + Sync>> | |
| lint_caps: FxHashMap::default(), // FxHashMap<lint::LintId, lint::Level> | |
| // This is a callback from the driver that is called when [`ParseSess`] is created. | |
| psess_created: None, //Option<Box<dyn FnOnce(&mut ParseSess) + Send>> | |
| // This is a callback from the driver that is called when we're registering lints; | |
| // it is called during plugin registration when we have the LintStore in a non-shared state. | |
| // | |
| // Note that if you find a Some here you probably want to call that function in the new | |
| // function being registered. | |
| register_lints: None, // Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>> | |
| // This is a callback from the driver that is called just after we have populated | |
| // the list of queries. | |
| // | |
| // The second parameter is local providers and the third parameter is external providers. | |
| override_queries: None, // Option<fn(&Session, &mut ty::query::Providers<'_>, &mut ty::query::Providers<'_>)> | |
| make_codegen_backend: None, | |
| expanded_args: Vec::new(), | |
| ice_file: None, | |
| track_state: None, | |
| using_internal_features: &rustc_driver::USING_INTERNAL_FEATURES, | |
| }; | |
| rustc_interface::run_compiler(config, |compiler| { | |
| // Parse the program and print the syntax tree. | |
| let krate = rustc_interface::passes::parse(&compiler.sess); | |
| println!("{krate:?}"); | |
| // Analyze the program and inspect the types of definitions. | |
| rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| { | |
| for id in tcx.hir_free_items() { | |
| let item = tcx.hir_item(id); | |
| match item.kind { | |
| rustc_hir::ItemKind::Static(ident, ..) | |
| | rustc_hir::ItemKind::Fn { ident, .. } => { | |
| let ty = tcx.type_of(item.hir_id().owner.def_id); | |
| println!("{ident:?}:\t{ty:?}") | |
| } | |
| _ => (), | |
| } | |
| } | |
| }); | |
| }); | |
| } |