]>
Commit | Line | Data |
---|---|---|
6a06907d XL |
1 | #![feature(rustc_private)] |
2 | ||
3 | // NOTE: For the example to compile, you will need to first run the following: | |
923072b8 | 4 | // rustup component add rustc-dev llvm-tools-preview |
6a06907d | 5 | |
923072b8 | 6 | // version: 1.62.0-nightly (7c4b47696 2022-04-30) |
cdc7bbd5 | 7 | |
6a06907d XL |
8 | extern crate rustc_ast_pretty; |
9 | extern crate rustc_error_codes; | |
10 | extern crate rustc_errors; | |
11 | extern crate rustc_hash; | |
12 | extern crate rustc_hir; | |
13 | extern crate rustc_interface; | |
14 | extern crate rustc_session; | |
15 | extern crate rustc_span; | |
16 | ||
923072b8 FG |
17 | use std::{path, process, str}; |
18 | ||
6a06907d XL |
19 | use rustc_ast_pretty::pprust::item_to_string; |
20 | use rustc_errors::registry; | |
04454e1e | 21 | use rustc_session::config::{self, CheckCfg}; |
6a06907d | 22 | use rustc_span::source_map; |
6a06907d XL |
23 | |
24 | fn main() { | |
25 | let out = process::Command::new("rustc") | |
26 | .arg("--print=sysroot") | |
27 | .current_dir(".") | |
28 | .output() | |
29 | .unwrap(); | |
30 | let sysroot = str::from_utf8(&out.stdout).unwrap().trim(); | |
31 | let config = rustc_interface::Config { | |
32 | opts: config::Options { | |
33 | maybe_sysroot: Some(path::PathBuf::from(sysroot)), | |
34 | ..config::Options::default() | |
35 | }, | |
36 | input: config::Input::Str { | |
37 | name: source_map::FileName::Custom("main.rs".to_string()), | |
923072b8 FG |
38 | input: r#" |
39 | fn main() { | |
40 | let message = "Hello, World!"; | |
41 | println!("{message}"); | |
42 | } | |
43 | "# | |
44 | .to_string(), | |
6a06907d XL |
45 | }, |
46 | diagnostic_output: rustc_session::DiagnosticOutput::Default, | |
47 | crate_cfg: rustc_hash::FxHashSet::default(), | |
04454e1e | 48 | crate_check_cfg: CheckCfg::default(), |
6a06907d XL |
49 | input_path: None, |
50 | output_dir: None, | |
51 | output_file: None, | |
52 | file_loader: None, | |
6a06907d | 53 | lint_caps: rustc_hash::FxHashMap::default(), |
cdc7bbd5 | 54 | parse_sess_created: None, |
6a06907d XL |
55 | register_lints: None, |
56 | override_queries: None, | |
57 | make_codegen_backend: None, | |
58 | registry: registry::Registry::new(&rustc_error_codes::DIAGNOSTICS), | |
59 | }; | |
60 | rustc_interface::run_compiler(config, |compiler| { | |
61 | compiler.enter(|queries| { | |
62 | // TODO: add this to -Z unpretty | |
63 | let ast_krate = queries.parse().unwrap().take(); | |
cdc7bbd5 | 64 | for item in ast_krate.items { |
6a06907d XL |
65 | println!("{}", item_to_string(&item)); |
66 | } | |
67 | ||
68 | // Analyze the crate and inspect the types under the cursor. | |
69 | queries.global_ctxt().unwrap().take().enter(|tcx| { | |
70 | // Every compilation contains a single crate. | |
a2a8927a | 71 | let hir_krate = tcx.hir(); |
6a06907d | 72 | // Iterate over the top-level items in the crate, looking for the main function. |
923072b8 FG |
73 | for id in hir_krate.items() { |
74 | let item = hir_krate.item(id); | |
6a06907d XL |
75 | // Use pattern-matching to find a specific node inside the main function. |
76 | if let rustc_hir::ItemKind::Fn(_, _, body_id) = item.kind { | |
77 | let expr = &tcx.hir().body(body_id).value; | |
78 | if let rustc_hir::ExprKind::Block(block, _) = expr.kind { | |
79 | if let rustc_hir::StmtKind::Local(local) = block.stmts[0].kind { | |
80 | if let Some(expr) = local.init { | |
81 | let hir_id = expr.hir_id; // hir_id identifies the string "Hello, world!" | |
cdc7bbd5 | 82 | let def_id = tcx.hir().local_def_id(item.hir_id()); // def_id identifies the main function |
6a06907d | 83 | let ty = tcx.typeck(def_id).node_type(hir_id); |
923072b8 | 84 | println!("{expr:#?}: {ty:?}"); |
6a06907d XL |
85 | } |
86 | } | |
87 | } | |
88 | } | |
89 | } | |
90 | }) | |
91 | }); | |
92 | }); | |
93 | } |