]>
git.proxmox.com Git - rustc.git/blob - src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs
1 #![feature(rustc_private)]
3 extern crate rustc_ast_pretty
;
4 extern crate rustc_driver
;
5 extern crate rustc_error_codes
;
6 extern crate rustc_errors
;
7 extern crate rustc_hash
;
8 extern crate rustc_hir
;
9 extern crate rustc_interface
;
10 extern crate rustc_session
;
11 extern crate rustc_span
;
13 use std
::{path, process, str}
;
15 use rustc_ast_pretty
::pprust
::item_to_string
;
16 use rustc_errors
::registry
;
17 use rustc_session
::config
::{self, CheckCfg}
;
18 use rustc_span
::source_map
;
21 let out
= process
::Command
::new("rustc")
22 .arg("--print=sysroot")
26 let sysroot
= str::from_utf8(&out
.stdout
).unwrap().trim();
27 let config
= rustc_interface
::Config
{
28 opts
: config
::Options
{
29 maybe_sysroot
: Some(path
::PathBuf
::from(sysroot
)),
30 ..config
::Options
::default()
32 input
: config
::Input
::Str
{
33 name
: source_map
::FileName
::Custom("main.rs".to_string()),
36 let message = "Hello, World!";
37 println!("{message}");
42 crate_cfg
: rustc_hash
::FxHashSet
::default(),
43 crate_check_cfg
: CheckCfg
::default(),
47 locale_resources
: rustc_driver
::DEFAULT_LOCALE_RESOURCES
,
48 lint_caps
: rustc_hash
::FxHashMap
::default(),
49 parse_sess_created
: None
,
51 override_queries
: None
,
52 make_codegen_backend
: None
,
53 registry
: registry
::Registry
::new(&rustc_error_codes
::DIAGNOSTICS
),
55 rustc_interface
::run_compiler(config
, |compiler
| {
56 compiler
.enter(|queries
| {
57 // TODO: add this to -Z unpretty
58 let ast_krate
= queries
.parse().unwrap().get_mut().clone();
59 for item
in ast_krate
.items
{
60 println
!("{}", item_to_string(&item
));
62 // Analyze the crate and inspect the types under the cursor.
63 queries
.global_ctxt().unwrap().enter(|tcx
| {
64 // Every compilation contains a single crate.
65 let hir_krate
= tcx
.hir();
66 // Iterate over the top-level items in the crate, looking for the main function.
67 for id
in hir_krate
.items() {
68 let item
= hir_krate
.item(id
);
69 // Use pattern-matching to find a specific node inside the main function.
70 if let rustc_hir
::ItemKind
::Fn(_
, _
, body_id
) = item
.kind
{
71 let expr
= &tcx
.hir().body(body_id
).value
;
72 if let rustc_hir
::ExprKind
::Block(block
, _
) = expr
.kind
{
73 if let rustc_hir
::StmtKind
::Local(local
) = block
.stmts
[0].kind
{
74 if let Some(expr
) = local
.init
{
75 let hir_id
= expr
.hir_id
; // hir_id identifies the string "Hello, world!"
76 let def_id
= item
.hir_id().owner
.def_id
; // def_id identifies the main function
77 let ty
= tcx
.typeck(def_id
).node_type(hir_id
);
78 println
!("{expr:#?}: {ty:?}");