]>
Commit | Line | Data |
---|---|---|
0731742a | 1 | //! The various pretty-printing routines. |
1a4d82fc | 2 | |
0731742a XL |
3 | use rustc::hir; |
4 | use rustc::hir::map as hir_map; | |
0731742a | 5 | use rustc::hir::print as pprust_hir; |
532ac7d7 | 6 | use rustc::hir::def_id::LOCAL_CRATE; |
1a4d82fc | 7 | use rustc::session::Session; |
60c5eb7d | 8 | use rustc::session::config::{PpMode, PpSourceMode, Input}; |
532ac7d7 XL |
9 | use rustc::ty::{self, TyCtxt}; |
10 | use rustc::util::common::ErrorReported; | |
cc61c64b | 11 | use rustc_mir::util::{write_mir_pretty, write_mir_graphviz}; |
7453a54e | 12 | |
532ac7d7 | 13 | use syntax::ast; |
041b39d2 | 14 | use syntax::print::{pprust}; |
532ac7d7 | 15 | use syntax_pos::FileName; |
1a4d82fc | 16 | |
32a655c1 | 17 | use std::cell::Cell; |
c34b1796 | 18 | use std::fs::File; |
e74abb32 | 19 | use std::io::Write; |
a7813a04 | 20 | use std::path::Path; |
1a4d82fc | 21 | |
0731742a XL |
22 | pub use self::PpSourceMode::*; |
23 | pub use self::PpMode::*; | |
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`. | |
35 | // | |
36 | // (The `use_once_payload` is working around the current lack of once | |
37 | // functions in the compiler.) | |
38 | ||
60c5eb7d XL |
39 | /// Constructs a `PrinterSupport` object and passes it to `f`. |
40 | fn call_with_pp_support<'tcx, A, F>( | |
41 | ppmode: &PpSourceMode, | |
42 | sess: &'tcx Session, | |
43 | tcx: Option<TyCtxt<'tcx>>, | |
44 | f: F, | |
45 | ) -> A | |
46 | where | |
47 | F: FnOnce(&dyn PrinterSupport) -> A, | |
48 | { | |
49 | match *ppmode { | |
50 | PpmNormal | PpmEveryBodyLoops | PpmExpanded => { | |
51 | let annotation = NoAnn { | |
52 | sess, | |
53 | tcx, | |
54 | }; | |
55 | f(&annotation) | |
56 | } | |
1a4d82fc | 57 | |
60c5eb7d XL |
58 | PpmIdentified | PpmExpandedIdentified => { |
59 | let annotation = IdentifiedAnnotation { | |
60 | sess, | |
61 | tcx, | |
62 | }; | |
63 | f(&annotation) | |
64 | } | |
65 | PpmExpandedHygiene => { | |
66 | let annotation = HygieneAnnotation { | |
67 | sess, | |
68 | }; | |
69 | f(&annotation) | |
70 | } | |
71 | _ => panic!("Should use call_with_pp_support_hir"), | |
72 | } | |
73 | } | |
74 | fn call_with_pp_support_hir<A, F>(ppmode: &PpSourceMode, tcx: TyCtxt<'_>, f: F) -> A | |
75 | where | |
76 | F: FnOnce(&dyn HirPrinterSupport<'_>, &hir::Crate) -> A, | |
77 | { | |
78 | match *ppmode { | |
79 | PpmNormal => { | |
80 | let annotation = NoAnn { | |
81 | sess: tcx.sess, | |
82 | tcx: Some(tcx), | |
83 | }; | |
84 | f(&annotation, tcx.hir().forest.krate()) | |
e9174d1e | 85 | } |
e9174d1e | 86 | |
60c5eb7d XL |
87 | PpmIdentified => { |
88 | let annotation = IdentifiedAnnotation { | |
89 | sess: tcx.sess, | |
90 | tcx: Some(tcx), | |
91 | }; | |
92 | f(&annotation, tcx.hir().forest.krate()) | |
93 | } | |
94 | PpmTyped => { | |
95 | abort_on_err(tcx.analysis(LOCAL_CRATE), tcx.sess); | |
96 | ||
97 | let empty_tables = ty::TypeckTables::empty(None); | |
98 | let annotation = TypedAnnotation { | |
99 | tcx, | |
100 | tables: Cell::new(&empty_tables) | |
101 | }; | |
102 | tcx.dep_graph.with_ignore(|| { | |
532ac7d7 | 103 | f(&annotation, tcx.hir().forest.krate()) |
60c5eb7d | 104 | }) |
1a4d82fc | 105 | } |
60c5eb7d | 106 | _ => panic!("Should use call_with_pp_support"), |
1a4d82fc JJ |
107 | } |
108 | } | |
109 | ||
32a655c1 | 110 | trait PrinterSupport: pprust::PpAnn { |
1a4d82fc JJ |
111 | /// Provides a uniform interface for re-extracting a reference to a |
112 | /// `Session` from a value that now owns it. | |
416331ca | 113 | fn sess(&self) -> &Session; |
1a4d82fc | 114 | |
1a4d82fc JJ |
115 | /// Produces the pretty-print annotation object. |
116 | /// | |
117 | /// (Rust does not yet support upcasting from a trait object to | |
118 | /// an object for one of its super-traits.) | |
8faf50e0 | 119 | fn pp_ann<'a>(&'a self) -> &'a dyn pprust::PpAnn; |
1a4d82fc JJ |
120 | } |
121 | ||
32a655c1 | 122 | trait HirPrinterSupport<'hir>: pprust_hir::PpAnn { |
e9174d1e SL |
123 | /// Provides a uniform interface for re-extracting a reference to a |
124 | /// `Session` from a value that now owns it. | |
416331ca | 125 | fn sess(&self) -> &Session; |
e9174d1e SL |
126 | |
127 | /// Provides a uniform interface for re-extracting a reference to an | |
128 | /// `hir_map::Map` from a value that now owns it. | |
32a655c1 | 129 | fn hir_map<'a>(&'a self) -> Option<&'a hir_map::Map<'hir>>; |
e9174d1e SL |
130 | |
131 | /// Produces the pretty-print annotation object. | |
132 | /// | |
133 | /// (Rust does not yet support upcasting from a trait object to | |
134 | /// an object for one of its super-traits.) | |
8faf50e0 | 135 | fn pp_ann<'a>(&'a self) -> &'a dyn pprust_hir::PpAnn; |
54a0048b SL |
136 | |
137 | /// Computes an user-readable representation of a path, if possible. | |
dc9dc135 | 138 | fn node_path(&self, id: hir::HirId) -> Option<String> { |
48663c56 | 139 | self.hir_map().and_then(|map| { |
dc9dc135 | 140 | map.def_path_from_hir_id(id) |
48663c56 | 141 | }).map(|path| { |
c30ab7b3 SL |
142 | path.data |
143 | .into_iter() | |
144 | .map(|elem| elem.data.to_string()) | |
145 | .collect::<Vec<_>>() | |
146 | .join("::") | |
54a0048b SL |
147 | }) |
148 | } | |
e9174d1e SL |
149 | } |
150 | ||
32a655c1 SL |
151 | struct NoAnn<'hir> { |
152 | sess: &'hir Session, | |
dc9dc135 | 153 | tcx: Option<TyCtxt<'hir>>, |
1a4d82fc JJ |
154 | } |
155 | ||
32a655c1 | 156 | impl<'hir> PrinterSupport for NoAnn<'hir> { |
416331ca | 157 | fn sess(&self) -> &Session { |
92a42be0 SL |
158 | self.sess |
159 | } | |
1a4d82fc | 160 | |
8faf50e0 | 161 | fn pp_ann<'a>(&'a self) -> &'a dyn pprust::PpAnn { |
92a42be0 SL |
162 | self |
163 | } | |
1a4d82fc JJ |
164 | } |
165 | ||
32a655c1 | 166 | impl<'hir> HirPrinterSupport<'hir> for NoAnn<'hir> { |
416331ca | 167 | fn sess(&self) -> &Session { |
92a42be0 SL |
168 | self.sess |
169 | } | |
e9174d1e | 170 | |
32a655c1 | 171 | fn hir_map<'a>(&'a self) -> Option<&'a hir_map::Map<'hir>> { |
532ac7d7 | 172 | self.tcx.map(|tcx| tcx.hir()) |
e9174d1e SL |
173 | } |
174 | ||
8faf50e0 | 175 | fn pp_ann<'a>(&'a self) -> &'a dyn pprust_hir::PpAnn { |
92a42be0 SL |
176 | self |
177 | } | |
e9174d1e SL |
178 | } |
179 | ||
32a655c1 SL |
180 | impl<'hir> pprust::PpAnn for NoAnn<'hir> {} |
181 | impl<'hir> pprust_hir::PpAnn for NoAnn<'hir> { | |
416331ca | 182 | fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { |
532ac7d7 XL |
183 | if let Some(tcx) = self.tcx { |
184 | pprust_hir::PpAnn::nested(tcx.hir(), state, nested) | |
32a655c1 SL |
185 | } |
186 | } | |
187 | } | |
1a4d82fc | 188 | |
32a655c1 SL |
189 | struct IdentifiedAnnotation<'hir> { |
190 | sess: &'hir Session, | |
dc9dc135 | 191 | tcx: Option<TyCtxt<'hir>>, |
1a4d82fc JJ |
192 | } |
193 | ||
32a655c1 | 194 | impl<'hir> PrinterSupport for IdentifiedAnnotation<'hir> { |
416331ca | 195 | fn sess(&self) -> &Session { |
92a42be0 SL |
196 | self.sess |
197 | } | |
1a4d82fc | 198 | |
8faf50e0 | 199 | fn pp_ann<'a>(&'a self) -> &'a dyn pprust::PpAnn { |
92a42be0 SL |
200 | self |
201 | } | |
1a4d82fc JJ |
202 | } |
203 | ||
32a655c1 | 204 | impl<'hir> pprust::PpAnn for IdentifiedAnnotation<'hir> { |
416331ca | 205 | fn pre(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) { |
1a4d82fc | 206 | match node { |
b7449926 | 207 | pprust::AnnNode::Expr(_) => s.popen(), |
416331ca | 208 | _ => {} |
1a4d82fc JJ |
209 | } |
210 | } | |
416331ca | 211 | fn post(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) { |
1a4d82fc | 212 | match node { |
e1599b0c | 213 | pprust::AnnNode::Crate(_) | |
b7449926 | 214 | pprust::AnnNode::Ident(_) | |
416331ca | 215 | pprust::AnnNode::Name(_) => {}, |
1a4d82fc | 216 | |
b7449926 | 217 | pprust::AnnNode::Item(item) => { |
416331ca | 218 | s.s.space(); |
1a4d82fc JJ |
219 | s.synth_comment(item.id.to_string()) |
220 | } | |
b7449926 | 221 | pprust::AnnNode::SubItem(id) => { |
416331ca | 222 | s.s.space(); |
c34b1796 AL |
223 | s.synth_comment(id.to_string()) |
224 | } | |
b7449926 | 225 | pprust::AnnNode::Block(blk) => { |
416331ca | 226 | s.s.space(); |
1a4d82fc JJ |
227 | s.synth_comment(format!("block {}", blk.id)) |
228 | } | |
b7449926 | 229 | pprust::AnnNode::Expr(expr) => { |
416331ca XL |
230 | s.s.space(); |
231 | s.synth_comment(expr.id.to_string()); | |
1a4d82fc JJ |
232 | s.pclose() |
233 | } | |
b7449926 | 234 | pprust::AnnNode::Pat(pat) => { |
416331ca XL |
235 | s.s.space(); |
236 | s.synth_comment(format!("pat {}", pat.id)); | |
1a4d82fc JJ |
237 | } |
238 | } | |
239 | } | |
240 | } | |
241 | ||
32a655c1 | 242 | impl<'hir> HirPrinterSupport<'hir> for IdentifiedAnnotation<'hir> { |
416331ca | 243 | fn sess(&self) -> &Session { |
92a42be0 SL |
244 | self.sess |
245 | } | |
e9174d1e | 246 | |
32a655c1 | 247 | fn hir_map<'a>(&'a self) -> Option<&'a hir_map::Map<'hir>> { |
532ac7d7 | 248 | self.tcx.map(|tcx| tcx.hir()) |
e9174d1e SL |
249 | } |
250 | ||
8faf50e0 | 251 | fn pp_ann<'a>(&'a self) -> &'a dyn pprust_hir::PpAnn { |
92a42be0 SL |
252 | self |
253 | } | |
e9174d1e SL |
254 | } |
255 | ||
32a655c1 | 256 | impl<'hir> pprust_hir::PpAnn for IdentifiedAnnotation<'hir> { |
416331ca | 257 | fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { |
532ac7d7 XL |
258 | if let Some(ref tcx) = self.tcx { |
259 | pprust_hir::PpAnn::nested(tcx.hir(), state, nested) | |
32a655c1 SL |
260 | } |
261 | } | |
416331ca | 262 | fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { |
e9174d1e | 263 | match node { |
b7449926 | 264 | pprust_hir::AnnNode::Expr(_) => s.popen(), |
416331ca | 265 | _ => {} |
e9174d1e SL |
266 | } |
267 | } | |
416331ca | 268 | fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { |
e9174d1e | 269 | match node { |
416331ca | 270 | pprust_hir::AnnNode::Name(_) => {}, |
b7449926 | 271 | pprust_hir::AnnNode::Item(item) => { |
416331ca XL |
272 | s.s.space(); |
273 | s.synth_comment(format!("hir_id: {}", item.hir_id)); | |
e9174d1e | 274 | } |
b7449926 | 275 | pprust_hir::AnnNode::SubItem(id) => { |
416331ca XL |
276 | s.s.space(); |
277 | s.synth_comment(id.to_string()); | |
e9174d1e | 278 | } |
b7449926 | 279 | pprust_hir::AnnNode::Block(blk) => { |
416331ca XL |
280 | s.s.space(); |
281 | s.synth_comment(format!("block hir_id: {}", blk.hir_id)); | |
e9174d1e | 282 | } |
b7449926 | 283 | pprust_hir::AnnNode::Expr(expr) => { |
416331ca XL |
284 | s.s.space(); |
285 | s.synth_comment(format!("expr hir_id: {}", expr.hir_id)); | |
286 | s.pclose(); | |
e9174d1e | 287 | } |
b7449926 | 288 | pprust_hir::AnnNode::Pat(pat) => { |
416331ca XL |
289 | s.s.space(); |
290 | s.synth_comment(format!("pat hir_id: {}", pat.hir_id)); | |
291 | } | |
292 | pprust_hir::AnnNode::Arm(arm) => { | |
293 | s.s.space(); | |
294 | s.synth_comment(format!("arm hir_id: {}", arm.hir_id)); | |
e9174d1e SL |
295 | } |
296 | } | |
297 | } | |
298 | } | |
299 | ||
32a655c1 SL |
300 | struct HygieneAnnotation<'a> { |
301 | sess: &'a Session | |
1a4d82fc JJ |
302 | } |
303 | ||
32a655c1 SL |
304 | impl<'a> PrinterSupport for HygieneAnnotation<'a> { |
305 | fn sess(&self) -> &Session { | |
92a42be0 SL |
306 | self.sess |
307 | } | |
1a4d82fc | 308 | |
8faf50e0 | 309 | fn pp_ann(&self) -> &dyn pprust::PpAnn { |
92a42be0 SL |
310 | self |
311 | } | |
1a4d82fc JJ |
312 | } |
313 | ||
32a655c1 | 314 | impl<'a> pprust::PpAnn for HygieneAnnotation<'a> { |
416331ca | 315 | fn post(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) { |
1a4d82fc | 316 | match node { |
b7449926 | 317 | pprust::AnnNode::Ident(&ast::Ident { name, span }) => { |
416331ca | 318 | s.s.space(); |
83c7162d | 319 | s.synth_comment(format!("{}{:?}", name.as_u32(), span.ctxt())) |
1a4d82fc | 320 | } |
b7449926 | 321 | pprust::AnnNode::Name(&name) => { |
416331ca | 322 | s.s.space(); |
476ff2be | 323 | s.synth_comment(name.as_u32().to_string()) |
1a4d82fc | 324 | } |
e1599b0c XL |
325 | pprust::AnnNode::Crate(_) => { |
326 | s.s.hardbreak(); | |
327 | let verbose = self.sess.verbose(); | |
328 | s.synth_comment(syntax_pos::hygiene::debug_hygiene_data(verbose)); | |
329 | s.s.hardbreak_if_not_bol(); | |
330 | } | |
416331ca | 331 | _ => {} |
1a4d82fc JJ |
332 | } |
333 | } | |
334 | } | |
335 | ||
dc9dc135 XL |
336 | struct TypedAnnotation<'a, 'tcx> { |
337 | tcx: TyCtxt<'tcx>, | |
32a655c1 | 338 | tables: Cell<&'a ty::TypeckTables<'tcx>>, |
1a4d82fc JJ |
339 | } |
340 | ||
e9174d1e | 341 | impl<'b, 'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'b, 'tcx> { |
416331ca | 342 | fn sess(&self) -> &Session { |
92a42be0 SL |
343 | &self.tcx.sess |
344 | } | |
1a4d82fc | 345 | |
32a655c1 | 346 | fn hir_map<'a>(&'a self) -> Option<&'a hir_map::Map<'tcx>> { |
0731742a | 347 | Some(&self.tcx.hir()) |
1a4d82fc JJ |
348 | } |
349 | ||
8faf50e0 | 350 | fn pp_ann<'a>(&'a self) -> &'a dyn pprust_hir::PpAnn { |
92a42be0 SL |
351 | self |
352 | } | |
54a0048b | 353 | |
dc9dc135 | 354 | fn node_path(&self, id: hir::HirId) -> Option<String> { |
416331ca | 355 | Some(self.tcx.def_path_str(self.tcx.hir().local_def_id(id))) |
54a0048b | 356 | } |
1a4d82fc JJ |
357 | } |
358 | ||
e9174d1e | 359 | impl<'a, 'tcx> pprust_hir::PpAnn for TypedAnnotation<'a, 'tcx> { |
416331ca | 360 | fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { |
32a655c1 SL |
361 | let old_tables = self.tables.get(); |
362 | if let pprust_hir::Nested::Body(id) = nested { | |
363 | self.tables.set(self.tcx.body_tables(id)); | |
364 | } | |
416331ca | 365 | pprust_hir::PpAnn::nested(self.tcx.hir(), state, nested); |
32a655c1 | 366 | self.tables.set(old_tables); |
32a655c1 | 367 | } |
416331ca | 368 | fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { |
1a4d82fc | 369 | match node { |
b7449926 | 370 | pprust_hir::AnnNode::Expr(_) => s.popen(), |
416331ca | 371 | _ => {} |
1a4d82fc JJ |
372 | } |
373 | } | |
416331ca | 374 | fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { |
1a4d82fc | 375 | match node { |
b7449926 | 376 | pprust_hir::AnnNode::Expr(expr) => { |
416331ca XL |
377 | s.s.space(); |
378 | s.s.word("as"); | |
379 | s.s.space(); | |
380 | s.s.word(self.tables.get().expr_ty(expr).to_string()); | |
381 | s.pclose(); | |
1a4d82fc | 382 | } |
416331ca | 383 | _ => {}, |
1a4d82fc JJ |
384 | } |
385 | } | |
386 | } | |
387 | ||
416331ca | 388 | fn get_source(input: &Input, sess: &Session) -> (String, FileName) { |
60c5eb7d | 389 | let src_name = input.source_name(); |
416331ca | 390 | let src = String::clone(&sess.source_map() |
b7449926 | 391 | .get_source_file(&src_name) |
c30ab7b3 SL |
392 | .unwrap() |
393 | .src | |
394 | .as_ref() | |
416331ca | 395 | .unwrap()); |
a7813a04 XL |
396 | (src, src_name) |
397 | } | |
398 | ||
399 | fn write_output(out: Vec<u8>, ofile: Option<&Path>) { | |
400 | match ofile { | |
401 | None => print!("{}", String::from_utf8(out).unwrap()), | |
402 | Some(p) => { | |
403 | match File::create(p) { | |
404 | Ok(mut w) => w.write_all(&out).unwrap(), | |
405 | Err(e) => panic!("print-print failed to open {} due to {}", p.display(), e), | |
406 | } | |
407 | } | |
408 | } | |
409 | } | |
1a4d82fc | 410 | |
a7813a04 XL |
411 | pub fn print_after_parsing(sess: &Session, |
412 | input: &Input, | |
413 | krate: &ast::Crate, | |
414 | ppm: PpMode, | |
415 | ofile: Option<&Path>) { | |
a7813a04 XL |
416 | let (src, src_name) = get_source(input, sess); |
417 | ||
416331ca | 418 | let mut out = String::new(); |
a7813a04 XL |
419 | |
420 | if let PpmSource(s) = ppm { | |
421 | // Silently ignores an identified node. | |
416331ca | 422 | let out = &mut out; |
60c5eb7d | 423 | call_with_pp_support(&s, sess, None, move |annotation| { |
0bf4aa26 XL |
424 | debug!("pretty printing source code {:?}", s); |
425 | let sess = annotation.sess(); | |
416331ca | 426 | *out = pprust::print_crate(sess.source_map(), |
0bf4aa26 XL |
427 | &sess.parse_sess, |
428 | krate, | |
429 | src_name, | |
416331ca | 430 | src, |
0bf4aa26 XL |
431 | annotation.pp_ann(), |
432 | false) | |
416331ca | 433 | }) |
a7813a04 XL |
434 | } else { |
435 | unreachable!(); | |
436 | }; | |
437 | ||
416331ca | 438 | write_output(out.into_bytes(), ofile); |
a7813a04 XL |
439 | } |
440 | ||
532ac7d7 | 441 | pub fn print_after_hir_lowering<'tcx>( |
dc9dc135 | 442 | tcx: TyCtxt<'tcx>, |
532ac7d7 XL |
443 | input: &Input, |
444 | krate: &ast::Crate, | |
445 | ppm: PpMode, | |
dc9dc135 XL |
446 | ofile: Option<&Path>, |
447 | ) { | |
a7813a04 | 448 | if ppm.needs_analysis() { |
532ac7d7 XL |
449 | abort_on_err(print_with_analysis( |
450 | tcx, | |
451 | ppm, | |
532ac7d7 XL |
452 | ofile |
453 | ), tcx.sess); | |
a7813a04 XL |
454 | return; |
455 | } | |
456 | ||
532ac7d7 | 457 | let (src, src_name) = get_source(input, tcx.sess); |
a7813a04 | 458 | |
416331ca | 459 | let mut out = String::new(); |
1a4d82fc | 460 | |
60c5eb7d XL |
461 | match ppm { |
462 | PpmSource(s) => { | |
c30ab7b3 | 463 | // Silently ignores an identified node. |
416331ca XL |
464 | let out = &mut out; |
465 | let src = src.clone(); | |
60c5eb7d | 466 | call_with_pp_support(&s, tcx.sess, Some(tcx), move |annotation| { |
c30ab7b3 SL |
467 | debug!("pretty printing source code {:?}", s); |
468 | let sess = annotation.sess(); | |
416331ca | 469 | *out = pprust::print_crate(sess.source_map(), |
32a655c1 | 470 | &sess.parse_sess, |
c30ab7b3 | 471 | krate, |
ff7c6d11 | 472 | src_name, |
416331ca | 473 | src, |
c30ab7b3 SL |
474 | annotation.pp_ann(), |
475 | true) | |
476 | }) | |
477 | } | |
1a4d82fc | 478 | |
60c5eb7d | 479 | PpmHir(s) => { |
416331ca XL |
480 | let out = &mut out; |
481 | let src = src.clone(); | |
60c5eb7d | 482 | call_with_pp_support_hir(&s, tcx, move |annotation, krate| { |
c30ab7b3 SL |
483 | debug!("pretty printing source code {:?}", s); |
484 | let sess = annotation.sess(); | |
416331ca | 485 | *out = pprust_hir::print_crate(sess.source_map(), |
32a655c1 | 486 | &sess.parse_sess, |
c30ab7b3 | 487 | krate, |
ff7c6d11 | 488 | src_name, |
416331ca | 489 | src, |
48663c56 | 490 | annotation.pp_ann()) |
c30ab7b3 SL |
491 | }) |
492 | } | |
e9174d1e | 493 | |
60c5eb7d | 494 | PpmHirTree(s) => { |
416331ca | 495 | let out = &mut out; |
60c5eb7d | 496 | call_with_pp_support_hir(&s, tcx, move |_annotation, krate| { |
ff7c6d11 | 497 | debug!("pretty printing source code {:?}", s); |
416331ca XL |
498 | *out = format!("{:#?}", krate); |
499 | }); | |
ff7c6d11 XL |
500 | } |
501 | ||
c30ab7b3 SL |
502 | _ => unreachable!(), |
503 | } | |
a7813a04 | 504 | |
416331ca | 505 | write_output(out.into_bytes(), ofile); |
a7813a04 XL |
506 | } |
507 | ||
508 | // In an ideal world, this would be a public function called by the driver after | |
9fa01778 | 509 | // analysis is performed. However, we want to call `phase_3_run_analysis_passes` |
a7813a04 XL |
510 | // with a different callback than the standard driver, so that isn't easy. |
511 | // Instead, we call that function ourselves. | |
416331ca XL |
512 | fn print_with_analysis( |
513 | tcx: TyCtxt<'_>, | |
532ac7d7 | 514 | ppm: PpMode, |
dc9dc135 | 515 | ofile: Option<&Path>, |
532ac7d7 | 516 | ) -> Result<(), ErrorReported> { |
a7813a04 XL |
517 | let mut out = Vec::new(); |
518 | ||
532ac7d7 XL |
519 | tcx.analysis(LOCAL_CRATE)?; |
520 | ||
e74abb32 | 521 | match ppm { |
532ac7d7 | 522 | PpmMir | PpmMirCFG => { |
e74abb32 | 523 | match ppm { |
60c5eb7d XL |
524 | PpmMir => write_mir_pretty(tcx, None, &mut out), |
525 | PpmMirCFG => write_mir_graphviz(tcx, None, &mut out), | |
e74abb32 | 526 | _ => unreachable!(), |
1a4d82fc JJ |
527 | } |
528 | } | |
532ac7d7 | 529 | _ => unreachable!(), |
e74abb32 | 530 | }.unwrap(); |
c34b1796 | 531 | |
a7813a04 | 532 | write_output(out, ofile); |
532ac7d7 XL |
533 | |
534 | Ok(()) | |
1a4d82fc | 535 | } |