]>
Commit | Line | Data |
---|---|---|
0731742a | 1 | //! The various pretty-printing routines. |
1a4d82fc | 2 | |
3dfed10e | 3 | use rustc_ast as ast; |
74b04a01 | 4 | use rustc_ast_pretty::pprust; |
ba9703b0 | 5 | use rustc_errors::ErrorReported; |
dfeec247 XL |
6 | use rustc_hir as hir; |
7 | use rustc_hir::def_id::LOCAL_CRATE; | |
ba9703b0 XL |
8 | use rustc_hir_pretty as pprust_hir; |
9 | use rustc_middle::hir::map as hir_map; | |
10 | use rustc_middle::ty::{self, TyCtxt}; | |
dfeec247 | 11 | use rustc_mir::util::{write_mir_graphviz, write_mir_pretty}; |
6a06907d XL |
12 | use rustc_mir_build::thir; |
13 | use rustc_session::config::{Input, PpAstTreeMode, PpHirMode, PpMode, PpSourceMode}; | |
ba9703b0 | 14 | use rustc_session::Session; |
f9f354fc | 15 | use rustc_span::symbol::Ident; |
dfeec247 | 16 | use rustc_span::FileName; |
1a4d82fc | 17 | |
32a655c1 | 18 | use std::cell::Cell; |
6a06907d | 19 | use std::fmt::Write; |
a7813a04 | 20 | use std::path::Path; |
1a4d82fc | 21 | |
0731742a | 22 | pub use self::PpMode::*; |
dfeec247 | 23 | pub use self::PpSourceMode::*; |
532ac7d7 XL |
24 | use crate::abort_on_err; |
25 | ||
1a4d82fc JJ |
26 | // This slightly awkward construction is to allow for each PpMode to |
27 | // choose whether it needs to do analyses (which can consume the | |
28 | // Session) and then pass through the session (now attached to the | |
29 | // analysis results) on to the chosen pretty-printer, along with the | |
30 | // `&PpAnn` object. | |
31 | // | |
32 | // Note that since the `&PrinterSupport` is freshly constructed on each | |
33 | // call, it would not make sense to try to attach the lifetime of `self` | |
34 | // to the lifetime of the `&PrinterObject`. | |
1a4d82fc | 35 | |
60c5eb7d XL |
36 | /// Constructs a `PrinterSupport` object and passes it to `f`. |
37 | fn call_with_pp_support<'tcx, A, F>( | |
38 | ppmode: &PpSourceMode, | |
39 | sess: &'tcx Session, | |
40 | tcx: Option<TyCtxt<'tcx>>, | |
41 | f: F, | |
42 | ) -> A | |
43 | where | |
44 | F: FnOnce(&dyn PrinterSupport) -> A, | |
45 | { | |
46 | match *ppmode { | |
6a06907d | 47 | Normal | EveryBodyLoops | Expanded => { |
dfeec247 | 48 | let annotation = NoAnn { sess, tcx }; |
60c5eb7d XL |
49 | f(&annotation) |
50 | } | |
1a4d82fc | 51 | |
6a06907d | 52 | Identified | ExpandedIdentified => { |
dfeec247 | 53 | let annotation = IdentifiedAnnotation { sess, tcx }; |
60c5eb7d XL |
54 | f(&annotation) |
55 | } | |
6a06907d | 56 | ExpandedHygiene => { |
dfeec247 | 57 | let annotation = HygieneAnnotation { sess }; |
60c5eb7d XL |
58 | f(&annotation) |
59 | } | |
60c5eb7d XL |
60 | } |
61 | } | |
6a06907d | 62 | fn call_with_pp_support_hir<A, F>(ppmode: &PpHirMode, tcx: TyCtxt<'_>, f: F) -> A |
60c5eb7d | 63 | where |
dfeec247 | 64 | F: FnOnce(&dyn HirPrinterSupport<'_>, &hir::Crate<'_>) -> A, |
60c5eb7d XL |
65 | { |
66 | match *ppmode { | |
6a06907d | 67 | PpHirMode::Normal => { |
dfeec247 | 68 | let annotation = NoAnn { sess: tcx.sess, tcx: Some(tcx) }; |
74b04a01 | 69 | f(&annotation, tcx.hir().krate()) |
e9174d1e | 70 | } |
e9174d1e | 71 | |
6a06907d | 72 | PpHirMode::Identified => { |
dfeec247 | 73 | let annotation = IdentifiedAnnotation { sess: tcx.sess, tcx: Some(tcx) }; |
74b04a01 | 74 | f(&annotation, tcx.hir().krate()) |
60c5eb7d | 75 | } |
6a06907d | 76 | PpHirMode::Typed => { |
60c5eb7d XL |
77 | abort_on_err(tcx.analysis(LOCAL_CRATE), tcx.sess); |
78 | ||
3dfed10e | 79 | let annotation = TypedAnnotation { tcx, maybe_typeck_results: Cell::new(None) }; |
74b04a01 | 80 | tcx.dep_graph.with_ignore(|| f(&annotation, tcx.hir().krate())) |
1a4d82fc JJ |
81 | } |
82 | } | |
83 | } | |
84 | ||
32a655c1 | 85 | trait PrinterSupport: pprust::PpAnn { |
1a4d82fc JJ |
86 | /// Provides a uniform interface for re-extracting a reference to a |
87 | /// `Session` from a value that now owns it. | |
416331ca | 88 | fn sess(&self) -> &Session; |
1a4d82fc | 89 | |
1a4d82fc JJ |
90 | /// Produces the pretty-print annotation object. |
91 | /// | |
92 | /// (Rust does not yet support upcasting from a trait object to | |
93 | /// an object for one of its super-traits.) | |
ba9703b0 | 94 | fn pp_ann(&self) -> &dyn pprust::PpAnn; |
1a4d82fc JJ |
95 | } |
96 | ||
32a655c1 | 97 | trait HirPrinterSupport<'hir>: pprust_hir::PpAnn { |
e9174d1e SL |
98 | /// Provides a uniform interface for re-extracting a reference to a |
99 | /// `Session` from a value that now owns it. | |
416331ca | 100 | fn sess(&self) -> &Session; |
e9174d1e SL |
101 | |
102 | /// Provides a uniform interface for re-extracting a reference to an | |
103 | /// `hir_map::Map` from a value that now owns it. | |
ba9703b0 | 104 | fn hir_map(&self) -> Option<hir_map::Map<'hir>>; |
e9174d1e SL |
105 | |
106 | /// Produces the pretty-print annotation object. | |
107 | /// | |
108 | /// (Rust does not yet support upcasting from a trait object to | |
109 | /// an object for one of its super-traits.) | |
ba9703b0 | 110 | fn pp_ann(&self) -> &dyn pprust_hir::PpAnn; |
e9174d1e SL |
111 | } |
112 | ||
32a655c1 SL |
113 | struct NoAnn<'hir> { |
114 | sess: &'hir Session, | |
dc9dc135 | 115 | tcx: Option<TyCtxt<'hir>>, |
1a4d82fc JJ |
116 | } |
117 | ||
32a655c1 | 118 | impl<'hir> PrinterSupport for NoAnn<'hir> { |
416331ca | 119 | fn sess(&self) -> &Session { |
92a42be0 SL |
120 | self.sess |
121 | } | |
1a4d82fc | 122 | |
ba9703b0 | 123 | fn pp_ann(&self) -> &dyn pprust::PpAnn { |
92a42be0 SL |
124 | self |
125 | } | |
1a4d82fc JJ |
126 | } |
127 | ||
32a655c1 | 128 | impl<'hir> HirPrinterSupport<'hir> for NoAnn<'hir> { |
416331ca | 129 | fn sess(&self) -> &Session { |
92a42be0 SL |
130 | self.sess |
131 | } | |
e9174d1e | 132 | |
ba9703b0 XL |
133 | fn hir_map(&self) -> Option<hir_map::Map<'hir>> { |
134 | self.tcx.map(|tcx| tcx.hir()) | |
e9174d1e SL |
135 | } |
136 | ||
ba9703b0 | 137 | fn pp_ann(&self) -> &dyn pprust_hir::PpAnn { |
92a42be0 SL |
138 | self |
139 | } | |
e9174d1e SL |
140 | } |
141 | ||
32a655c1 SL |
142 | impl<'hir> pprust::PpAnn for NoAnn<'hir> {} |
143 | impl<'hir> pprust_hir::PpAnn for NoAnn<'hir> { | |
416331ca | 144 | fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { |
532ac7d7 | 145 | if let Some(tcx) = self.tcx { |
ba9703b0 | 146 | pprust_hir::PpAnn::nested(&(&tcx.hir() as &dyn hir::intravisit::Map<'_>), state, nested) |
32a655c1 SL |
147 | } |
148 | } | |
149 | } | |
1a4d82fc | 150 | |
32a655c1 SL |
151 | struct IdentifiedAnnotation<'hir> { |
152 | sess: &'hir Session, | |
dc9dc135 | 153 | tcx: Option<TyCtxt<'hir>>, |
1a4d82fc JJ |
154 | } |
155 | ||
32a655c1 | 156 | impl<'hir> PrinterSupport for IdentifiedAnnotation<'hir> { |
416331ca | 157 | fn sess(&self) -> &Session { |
92a42be0 SL |
158 | self.sess |
159 | } | |
1a4d82fc | 160 | |
ba9703b0 | 161 | fn pp_ann(&self) -> &dyn pprust::PpAnn { |
92a42be0 SL |
162 | self |
163 | } | |
1a4d82fc JJ |
164 | } |
165 | ||
32a655c1 | 166 | impl<'hir> pprust::PpAnn for IdentifiedAnnotation<'hir> { |
416331ca | 167 | fn pre(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) { |
ba9703b0 XL |
168 | if let pprust::AnnNode::Expr(_) = node { |
169 | s.popen(); | |
1a4d82fc JJ |
170 | } |
171 | } | |
416331ca | 172 | fn post(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) { |
1a4d82fc | 173 | match node { |
dfeec247 | 174 | pprust::AnnNode::Crate(_) | pprust::AnnNode::Ident(_) | pprust::AnnNode::Name(_) => {} |
1a4d82fc | 175 | |
b7449926 | 176 | pprust::AnnNode::Item(item) => { |
416331ca | 177 | s.s.space(); |
1a4d82fc JJ |
178 | s.synth_comment(item.id.to_string()) |
179 | } | |
b7449926 | 180 | pprust::AnnNode::SubItem(id) => { |
416331ca | 181 | s.s.space(); |
c34b1796 AL |
182 | s.synth_comment(id.to_string()) |
183 | } | |
b7449926 | 184 | pprust::AnnNode::Block(blk) => { |
416331ca | 185 | s.s.space(); |
1a4d82fc JJ |
186 | s.synth_comment(format!("block {}", blk.id)) |
187 | } | |
b7449926 | 188 | pprust::AnnNode::Expr(expr) => { |
416331ca XL |
189 | s.s.space(); |
190 | s.synth_comment(expr.id.to_string()); | |
1a4d82fc JJ |
191 | s.pclose() |
192 | } | |
b7449926 | 193 | pprust::AnnNode::Pat(pat) => { |
416331ca XL |
194 | s.s.space(); |
195 | s.synth_comment(format!("pat {}", pat.id)); | |
1a4d82fc JJ |
196 | } |
197 | } | |
198 | } | |
199 | } | |
200 | ||
32a655c1 | 201 | impl<'hir> HirPrinterSupport<'hir> for IdentifiedAnnotation<'hir> { |
416331ca | 202 | fn sess(&self) -> &Session { |
92a42be0 SL |
203 | self.sess |
204 | } | |
e9174d1e | 205 | |
ba9703b0 XL |
206 | fn hir_map(&self) -> Option<hir_map::Map<'hir>> { |
207 | self.tcx.map(|tcx| tcx.hir()) | |
e9174d1e SL |
208 | } |
209 | ||
ba9703b0 | 210 | fn pp_ann(&self) -> &dyn pprust_hir::PpAnn { |
92a42be0 SL |
211 | self |
212 | } | |
e9174d1e SL |
213 | } |
214 | ||
32a655c1 | 215 | impl<'hir> pprust_hir::PpAnn for IdentifiedAnnotation<'hir> { |
416331ca | 216 | fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { |
532ac7d7 | 217 | if let Some(ref tcx) = self.tcx { |
ba9703b0 | 218 | pprust_hir::PpAnn::nested(&(&tcx.hir() as &dyn hir::intravisit::Map<'_>), state, nested) |
32a655c1 SL |
219 | } |
220 | } | |
416331ca | 221 | fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { |
ba9703b0 XL |
222 | if let pprust_hir::AnnNode::Expr(_) = node { |
223 | s.popen(); | |
e9174d1e SL |
224 | } |
225 | } | |
416331ca | 226 | fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { |
e9174d1e | 227 | match node { |
dfeec247 | 228 | pprust_hir::AnnNode::Name(_) => {} |
b7449926 | 229 | pprust_hir::AnnNode::Item(item) => { |
416331ca | 230 | s.s.space(); |
6a06907d | 231 | s.synth_comment(format!("hir_id: {}", item.hir_id())); |
e9174d1e | 232 | } |
b7449926 | 233 | pprust_hir::AnnNode::SubItem(id) => { |
416331ca XL |
234 | s.s.space(); |
235 | s.synth_comment(id.to_string()); | |
e9174d1e | 236 | } |
b7449926 | 237 | pprust_hir::AnnNode::Block(blk) => { |
416331ca XL |
238 | s.s.space(); |
239 | s.synth_comment(format!("block hir_id: {}", blk.hir_id)); | |
e9174d1e | 240 | } |
b7449926 | 241 | pprust_hir::AnnNode::Expr(expr) => { |
416331ca XL |
242 | s.s.space(); |
243 | s.synth_comment(format!("expr hir_id: {}", expr.hir_id)); | |
244 | s.pclose(); | |
e9174d1e | 245 | } |
b7449926 | 246 | pprust_hir::AnnNode::Pat(pat) => { |
416331ca XL |
247 | s.s.space(); |
248 | s.synth_comment(format!("pat hir_id: {}", pat.hir_id)); | |
249 | } | |
250 | pprust_hir::AnnNode::Arm(arm) => { | |
251 | s.s.space(); | |
252 | s.synth_comment(format!("arm hir_id: {}", arm.hir_id)); | |
e9174d1e SL |
253 | } |
254 | } | |
255 | } | |
256 | } | |
257 | ||
32a655c1 | 258 | struct HygieneAnnotation<'a> { |
dfeec247 | 259 | sess: &'a Session, |
1a4d82fc JJ |
260 | } |
261 | ||
32a655c1 SL |
262 | impl<'a> PrinterSupport for HygieneAnnotation<'a> { |
263 | fn sess(&self) -> &Session { | |
92a42be0 SL |
264 | self.sess |
265 | } | |
1a4d82fc | 266 | |
8faf50e0 | 267 | fn pp_ann(&self) -> &dyn pprust::PpAnn { |
92a42be0 SL |
268 | self |
269 | } | |
1a4d82fc JJ |
270 | } |
271 | ||
32a655c1 | 272 | impl<'a> pprust::PpAnn for HygieneAnnotation<'a> { |
416331ca | 273 | fn post(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) { |
1a4d82fc | 274 | match node { |
f9f354fc | 275 | pprust::AnnNode::Ident(&Ident { name, span }) => { |
416331ca | 276 | s.s.space(); |
83c7162d | 277 | s.synth_comment(format!("{}{:?}", name.as_u32(), span.ctxt())) |
1a4d82fc | 278 | } |
b7449926 | 279 | pprust::AnnNode::Name(&name) => { |
416331ca | 280 | s.s.space(); |
476ff2be | 281 | s.synth_comment(name.as_u32().to_string()) |
1a4d82fc | 282 | } |
e1599b0c XL |
283 | pprust::AnnNode::Crate(_) => { |
284 | s.s.hardbreak(); | |
285 | let verbose = self.sess.verbose(); | |
dfeec247 | 286 | s.synth_comment(rustc_span::hygiene::debug_hygiene_data(verbose)); |
e1599b0c XL |
287 | s.s.hardbreak_if_not_bol(); |
288 | } | |
416331ca | 289 | _ => {} |
1a4d82fc JJ |
290 | } |
291 | } | |
292 | } | |
293 | ||
f035d41b | 294 | struct TypedAnnotation<'tcx> { |
dc9dc135 | 295 | tcx: TyCtxt<'tcx>, |
3dfed10e | 296 | maybe_typeck_results: Cell<Option<&'tcx ty::TypeckResults<'tcx>>>, |
1a4d82fc JJ |
297 | } |
298 | ||
f035d41b | 299 | impl<'tcx> TypedAnnotation<'tcx> { |
3dfed10e | 300 | /// Gets the type-checking results for the current body. |
f035d41b XL |
301 | /// As this will ICE if called outside bodies, only call when working with |
302 | /// `Expr` or `Pat` nodes (they are guaranteed to be found only in bodies). | |
303 | #[track_caller] | |
3dfed10e XL |
304 | fn typeck_results(&self) -> &'tcx ty::TypeckResults<'tcx> { |
305 | self.maybe_typeck_results | |
306 | .get() | |
307 | .expect("`TypedAnnotation::typeck_results` called outside of body") | |
f035d41b XL |
308 | } |
309 | } | |
310 | ||
311 | impl<'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'tcx> { | |
416331ca | 312 | fn sess(&self) -> &Session { |
92a42be0 SL |
313 | &self.tcx.sess |
314 | } | |
1a4d82fc | 315 | |
ba9703b0 XL |
316 | fn hir_map(&self) -> Option<hir_map::Map<'tcx>> { |
317 | Some(self.tcx.hir()) | |
1a4d82fc JJ |
318 | } |
319 | ||
ba9703b0 | 320 | fn pp_ann(&self) -> &dyn pprust_hir::PpAnn { |
92a42be0 SL |
321 | self |
322 | } | |
1a4d82fc JJ |
323 | } |
324 | ||
f035d41b | 325 | impl<'tcx> pprust_hir::PpAnn for TypedAnnotation<'tcx> { |
416331ca | 326 | fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { |
3dfed10e | 327 | let old_maybe_typeck_results = self.maybe_typeck_results.get(); |
32a655c1 | 328 | if let pprust_hir::Nested::Body(id) = nested { |
3dfed10e | 329 | self.maybe_typeck_results.set(Some(self.tcx.typeck_body(id))); |
32a655c1 | 330 | } |
ba9703b0 XL |
331 | let pp_ann = &(&self.tcx.hir() as &dyn hir::intravisit::Map<'_>); |
332 | pprust_hir::PpAnn::nested(pp_ann, state, nested); | |
3dfed10e | 333 | self.maybe_typeck_results.set(old_maybe_typeck_results); |
32a655c1 | 334 | } |
416331ca | 335 | fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { |
ba9703b0 XL |
336 | if let pprust_hir::AnnNode::Expr(_) = node { |
337 | s.popen(); | |
1a4d82fc JJ |
338 | } |
339 | } | |
416331ca | 340 | fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { |
ba9703b0 XL |
341 | if let pprust_hir::AnnNode::Expr(expr) = node { |
342 | s.s.space(); | |
343 | s.s.word("as"); | |
344 | s.s.space(); | |
3dfed10e | 345 | s.s.word(self.typeck_results().expr_ty(expr).to_string()); |
ba9703b0 | 346 | s.pclose(); |
1a4d82fc JJ |
347 | } |
348 | } | |
349 | } | |
350 | ||
416331ca | 351 | fn get_source(input: &Input, sess: &Session) -> (String, FileName) { |
60c5eb7d | 352 | let src_name = input.source_name(); |
5869c6ff XL |
353 | let src = String::clone( |
354 | &sess | |
355 | .source_map() | |
356 | .get_source_file(&src_name) | |
357 | .expect("get_source_file") | |
358 | .src | |
359 | .as_ref() | |
360 | .expect("src"), | |
361 | ); | |
a7813a04 XL |
362 | (src, src_name) |
363 | } | |
364 | ||
6a06907d | 365 | fn write_or_print(out: &str, ofile: Option<&Path>) { |
a7813a04 | 366 | match ofile { |
6a06907d XL |
367 | None => print!("{}", out), |
368 | Some(p) => { | |
369 | if let Err(e) = std::fs::write(p, out) { | |
370 | panic!("print-print failed to write {} due to {}", p.display(), e); | |
371 | } | |
372 | } | |
a7813a04 XL |
373 | } |
374 | } | |
1a4d82fc | 375 | |
dfeec247 XL |
376 | pub fn print_after_parsing( |
377 | sess: &Session, | |
378 | input: &Input, | |
379 | krate: &ast::Crate, | |
380 | ppm: PpMode, | |
381 | ofile: Option<&Path>, | |
382 | ) { | |
a7813a04 XL |
383 | let (src, src_name) = get_source(input, sess); |
384 | ||
6a06907d XL |
385 | let out = match ppm { |
386 | Source(s) => { | |
387 | // Silently ignores an identified node. | |
388 | call_with_pp_support(&s, sess, None, move |annotation| { | |
389 | debug!("pretty printing source code {:?}", s); | |
390 | let sess = annotation.sess(); | |
391 | let parse = &sess.parse_sess; | |
392 | pprust::print_crate( | |
393 | sess.source_map(), | |
394 | krate, | |
395 | src_name, | |
396 | src, | |
397 | annotation.pp_ann(), | |
398 | false, | |
399 | parse.edition, | |
400 | ) | |
401 | }) | |
402 | } | |
403 | AstTree(PpAstTreeMode::Normal) => { | |
404 | debug!("pretty printing AST tree"); | |
405 | format!("{:#?}", krate) | |
406 | } | |
407 | _ => unreachable!(), | |
a7813a04 XL |
408 | }; |
409 | ||
6a06907d | 410 | write_or_print(&out, ofile); |
a7813a04 XL |
411 | } |
412 | ||
532ac7d7 | 413 | pub fn print_after_hir_lowering<'tcx>( |
dc9dc135 | 414 | tcx: TyCtxt<'tcx>, |
532ac7d7 XL |
415 | input: &Input, |
416 | krate: &ast::Crate, | |
417 | ppm: PpMode, | |
dc9dc135 XL |
418 | ofile: Option<&Path>, |
419 | ) { | |
a7813a04 | 420 | if ppm.needs_analysis() { |
dfeec247 | 421 | abort_on_err(print_with_analysis(tcx, ppm, ofile), tcx.sess); |
a7813a04 XL |
422 | return; |
423 | } | |
424 | ||
532ac7d7 | 425 | let (src, src_name) = get_source(input, tcx.sess); |
a7813a04 | 426 | |
6a06907d XL |
427 | let out = match ppm { |
428 | Source(s) => { | |
dfeec247 | 429 | // Silently ignores an identified node. |
dfeec247 XL |
430 | call_with_pp_support(&s, tcx.sess, Some(tcx), move |annotation| { |
431 | debug!("pretty printing source code {:?}", s); | |
432 | let sess = annotation.sess(); | |
74b04a01 | 433 | let parse = &sess.parse_sess; |
6a06907d | 434 | pprust::print_crate( |
dfeec247 | 435 | sess.source_map(), |
dfeec247 XL |
436 | krate, |
437 | src_name, | |
438 | src, | |
439 | annotation.pp_ann(), | |
440 | true, | |
74b04a01 | 441 | parse.edition, |
dfeec247 XL |
442 | ) |
443 | }) | |
444 | } | |
e9174d1e | 445 | |
6a06907d XL |
446 | AstTree(PpAstTreeMode::Expanded) => { |
447 | debug!("pretty-printing expanded AST"); | |
448 | format!("{:#?}", krate) | |
dfeec247 | 449 | } |
ff7c6d11 | 450 | |
6a06907d XL |
451 | Hir(s) => call_with_pp_support_hir(&s, tcx, move |annotation, krate| { |
452 | debug!("pretty printing HIR {:?}", s); | |
453 | let sess = annotation.sess(); | |
454 | let sm = sess.source_map(); | |
455 | pprust_hir::print_crate(sm, krate, src_name, src, annotation.pp_ann()) | |
456 | }), | |
457 | ||
458 | HirTree => call_with_pp_support_hir(&PpHirMode::Normal, tcx, move |_annotation, krate| { | |
459 | debug!("pretty printing HIR tree"); | |
460 | format!("{:#?}", krate) | |
461 | }), | |
462 | ||
dfeec247 | 463 | _ => unreachable!(), |
6a06907d | 464 | }; |
dfeec247 | 465 | |
6a06907d | 466 | write_or_print(&out, ofile); |
a7813a04 XL |
467 | } |
468 | ||
469 | // In an ideal world, this would be a public function called by the driver after | |
9fa01778 | 470 | // analysis is performed. However, we want to call `phase_3_run_analysis_passes` |
a7813a04 XL |
471 | // with a different callback than the standard driver, so that isn't easy. |
472 | // Instead, we call that function ourselves. | |
416331ca XL |
473 | fn print_with_analysis( |
474 | tcx: TyCtxt<'_>, | |
532ac7d7 | 475 | ppm: PpMode, |
dc9dc135 | 476 | ofile: Option<&Path>, |
532ac7d7 | 477 | ) -> Result<(), ErrorReported> { |
532ac7d7 XL |
478 | tcx.analysis(LOCAL_CRATE)?; |
479 | ||
cdc7bbd5 XL |
480 | let out = match ppm { |
481 | Mir => { | |
482 | let mut out = Vec::new(); | |
483 | write_mir_pretty(tcx, None, &mut out).unwrap(); | |
484 | String::from_utf8(out).unwrap() | |
485 | } | |
486 | ||
487 | MirCFG => { | |
488 | let mut out = Vec::new(); | |
489 | write_mir_graphviz(tcx, None, &mut out).unwrap(); | |
490 | String::from_utf8(out).unwrap() | |
491 | } | |
492 | ||
493 | ThirTree => { | |
494 | let mut out = String::new(); | |
495 | abort_on_err(rustc_typeck::check_crate(tcx), tcx.sess); | |
496 | debug!("pretty printing THIR tree"); | |
497 | for did in tcx.body_owners() { | |
498 | let hir = tcx.hir(); | |
499 | let body = hir.body(hir.body_owned_by(hir.local_def_id_to_hir_id(did))); | |
500 | let arena = thir::Arena::default(); | |
501 | let thir = | |
502 | thir::build_thir(tcx, ty::WithOptConstParam::unknown(did), &arena, &body.value); | |
503 | let _ = writeln!(out, "{:?}:\n{:#?}\n", did, thir); | |
504 | } | |
505 | out | |
506 | } | |
507 | ||
532ac7d7 | 508 | _ => unreachable!(), |
cdc7bbd5 | 509 | }; |
c34b1796 | 510 | |
cdc7bbd5 | 511 | write_or_print(&out, ofile); |
532ac7d7 XL |
512 | |
513 | Ok(()) | |
1a4d82fc | 514 | } |