]> git.proxmox.com Git - rustc.git/blame - src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs
New upstream version 1.63.0+dfsg1
[rustc.git] / src / doc / rustc-dev-guide / examples / rustc-driver-interacting-with-the-ast.rs
CommitLineData
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
8extern crate rustc_ast_pretty;
9extern crate rustc_error_codes;
10extern crate rustc_errors;
11extern crate rustc_hash;
12extern crate rustc_hir;
13extern crate rustc_interface;
14extern crate rustc_session;
15extern crate rustc_span;
16
923072b8
FG
17use std::{path, process, str};
18
6a06907d
XL
19use rustc_ast_pretty::pprust::item_to_string;
20use rustc_errors::registry;
04454e1e 21use rustc_session::config::{self, CheckCfg};
6a06907d 22use rustc_span::source_map;
6a06907d
XL
23
24fn 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#"
39fn 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}