]>
Commit | Line | Data |
---|---|---|
ba9703b0 | 1 | #![recursion_limit = "256"] |
f2b60f7d FG |
2 | #![deny(rustc::untranslatable_diagnostic)] |
3 | #![deny(rustc::diagnostic_outside_of_impl)] | |
ba9703b0 | 4 | |
3dfed10e | 5 | use rustc_ast as ast; |
74b04a01 XL |
6 | use rustc_ast::util::parser::{self, AssocOp, Fixity}; |
7 | use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent}; | |
8 | use rustc_ast_pretty::pp::{self, Breaks}; | |
9 | use rustc_ast_pretty::pprust::{Comments, PrintState}; | |
ba9703b0 | 10 | use rustc_hir as hir; |
064997fb | 11 | use rustc_hir::LifetimeParamKind; |
f2b60f7d FG |
12 | use rustc_hir::{ |
13 | BindingAnnotation, ByRef, GenericArg, GenericParam, GenericParamKind, Mutability, Node, Term, | |
14 | }; | |
ba9703b0 | 15 | use rustc_hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier}; |
04454e1e | 16 | use rustc_span::source_map::SourceMap; |
f9f354fc | 17 | use rustc_span::symbol::{kw, Ident, IdentPrinter, Symbol}; |
a2a8927a | 18 | use rustc_span::{self, FileName}; |
83c7162d | 19 | use rustc_target::spec::abi::Abi; |
e9174d1e | 20 | |
32a655c1 | 21 | use std::cell::Cell; |
041b39d2 | 22 | use std::vec; |
e9174d1e | 23 | |
ba9703b0 XL |
24 | pub fn id_to_string(map: &dyn rustc_hir::intravisit::Map<'_>, hir_id: hir::HirId) -> String { |
25 | to_string(&map, |s| s.print_node(map.find(hir_id).unwrap())) | |
26 | } | |
27 | ||
e9174d1e | 28 | pub enum AnnNode<'a> { |
f9f354fc | 29 | Name(&'a Symbol), |
dfeec247 XL |
30 | Block(&'a hir::Block<'a>), |
31 | Item(&'a hir::Item<'a>), | |
532ac7d7 | 32 | SubItem(hir::HirId), |
dfeec247 XL |
33 | Expr(&'a hir::Expr<'a>), |
34 | Pat(&'a hir::Pat<'a>), | |
35 | Arm(&'a hir::Arm<'a>), | |
e9174d1e SL |
36 | } |
37 | ||
32a655c1 SL |
38 | pub enum Nested { |
39 | Item(hir::ItemId), | |
40 | TraitItem(hir::TraitItemId), | |
41 | ImplItem(hir::ImplItemId), | |
fc512014 | 42 | ForeignItem(hir::ForeignItemId), |
32a655c1 | 43 | Body(hir::BodyId), |
dfeec247 | 44 | BodyParamPat(hir::BodyId, usize), |
32a655c1 SL |
45 | } |
46 | ||
e9174d1e | 47 | pub trait PpAnn { |
dfeec247 XL |
48 | fn nested(&self, _state: &mut State<'_>, _nested: Nested) {} |
49 | fn pre(&self, _state: &mut State<'_>, _node: AnnNode<'_>) {} | |
50 | fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) {} | |
e9174d1e SL |
51 | } |
52 | ||
e9174d1e | 53 | pub struct NoAnn; |
e9174d1e | 54 | impl PpAnn for NoAnn {} |
0731742a | 55 | pub const NO_ANN: &dyn PpAnn = &NoAnn; |
e9174d1e | 56 | |
ba9703b0 XL |
57 | /// Identical to the `PpAnn` implementation for `hir::Crate`, |
58 | /// except it avoids creating a dependency on the whole crate. | |
59 | impl PpAnn for &dyn rustc_hir::intravisit::Map<'_> { | |
60 | fn nested(&self, state: &mut State<'_>, nested: Nested) { | |
61 | match nested { | |
6a06907d | 62 | Nested::Item(id) => state.print_item(self.item(id)), |
ba9703b0 XL |
63 | Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)), |
64 | Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)), | |
fc512014 | 65 | Nested::ForeignItem(id) => state.print_foreign_item(self.foreign_item(id)), |
ba9703b0 | 66 | Nested::Body(id) => state.print_expr(&self.body(id).value), |
064997fb | 67 | Nested::BodyParamPat(id, i) => state.print_pat(self.body(id).params[i].pat), |
ba9703b0 XL |
68 | } |
69 | } | |
70 | } | |
71 | ||
e9174d1e | 72 | pub struct State<'a> { |
416331ca XL |
73 | pub s: pp::Printer, |
74 | comments: Option<Comments<'a>>, | |
3c0e092e | 75 | attrs: &'a dyn Fn(hir::HirId) -> &'a [ast::Attribute], |
0531ce1d | 76 | ann: &'a (dyn PpAnn + 'a), |
e9174d1e SL |
77 | } |
78 | ||
dfeec247 XL |
79 | impl<'a> State<'a> { |
80 | pub fn print_node(&mut self, node: Node<'_>) { | |
81 | match node { | |
064997fb FG |
82 | Node::Param(a) => self.print_param(a), |
83 | Node::Item(a) => self.print_item(a), | |
84 | Node::ForeignItem(a) => self.print_foreign_item(a), | |
dfeec247 XL |
85 | Node::TraitItem(a) => self.print_trait_item(a), |
86 | Node::ImplItem(a) => self.print_impl_item(a), | |
064997fb FG |
87 | Node::Variant(a) => self.print_variant(a), |
88 | Node::AnonConst(a) => self.print_anon_const(a), | |
89 | Node::Expr(a) => self.print_expr(a), | |
f2b60f7d | 90 | Node::ExprField(a) => self.print_expr_field(&a), |
064997fb FG |
91 | Node::Stmt(a) => self.print_stmt(a), |
92 | Node::PathSegment(a) => self.print_path_segment(a), | |
93 | Node::Ty(a) => self.print_type(a), | |
94 | Node::TypeBinding(a) => self.print_type_binding(a), | |
95 | Node::TraitRef(a) => self.print_trait_ref(a), | |
96 | Node::Pat(a) => self.print_pat(a), | |
f2b60f7d | 97 | Node::PatField(a) => self.print_patfield(&a), |
064997fb | 98 | Node::Arm(a) => self.print_arm(a), |
a2a8927a | 99 | Node::Infer(_) => self.word("_"), |
dfeec247 XL |
100 | Node::Block(a) => { |
101 | // Containing cbox, will be closed by print-block at `}`. | |
102 | self.cbox(INDENT_UNIT); | |
103 | // Head-ibox, will be closed by print-block after `{`. | |
104 | self.ibox(0); | |
064997fb | 105 | self.print_block(a); |
dfeec247 | 106 | } |
064997fb | 107 | Node::Lifetime(a) => self.print_lifetime(a), |
dfeec247 | 108 | Node::GenericParam(_) => panic!("cannot print Node::GenericParam"), |
6a06907d | 109 | Node::Field(_) => panic!("cannot print Node::Field"), |
dfeec247 XL |
110 | // These cases do not carry enough information in the |
111 | // `hir_map` to reconstruct their full structure for pretty | |
112 | // printing. | |
113 | Node::Ctor(..) => panic!("cannot print isolated Ctor"), | |
064997fb | 114 | Node::Local(a) => self.print_local_decl(a), |
ba9703b0 | 115 | Node::Crate(..) => panic!("cannot print Crate"), |
dfeec247 XL |
116 | } |
117 | } | |
118 | } | |
119 | ||
416331ca XL |
120 | impl std::ops::Deref for State<'_> { |
121 | type Target = pp::Printer; | |
122 | fn deref(&self) -> &Self::Target { | |
123 | &self.s | |
b039eaaf | 124 | } |
416331ca | 125 | } |
b039eaaf | 126 | |
416331ca XL |
127 | impl std::ops::DerefMut for State<'_> { |
128 | fn deref_mut(&mut self) -> &mut Self::Target { | |
129 | &mut self.s | |
b039eaaf | 130 | } |
416331ca | 131 | } |
b039eaaf | 132 | |
416331ca XL |
133 | impl<'a> PrintState<'a> for State<'a> { |
134 | fn comments(&mut self) -> &mut Option<Comments<'a>> { | |
b039eaaf SL |
135 | &mut self.comments |
136 | } | |
137 | ||
f9f354fc | 138 | fn print_ident(&mut self, ident: Ident) { |
a2a8927a | 139 | self.word(IdentPrinter::for_ast_ident(ident, ident.is_raw_guess()).to_string()); |
416331ca XL |
140 | self.ann.post(self, AnnNode::Name(&ident.name)) |
141 | } | |
142 | ||
dfeec247 XL |
143 | fn print_generic_args(&mut self, _: &ast::GenericArgs, _colons_before_params: bool) { |
144 | panic!("AST generic args printed by HIR pretty-printer"); | |
b039eaaf | 145 | } |
b039eaaf SL |
146 | } |
147 | ||
5099ac24 | 148 | pub const INDENT_UNIT: isize = 4; |
e9174d1e SL |
149 | |
150 | /// Requires you to pass an input filename and reader so that | |
48663c56 | 151 | /// it can scan the input text for comments to copy forward. |
dfeec247 | 152 | pub fn print_crate<'a>( |
74b04a01 | 153 | sm: &'a SourceMap, |
3c0e092e | 154 | krate: &hir::Mod<'_>, |
dfeec247 XL |
155 | filename: FileName, |
156 | input: String, | |
3c0e092e | 157 | attrs: &'a dyn Fn(hir::HirId) -> &'a [ast::Attribute], |
dfeec247 XL |
158 | ann: &'a dyn PpAnn, |
159 | ) -> String { | |
3c0e092e | 160 | let mut s = State::new_from_input(sm, filename, input, attrs, ann); |
e9174d1e SL |
161 | |
162 | // When printing the AST, we sometimes need to inject `#[no_std]` here. | |
163 | // Since you can't compile the HIR, it's not necessary. | |
164 | ||
3c0e092e | 165 | s.print_mod(krate, (*attrs)(hir::CRATE_HIR_ID)); |
416331ca | 166 | s.print_remaining_comments(); |
041b39d2 | 167 | s.s.eof() |
e9174d1e SL |
168 | } |
169 | ||
170 | impl<'a> State<'a> { | |
dfeec247 | 171 | pub fn new_from_input( |
74b04a01 | 172 | sm: &'a SourceMap, |
dfeec247 XL |
173 | filename: FileName, |
174 | input: String, | |
3c0e092e | 175 | attrs: &'a dyn Fn(hir::HirId) -> &'a [ast::Attribute], |
dfeec247 XL |
176 | ann: &'a dyn PpAnn, |
177 | ) -> State<'a> { | |
6a06907d | 178 | State { |
5099ac24 | 179 | s: pp::Printer::new(), |
6a06907d XL |
180 | comments: Some(Comments::new(sm, filename, input)), |
181 | attrs, | |
182 | ann, | |
183 | } | |
184 | } | |
185 | ||
186 | fn attrs(&self, id: hir::HirId) -> &'a [ast::Attribute] { | |
3c0e092e | 187 | (self.attrs)(id) |
e9174d1e SL |
188 | } |
189 | } | |
190 | ||
0531ce1d | 191 | pub fn to_string<F>(ann: &dyn PpAnn, f: F) -> String |
dfeec247 XL |
192 | where |
193 | F: FnOnce(&mut State<'_>), | |
e9174d1e | 194 | { |
5099ac24 | 195 | let mut printer = State { s: pp::Printer::new(), comments: None, attrs: &|_| &[], ann }; |
416331ca XL |
196 | f(&mut printer); |
197 | printer.s.eof() | |
e9174d1e SL |
198 | } |
199 | ||
f035d41b XL |
200 | pub fn generic_params_to_string(generic_params: &[GenericParam<'_>]) -> String { |
201 | to_string(NO_ANN, |s| s.print_generic_params(generic_params)) | |
202 | } | |
203 | ||
204 | pub fn bounds_to_string<'b>(bounds: impl IntoIterator<Item = &'b hir::GenericBound<'b>>) -> String { | |
205 | to_string(NO_ANN, |s| s.print_bounds("", bounds)) | |
206 | } | |
207 | ||
f035d41b XL |
208 | pub fn ty_to_string(ty: &hir::Ty<'_>) -> String { |
209 | to_string(NO_ANN, |s| s.print_type(ty)) | |
210 | } | |
211 | ||
212 | pub fn path_segment_to_string(segment: &hir::PathSegment<'_>) -> String { | |
213 | to_string(NO_ANN, |s| s.print_path_segment(segment)) | |
214 | } | |
215 | ||
216 | pub fn path_to_string(segment: &hir::Path<'_>) -> String { | |
217 | to_string(NO_ANN, |s| s.print_path(segment, false)) | |
218 | } | |
219 | ||
064997fb FG |
220 | pub fn qpath_to_string(segment: &hir::QPath<'_>) -> String { |
221 | to_string(NO_ANN, |s| s.print_qpath(segment, false)) | |
222 | } | |
223 | ||
f035d41b XL |
224 | pub fn fn_to_string( |
225 | decl: &hir::FnDecl<'_>, | |
226 | header: hir::FnHeader, | |
227 | name: Option<Symbol>, | |
228 | generics: &hir::Generics<'_>, | |
f035d41b XL |
229 | arg_names: &[Ident], |
230 | body_id: Option<hir::BodyId>, | |
231 | ) -> String { | |
04454e1e | 232 | to_string(NO_ANN, |s| s.print_fn(decl, header, name, generics, arg_names, body_id)) |
f035d41b XL |
233 | } |
234 | ||
235 | pub fn enum_def_to_string( | |
236 | enum_definition: &hir::EnumDef<'_>, | |
237 | generics: &hir::Generics<'_>, | |
238 | name: Symbol, | |
239 | span: rustc_span::Span, | |
f035d41b | 240 | ) -> String { |
04454e1e | 241 | to_string(NO_ANN, |s| s.print_enum_def(enum_definition, generics, name, span)) |
f035d41b XL |
242 | } |
243 | ||
e9174d1e | 244 | impl<'a> State<'a> { |
dfeec247 | 245 | pub fn bclose_maybe_open(&mut self, span: rustc_span::Span, close_box: bool) { |
416331ca XL |
246 | self.maybe_print_comment(span.hi()); |
247 | self.break_offset_if_not_bol(1, -(INDENT_UNIT as isize)); | |
a2a8927a | 248 | self.word("}"); |
e9174d1e | 249 | if close_box { |
416331ca | 250 | self.end(); // close the outer-box |
e9174d1e | 251 | } |
e9174d1e | 252 | } |
b7449926 | 253 | |
dfeec247 | 254 | pub fn bclose(&mut self, span: rustc_span::Span) { |
416331ca | 255 | self.bclose_maybe_open(span, true) |
e9174d1e SL |
256 | } |
257 | ||
dfeec247 XL |
258 | pub fn commasep_cmnt<T, F, G>(&mut self, b: Breaks, elts: &[T], mut op: F, mut get_span: G) |
259 | where | |
260 | F: FnMut(&mut State<'_>, &T), | |
261 | G: FnMut(&T) -> rustc_span::Span, | |
e9174d1e | 262 | { |
416331ca | 263 | self.rbox(0, b); |
e9174d1e SL |
264 | let len = elts.len(); |
265 | let mut i = 0; | |
266 | for elt in elts { | |
416331ca XL |
267 | self.maybe_print_comment(get_span(elt).hi()); |
268 | op(self, elt); | |
e9174d1e SL |
269 | i += 1; |
270 | if i < len { | |
a2a8927a | 271 | self.word(","); |
416331ca XL |
272 | self.maybe_print_trailing_comment(get_span(elt), Some(get_span(&elts[i]).hi())); |
273 | self.space_if_not_bol(); | |
e9174d1e SL |
274 | } |
275 | } | |
416331ca | 276 | self.end(); |
e9174d1e SL |
277 | } |
278 | ||
dfeec247 | 279 | pub fn commasep_exprs(&mut self, b: Breaks, exprs: &[hir::Expr<'_>]) { |
064997fb | 280 | self.commasep_cmnt(b, exprs, |s, e| s.print_expr(e), |e| e.span); |
e9174d1e SL |
281 | } |
282 | ||
dfeec247 | 283 | pub fn print_mod(&mut self, _mod: &hir::Mod<'_>, attrs: &[ast::Attribute]) { |
416331ca | 284 | self.print_inner_attributes(attrs); |
dfeec247 | 285 | for &item_id in _mod.item_ids { |
416331ca | 286 | self.ann.nested(self, Nested::Item(item_id)); |
e9174d1e | 287 | } |
e9174d1e SL |
288 | } |
289 | ||
416331ca | 290 | pub fn print_opt_lifetime(&mut self, lifetime: &hir::Lifetime) { |
32a655c1 | 291 | if !lifetime.is_elided() { |
416331ca XL |
292 | self.print_lifetime(lifetime); |
293 | self.nbsp(); | |
e9174d1e | 294 | } |
e9174d1e SL |
295 | } |
296 | ||
dfeec247 | 297 | pub fn print_type(&mut self, ty: &hir::Ty<'_>) { |
416331ca XL |
298 | self.maybe_print_comment(ty.span.lo()); |
299 | self.ibox(0); | |
e74abb32 | 300 | match ty.kind { |
064997fb | 301 | hir::TyKind::Slice(ty) => { |
a2a8927a | 302 | self.word("["); |
064997fb | 303 | self.print_type(ty); |
a2a8927a | 304 | self.word("]"); |
e9174d1e | 305 | } |
8faf50e0 | 306 | hir::TyKind::Ptr(ref mt) => { |
a2a8927a | 307 | self.word("*"); |
60c5eb7d | 308 | self.print_mt(mt, true); |
e9174d1e | 309 | } |
9c376795 | 310 | hir::TyKind::Ref(ref lifetime, ref mt) => { |
a2a8927a | 311 | self.word("&"); |
416331ca | 312 | self.print_opt_lifetime(lifetime); |
60c5eb7d | 313 | self.print_mt(mt, false); |
e9174d1e | 314 | } |
8faf50e0 | 315 | hir::TyKind::Never => { |
a2a8927a | 316 | self.word("!"); |
dfeec247 | 317 | } |
064997fb | 318 | hir::TyKind::Tup(elts) => { |
416331ca | 319 | self.popen(); |
064997fb | 320 | self.commasep(Inconsistent, elts, |s, ty| s.print_type(ty)); |
e9174d1e | 321 | if elts.len() == 1 { |
a2a8927a | 322 | self.word(","); |
e9174d1e | 323 | } |
416331ca | 324 | self.pclose(); |
e9174d1e | 325 | } |
064997fb FG |
326 | hir::TyKind::BareFn(f) => { |
327 | self.print_ty_fn(f.abi, f.unsafety, f.decl, None, f.generic_params, f.param_names); | |
dfeec247 | 328 | } |
a2a8927a | 329 | hir::TyKind::OpaqueDef(..) => self.word("/*impl Trait*/"), |
dfeec247 | 330 | hir::TyKind::Path(ref qpath) => self.print_qpath(qpath, false), |
6a06907d XL |
331 | hir::TyKind::TraitObject(bounds, ref lifetime, syntax) => { |
332 | if syntax == ast::TraitObjectSyntax::Dyn { | |
333 | self.word_space("dyn"); | |
334 | } | |
32a655c1 SL |
335 | let mut first = true; |
336 | for bound in bounds { | |
32a655c1 SL |
337 | if first { |
338 | first = false; | |
339 | } else { | |
416331ca XL |
340 | self.nbsp(); |
341 | self.word_space("+"); | |
32a655c1 | 342 | } |
416331ca | 343 | self.print_poly_trait_ref(bound); |
32a655c1 SL |
344 | } |
345 | if !lifetime.is_elided() { | |
416331ca XL |
346 | self.nbsp(); |
347 | self.word_space("+"); | |
348 | self.print_lifetime(lifetime); | |
32a655c1 | 349 | } |
e9174d1e | 350 | } |
064997fb | 351 | hir::TyKind::Array(ty, ref length) => { |
a2a8927a | 352 | self.word("["); |
064997fb | 353 | self.print_type(ty); |
a2a8927a XL |
354 | self.word("; "); |
355 | self.print_array_length(length); | |
356 | self.word("]"); | |
e9174d1e | 357 | } |
8faf50e0 | 358 | hir::TyKind::Typeof(ref e) => { |
a2a8927a | 359 | self.word("typeof("); |
416331ca | 360 | self.print_anon_const(e); |
a2a8927a | 361 | self.word(")"); |
e9174d1e | 362 | } |
8faf50e0 | 363 | hir::TyKind::Err => { |
416331ca | 364 | self.popen(); |
a2a8927a | 365 | self.word("/*ERROR*/"); |
416331ca | 366 | self.pclose(); |
cc61c64b | 367 | } |
94222f64 | 368 | hir::TyKind::Infer => { |
a2a8927a | 369 | self.word("_"); |
94222f64 | 370 | } |
e9174d1e SL |
371 | } |
372 | self.end() | |
373 | } | |
374 | ||
dfeec247 | 375 | pub fn print_foreign_item(&mut self, item: &hir::ForeignItem<'_>) { |
416331ca XL |
376 | self.hardbreak_if_not_bol(); |
377 | self.maybe_print_comment(item.span.lo()); | |
6a06907d | 378 | self.print_outer_attributes(self.attrs(item.hir_id())); |
e74abb32 | 379 | match item.kind { |
064997fb | 380 | hir::ForeignItemKind::Fn(decl, arg_names, generics) => { |
416331ca | 381 | self.head(""); |
dfeec247 XL |
382 | self.print_fn( |
383 | decl, | |
384 | hir::FnHeader { | |
385 | unsafety: hir::Unsafety::Normal, | |
386 | constness: hir::Constness::NotConst, | |
387 | abi: Abi::Rust, | |
388 | asyncness: hir::IsAsync::NotAsync, | |
389 | }, | |
390 | Some(item.ident.name), | |
391 | generics, | |
dfeec247 XL |
392 | arg_names, |
393 | None, | |
394 | ); | |
416331ca | 395 | self.end(); // end head-ibox |
a2a8927a | 396 | self.word(";"); |
e9174d1e SL |
397 | self.end() // end the outer fn box |
398 | } | |
064997fb | 399 | hir::ForeignItemKind::Static(t, m) => { |
04454e1e | 400 | self.head("static"); |
487cf647 | 401 | if m.is_mut() { |
416331ca | 402 | self.word_space("mut"); |
e9174d1e | 403 | } |
416331ca XL |
404 | self.print_ident(item.ident); |
405 | self.word_space(":"); | |
064997fb | 406 | self.print_type(t); |
a2a8927a | 407 | self.word(";"); |
416331ca | 408 | self.end(); // end the head-ibox |
e9174d1e SL |
409 | self.end() // end the outer cbox |
410 | } | |
8faf50e0 | 411 | hir::ForeignItemKind::Type => { |
04454e1e | 412 | self.head("type"); |
416331ca | 413 | self.print_ident(item.ident); |
a2a8927a | 414 | self.word(";"); |
416331ca | 415 | self.end(); // end the head-ibox |
abe05a73 XL |
416 | self.end() // end the outer cbox |
417 | } | |
e9174d1e SL |
418 | } |
419 | } | |
420 | ||
dfeec247 XL |
421 | fn print_associated_const( |
422 | &mut self, | |
f9f354fc | 423 | ident: Ident, |
dfeec247 XL |
424 | ty: &hir::Ty<'_>, |
425 | default: Option<hir::BodyId>, | |
dfeec247 | 426 | ) { |
04454e1e | 427 | self.head(""); |
416331ca XL |
428 | self.word_space("const"); |
429 | self.print_ident(ident); | |
430 | self.word_space(":"); | |
431 | self.print_type(ty); | |
e9174d1e | 432 | if let Some(expr) = default { |
a2a8927a | 433 | self.space(); |
416331ca XL |
434 | self.word_space("="); |
435 | self.ann.nested(self, Nested::Body(expr)); | |
e9174d1e | 436 | } |
a2a8927a | 437 | self.word(";") |
e9174d1e SL |
438 | } |
439 | ||
dfeec247 XL |
440 | fn print_associated_type( |
441 | &mut self, | |
f9f354fc | 442 | ident: Ident, |
74b04a01 | 443 | generics: &hir::Generics<'_>, |
dfeec247 XL |
444 | bounds: Option<hir::GenericBounds<'_>>, |
445 | ty: Option<&hir::Ty<'_>>, | |
446 | ) { | |
416331ca XL |
447 | self.word_space("type"); |
448 | self.print_ident(ident); | |
064997fb | 449 | self.print_generic_params(generics.params); |
e9174d1e | 450 | if let Some(bounds) = bounds { |
416331ca | 451 | self.print_bounds(":", bounds); |
e9174d1e | 452 | } |
04454e1e | 453 | self.print_where_clause(generics); |
e9174d1e | 454 | if let Some(ty) = ty { |
a2a8927a | 455 | self.space(); |
416331ca XL |
456 | self.word_space("="); |
457 | self.print_type(ty); | |
e9174d1e | 458 | } |
a2a8927a | 459 | self.word(";") |
e9174d1e SL |
460 | } |
461 | ||
416331ca XL |
462 | fn print_item_type( |
463 | &mut self, | |
dfeec247 XL |
464 | item: &hir::Item<'_>, |
465 | generics: &hir::Generics<'_>, | |
416331ca XL |
466 | inner: impl Fn(&mut Self), |
467 | ) { | |
04454e1e | 468 | self.head("type"); |
416331ca | 469 | self.print_ident(item.ident); |
064997fb | 470 | self.print_generic_params(generics.params); |
416331ca XL |
471 | self.end(); // end the inner ibox |
472 | ||
04454e1e | 473 | self.print_where_clause(generics); |
a2a8927a | 474 | self.space(); |
416331ca | 475 | inner(self); |
a2a8927a | 476 | self.word(";"); |
416331ca XL |
477 | self.end(); // end the outer ibox |
478 | } | |
479 | ||
e9174d1e | 480 | /// Pretty-print an item |
dfeec247 | 481 | pub fn print_item(&mut self, item: &hir::Item<'_>) { |
416331ca XL |
482 | self.hardbreak_if_not_bol(); |
483 | self.maybe_print_comment(item.span.lo()); | |
6a06907d XL |
484 | let attrs = self.attrs(item.hir_id()); |
485 | self.print_outer_attributes(attrs); | |
416331ca | 486 | self.ann.pre(self, AnnNode::Item(item)); |
e74abb32 | 487 | match item.kind { |
8faf50e0 | 488 | hir::ItemKind::ExternCrate(orig_name) => { |
04454e1e | 489 | self.head("extern crate"); |
0531ce1d | 490 | if let Some(orig_name) = orig_name { |
416331ca | 491 | self.print_name(orig_name); |
a2a8927a XL |
492 | self.space(); |
493 | self.word("as"); | |
494 | self.space(); | |
e9174d1e | 495 | } |
416331ca | 496 | self.print_ident(item.ident); |
a2a8927a | 497 | self.word(";"); |
416331ca XL |
498 | self.end(); // end inner head-block |
499 | self.end(); // end outer head-block | |
e9174d1e | 500 | } |
064997fb | 501 | hir::ItemKind::Use(path, kind) => { |
04454e1e | 502 | self.head("use"); |
416331ca | 503 | self.print_path(path, false); |
476ff2be SL |
504 | |
505 | match kind { | |
506 | hir::UseKind::Single => { | |
0731742a | 507 | if path.segments.last().unwrap().ident != item.ident { |
a2a8927a | 508 | self.space(); |
416331ca XL |
509 | self.word_space("as"); |
510 | self.print_ident(item.ident); | |
476ff2be | 511 | } |
a2a8927a | 512 | self.word(";"); |
476ff2be | 513 | } |
a2a8927a XL |
514 | hir::UseKind::Glob => self.word("::*;"), |
515 | hir::UseKind::ListStem => self.word("::{};"), | |
476ff2be | 516 | } |
416331ca XL |
517 | self.end(); // end inner head-block |
518 | self.end(); // end outer head-block | |
e9174d1e | 519 | } |
064997fb | 520 | hir::ItemKind::Static(ty, m, expr) => { |
04454e1e | 521 | self.head("static"); |
487cf647 | 522 | if m.is_mut() { |
416331ca | 523 | self.word_space("mut"); |
e9174d1e | 524 | } |
416331ca XL |
525 | self.print_ident(item.ident); |
526 | self.word_space(":"); | |
064997fb | 527 | self.print_type(ty); |
a2a8927a | 528 | self.space(); |
416331ca | 529 | self.end(); // end the head-ibox |
e9174d1e | 530 | |
416331ca XL |
531 | self.word_space("="); |
532 | self.ann.nested(self, Nested::Body(expr)); | |
a2a8927a | 533 | self.word(";"); |
416331ca | 534 | self.end(); // end the outer cbox |
e9174d1e | 535 | } |
064997fb | 536 | hir::ItemKind::Const(ty, expr) => { |
04454e1e | 537 | self.head("const"); |
416331ca XL |
538 | self.print_ident(item.ident); |
539 | self.word_space(":"); | |
064997fb | 540 | self.print_type(ty); |
a2a8927a | 541 | self.space(); |
416331ca XL |
542 | self.end(); // end the head-ibox |
543 | ||
544 | self.word_space("="); | |
545 | self.ann.nested(self, Nested::Body(expr)); | |
a2a8927a | 546 | self.word(";"); |
416331ca | 547 | self.end(); // end the outer cbox |
e9174d1e | 548 | } |
064997fb | 549 | hir::ItemKind::Fn(ref sig, param_names, body) => { |
416331ca | 550 | self.head(""); |
dfeec247 | 551 | self.print_fn( |
064997fb | 552 | sig.decl, |
dfeec247 XL |
553 | sig.header, |
554 | Some(item.ident.name), | |
555 | param_names, | |
dfeec247 XL |
556 | &[], |
557 | Some(body), | |
558 | ); | |
a2a8927a | 559 | self.word(" "); |
416331ca XL |
560 | self.end(); // need to close a box |
561 | self.end(); // need to close a box | |
562 | self.ann.nested(self, Nested::Body(body)); | |
e9174d1e | 563 | } |
5e7ed085 | 564 | hir::ItemKind::Macro(ref macro_def, _) => { |
04454e1e | 565 | self.print_mac_def(macro_def, &item.ident, item.span, |_| {}); |
94222f64 | 566 | } |
8faf50e0 | 567 | hir::ItemKind::Mod(ref _mod) => { |
04454e1e | 568 | self.head("mod"); |
416331ca XL |
569 | self.print_ident(item.ident); |
570 | self.nbsp(); | |
571 | self.bopen(); | |
6a06907d | 572 | self.print_mod(_mod, attrs); |
416331ca | 573 | self.bclose(item.span); |
e9174d1e | 574 | } |
fc512014 | 575 | hir::ItemKind::ForeignMod { abi, items } => { |
416331ca | 576 | self.head("extern"); |
fc512014 | 577 | self.word_nbsp(abi.to_string()); |
416331ca | 578 | self.bopen(); |
6a06907d | 579 | self.print_inner_attributes(self.attrs(item.hir_id())); |
fc512014 XL |
580 | for item in items { |
581 | self.ann.nested(self, Nested::ForeignItem(item.id)); | |
582 | } | |
416331ca | 583 | self.bclose(item.span); |
e9174d1e | 584 | } |
064997fb | 585 | hir::ItemKind::GlobalAsm(asm) => { |
04454e1e | 586 | self.head("global_asm!"); |
17df50a5 | 587 | self.print_inline_asm(asm); |
416331ca XL |
588 | self.end() |
589 | } | |
064997fb FG |
590 | hir::ItemKind::TyAlias(ty, generics) => { |
591 | self.print_item_type(item, generics, |state| { | |
416331ca | 592 | state.word_space("="); |
064997fb | 593 | state.print_type(ty); |
416331ca XL |
594 | }); |
595 | } | |
596 | hir::ItemKind::OpaqueTy(ref opaque_ty) => { | |
064997fb | 597 | self.print_item_type(item, opaque_ty.generics, |state| { |
416331ca | 598 | let mut real_bounds = Vec::with_capacity(opaque_ty.bounds.len()); |
064997fb FG |
599 | for b in opaque_ty.bounds { |
600 | if let GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = b { | |
a2a8927a | 601 | state.space(); |
416331ca XL |
602 | state.word_space("for ?"); |
603 | state.print_trait_ref(&ptr.trait_ref); | |
604 | } else { | |
605 | real_bounds.push(b); | |
606 | } | |
94b46f34 | 607 | } |
416331ca XL |
608 | state.print_bounds("= impl", real_bounds); |
609 | }); | |
94b46f34 | 610 | } |
064997fb | 611 | hir::ItemKind::Enum(ref enum_definition, params) => { |
04454e1e | 612 | self.print_enum_def(enum_definition, params, item.ident.name, item.span); |
e9174d1e | 613 | } |
064997fb | 614 | hir::ItemKind::Struct(ref struct_def, generics) => { |
04454e1e | 615 | self.head("struct"); |
416331ca | 616 | self.print_struct(struct_def, generics, item.ident.name, item.span, true); |
e9174d1e | 617 | } |
064997fb | 618 | hir::ItemKind::Union(ref struct_def, generics) => { |
04454e1e | 619 | self.head("union"); |
416331ca | 620 | self.print_struct(struct_def, generics, item.ident.name, item.span, true); |
9e0c209e | 621 | } |
064997fb | 622 | hir::ItemKind::Impl(&hir::Impl { |
dfeec247 XL |
623 | unsafety, |
624 | polarity, | |
625 | defaultness, | |
626 | constness, | |
ba9703b0 | 627 | defaultness_span: _, |
064997fb | 628 | generics, |
dfeec247 | 629 | ref of_trait, |
064997fb | 630 | self_ty, |
dfeec247 | 631 | items, |
5869c6ff | 632 | }) => { |
416331ca | 633 | self.head(""); |
064997fb FG |
634 | self.print_defaultness(defaultness); |
635 | self.print_unsafety(unsafety); | |
416331ca | 636 | self.word_nbsp("impl"); |
e9174d1e | 637 | |
ff7c6d11 | 638 | if !generics.params.is_empty() { |
064997fb | 639 | self.print_generic_params(generics.params); |
a2a8927a | 640 | self.space(); |
e9174d1e SL |
641 | } |
642 | ||
064997fb | 643 | if constness == hir::Constness::Const { |
dfeec247 XL |
644 | self.word_nbsp("const"); |
645 | } | |
646 | ||
ba9703b0 | 647 | if let hir::ImplPolarity::Negative(_) = polarity { |
a2a8927a | 648 | self.word("!"); |
e9174d1e SL |
649 | } |
650 | ||
064997fb | 651 | if let Some(t) = of_trait { |
416331ca | 652 | self.print_trait_ref(t); |
a2a8927a | 653 | self.space(); |
416331ca | 654 | self.word_space("for"); |
e9174d1e SL |
655 | } |
656 | ||
064997fb | 657 | self.print_type(self_ty); |
04454e1e | 658 | self.print_where_clause(generics); |
e9174d1e | 659 | |
a2a8927a | 660 | self.space(); |
416331ca | 661 | self.bopen(); |
6a06907d | 662 | self.print_inner_attributes(attrs); |
064997fb | 663 | for impl_item in items { |
416331ca | 664 | self.ann.nested(self, Nested::ImplItem(impl_item.id)); |
e9174d1e | 665 | } |
416331ca | 666 | self.bclose(item.span); |
e9174d1e | 667 | } |
064997fb | 668 | hir::ItemKind::Trait(is_auto, unsafety, generics, bounds, trait_items) => { |
416331ca | 669 | self.head(""); |
416331ca XL |
670 | self.print_is_auto(is_auto); |
671 | self.print_unsafety(unsafety); | |
672 | self.word_nbsp("trait"); | |
673 | self.print_ident(item.ident); | |
064997fb | 674 | self.print_generic_params(generics.params); |
e9174d1e | 675 | let mut real_bounds = Vec::with_capacity(bounds.len()); |
064997fb FG |
676 | for b in bounds { |
677 | if let GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = b { | |
a2a8927a | 678 | self.space(); |
416331ca XL |
679 | self.word_space("for ?"); |
680 | self.print_trait_ref(&ptr.trait_ref); | |
e9174d1e | 681 | } else { |
dc9dc135 | 682 | real_bounds.push(b); |
e9174d1e SL |
683 | } |
684 | } | |
416331ca | 685 | self.print_bounds(":", real_bounds); |
04454e1e | 686 | self.print_where_clause(generics); |
a2a8927a | 687 | self.word(" "); |
416331ca | 688 | self.bopen(); |
e9174d1e | 689 | for trait_item in trait_items { |
416331ca | 690 | self.ann.nested(self, Nested::TraitItem(trait_item.id)); |
e9174d1e | 691 | } |
416331ca | 692 | self.bclose(item.span); |
e9174d1e | 693 | } |
064997fb | 694 | hir::ItemKind::TraitAlias(generics, bounds) => { |
04454e1e | 695 | self.head("trait"); |
416331ca | 696 | self.print_ident(item.ident); |
064997fb | 697 | self.print_generic_params(generics.params); |
416331ca | 698 | self.nbsp(); |
487cf647 | 699 | self.print_bounds("=", bounds); |
04454e1e | 700 | self.print_where_clause(generics); |
a2a8927a | 701 | self.word(";"); |
5099ac24 FG |
702 | self.end(); // end inner head-block |
703 | self.end(); // end outer head-block | |
ff7c6d11 | 704 | } |
e9174d1e | 705 | } |
b7449926 | 706 | self.ann.post(self, AnnNode::Item(item)) |
e9174d1e SL |
707 | } |
708 | ||
dfeec247 | 709 | pub fn print_trait_ref(&mut self, t: &hir::TraitRef<'_>) { |
064997fb | 710 | self.print_path(t.path, false); |
e9174d1e SL |
711 | } |
712 | ||
dfeec247 | 713 | fn print_formal_generic_params(&mut self, generic_params: &[hir::GenericParam<'_>]) { |
ff7c6d11 | 714 | if !generic_params.is_empty() { |
a2a8927a | 715 | self.word("for"); |
416331ca XL |
716 | self.print_generic_params(generic_params); |
717 | self.nbsp(); | |
e9174d1e | 718 | } |
e9174d1e SL |
719 | } |
720 | ||
dfeec247 | 721 | fn print_poly_trait_ref(&mut self, t: &hir::PolyTraitRef<'_>) { |
064997fb FG |
722 | self.print_formal_generic_params(t.bound_generic_params); |
723 | self.print_trait_ref(&t.trait_ref); | |
e9174d1e SL |
724 | } |
725 | ||
dfeec247 XL |
726 | pub fn print_enum_def( |
727 | &mut self, | |
728 | enum_definition: &hir::EnumDef<'_>, | |
729 | generics: &hir::Generics<'_>, | |
f9f354fc | 730 | name: Symbol, |
dfeec247 | 731 | span: rustc_span::Span, |
dfeec247 | 732 | ) { |
04454e1e | 733 | self.head("enum"); |
416331ca | 734 | self.print_name(name); |
064997fb | 735 | self.print_generic_params(generics.params); |
04454e1e | 736 | self.print_where_clause(generics); |
a2a8927a | 737 | self.space(); |
064997fb | 738 | self.print_variants(enum_definition.variants, span); |
e9174d1e SL |
739 | } |
740 | ||
dfeec247 | 741 | pub fn print_variants(&mut self, variants: &[hir::Variant<'_>], span: rustc_span::Span) { |
416331ca | 742 | self.bopen(); |
e9174d1e | 743 | for v in variants { |
416331ca XL |
744 | self.space_if_not_bol(); |
745 | self.maybe_print_comment(v.span.lo()); | |
487cf647 | 746 | self.print_outer_attributes(self.attrs(v.hir_id)); |
416331ca XL |
747 | self.ibox(INDENT_UNIT); |
748 | self.print_variant(v); | |
a2a8927a | 749 | self.word(","); |
416331ca XL |
750 | self.end(); |
751 | self.maybe_print_trailing_comment(v.span, None); | |
e9174d1e SL |
752 | } |
753 | self.bclose(span) | |
754 | } | |
755 | ||
416331ca | 756 | pub fn print_defaultness(&mut self, defaultness: hir::Defaultness) { |
7cac9316 | 757 | match defaultness { |
416331ca | 758 | hir::Defaultness::Default { .. } => self.word_nbsp("default"), |
7cac9316 XL |
759 | hir::Defaultness::Final => (), |
760 | } | |
7cac9316 XL |
761 | } |
762 | ||
dfeec247 XL |
763 | pub fn print_struct( |
764 | &mut self, | |
765 | struct_def: &hir::VariantData<'_>, | |
766 | generics: &hir::Generics<'_>, | |
f9f354fc | 767 | name: Symbol, |
dfeec247 XL |
768 | span: rustc_span::Span, |
769 | print_finalizer: bool, | |
770 | ) { | |
416331ca | 771 | self.print_name(name); |
064997fb | 772 | self.print_generic_params(generics.params); |
532ac7d7 XL |
773 | match struct_def { |
774 | hir::VariantData::Tuple(..) | hir::VariantData::Unit(..) => { | |
775 | if let hir::VariantData::Tuple(..) = struct_def { | |
416331ca | 776 | self.popen(); |
532ac7d7 | 777 | self.commasep(Inconsistent, struct_def.fields(), |s, field| { |
416331ca | 778 | s.maybe_print_comment(field.span.lo()); |
6a06907d | 779 | s.print_outer_attributes(s.attrs(field.hir_id)); |
064997fb | 780 | s.print_type(field.ty); |
416331ca XL |
781 | }); |
782 | self.pclose(); | |
532ac7d7 | 783 | } |
04454e1e | 784 | self.print_where_clause(generics); |
532ac7d7 | 785 | if print_finalizer { |
a2a8927a | 786 | self.word(";"); |
532ac7d7 | 787 | } |
416331ca | 788 | self.end(); |
532ac7d7 | 789 | self.end() // close the outer-box |
b039eaaf | 790 | } |
532ac7d7 | 791 | hir::VariantData::Struct(..) => { |
04454e1e | 792 | self.print_where_clause(generics); |
416331ca XL |
793 | self.nbsp(); |
794 | self.bopen(); | |
795 | self.hardbreak_if_not_bol(); | |
e9174d1e | 796 | |
532ac7d7 | 797 | for field in struct_def.fields() { |
416331ca XL |
798 | self.hardbreak_if_not_bol(); |
799 | self.maybe_print_comment(field.span.lo()); | |
6a06907d | 800 | self.print_outer_attributes(self.attrs(field.hir_id)); |
416331ca XL |
801 | self.print_ident(field.ident); |
802 | self.word_nbsp(":"); | |
064997fb | 803 | self.print_type(field.ty); |
a2a8927a | 804 | self.word(","); |
532ac7d7 XL |
805 | } |
806 | ||
807 | self.bclose(span) | |
808 | } | |
e9174d1e SL |
809 | } |
810 | } | |
811 | ||
dfeec247 | 812 | pub fn print_variant(&mut self, v: &hir::Variant<'_>) { |
416331ca | 813 | self.head(""); |
54a0048b | 814 | let generics = hir::Generics::empty(); |
064997fb | 815 | self.print_struct(&v.data, generics, v.ident.name, v.span, false); |
e1599b0c | 816 | if let Some(ref d) = v.disr_expr { |
a2a8927a | 817 | self.space(); |
416331ca XL |
818 | self.word_space("="); |
819 | self.print_anon_const(d); | |
e9174d1e SL |
820 | } |
821 | } | |
dfeec247 XL |
822 | pub fn print_method_sig( |
823 | &mut self, | |
f9f354fc | 824 | ident: Ident, |
dfeec247 XL |
825 | m: &hir::FnSig<'_>, |
826 | generics: &hir::Generics<'_>, | |
f9f354fc | 827 | arg_names: &[Ident], |
dfeec247 XL |
828 | body_id: Option<hir::BodyId>, |
829 | ) { | |
064997fb | 830 | self.print_fn(m.decl, m.header, Some(ident.name), generics, arg_names, body_id); |
dfeec247 XL |
831 | } |
832 | ||
833 | pub fn print_trait_item(&mut self, ti: &hir::TraitItem<'_>) { | |
6a06907d | 834 | self.ann.pre(self, AnnNode::SubItem(ti.hir_id())); |
416331ca XL |
835 | self.hardbreak_if_not_bol(); |
836 | self.maybe_print_comment(ti.span.lo()); | |
6a06907d | 837 | self.print_outer_attributes(self.attrs(ti.hir_id())); |
e74abb32 | 838 | match ti.kind { |
064997fb FG |
839 | hir::TraitItemKind::Const(ty, default) => { |
840 | self.print_associated_const(ti.ident, ty, default); | |
e9174d1e | 841 | } |
064997fb FG |
842 | hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(arg_names)) => { |
843 | self.print_method_sig(ti.ident, sig, ti.generics, arg_names, None); | |
a2a8927a | 844 | self.word(";"); |
32a655c1 | 845 | } |
ba9703b0 | 846 | hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => { |
416331ca | 847 | self.head(""); |
064997fb | 848 | self.print_method_sig(ti.ident, sig, ti.generics, &[], Some(body)); |
416331ca XL |
849 | self.nbsp(); |
850 | self.end(); // need to close a box | |
851 | self.end(); // need to close a box | |
852 | self.ann.nested(self, Nested::Body(body)); | |
32a655c1 | 853 | } |
064997fb FG |
854 | hir::TraitItemKind::Type(bounds, default) => { |
855 | self.print_associated_type(ti.ident, ti.generics, Some(bounds), default); | |
e9174d1e SL |
856 | } |
857 | } | |
6a06907d | 858 | self.ann.post(self, AnnNode::SubItem(ti.hir_id())) |
e9174d1e SL |
859 | } |
860 | ||
dfeec247 | 861 | pub fn print_impl_item(&mut self, ii: &hir::ImplItem<'_>) { |
6a06907d | 862 | self.ann.pre(self, AnnNode::SubItem(ii.hir_id())); |
416331ca XL |
863 | self.hardbreak_if_not_bol(); |
864 | self.maybe_print_comment(ii.span.lo()); | |
6a06907d | 865 | self.print_outer_attributes(self.attrs(ii.hir_id())); |
54a0048b | 866 | |
e74abb32 | 867 | match ii.kind { |
064997fb FG |
868 | hir::ImplItemKind::Const(ty, expr) => { |
869 | self.print_associated_const(ii.ident, ty, Some(expr)); | |
e9174d1e | 870 | } |
ba9703b0 | 871 | hir::ImplItemKind::Fn(ref sig, body) => { |
416331ca | 872 | self.head(""); |
064997fb | 873 | self.print_method_sig(ii.ident, sig, ii.generics, &[], Some(body)); |
416331ca XL |
874 | self.nbsp(); |
875 | self.end(); // need to close a box | |
876 | self.end(); // need to close a box | |
877 | self.ann.nested(self, Nested::Body(body)); | |
e9174d1e | 878 | } |
2b03887a | 879 | hir::ImplItemKind::Type(ty) => { |
064997fb | 880 | self.print_associated_type(ii.ident, ii.generics, None, Some(ty)); |
8faf50e0 | 881 | } |
e9174d1e | 882 | } |
6a06907d | 883 | self.ann.post(self, AnnNode::SubItem(ii.hir_id())) |
e9174d1e SL |
884 | } |
885 | ||
064997fb FG |
886 | pub fn print_local( |
887 | &mut self, | |
888 | init: Option<&hir::Expr<'_>>, | |
889 | els: Option<&hir::Block<'_>>, | |
890 | decl: impl Fn(&mut Self), | |
891 | ) { | |
416331ca XL |
892 | self.space_if_not_bol(); |
893 | self.ibox(INDENT_UNIT); | |
894 | self.word_nbsp("let"); | |
48663c56 | 895 | |
416331ca XL |
896 | self.ibox(INDENT_UNIT); |
897 | decl(self); | |
898 | self.end(); | |
48663c56 | 899 | |
064997fb | 900 | if let Some(init) = init { |
416331ca XL |
901 | self.nbsp(); |
902 | self.word_space("="); | |
064997fb FG |
903 | self.print_expr(init); |
904 | } | |
905 | ||
906 | if let Some(els) = els { | |
907 | self.nbsp(); | |
908 | self.word_space("else"); | |
f2b60f7d FG |
909 | // containing cbox, will be closed by print-block at `}` |
910 | self.cbox(0); | |
911 | // head-box, will be closed by print-block after `{` | |
912 | self.ibox(0); | |
064997fb | 913 | self.print_block(els); |
48663c56 | 914 | } |
064997fb | 915 | |
48663c56 XL |
916 | self.end() |
917 | } | |
918 | ||
dfeec247 | 919 | pub fn print_stmt(&mut self, st: &hir::Stmt<'_>) { |
416331ca | 920 | self.maybe_print_comment(st.span.lo()); |
e74abb32 | 921 | match st.kind { |
064997fb FG |
922 | hir::StmtKind::Local(loc) => { |
923 | self.print_local(loc.init, loc.els, |this| this.print_local_decl(loc)); | |
9fa01778 | 924 | } |
dfeec247 | 925 | hir::StmtKind::Item(item) => self.ann.nested(self, Nested::Item(item)), |
064997fb | 926 | hir::StmtKind::Expr(expr) => { |
416331ca | 927 | self.space_if_not_bol(); |
064997fb | 928 | self.print_expr(expr); |
e9174d1e | 929 | } |
064997fb | 930 | hir::StmtKind::Semi(expr) => { |
416331ca | 931 | self.space_if_not_bol(); |
064997fb | 932 | self.print_expr(expr); |
a2a8927a | 933 | self.word(";"); |
e9174d1e SL |
934 | } |
935 | } | |
e74abb32 | 936 | if stmt_ends_with_semi(&st.kind) { |
a2a8927a | 937 | self.word(";"); |
e9174d1e SL |
938 | } |
939 | self.maybe_print_trailing_comment(st.span, None) | |
940 | } | |
941 | ||
dfeec247 | 942 | pub fn print_block(&mut self, blk: &hir::Block<'_>) { |
e9174d1e SL |
943 | self.print_block_with_attrs(blk, &[]) |
944 | } | |
945 | ||
dfeec247 | 946 | pub fn print_block_unclosed(&mut self, blk: &hir::Block<'_>) { |
416331ca | 947 | self.print_block_maybe_unclosed(blk, &[], false) |
e9174d1e SL |
948 | } |
949 | ||
dfeec247 | 950 | pub fn print_block_with_attrs(&mut self, blk: &hir::Block<'_>, attrs: &[ast::Attribute]) { |
416331ca | 951 | self.print_block_maybe_unclosed(blk, attrs, true) |
e9174d1e SL |
952 | } |
953 | ||
dfeec247 XL |
954 | pub fn print_block_maybe_unclosed( |
955 | &mut self, | |
956 | blk: &hir::Block<'_>, | |
957 | attrs: &[ast::Attribute], | |
958 | close_box: bool, | |
959 | ) { | |
e9174d1e | 960 | match blk.rules { |
ba9703b0 | 961 | hir::BlockCheckMode::UnsafeBlock(..) => self.word_space("unsafe"), |
ba9703b0 | 962 | hir::BlockCheckMode::DefaultBlock => (), |
e9174d1e | 963 | } |
416331ca XL |
964 | self.maybe_print_comment(blk.span.lo()); |
965 | self.ann.pre(self, AnnNode::Block(blk)); | |
966 | self.bopen(); | |
e9174d1e | 967 | |
416331ca | 968 | self.print_inner_attributes(attrs); |
e9174d1e | 969 | |
dfeec247 | 970 | for st in blk.stmts { |
416331ca | 971 | self.print_stmt(st); |
e9174d1e | 972 | } |
064997fb | 973 | if let Some(expr) = blk.expr { |
416331ca | 974 | self.space_if_not_bol(); |
064997fb | 975 | self.print_expr(expr); |
416331ca | 976 | self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi())); |
e9174d1e | 977 | } |
416331ca | 978 | self.bclose_maybe_open(blk.span, close_box); |
b7449926 | 979 | self.ann.post(self, AnnNode::Block(blk)) |
e9174d1e SL |
980 | } |
981 | ||
5869c6ff | 982 | fn print_else(&mut self, els: Option<&hir::Expr<'_>>) { |
94222f64 XL |
983 | if let Some(els_inner) = els { |
984 | match els_inner.kind { | |
985 | // Another `else if` block. | |
064997fb | 986 | hir::ExprKind::If(i, then, e) => { |
94222f64 XL |
987 | self.cbox(INDENT_UNIT - 1); |
988 | self.ibox(0); | |
a2a8927a | 989 | self.word(" else if "); |
064997fb | 990 | self.print_expr_as_cond(i); |
a2a8927a | 991 | self.space(); |
064997fb FG |
992 | self.print_expr(then); |
993 | self.print_else(e); | |
94222f64 XL |
994 | } |
995 | // Final `else` block. | |
064997fb | 996 | hir::ExprKind::Block(b, _) => { |
94222f64 XL |
997 | self.cbox(INDENT_UNIT - 1); |
998 | self.ibox(0); | |
a2a8927a | 999 | self.word(" else "); |
064997fb | 1000 | self.print_block(b); |
94222f64 XL |
1001 | } |
1002 | // Constraints would be great here! | |
1003 | _ => { | |
1004 | panic!("print_if saw if with weird alternative"); | |
5869c6ff XL |
1005 | } |
1006 | } | |
5869c6ff XL |
1007 | } |
1008 | } | |
1009 | ||
1010 | pub fn print_if( | |
1011 | &mut self, | |
1012 | test: &hir::Expr<'_>, | |
1013 | blk: &hir::Expr<'_>, | |
1014 | elseopt: Option<&hir::Expr<'_>>, | |
1015 | ) { | |
1016 | self.head("if"); | |
1017 | self.print_expr_as_cond(test); | |
a2a8927a | 1018 | self.space(); |
5869c6ff XL |
1019 | self.print_expr(blk); |
1020 | self.print_else(elseopt) | |
1021 | } | |
1022 | ||
a2a8927a XL |
1023 | pub fn print_array_length(&mut self, len: &hir::ArrayLen) { |
1024 | match len { | |
1025 | hir::ArrayLen::Infer(_, _) => self.word("_"), | |
1026 | hir::ArrayLen::Body(ct) => self.print_anon_const(ct), | |
1027 | } | |
1028 | } | |
1029 | ||
416331ca | 1030 | pub fn print_anon_const(&mut self, constant: &hir::AnonConst) { |
94b46f34 XL |
1031 | self.ann.nested(self, Nested::Body(constant.body)) |
1032 | } | |
e9174d1e | 1033 | |
dfeec247 | 1034 | fn print_call_post(&mut self, args: &[hir::Expr<'_>]) { |
416331ca XL |
1035 | self.popen(); |
1036 | self.commasep_exprs(Inconsistent, args); | |
e9174d1e SL |
1037 | self.pclose() |
1038 | } | |
1039 | ||
94222f64 XL |
1040 | fn print_expr_maybe_paren(&mut self, expr: &hir::Expr<'_>, prec: i8) { |
1041 | self.print_expr_cond_paren(expr, expr.precedence().order() < prec) | |
ea8adc8c XL |
1042 | } |
1043 | ||
94222f64 | 1044 | /// Prints an expr using syntax that's acceptable in a condition position, such as the `cond` in |
ea8adc8c | 1045 | /// `if cond { ... }`. |
dfeec247 | 1046 | pub fn print_expr_as_cond(&mut self, expr: &hir::Expr<'_>) { |
94222f64 XL |
1047 | self.print_expr_cond_paren(expr, Self::cond_needs_par(expr)) |
1048 | } | |
ea8adc8c | 1049 | |
94222f64 XL |
1050 | /// Prints `expr` or `(expr)` when `needs_par` holds. |
1051 | fn print_expr_cond_paren(&mut self, expr: &hir::Expr<'_>, needs_par: bool) { | |
e9174d1e | 1052 | if needs_par { |
416331ca | 1053 | self.popen(); |
e9174d1e | 1054 | } |
064997fb | 1055 | if let hir::ExprKind::DropTemps(actual_expr) = expr.kind { |
94222f64 XL |
1056 | self.print_expr(actual_expr); |
1057 | } else { | |
1058 | self.print_expr(expr); | |
1059 | } | |
e9174d1e | 1060 | if needs_par { |
416331ca | 1061 | self.pclose(); |
e9174d1e | 1062 | } |
e9174d1e SL |
1063 | } |
1064 | ||
94222f64 | 1065 | /// Print a `let pat = expr` expression. |
a2a8927a XL |
1066 | fn print_let(&mut self, pat: &hir::Pat<'_>, ty: Option<&hir::Ty<'_>>, init: &hir::Expr<'_>) { |
1067 | self.word_space("let"); | |
94222f64 | 1068 | self.print_pat(pat); |
a2a8927a XL |
1069 | if let Some(ty) = ty { |
1070 | self.word_space(":"); | |
1071 | self.print_type(ty); | |
1072 | } | |
1073 | self.space(); | |
94222f64 | 1074 | self.word_space("="); |
a2a8927a XL |
1075 | let npals = || parser::needs_par_as_let_scrutinee(init.precedence().order()); |
1076 | self.print_expr_cond_paren(init, Self::cond_needs_par(init) || npals()) | |
94222f64 XL |
1077 | } |
1078 | ||
3c0e092e | 1079 | // Does `expr` need parentheses when printed in a condition position? |
94222f64 XL |
1080 | // |
1081 | // These cases need parens due to the parse error observed in #26461: `if return {}` | |
1082 | // parses as the erroneous construct `if (return {})`, not `if (return) {}`. | |
1083 | fn cond_needs_par(expr: &hir::Expr<'_>) -> bool { | |
1084 | match expr.kind { | |
923072b8 FG |
1085 | hir::ExprKind::Break(..) | hir::ExprKind::Closure { .. } | hir::ExprKind::Ret(..) => { |
1086 | true | |
1087 | } | |
94222f64 XL |
1088 | _ => contains_exterior_struct_lit(expr), |
1089 | } | |
1090 | } | |
1091 | ||
dfeec247 | 1092 | fn print_expr_vec(&mut self, exprs: &[hir::Expr<'_>]) { |
416331ca | 1093 | self.ibox(INDENT_UNIT); |
a2a8927a | 1094 | self.word("["); |
416331ca | 1095 | self.commasep_exprs(Inconsistent, exprs); |
a2a8927a | 1096 | self.word("]"); |
e9174d1e SL |
1097 | self.end() |
1098 | } | |
1099 | ||
29967ef6 XL |
1100 | fn print_expr_anon_const(&mut self, anon_const: &hir::AnonConst) { |
1101 | self.ibox(INDENT_UNIT); | |
a2a8927a | 1102 | self.word_space("const"); |
29967ef6 XL |
1103 | self.print_anon_const(anon_const); |
1104 | self.end() | |
1105 | } | |
1106 | ||
a2a8927a | 1107 | fn print_expr_repeat(&mut self, element: &hir::Expr<'_>, count: &hir::ArrayLen) { |
416331ca | 1108 | self.ibox(INDENT_UNIT); |
a2a8927a | 1109 | self.word("["); |
416331ca XL |
1110 | self.print_expr(element); |
1111 | self.word_space(";"); | |
a2a8927a XL |
1112 | self.print_array_length(count); |
1113 | self.word("]"); | |
e9174d1e SL |
1114 | self.end() |
1115 | } | |
1116 | ||
dfeec247 XL |
1117 | fn print_expr_struct( |
1118 | &mut self, | |
1119 | qpath: &hir::QPath<'_>, | |
6a06907d | 1120 | fields: &[hir::ExprField<'_>], |
064997fb | 1121 | wth: Option<&hir::Expr<'_>>, |
dfeec247 | 1122 | ) { |
416331ca | 1123 | self.print_qpath(qpath, true); |
a2a8927a | 1124 | self.word("{"); |
f2b60f7d | 1125 | self.commasep_cmnt(Consistent, fields, |s, field| s.print_expr_field(field), |f| f.span); |
064997fb FG |
1126 | if let Some(expr) = wth { |
1127 | self.ibox(INDENT_UNIT); | |
1128 | if !fields.is_empty() { | |
1129 | self.word(","); | |
1130 | self.space(); | |
dfeec247 | 1131 | } |
064997fb FG |
1132 | self.word(".."); |
1133 | self.print_expr(expr); | |
1134 | self.end(); | |
1135 | } else if !fields.is_empty() { | |
1136 | self.word(","); | |
e9174d1e | 1137 | } |
064997fb | 1138 | |
a2a8927a | 1139 | self.word("}"); |
e9174d1e SL |
1140 | } |
1141 | ||
f2b60f7d FG |
1142 | fn print_expr_field(&mut self, field: &hir::ExprField<'_>) { |
1143 | if self.attrs(field.hir_id).is_empty() { | |
1144 | self.space(); | |
1145 | } | |
1146 | self.cbox(INDENT_UNIT); | |
1147 | self.print_outer_attributes(&self.attrs(field.hir_id)); | |
1148 | if !field.is_shorthand { | |
1149 | self.print_ident(field.ident); | |
1150 | self.word_space(":"); | |
1151 | } | |
1152 | self.print_expr(&field.expr); | |
1153 | self.end() | |
1154 | } | |
1155 | ||
dfeec247 | 1156 | fn print_expr_tup(&mut self, exprs: &[hir::Expr<'_>]) { |
416331ca XL |
1157 | self.popen(); |
1158 | self.commasep_exprs(Inconsistent, exprs); | |
e9174d1e | 1159 | if exprs.len() == 1 { |
a2a8927a | 1160 | self.word(","); |
e9174d1e SL |
1161 | } |
1162 | self.pclose() | |
1163 | } | |
1164 | ||
dfeec247 | 1165 | fn print_expr_call(&mut self, func: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { |
e74abb32 XL |
1166 | let prec = match func.kind { |
1167 | hir::ExprKind::Field(..) => parser::PREC_FORCE_PAREN, | |
1168 | _ => parser::PREC_POSTFIX, | |
1169 | }; | |
ea8adc8c | 1170 | |
416331ca | 1171 | self.print_expr_maybe_paren(func, prec); |
e9174d1e SL |
1172 | self.print_call_post(args) |
1173 | } | |
1174 | ||
f2b60f7d FG |
1175 | fn print_expr_method_call( |
1176 | &mut self, | |
1177 | segment: &hir::PathSegment<'_>, | |
1178 | receiver: &hir::Expr<'_>, | |
1179 | args: &[hir::Expr<'_>], | |
1180 | ) { | |
1181 | let base_args = args; | |
1182 | self.print_expr_maybe_paren(&receiver, parser::PREC_POSTFIX); | |
a2a8927a | 1183 | self.word("."); |
416331ca | 1184 | self.print_ident(segment.ident); |
8faf50e0 | 1185 | |
5869c6ff | 1186 | let generic_args = segment.args(); |
dc9dc135 | 1187 | if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() { |
f2b60f7d | 1188 | self.print_generic_args(generic_args, true); |
dc9dc135 XL |
1189 | } |
1190 | ||
e9174d1e SL |
1191 | self.print_call_post(base_args) |
1192 | } | |
1193 | ||
dfeec247 | 1194 | fn print_expr_binary(&mut self, op: hir::BinOp, lhs: &hir::Expr<'_>, rhs: &hir::Expr<'_>) { |
ea8adc8c XL |
1195 | let assoc_op = bin_op_to_assoc_op(op.node); |
1196 | let prec = assoc_op.precedence() as i8; | |
1197 | let fixity = assoc_op.fixity(); | |
1198 | ||
1199 | let (left_prec, right_prec) = match fixity { | |
1200 | Fixity::Left => (prec, prec + 1), | |
1201 | Fixity::Right => (prec + 1, prec), | |
1202 | Fixity::None => (prec + 1, prec + 1), | |
1203 | }; | |
1204 | ||
e74abb32 | 1205 | let left_prec = match (&lhs.kind, op.node) { |
abe05a73 XL |
1206 | // These cases need parens: `x as i32 < y` has the parser thinking that `i32 < y` is |
1207 | // the beginning of a path type. It starts trying to parse `x as (i32 < y ...` instead | |
1208 | // of `(x as i32) < ...`. We need to convince it _not_ to do that. | |
ba9703b0 XL |
1209 | (&hir::ExprKind::Cast { .. }, hir::BinOpKind::Lt | hir::BinOpKind::Shl) => { |
1210 | parser::PREC_FORCE_PAREN | |
1211 | } | |
94222f64 XL |
1212 | (&hir::ExprKind::Let { .. }, _) if !parser::needs_par_as_let_scrutinee(prec) => { |
1213 | parser::PREC_FORCE_PAREN | |
1214 | } | |
abe05a73 XL |
1215 | _ => left_prec, |
1216 | }; | |
1217 | ||
416331ca | 1218 | self.print_expr_maybe_paren(lhs, left_prec); |
a2a8927a | 1219 | self.space(); |
416331ca | 1220 | self.word_space(op.node.as_str()); |
ea8adc8c | 1221 | self.print_expr_maybe_paren(rhs, right_prec) |
e9174d1e SL |
1222 | } |
1223 | ||
dfeec247 | 1224 | fn print_expr_unary(&mut self, op: hir::UnOp, expr: &hir::Expr<'_>) { |
a2a8927a | 1225 | self.word(op.as_str()); |
ea8adc8c | 1226 | self.print_expr_maybe_paren(expr, parser::PREC_PREFIX) |
e9174d1e SL |
1227 | } |
1228 | ||
dfeec247 XL |
1229 | fn print_expr_addr_of( |
1230 | &mut self, | |
1231 | kind: hir::BorrowKind, | |
1232 | mutability: hir::Mutability, | |
1233 | expr: &hir::Expr<'_>, | |
1234 | ) { | |
a2a8927a | 1235 | self.word("&"); |
60c5eb7d XL |
1236 | match kind { |
1237 | hir::BorrowKind::Ref => self.print_mutability(mutability, false), | |
1238 | hir::BorrowKind::Raw => { | |
1239 | self.word_nbsp("raw"); | |
1240 | self.print_mutability(mutability, true); | |
1241 | } | |
1242 | } | |
ea8adc8c | 1243 | self.print_expr_maybe_paren(expr, parser::PREC_PREFIX) |
e9174d1e SL |
1244 | } |
1245 | ||
416331ca XL |
1246 | fn print_literal(&mut self, lit: &hir::Lit) { |
1247 | self.maybe_print_comment(lit.span.lo()); | |
9c376795 | 1248 | self.word(lit.node.to_string()) |
48663c56 XL |
1249 | } |
1250 | ||
17df50a5 XL |
1251 | fn print_inline_asm(&mut self, asm: &hir::InlineAsm<'_>) { |
1252 | enum AsmArg<'a> { | |
1253 | Template(String), | |
1254 | Operand(&'a hir::InlineAsmOperand<'a>), | |
1255 | Options(ast::InlineAsmOptions), | |
1256 | } | |
1257 | ||
064997fb | 1258 | let mut args = vec![AsmArg::Template(ast::InlineAsmTemplatePiece::to_string(asm.template))]; |
17df50a5 XL |
1259 | args.extend(asm.operands.iter().map(|(o, _)| AsmArg::Operand(o))); |
1260 | if !asm.options.is_empty() { | |
1261 | args.push(AsmArg::Options(asm.options)); | |
1262 | } | |
1263 | ||
1264 | self.popen(); | |
064997fb FG |
1265 | self.commasep(Consistent, &args, |s, arg| match *arg { |
1266 | AsmArg::Template(ref template) => s.print_string(template, ast::StrStyle::Cooked), | |
1267 | AsmArg::Operand(op) => match *op { | |
1268 | hir::InlineAsmOperand::In { reg, ref expr } => { | |
17df50a5 XL |
1269 | s.word("in"); |
1270 | s.popen(); | |
9c376795 | 1271 | s.word(format!("{reg}")); |
17df50a5 XL |
1272 | s.pclose(); |
1273 | s.space(); | |
1274 | s.print_expr(expr); | |
1275 | } | |
064997fb FG |
1276 | hir::InlineAsmOperand::Out { reg, late, ref expr } => { |
1277 | s.word(if late { "lateout" } else { "out" }); | |
17df50a5 | 1278 | s.popen(); |
9c376795 | 1279 | s.word(format!("{reg}")); |
17df50a5 XL |
1280 | s.pclose(); |
1281 | s.space(); | |
1282 | match expr { | |
1283 | Some(expr) => s.print_expr(expr), | |
1284 | None => s.word("_"), | |
1285 | } | |
1286 | } | |
064997fb FG |
1287 | hir::InlineAsmOperand::InOut { reg, late, ref expr } => { |
1288 | s.word(if late { "inlateout" } else { "inout" }); | |
17df50a5 | 1289 | s.popen(); |
9c376795 | 1290 | s.word(format!("{reg}")); |
17df50a5 XL |
1291 | s.pclose(); |
1292 | s.space(); | |
1293 | s.print_expr(expr); | |
1294 | } | |
064997fb FG |
1295 | hir::InlineAsmOperand::SplitInOut { reg, late, ref in_expr, ref out_expr } => { |
1296 | s.word(if late { "inlateout" } else { "inout" }); | |
17df50a5 | 1297 | s.popen(); |
9c376795 | 1298 | s.word(format!("{reg}")); |
17df50a5 XL |
1299 | s.pclose(); |
1300 | s.space(); | |
1301 | s.print_expr(in_expr); | |
1302 | s.space(); | |
1303 | s.word_space("=>"); | |
1304 | match out_expr { | |
1305 | Some(out_expr) => s.print_expr(out_expr), | |
1306 | None => s.word("_"), | |
1307 | } | |
1308 | } | |
064997fb | 1309 | hir::InlineAsmOperand::Const { ref anon_const } => { |
17df50a5 XL |
1310 | s.word("const"); |
1311 | s.space(); | |
1312 | s.print_anon_const(anon_const); | |
1313 | } | |
064997fb | 1314 | hir::InlineAsmOperand::SymFn { ref anon_const } => { |
04454e1e | 1315 | s.word("sym_fn"); |
17df50a5 | 1316 | s.space(); |
04454e1e FG |
1317 | s.print_anon_const(anon_const); |
1318 | } | |
064997fb | 1319 | hir::InlineAsmOperand::SymStatic { ref path, def_id: _ } => { |
04454e1e FG |
1320 | s.word("sym_static"); |
1321 | s.space(); | |
1322 | s.print_qpath(path, true); | |
17df50a5 XL |
1323 | } |
1324 | }, | |
1325 | AsmArg::Options(opts) => { | |
1326 | s.word("options"); | |
1327 | s.popen(); | |
1328 | let mut options = vec![]; | |
1329 | if opts.contains(ast::InlineAsmOptions::PURE) { | |
1330 | options.push("pure"); | |
1331 | } | |
1332 | if opts.contains(ast::InlineAsmOptions::NOMEM) { | |
1333 | options.push("nomem"); | |
1334 | } | |
1335 | if opts.contains(ast::InlineAsmOptions::READONLY) { | |
1336 | options.push("readonly"); | |
1337 | } | |
1338 | if opts.contains(ast::InlineAsmOptions::PRESERVES_FLAGS) { | |
1339 | options.push("preserves_flags"); | |
1340 | } | |
1341 | if opts.contains(ast::InlineAsmOptions::NORETURN) { | |
1342 | options.push("noreturn"); | |
1343 | } | |
1344 | if opts.contains(ast::InlineAsmOptions::NOSTACK) { | |
1345 | options.push("nostack"); | |
1346 | } | |
1347 | if opts.contains(ast::InlineAsmOptions::ATT_SYNTAX) { | |
1348 | options.push("att_syntax"); | |
1349 | } | |
136023e0 XL |
1350 | if opts.contains(ast::InlineAsmOptions::RAW) { |
1351 | options.push("raw"); | |
1352 | } | |
a2a8927a XL |
1353 | if opts.contains(ast::InlineAsmOptions::MAY_UNWIND) { |
1354 | options.push("may_unwind"); | |
1355 | } | |
17df50a5 XL |
1356 | s.commasep(Inconsistent, &options, |s, &opt| { |
1357 | s.word(opt); | |
1358 | }); | |
1359 | s.pclose(); | |
1360 | } | |
1361 | }); | |
1362 | self.pclose(); | |
1363 | } | |
1364 | ||
dfeec247 | 1365 | pub fn print_expr(&mut self, expr: &hir::Expr<'_>) { |
416331ca | 1366 | self.maybe_print_comment(expr.span.lo()); |
6a06907d | 1367 | self.print_outer_attributes(self.attrs(expr.hir_id)); |
416331ca XL |
1368 | self.ibox(INDENT_UNIT); |
1369 | self.ann.pre(self, AnnNode::Expr(expr)); | |
e74abb32 | 1370 | match expr.kind { |
064997fb | 1371 | hir::ExprKind::Box(expr) => { |
416331ca XL |
1372 | self.word_space("box"); |
1373 | self.print_expr_maybe_paren(expr, parser::PREC_PREFIX); | |
e9174d1e | 1374 | } |
064997fb | 1375 | hir::ExprKind::Array(exprs) => { |
416331ca | 1376 | self.print_expr_vec(exprs); |
e9174d1e | 1377 | } |
29967ef6 XL |
1378 | hir::ExprKind::ConstBlock(ref anon_const) => { |
1379 | self.print_expr_anon_const(anon_const); | |
1380 | } | |
064997fb FG |
1381 | hir::ExprKind::Repeat(element, ref count) => { |
1382 | self.print_expr_repeat(element, count); | |
e9174d1e | 1383 | } |
064997fb | 1384 | hir::ExprKind::Struct(qpath, fields, wth) => { |
dfeec247 | 1385 | self.print_expr_struct(qpath, fields, wth); |
e9174d1e | 1386 | } |
064997fb | 1387 | hir::ExprKind::Tup(exprs) => { |
416331ca | 1388 | self.print_expr_tup(exprs); |
e9174d1e | 1389 | } |
064997fb FG |
1390 | hir::ExprKind::Call(func, args) => { |
1391 | self.print_expr_call(func, args); | |
e9174d1e | 1392 | } |
f2b60f7d FG |
1393 | hir::ExprKind::MethodCall(segment, receiver, args, _) => { |
1394 | self.print_expr_method_call(segment, receiver, args); | |
e9174d1e | 1395 | } |
064997fb FG |
1396 | hir::ExprKind::Binary(op, lhs, rhs) => { |
1397 | self.print_expr_binary(op, lhs, rhs); | |
e9174d1e | 1398 | } |
064997fb FG |
1399 | hir::ExprKind::Unary(op, expr) => { |
1400 | self.print_expr_unary(op, expr); | |
e9174d1e | 1401 | } |
064997fb FG |
1402 | hir::ExprKind::AddrOf(k, m, expr) => { |
1403 | self.print_expr_addr_of(k, m, expr); | |
e9174d1e | 1404 | } |
8faf50e0 | 1405 | hir::ExprKind::Lit(ref lit) => { |
064997fb | 1406 | self.print_literal(lit); |
e9174d1e | 1407 | } |
064997fb | 1408 | hir::ExprKind::Cast(expr, ty) => { |
ea8adc8c | 1409 | let prec = AssocOp::As.precedence() as i8; |
064997fb | 1410 | self.print_expr_maybe_paren(expr, prec); |
a2a8927a | 1411 | self.space(); |
416331ca | 1412 | self.word_space("as"); |
064997fb | 1413 | self.print_type(ty); |
e9174d1e | 1414 | } |
064997fb | 1415 | hir::ExprKind::Type(expr, ty) => { |
ea8adc8c | 1416 | let prec = AssocOp::Colon.precedence() as i8; |
064997fb | 1417 | self.print_expr_maybe_paren(expr, prec); |
416331ca | 1418 | self.word_space(":"); |
064997fb | 1419 | self.print_type(ty); |
9cc50fc6 | 1420 | } |
064997fb | 1421 | hir::ExprKind::DropTemps(init) => { |
48663c56 | 1422 | // Print `{`: |
416331ca XL |
1423 | self.cbox(INDENT_UNIT); |
1424 | self.ibox(0); | |
1425 | self.bopen(); | |
48663c56 XL |
1426 | |
1427 | // Print `let _t = $init;`: | |
f9f354fc | 1428 | let temp = Ident::from_str("_t"); |
064997fb | 1429 | self.print_local(Some(init), None, |this| this.print_ident(temp)); |
a2a8927a | 1430 | self.word(";"); |
48663c56 XL |
1431 | |
1432 | // Print `_t`: | |
416331ca XL |
1433 | self.space_if_not_bol(); |
1434 | self.print_ident(temp); | |
48663c56 XL |
1435 | |
1436 | // Print `}`: | |
416331ca | 1437 | self.bclose_maybe_open(expr.span, true); |
e9174d1e | 1438 | } |
064997fb FG |
1439 | hir::ExprKind::Let(&hir::Let { pat, ty, init, .. }) => { |
1440 | self.print_let(pat, ty, init); | |
94222f64 | 1441 | } |
064997fb FG |
1442 | hir::ExprKind::If(test, blk, elseopt) => { |
1443 | self.print_if(test, blk, elseopt); | |
5869c6ff | 1444 | } |
064997fb | 1445 | hir::ExprKind::Loop(blk, opt_label, _, _) => { |
2c00a5a8 | 1446 | if let Some(label) = opt_label { |
416331ca XL |
1447 | self.print_ident(label.ident); |
1448 | self.word_space(":"); | |
e9174d1e | 1449 | } |
416331ca | 1450 | self.head("loop"); |
064997fb | 1451 | self.print_block(blk); |
e9174d1e | 1452 | } |
064997fb | 1453 | hir::ExprKind::Match(expr, arms, _) => { |
416331ca XL |
1454 | self.cbox(INDENT_UNIT); |
1455 | self.ibox(INDENT_UNIT); | |
1456 | self.word_nbsp("match"); | |
064997fb | 1457 | self.print_expr_as_cond(expr); |
a2a8927a | 1458 | self.space(); |
416331ca | 1459 | self.bopen(); |
e9174d1e | 1460 | for arm in arms { |
416331ca | 1461 | self.print_arm(arm); |
e9174d1e | 1462 | } |
416331ca | 1463 | self.bclose(expr.span); |
e9174d1e | 1464 | } |
064997fb FG |
1465 | hir::ExprKind::Closure(&hir::Closure { |
1466 | binder, | |
9c376795 | 1467 | constness, |
923072b8 FG |
1468 | capture_clause, |
1469 | bound_generic_params, | |
064997fb | 1470 | fn_decl, |
923072b8 FG |
1471 | body, |
1472 | fn_decl_span: _, | |
487cf647 | 1473 | fn_arg_span: _, |
923072b8 | 1474 | movability: _, |
487cf647 | 1475 | def_id: _, |
064997fb FG |
1476 | }) => { |
1477 | self.print_closure_binder(binder, bound_generic_params); | |
9c376795 | 1478 | self.print_constness(constness); |
416331ca | 1479 | self.print_capture_clause(capture_clause); |
e9174d1e | 1480 | |
064997fb | 1481 | self.print_closure_params(fn_decl, body); |
a2a8927a | 1482 | self.space(); |
e9174d1e | 1483 | |
e1599b0c | 1484 | // This is a bare expression. |
416331ca XL |
1485 | self.ann.nested(self, Nested::Body(body)); |
1486 | self.end(); // need to close a box | |
e9174d1e | 1487 | |
e1599b0c | 1488 | // A box will be closed by `print_expr`, but we didn't want an overall |
e9174d1e SL |
1489 | // wrapper so we closed the corresponding opening. so create an |
1490 | // empty box to satisfy the close. | |
416331ca | 1491 | self.ibox(0); |
e9174d1e | 1492 | } |
064997fb | 1493 | hir::ExprKind::Block(blk, opt_label) => { |
94b46f34 | 1494 | if let Some(label) = opt_label { |
416331ca XL |
1495 | self.print_ident(label.ident); |
1496 | self.word_space(":"); | |
94b46f34 | 1497 | } |
e1599b0c | 1498 | // containing cbox, will be closed by print-block at `}` |
416331ca | 1499 | self.cbox(INDENT_UNIT); |
e1599b0c | 1500 | // head-box, will be closed by print-block after `{` |
416331ca | 1501 | self.ibox(0); |
064997fb | 1502 | self.print_block(blk); |
e9174d1e | 1503 | } |
064997fb | 1504 | hir::ExprKind::Assign(lhs, rhs, _) => { |
ea8adc8c | 1505 | let prec = AssocOp::Assign.precedence() as i8; |
064997fb | 1506 | self.print_expr_maybe_paren(lhs, prec + 1); |
a2a8927a | 1507 | self.space(); |
416331ca | 1508 | self.word_space("="); |
064997fb | 1509 | self.print_expr_maybe_paren(rhs, prec); |
e9174d1e | 1510 | } |
064997fb | 1511 | hir::ExprKind::AssignOp(op, lhs, rhs) => { |
ea8adc8c | 1512 | let prec = AssocOp::Assign.precedence() as i8; |
064997fb | 1513 | self.print_expr_maybe_paren(lhs, prec + 1); |
a2a8927a XL |
1514 | self.space(); |
1515 | self.word(op.node.as_str()); | |
416331ca | 1516 | self.word_space("="); |
064997fb | 1517 | self.print_expr_maybe_paren(rhs, prec); |
e9174d1e | 1518 | } |
064997fb | 1519 | hir::ExprKind::Field(expr, ident) => { |
416331ca | 1520 | self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); |
a2a8927a | 1521 | self.word("."); |
416331ca | 1522 | self.print_ident(ident); |
e9174d1e | 1523 | } |
064997fb FG |
1524 | hir::ExprKind::Index(expr, index) => { |
1525 | self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); | |
a2a8927a | 1526 | self.word("["); |
064997fb | 1527 | self.print_expr(index); |
a2a8927a | 1528 | self.word("]"); |
e9174d1e | 1529 | } |
dfeec247 | 1530 | hir::ExprKind::Path(ref qpath) => self.print_qpath(qpath, true), |
064997fb | 1531 | hir::ExprKind::Break(destination, opt_expr) => { |
a2a8927a | 1532 | self.word("break"); |
2c00a5a8 | 1533 | if let Some(label) = destination.label { |
a2a8927a | 1534 | self.space(); |
416331ca | 1535 | self.print_ident(label.ident); |
476ff2be | 1536 | } |
064997fb | 1537 | if let Some(expr) = opt_expr { |
a2a8927a | 1538 | self.space(); |
416331ca | 1539 | self.print_expr_maybe_paren(expr, parser::PREC_JUMP); |
e9174d1e SL |
1540 | } |
1541 | } | |
8faf50e0 | 1542 | hir::ExprKind::Continue(destination) => { |
a2a8927a | 1543 | self.word("continue"); |
2c00a5a8 | 1544 | if let Some(label) = destination.label { |
a2a8927a | 1545 | self.space(); |
416331ca | 1546 | self.print_ident(label.ident); |
e9174d1e SL |
1547 | } |
1548 | } | |
064997fb | 1549 | hir::ExprKind::Ret(result) => { |
a2a8927a | 1550 | self.word("return"); |
064997fb | 1551 | if let Some(expr) = result { |
a2a8927a | 1552 | self.word(" "); |
064997fb | 1553 | self.print_expr_maybe_paren(expr, parser::PREC_JUMP); |
e9174d1e SL |
1554 | } |
1555 | } | |
064997fb | 1556 | hir::ExprKind::InlineAsm(asm) => { |
f9f354fc | 1557 | self.word("asm!"); |
17df50a5 | 1558 | self.print_inline_asm(asm); |
f9f354fc | 1559 | } |
064997fb | 1560 | hir::ExprKind::Yield(expr, _) => { |
416331ca | 1561 | self.word_space("yield"); |
064997fb | 1562 | self.print_expr_maybe_paren(expr, parser::PREC_JUMP); |
ea8adc8c | 1563 | } |
0731742a | 1564 | hir::ExprKind::Err => { |
416331ca | 1565 | self.popen(); |
a2a8927a | 1566 | self.word("/*ERROR*/"); |
416331ca | 1567 | self.pclose(); |
0731742a | 1568 | } |
e9174d1e | 1569 | } |
416331ca | 1570 | self.ann.post(self, AnnNode::Expr(expr)); |
e9174d1e SL |
1571 | self.end() |
1572 | } | |
1573 | ||
dfeec247 | 1574 | pub fn print_local_decl(&mut self, loc: &hir::Local<'_>) { |
064997fb FG |
1575 | self.print_pat(loc.pat); |
1576 | if let Some(ty) = loc.ty { | |
416331ca | 1577 | self.word_space(":"); |
064997fb | 1578 | self.print_type(ty); |
e9174d1e | 1579 | } |
e9174d1e SL |
1580 | } |
1581 | ||
f9f354fc XL |
1582 | pub fn print_name(&mut self, name: Symbol) { |
1583 | self.print_ident(Ident::with_dummy_span(name)) | |
e9174d1e SL |
1584 | } |
1585 | ||
487cf647 | 1586 | pub fn print_path<R>(&mut self, path: &hir::Path<'_, R>, colons_before_params: bool) { |
416331ca | 1587 | self.maybe_print_comment(path.span.lo()); |
e9174d1e | 1588 | |
32a655c1 SL |
1589 | for (i, segment) in path.segments.iter().enumerate() { |
1590 | if i > 0 { | |
a2a8927a | 1591 | self.word("::") |
e9174d1e | 1592 | } |
dc9dc135 | 1593 | if segment.ident.name != kw::PathRoot { |
416331ca | 1594 | self.print_ident(segment.ident); |
f2b60f7d | 1595 | self.print_generic_args(segment.args(), colons_before_params); |
32a655c1 | 1596 | } |
e9174d1e | 1597 | } |
e9174d1e SL |
1598 | } |
1599 | ||
dfeec247 | 1600 | pub fn print_path_segment(&mut self, segment: &hir::PathSegment<'_>) { |
dc9dc135 | 1601 | if segment.ident.name != kw::PathRoot { |
416331ca | 1602 | self.print_ident(segment.ident); |
f2b60f7d | 1603 | self.print_generic_args(segment.args(), false); |
13cf67c4 | 1604 | } |
13cf67c4 XL |
1605 | } |
1606 | ||
dfeec247 | 1607 | pub fn print_qpath(&mut self, qpath: &hir::QPath<'_>, colons_before_params: bool) { |
476ff2be | 1608 | match *qpath { |
064997fb FG |
1609 | hir::QPath::Resolved(None, path) => self.print_path(path, colons_before_params), |
1610 | hir::QPath::Resolved(Some(qself), path) => { | |
a2a8927a | 1611 | self.word("<"); |
416331ca | 1612 | self.print_type(qself); |
a2a8927a | 1613 | self.space(); |
416331ca | 1614 | self.word_space("as"); |
476ff2be | 1615 | |
32a655c1 SL |
1616 | for (i, segment) in path.segments[..path.segments.len() - 1].iter().enumerate() { |
1617 | if i > 0 { | |
a2a8927a | 1618 | self.word("::") |
476ff2be | 1619 | } |
dc9dc135 | 1620 | if segment.ident.name != kw::PathRoot { |
416331ca | 1621 | self.print_ident(segment.ident); |
f2b60f7d | 1622 | self.print_generic_args(segment.args(), colons_before_params); |
32a655c1 | 1623 | } |
476ff2be SL |
1624 | } |
1625 | ||
a2a8927a XL |
1626 | self.word(">"); |
1627 | self.word("::"); | |
476ff2be | 1628 | let item_segment = path.segments.last().unwrap(); |
416331ca | 1629 | self.print_ident(item_segment.ident); |
f2b60f7d | 1630 | self.print_generic_args(item_segment.args(), colons_before_params) |
476ff2be | 1631 | } |
064997fb | 1632 | hir::QPath::TypeRelative(qself, item_segment) => { |
e74abb32 XL |
1633 | // If we've got a compound-qualified-path, let's push an additional pair of angle |
1634 | // brackets, so that we pretty-print `<<A::B>::C>` as `<A::B>::C`, instead of just | |
1635 | // `A::B::C` (since the latter could be ambiguous to the user) | |
064997fb | 1636 | if let hir::TyKind::Path(hir::QPath::Resolved(None, _)) = qself.kind { |
e74abb32 XL |
1637 | self.print_type(qself); |
1638 | } else { | |
a2a8927a | 1639 | self.word("<"); |
e74abb32 | 1640 | self.print_type(qself); |
a2a8927a | 1641 | self.word(">"); |
e74abb32 XL |
1642 | } |
1643 | ||
a2a8927a | 1644 | self.word("::"); |
416331ca | 1645 | self.print_ident(item_segment.ident); |
f2b60f7d | 1646 | self.print_generic_args(item_segment.args(), colons_before_params) |
476ff2be | 1647 | } |
a2a8927a XL |
1648 | hir::QPath::LangItem(lang_item, span, _) => { |
1649 | self.word("#[lang = \""); | |
3dfed10e | 1650 | self.print_ident(Ident::new(lang_item.name(), span)); |
a2a8927a | 1651 | self.word("\"]"); |
3dfed10e | 1652 | } |
e9174d1e | 1653 | } |
e9174d1e SL |
1654 | } |
1655 | ||
dfeec247 XL |
1656 | fn print_generic_args( |
1657 | &mut self, | |
1658 | generic_args: &hir::GenericArgs<'_>, | |
dfeec247 XL |
1659 | colons_before_params: bool, |
1660 | ) { | |
8faf50e0 | 1661 | if generic_args.parenthesized { |
a2a8927a | 1662 | self.word("("); |
064997fb | 1663 | self.commasep(Inconsistent, generic_args.inputs(), |s, ty| s.print_type(ty)); |
a2a8927a | 1664 | self.word(")"); |
e9174d1e | 1665 | |
416331ca XL |
1666 | self.space_if_not_bol(); |
1667 | self.word_space("->"); | |
1668 | self.print_type(generic_args.bindings[0].ty()); | |
3b2f2976 XL |
1669 | } else { |
1670 | let start = if colons_before_params { "::<" } else { "<" }; | |
1671 | let empty = Cell::new(true); | |
1672 | let start_or_comma = |this: &mut Self| { | |
1673 | if empty.get() { | |
1674 | empty.set(false); | |
a2a8927a | 1675 | this.word(start) |
3b2f2976 XL |
1676 | } else { |
1677 | this.word_space(",") | |
e9174d1e | 1678 | } |
3b2f2976 | 1679 | }; |
e9174d1e | 1680 | |
9fa01778 XL |
1681 | let mut nonelided_generic_args: bool = false; |
1682 | let elide_lifetimes = generic_args.args.iter().all(|arg| match arg { | |
2b03887a FG |
1683 | GenericArg::Lifetime(lt) if lt.is_elided() => true, |
1684 | GenericArg::Lifetime(_) => { | |
1685 | nonelided_generic_args = true; | |
1686 | false | |
1687 | } | |
9fa01778 XL |
1688 | _ => { |
1689 | nonelided_generic_args = true; | |
1690 | true | |
476ff2be | 1691 | } |
9fa01778 XL |
1692 | }); |
1693 | ||
1694 | if nonelided_generic_args { | |
416331ca | 1695 | start_or_comma(self); |
dfeec247 XL |
1696 | self.commasep( |
1697 | Inconsistent, | |
064997fb | 1698 | generic_args.args, |
dfeec247 | 1699 | |s, generic_arg| match generic_arg { |
9fa01778 | 1700 | GenericArg::Lifetime(lt) if !elide_lifetimes => s.print_lifetime(lt), |
dfeec247 | 1701 | GenericArg::Lifetime(_) => {} |
8faf50e0 | 1702 | GenericArg::Type(ty) => s.print_type(ty), |
9fa01778 | 1703 | GenericArg::Const(ct) => s.print_anon_const(&ct.value), |
94222f64 | 1704 | GenericArg::Infer(_inf) => s.word("_"), |
dfeec247 XL |
1705 | }, |
1706 | ); | |
3b2f2976 | 1707 | } |
e9174d1e | 1708 | |
064997fb | 1709 | for binding in generic_args.bindings { |
416331ca | 1710 | start_or_comma(self); |
923072b8 | 1711 | self.print_type_binding(binding); |
3b2f2976 | 1712 | } |
e9174d1e | 1713 | |
3b2f2976 | 1714 | if !empty.get() { |
a2a8927a | 1715 | self.word(">") |
e9174d1e SL |
1716 | } |
1717 | } | |
e9174d1e SL |
1718 | } |
1719 | ||
923072b8 FG |
1720 | pub fn print_type_binding(&mut self, binding: &hir::TypeBinding<'_>) { |
1721 | self.print_ident(binding.ident); | |
f2b60f7d | 1722 | self.print_generic_args(binding.gen_args, false); |
923072b8 FG |
1723 | self.space(); |
1724 | match binding.kind { | |
1725 | hir::TypeBindingKind::Equality { ref term } => { | |
1726 | self.word_space("="); | |
1727 | match term { | |
064997fb | 1728 | Term::Ty(ty) => self.print_type(ty), |
923072b8 FG |
1729 | Term::Const(ref c) => self.print_anon_const(c), |
1730 | } | |
1731 | } | |
1732 | hir::TypeBindingKind::Constraint { bounds } => { | |
1733 | self.print_bounds(":", bounds); | |
1734 | } | |
1735 | } | |
1736 | } | |
1737 | ||
dfeec247 | 1738 | pub fn print_pat(&mut self, pat: &hir::Pat<'_>) { |
416331ca XL |
1739 | self.maybe_print_comment(pat.span.lo()); |
1740 | self.ann.pre(self, AnnNode::Pat(pat)); | |
92a42be0 SL |
1741 | // Pat isn't normalized, but the beauty of it |
1742 | // is that it doesn't matter | |
e74abb32 | 1743 | match pat.kind { |
a2a8927a | 1744 | PatKind::Wild => self.word("_"), |
f2b60f7d FG |
1745 | PatKind::Binding(BindingAnnotation(by_ref, mutbl), _, ident, sub) => { |
1746 | if by_ref == ByRef::Yes { | |
1747 | self.word_nbsp("ref"); | |
1748 | } | |
1749 | if mutbl == Mutability::Mut { | |
1750 | self.word_nbsp("mut"); | |
e9174d1e | 1751 | } |
416331ca | 1752 | self.print_ident(ident); |
064997fb | 1753 | if let Some(p) = sub { |
a2a8927a | 1754 | self.word("@"); |
064997fb | 1755 | self.print_pat(p); |
e9174d1e SL |
1756 | } |
1757 | } | |
064997fb | 1758 | PatKind::TupleStruct(ref qpath, elts, ddpos) => { |
416331ca XL |
1759 | self.print_qpath(qpath, true); |
1760 | self.popen(); | |
f2b60f7d | 1761 | if let Some(ddpos) = ddpos.as_opt_usize() { |
064997fb | 1762 | self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p)); |
3157f602 | 1763 | if ddpos != 0 { |
416331ca | 1764 | self.word_space(","); |
e9174d1e | 1765 | } |
a2a8927a | 1766 | self.word(".."); |
3157f602 | 1767 | if ddpos != elts.len() { |
a2a8927a | 1768 | self.word(","); |
064997fb | 1769 | self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(p)); |
3157f602 XL |
1770 | } |
1771 | } else { | |
064997fb | 1772 | self.commasep(Inconsistent, elts, |s, p| s.print_pat(p)); |
e9174d1e | 1773 | } |
416331ca | 1774 | self.pclose(); |
e9174d1e | 1775 | } |
476ff2be | 1776 | PatKind::Path(ref qpath) => { |
416331ca | 1777 | self.print_qpath(qpath, true); |
e9174d1e | 1778 | } |
064997fb | 1779 | PatKind::Struct(ref qpath, fields, etc) => { |
416331ca XL |
1780 | self.print_qpath(qpath, true); |
1781 | self.nbsp(); | |
a2a8927a XL |
1782 | self.word("{"); |
1783 | let empty = fields.is_empty() && !etc; | |
1784 | if !empty { | |
1785 | self.space(); | |
1786 | } | |
f2b60f7d | 1787 | self.commasep_cmnt(Consistent, &fields, |s, f| s.print_patfield(f), |f| f.pat.span); |
e9174d1e | 1788 | if etc { |
b039eaaf | 1789 | if !fields.is_empty() { |
416331ca | 1790 | self.word_space(","); |
b039eaaf | 1791 | } |
a2a8927a XL |
1792 | self.word(".."); |
1793 | } | |
1794 | if !empty { | |
1795 | self.space(); | |
e9174d1e | 1796 | } |
a2a8927a | 1797 | self.word("}"); |
e9174d1e | 1798 | } |
064997fb FG |
1799 | PatKind::Or(pats) => { |
1800 | self.strsep("|", true, Inconsistent, pats, |s, p| s.print_pat(p)); | |
e1599b0c | 1801 | } |
064997fb | 1802 | PatKind::Tuple(elts, ddpos) => { |
416331ca | 1803 | self.popen(); |
f2b60f7d | 1804 | if let Some(ddpos) = ddpos.as_opt_usize() { |
064997fb | 1805 | self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p)); |
3157f602 | 1806 | if ddpos != 0 { |
416331ca | 1807 | self.word_space(","); |
3157f602 | 1808 | } |
a2a8927a | 1809 | self.word(".."); |
3157f602 | 1810 | if ddpos != elts.len() { |
a2a8927a | 1811 | self.word(","); |
064997fb | 1812 | self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(p)); |
3157f602 XL |
1813 | } |
1814 | } else { | |
064997fb | 1815 | self.commasep(Inconsistent, elts, |s, p| s.print_pat(p)); |
3157f602 | 1816 | if elts.len() == 1 { |
a2a8927a | 1817 | self.word(","); |
3157f602 | 1818 | } |
e9174d1e | 1819 | } |
416331ca | 1820 | self.pclose(); |
e9174d1e | 1821 | } |
064997fb | 1822 | PatKind::Box(inner) => { |
29967ef6 | 1823 | let is_range_inner = matches!(inner.kind, PatKind::Range(..)); |
a2a8927a | 1824 | self.word("box "); |
0531ce1d | 1825 | if is_range_inner { |
416331ca | 1826 | self.popen(); |
0531ce1d | 1827 | } |
064997fb | 1828 | self.print_pat(inner); |
0531ce1d | 1829 | if is_range_inner { |
416331ca | 1830 | self.pclose(); |
0531ce1d | 1831 | } |
e9174d1e | 1832 | } |
064997fb | 1833 | PatKind::Ref(inner, mutbl) => { |
29967ef6 | 1834 | let is_range_inner = matches!(inner.kind, PatKind::Range(..)); |
a2a8927a XL |
1835 | self.word("&"); |
1836 | self.word(mutbl.prefix_str()); | |
0531ce1d | 1837 | if is_range_inner { |
416331ca | 1838 | self.popen(); |
0531ce1d | 1839 | } |
064997fb | 1840 | self.print_pat(inner); |
0531ce1d | 1841 | if is_range_inner { |
416331ca | 1842 | self.pclose(); |
0531ce1d | 1843 | } |
e9174d1e | 1844 | } |
064997fb FG |
1845 | PatKind::Lit(e) => self.print_expr(e), |
1846 | PatKind::Range(begin, end, end_kind) => { | |
dfeec247 XL |
1847 | if let Some(expr) = begin { |
1848 | self.print_expr(expr); | |
dfeec247 | 1849 | } |
064997fb | 1850 | match end_kind { |
a2a8927a XL |
1851 | RangeEnd::Included => self.word("..."), |
1852 | RangeEnd::Excluded => self.word(".."), | |
32a655c1 | 1853 | } |
dfeec247 XL |
1854 | if let Some(expr) = end { |
1855 | self.print_expr(expr); | |
1856 | } | |
e9174d1e | 1857 | } |
064997fb | 1858 | PatKind::Slice(before, slice, after) => { |
a2a8927a | 1859 | self.word("["); |
064997fb FG |
1860 | self.commasep(Inconsistent, before, |s, p| s.print_pat(p)); |
1861 | if let Some(p) = slice { | |
b039eaaf | 1862 | if !before.is_empty() { |
416331ca | 1863 | self.word_space(","); |
b039eaaf | 1864 | } |
e74abb32 | 1865 | if let PatKind::Wild = p.kind { |
e1599b0c | 1866 | // Print nothing. |
8faf50e0 | 1867 | } else { |
064997fb | 1868 | self.print_pat(p); |
e9174d1e | 1869 | } |
a2a8927a | 1870 | self.word(".."); |
b039eaaf | 1871 | if !after.is_empty() { |
416331ca | 1872 | self.word_space(","); |
b039eaaf | 1873 | } |
e9174d1e | 1874 | } |
064997fb | 1875 | self.commasep(Inconsistent, after, |s, p| s.print_pat(p)); |
a2a8927a | 1876 | self.word("]"); |
e9174d1e SL |
1877 | } |
1878 | } | |
b7449926 | 1879 | self.ann.post(self, AnnNode::Pat(pat)) |
e9174d1e SL |
1880 | } |
1881 | ||
f2b60f7d FG |
1882 | pub fn print_patfield(&mut self, field: &hir::PatField<'_>) { |
1883 | if self.attrs(field.hir_id).is_empty() { | |
1884 | self.space(); | |
1885 | } | |
1886 | self.cbox(INDENT_UNIT); | |
1887 | self.print_outer_attributes(&self.attrs(field.hir_id)); | |
1888 | if !field.is_shorthand { | |
1889 | self.print_ident(field.ident); | |
1890 | self.word_nbsp(":"); | |
1891 | } | |
1892 | self.print_pat(field.pat); | |
1893 | self.end(); | |
1894 | } | |
1895 | ||
dfeec247 | 1896 | pub fn print_param(&mut self, arg: &hir::Param<'_>) { |
6a06907d | 1897 | self.print_outer_attributes(self.attrs(arg.hir_id)); |
064997fb | 1898 | self.print_pat(arg.pat); |
416331ca XL |
1899 | } |
1900 | ||
dfeec247 | 1901 | pub fn print_arm(&mut self, arm: &hir::Arm<'_>) { |
e9174d1e SL |
1902 | // I have no idea why this check is necessary, but here it |
1903 | // is :( | |
6a06907d | 1904 | if self.attrs(arm.hir_id).is_empty() { |
a2a8927a | 1905 | self.space(); |
e9174d1e | 1906 | } |
416331ca XL |
1907 | self.cbox(INDENT_UNIT); |
1908 | self.ann.pre(self, AnnNode::Arm(arm)); | |
1909 | self.ibox(0); | |
064997fb FG |
1910 | self.print_outer_attributes(self.attrs(arm.hir_id)); |
1911 | self.print_pat(arm.pat); | |
a2a8927a | 1912 | self.space(); |
b7449926 | 1913 | if let Some(ref g) = arm.guard { |
064997fb | 1914 | match *g { |
b7449926 | 1915 | hir::Guard::If(e) => { |
416331ca | 1916 | self.word_space("if"); |
064997fb | 1917 | self.print_expr(e); |
a2a8927a | 1918 | self.space(); |
b7449926 | 1919 | } |
064997fb | 1920 | hir::Guard::IfLet(&hir::Let { pat, ty, init, .. }) => { |
fc512014 | 1921 | self.word_nbsp("if"); |
064997fb | 1922 | self.print_let(pat, ty, init); |
fc512014 | 1923 | } |
b7449926 | 1924 | } |
e9174d1e | 1925 | } |
416331ca | 1926 | self.word_space("=>"); |
e9174d1e | 1927 | |
e74abb32 | 1928 | match arm.body.kind { |
064997fb | 1929 | hir::ExprKind::Block(blk, opt_label) => { |
94b46f34 | 1930 | if let Some(label) = opt_label { |
416331ca XL |
1931 | self.print_ident(label.ident); |
1932 | self.word_space(":"); | |
94b46f34 | 1933 | } |
e9174d1e | 1934 | // the block will close the pattern's ibox |
064997fb | 1935 | self.print_block_unclosed(blk); |
e9174d1e SL |
1936 | |
1937 | // If it is a user-provided unsafe block, print a comma after it | |
ba9703b0 XL |
1938 | if let hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::UserProvided) = blk.rules |
1939 | { | |
a2a8927a | 1940 | self.word(","); |
e9174d1e SL |
1941 | } |
1942 | } | |
1943 | _ => { | |
416331ca | 1944 | self.end(); // close the ibox for the pattern |
064997fb | 1945 | self.print_expr(arm.body); |
a2a8927a | 1946 | self.word(","); |
e9174d1e SL |
1947 | } |
1948 | } | |
416331ca | 1949 | self.ann.post(self, AnnNode::Arm(arm)); |
e9174d1e SL |
1950 | self.end() // close enclosing cbox |
1951 | } | |
1952 | ||
dfeec247 XL |
1953 | pub fn print_fn( |
1954 | &mut self, | |
1955 | decl: &hir::FnDecl<'_>, | |
1956 | header: hir::FnHeader, | |
f9f354fc | 1957 | name: Option<Symbol>, |
dfeec247 | 1958 | generics: &hir::Generics<'_>, |
f9f354fc | 1959 | arg_names: &[Ident], |
dfeec247 XL |
1960 | body_id: Option<hir::BodyId>, |
1961 | ) { | |
04454e1e | 1962 | self.print_fn_header_info(header); |
e9174d1e SL |
1963 | |
1964 | if let Some(name) = name { | |
416331ca XL |
1965 | self.nbsp(); |
1966 | self.print_name(name); | |
e9174d1e | 1967 | } |
064997fb | 1968 | self.print_generic_params(generics.params); |
e9174d1e | 1969 | |
416331ca | 1970 | self.popen(); |
32a655c1 SL |
1971 | let mut i = 0; |
1972 | // Make sure we aren't supplied *both* `arg_names` and `body_id`. | |
1973 | assert!(arg_names.is_empty() || body_id.is_none()); | |
064997fb | 1974 | self.commasep(Inconsistent, decl.inputs, |s, ty| { |
416331ca | 1975 | s.ibox(INDENT_UNIT); |
8faf50e0 | 1976 | if let Some(arg_name) = arg_names.get(i) { |
a2a8927a XL |
1977 | s.word(arg_name.to_string()); |
1978 | s.word(":"); | |
1979 | s.space(); | |
32a655c1 | 1980 | } else if let Some(body_id) = body_id { |
e1599b0c | 1981 | s.ann.nested(s, Nested::BodyParamPat(body_id, i)); |
a2a8927a XL |
1982 | s.word(":"); |
1983 | s.space(); | |
32a655c1 SL |
1984 | } |
1985 | i += 1; | |
416331ca | 1986 | s.print_type(ty); |
32a655c1 | 1987 | s.end() |
416331ca | 1988 | }); |
532ac7d7 | 1989 | if decl.c_variadic { |
a2a8927a | 1990 | self.word(", ..."); |
e9174d1e | 1991 | } |
416331ca | 1992 | self.pclose(); |
e9174d1e | 1993 | |
416331ca | 1994 | self.print_fn_output(decl); |
04454e1e | 1995 | self.print_where_clause(generics) |
e9174d1e SL |
1996 | } |
1997 | ||
dfeec247 | 1998 | fn print_closure_params(&mut self, decl: &hir::FnDecl<'_>, body_id: hir::BodyId) { |
a2a8927a | 1999 | self.word("|"); |
32a655c1 | 2000 | let mut i = 0; |
064997fb | 2001 | self.commasep(Inconsistent, decl.inputs, |s, ty| { |
416331ca | 2002 | s.ibox(INDENT_UNIT); |
32a655c1 | 2003 | |
e1599b0c | 2004 | s.ann.nested(s, Nested::BodyParamPat(body_id, i)); |
32a655c1 SL |
2005 | i += 1; |
2006 | ||
e74abb32 | 2007 | if let hir::TyKind::Infer = ty.kind { |
e1599b0c | 2008 | // Print nothing. |
8faf50e0 | 2009 | } else { |
a2a8927a XL |
2010 | s.word(":"); |
2011 | s.space(); | |
416331ca | 2012 | s.print_type(ty); |
32a655c1 | 2013 | } |
416331ca XL |
2014 | s.end(); |
2015 | }); | |
a2a8927a | 2016 | self.word("|"); |
e9174d1e | 2017 | |
ba9703b0 | 2018 | if let hir::FnRetTy::DefaultReturn(..) = decl.output { |
416331ca | 2019 | return; |
e9174d1e SL |
2020 | } |
2021 | ||
416331ca XL |
2022 | self.space_if_not_bol(); |
2023 | self.word_space("->"); | |
e9174d1e | 2024 | match decl.output { |
064997fb FG |
2025 | hir::FnRetTy::Return(ty) => { |
2026 | self.print_type(ty); | |
a2a8927a | 2027 | self.maybe_print_comment(ty.span.lo()); |
e9174d1e | 2028 | } |
ba9703b0 | 2029 | hir::FnRetTy::DefaultReturn(..) => unreachable!(), |
e9174d1e SL |
2030 | } |
2031 | } | |
2032 | ||
60c5eb7d | 2033 | pub fn print_capture_clause(&mut self, capture_clause: hir::CaptureBy) { |
e9174d1e | 2034 | match capture_clause { |
60c5eb7d | 2035 | hir::CaptureBy::Value => self.word_space("move"), |
dfeec247 | 2036 | hir::CaptureBy::Ref => {} |
e9174d1e SL |
2037 | } |
2038 | } | |
2039 | ||
064997fb FG |
2040 | pub fn print_closure_binder( |
2041 | &mut self, | |
2042 | binder: hir::ClosureBinder, | |
2043 | generic_params: &[GenericParam<'_>], | |
2044 | ) { | |
2045 | let generic_params = generic_params | |
2046 | .iter() | |
2047 | .filter(|p| { | |
2048 | matches!( | |
2049 | p, | |
2050 | GenericParam { | |
2051 | kind: GenericParamKind::Lifetime { kind: LifetimeParamKind::Explicit }, | |
2052 | .. | |
2053 | } | |
2054 | ) | |
2055 | }) | |
2056 | .collect::<Vec<_>>(); | |
2057 | ||
2058 | match binder { | |
2059 | hir::ClosureBinder::Default => {} | |
2060 | // we need to distinguish `|...| {}` from `for<> |...| {}` as `for<>` adds additional restrictions | |
2061 | hir::ClosureBinder::For { .. } if generic_params.is_empty() => self.word("for<>"), | |
2062 | hir::ClosureBinder::For { .. } => { | |
2063 | self.word("for"); | |
2064 | self.word("<"); | |
2065 | ||
2066 | self.commasep(Inconsistent, &generic_params, |s, param| { | |
2067 | s.print_generic_param(param) | |
2068 | }); | |
2069 | ||
2070 | self.word(">"); | |
2071 | self.nbsp(); | |
2072 | } | |
2073 | } | |
2074 | } | |
2075 | ||
dc9dc135 XL |
2076 | pub fn print_bounds<'b>( |
2077 | &mut self, | |
2078 | prefix: &'static str, | |
dfeec247 | 2079 | bounds: impl IntoIterator<Item = &'b hir::GenericBound<'b>>, |
416331ca | 2080 | ) { |
dc9dc135 XL |
2081 | let mut first = true; |
2082 | for bound in bounds { | |
2083 | if first { | |
a2a8927a | 2084 | self.word(prefix); |
dc9dc135 XL |
2085 | } |
2086 | if !(first && prefix.is_empty()) { | |
416331ca | 2087 | self.nbsp(); |
dc9dc135 XL |
2088 | } |
2089 | if first { | |
2090 | first = false; | |
2091 | } else { | |
416331ca | 2092 | self.word_space("+"); |
dc9dc135 | 2093 | } |
e9174d1e | 2094 | |
dc9dc135 XL |
2095 | match bound { |
2096 | GenericBound::Trait(tref, modifier) => { | |
2097 | if modifier == &TraitBoundModifier::Maybe { | |
a2a8927a | 2098 | self.word("?"); |
e9174d1e | 2099 | } |
416331ca | 2100 | self.print_poly_trait_ref(tref); |
dc9dc135 | 2101 | } |
3dfed10e | 2102 | GenericBound::LangItemTrait(lang_item, span, ..) => { |
a2a8927a | 2103 | self.word("#[lang = \""); |
3dfed10e | 2104 | self.print_ident(Ident::new(lang_item.name(), *span)); |
a2a8927a | 2105 | self.word("\"]"); |
3dfed10e | 2106 | } |
dc9dc135 | 2107 | GenericBound::Outlives(lt) => { |
416331ca | 2108 | self.print_lifetime(lt); |
ff7c6d11 | 2109 | } |
e9174d1e | 2110 | } |
e9174d1e SL |
2111 | } |
2112 | } | |
2113 | ||
dfeec247 | 2114 | pub fn print_generic_params(&mut self, generic_params: &[GenericParam<'_>]) { |
ff7c6d11 | 2115 | if !generic_params.is_empty() { |
a2a8927a | 2116 | self.word("<"); |
e9174d1e | 2117 | |
dfeec247 | 2118 | self.commasep(Inconsistent, generic_params, |s, param| s.print_generic_param(param)); |
e9174d1e | 2119 | |
a2a8927a | 2120 | self.word(">"); |
e9174d1e | 2121 | } |
e9174d1e SL |
2122 | } |
2123 | ||
dfeec247 | 2124 | pub fn print_generic_param(&mut self, param: &GenericParam<'_>) { |
9fa01778 | 2125 | if let GenericParamKind::Const { .. } = param.kind { |
416331ca | 2126 | self.word_space("const"); |
9fa01778 XL |
2127 | } |
2128 | ||
416331ca | 2129 | self.print_ident(param.name.ident()); |
9fa01778 | 2130 | |
8faf50e0 | 2131 | match param.kind { |
04454e1e | 2132 | GenericParamKind::Lifetime { .. } => {} |
064997fb | 2133 | GenericParamKind::Type { default, .. } => { |
ba9703b0 | 2134 | if let Some(default) = default { |
a2a8927a | 2135 | self.space(); |
ba9703b0 | 2136 | self.word_space("="); |
064997fb | 2137 | self.print_type(default); |
8faf50e0 | 2138 | } |
e9174d1e | 2139 | } |
064997fb | 2140 | GenericParamKind::Const { ty, ref default } => { |
416331ca | 2141 | self.word_space(":"); |
5869c6ff | 2142 | self.print_type(ty); |
064997fb | 2143 | if let Some(default) = default { |
a2a8927a | 2144 | self.space(); |
cdc7bbd5 | 2145 | self.word_space("="); |
064997fb | 2146 | self.print_anon_const(default); |
5869c6ff | 2147 | } |
9fa01778 | 2148 | } |
e9174d1e SL |
2149 | } |
2150 | } | |
2151 | ||
416331ca | 2152 | pub fn print_lifetime(&mut self, lifetime: &hir::Lifetime) { |
487cf647 | 2153 | self.print_ident(lifetime.ident) |
8faf50e0 XL |
2154 | } |
2155 | ||
04454e1e FG |
2156 | pub fn print_where_clause(&mut self, generics: &hir::Generics<'_>) { |
2157 | if generics.predicates.is_empty() { | |
416331ca | 2158 | return; |
e9174d1e SL |
2159 | } |
2160 | ||
a2a8927a | 2161 | self.space(); |
416331ca | 2162 | self.word_space("where"); |
e9174d1e | 2163 | |
04454e1e | 2164 | for (i, predicate) in generics.predicates.iter().enumerate() { |
e9174d1e | 2165 | if i != 0 { |
416331ca | 2166 | self.word_space(","); |
e9174d1e SL |
2167 | } |
2168 | ||
064997fb | 2169 | match *predicate { |
5869c6ff XL |
2170 | hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { |
2171 | bound_generic_params, | |
2172 | bounded_ty, | |
dfeec247 | 2173 | bounds, |
ff7c6d11 XL |
2174 | .. |
2175 | }) => { | |
416331ca | 2176 | self.print_formal_generic_params(bound_generic_params); |
064997fb FG |
2177 | self.print_type(bounded_ty); |
2178 | self.print_bounds(":", bounds); | |
e9174d1e | 2179 | } |
5869c6ff | 2180 | hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { |
064997fb | 2181 | ref lifetime, |
5869c6ff | 2182 | bounds, |
dfeec247 XL |
2183 | .. |
2184 | }) => { | |
416331ca | 2185 | self.print_lifetime(lifetime); |
a2a8927a | 2186 | self.word(":"); |
e9174d1e SL |
2187 | |
2188 | for (i, bound) in bounds.iter().enumerate() { | |
8faf50e0 XL |
2189 | match bound { |
2190 | GenericBound::Outlives(lt) => { | |
416331ca | 2191 | self.print_lifetime(lt); |
8faf50e0 | 2192 | } |
dfeec247 | 2193 | _ => panic!(), |
8faf50e0 | 2194 | } |
e9174d1e SL |
2195 | |
2196 | if i != 0 { | |
a2a8927a | 2197 | self.word(":"); |
e9174d1e SL |
2198 | } |
2199 | } | |
2200 | } | |
5869c6ff XL |
2201 | hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { |
2202 | lhs_ty, rhs_ty, .. | |
dfeec247 | 2203 | }) => { |
416331ca | 2204 | self.print_type(lhs_ty); |
a2a8927a | 2205 | self.space(); |
416331ca XL |
2206 | self.word_space("="); |
2207 | self.print_type(rhs_ty); | |
e9174d1e SL |
2208 | } |
2209 | } | |
2210 | } | |
e9174d1e SL |
2211 | } |
2212 | ||
60c5eb7d | 2213 | pub fn print_mutability(&mut self, mutbl: hir::Mutability, print_const: bool) { |
e9174d1e | 2214 | match mutbl { |
dfeec247 XL |
2215 | hir::Mutability::Mut => self.word_nbsp("mut"), |
2216 | hir::Mutability::Not => { | |
2217 | if print_const { | |
2218 | self.word_nbsp("const") | |
2219 | } | |
2220 | } | |
e9174d1e SL |
2221 | } |
2222 | } | |
2223 | ||
dfeec247 | 2224 | pub fn print_mt(&mut self, mt: &hir::MutTy<'_>, print_const: bool) { |
60c5eb7d | 2225 | self.print_mutability(mt.mutbl, print_const); |
064997fb | 2226 | self.print_type(mt.ty); |
e9174d1e SL |
2227 | } |
2228 | ||
dfeec247 | 2229 | pub fn print_fn_output(&mut self, decl: &hir::FnDecl<'_>) { |
ba9703b0 | 2230 | if let hir::FnRetTy::DefaultReturn(..) = decl.output { |
416331ca | 2231 | return; |
e9174d1e SL |
2232 | } |
2233 | ||
416331ca XL |
2234 | self.space_if_not_bol(); |
2235 | self.ibox(INDENT_UNIT); | |
2236 | self.word_space("->"); | |
e9174d1e | 2237 | match decl.output { |
ba9703b0 | 2238 | hir::FnRetTy::DefaultReturn(..) => unreachable!(), |
064997fb | 2239 | hir::FnRetTy::Return(ty) => self.print_type(ty), |
e9174d1e | 2240 | } |
416331ca | 2241 | self.end(); |
e9174d1e | 2242 | |
064997fb | 2243 | if let hir::FnRetTy::Return(output) = decl.output { |
a2a8927a | 2244 | self.maybe_print_comment(output.span.lo()); |
e9174d1e SL |
2245 | } |
2246 | } | |
2247 | ||
dfeec247 XL |
2248 | pub fn print_ty_fn( |
2249 | &mut self, | |
2250 | abi: Abi, | |
2251 | unsafety: hir::Unsafety, | |
2252 | decl: &hir::FnDecl<'_>, | |
f9f354fc | 2253 | name: Option<Symbol>, |
dfeec247 | 2254 | generic_params: &[hir::GenericParam<'_>], |
f9f354fc | 2255 | arg_names: &[Ident], |
dfeec247 | 2256 | ) { |
416331ca | 2257 | self.ibox(INDENT_UNIT); |
a2a8927a | 2258 | self.print_formal_generic_params(generic_params); |
04454e1e | 2259 | let generics = hir::Generics::empty(); |
dfeec247 XL |
2260 | self.print_fn( |
2261 | decl, | |
2262 | hir::FnHeader { | |
2263 | unsafety, | |
2264 | abi, | |
2265 | constness: hir::Constness::NotConst, | |
2266 | asyncness: hir::IsAsync::NotAsync, | |
2267 | }, | |
2268 | name, | |
064997fb | 2269 | generics, |
dfeec247 XL |
2270 | arg_names, |
2271 | None, | |
2272 | ); | |
416331ca | 2273 | self.end(); |
e9174d1e SL |
2274 | } |
2275 | ||
04454e1e | 2276 | pub fn print_fn_header_info(&mut self, header: hir::FnHeader) { |
9c376795 | 2277 | self.print_constness(header.constness); |
e9174d1e | 2278 | |
8faf50e0 XL |
2279 | match header.asyncness { |
2280 | hir::IsAsync::NotAsync => {} | |
416331ca | 2281 | hir::IsAsync::Async => self.word_nbsp("async"), |
8faf50e0 XL |
2282 | } |
2283 | ||
416331ca | 2284 | self.print_unsafety(header.unsafety); |
8faf50e0 XL |
2285 | |
2286 | if header.abi != Abi::Rust { | |
416331ca XL |
2287 | self.word_nbsp("extern"); |
2288 | self.word_nbsp(header.abi.to_string()); | |
e9174d1e SL |
2289 | } |
2290 | ||
a2a8927a | 2291 | self.word("fn") |
e9174d1e SL |
2292 | } |
2293 | ||
9c376795 FG |
2294 | pub fn print_constness(&mut self, s: hir::Constness) { |
2295 | match s { | |
2296 | hir::Constness::NotConst => {} | |
2297 | hir::Constness::Const => self.word_nbsp("const"), | |
2298 | } | |
2299 | } | |
2300 | ||
416331ca | 2301 | pub fn print_unsafety(&mut self, s: hir::Unsafety) { |
e9174d1e | 2302 | match s { |
416331ca | 2303 | hir::Unsafety::Normal => {} |
e9174d1e SL |
2304 | hir::Unsafety::Unsafe => self.word_nbsp("unsafe"), |
2305 | } | |
2306 | } | |
abe05a73 | 2307 | |
416331ca | 2308 | pub fn print_is_auto(&mut self, s: hir::IsAuto) { |
abe05a73 XL |
2309 | match s { |
2310 | hir::IsAuto::Yes => self.word_nbsp("auto"), | |
dfeec247 | 2311 | hir::IsAuto::No => {} |
abe05a73 XL |
2312 | } |
2313 | } | |
e9174d1e SL |
2314 | } |
2315 | ||
e9174d1e SL |
2316 | /// Does this expression require a semicolon to be treated |
2317 | /// as a statement? The negation of this: 'can this expression | |
2318 | /// be used as a statement without a semicolon' -- is used | |
2319 | /// as an early-bail-out in the parser so that, for instance, | |
2320 | /// if true {...} else {...} | |
2321 | /// |x| 5 | |
2322 | /// isn't parsed as (if true {...} else {...} | x) | 5 | |
e1599b0c XL |
2323 | // |
2324 | // Duplicated from `parse::classify`, but adapted for the HIR. | |
dfeec247 | 2325 | fn expr_requires_semi_to_be_stmt(e: &hir::Expr<'_>) -> bool { |
5869c6ff XL |
2326 | !matches!( |
2327 | e.kind, | |
2328 | hir::ExprKind::If(..) | |
2329 | | hir::ExprKind::Match(..) | |
2330 | | hir::ExprKind::Block(..) | |
2331 | | hir::ExprKind::Loop(..) | |
2332 | ) | |
e9174d1e SL |
2333 | } |
2334 | ||
e1599b0c | 2335 | /// This statement requires a semicolon after it. |
e9174d1e SL |
2336 | /// note that in one case (stmt_semi), we've already |
2337 | /// seen the semicolon, and thus don't need another. | |
dfeec247 | 2338 | fn stmt_ends_with_semi(stmt: &hir::StmtKind<'_>) -> bool { |
e9174d1e | 2339 | match *stmt { |
9fa01778 XL |
2340 | hir::StmtKind::Local(_) => true, |
2341 | hir::StmtKind::Item(_) => false, | |
064997fb | 2342 | hir::StmtKind::Expr(e) => expr_requires_semi_to_be_stmt(e), |
9fa01778 | 2343 | hir::StmtKind::Semi(..) => false, |
e9174d1e SL |
2344 | } |
2345 | } | |
ea8adc8c | 2346 | |
8faf50e0 | 2347 | fn bin_op_to_assoc_op(op: hir::BinOpKind) -> AssocOp { |
9fa01778 | 2348 | use crate::hir::BinOpKind::*; |
ea8adc8c | 2349 | match op { |
8faf50e0 XL |
2350 | Add => AssocOp::Add, |
2351 | Sub => AssocOp::Subtract, | |
2352 | Mul => AssocOp::Multiply, | |
2353 | Div => AssocOp::Divide, | |
2354 | Rem => AssocOp::Modulus, | |
2355 | ||
2356 | And => AssocOp::LAnd, | |
2357 | Or => AssocOp::LOr, | |
2358 | ||
2359 | BitXor => AssocOp::BitXor, | |
2360 | BitAnd => AssocOp::BitAnd, | |
2361 | BitOr => AssocOp::BitOr, | |
2362 | Shl => AssocOp::ShiftLeft, | |
2363 | Shr => AssocOp::ShiftRight, | |
2364 | ||
2365 | Eq => AssocOp::Equal, | |
2366 | Lt => AssocOp::Less, | |
2367 | Le => AssocOp::LessEqual, | |
2368 | Ne => AssocOp::NotEqual, | |
2369 | Ge => AssocOp::GreaterEqual, | |
2370 | Gt => AssocOp::Greater, | |
ea8adc8c XL |
2371 | } |
2372 | } | |
2373 | ||
e1599b0c | 2374 | /// Expressions that syntactically contain an "exterior" struct literal, i.e., not surrounded by any |
0731742a | 2375 | /// parens or other delimiters, e.g., `X { y: 1 }`, `X { y: 1 }.method()`, `foo == X { y: 1 }` and |
ea8adc8c | 2376 | /// `X { y: 1 } == foo` all do, but `(X { y: 1 }) == foo` does not. |
dfeec247 | 2377 | fn contains_exterior_struct_lit(value: &hir::Expr<'_>) -> bool { |
e74abb32 | 2378 | match value.kind { |
8faf50e0 | 2379 | hir::ExprKind::Struct(..) => true, |
ea8adc8c | 2380 | |
064997fb FG |
2381 | hir::ExprKind::Assign(lhs, rhs, _) |
2382 | | hir::ExprKind::AssignOp(_, lhs, rhs) | |
2383 | | hir::ExprKind::Binary(_, lhs, rhs) => { | |
e1599b0c | 2384 | // `X { y: 1 } + X { y: 2 }` |
064997fb | 2385 | contains_exterior_struct_lit(lhs) || contains_exterior_struct_lit(rhs) |
ea8adc8c | 2386 | } |
064997fb FG |
2387 | hir::ExprKind::Unary(_, x) |
2388 | | hir::ExprKind::Cast(x, _) | |
2389 | | hir::ExprKind::Type(x, _) | |
2390 | | hir::ExprKind::Field(x, _) | |
2391 | | hir::ExprKind::Index(x, _) => { | |
e1599b0c | 2392 | // `&X { y: 1 }, X { y: 1 }.y` |
064997fb | 2393 | contains_exterior_struct_lit(x) |
ea8adc8c XL |
2394 | } |
2395 | ||
f2b60f7d | 2396 | hir::ExprKind::MethodCall(_, receiver, ..) => { |
e1599b0c | 2397 | // `X { y: 1 }.bar(...)` |
f2b60f7d | 2398 | contains_exterior_struct_lit(receiver) |
ea8adc8c XL |
2399 | } |
2400 | ||
2401 | _ => false, | |
2402 | } | |
2403 | } |