]>
Commit | Line | Data |
---|---|---|
74b04a01 XL |
1 | use crate::pp::Breaks::{Consistent, Inconsistent}; |
2 | use crate::pp::{self, Breaks}; | |
3 | ||
4 | use rustc_ast::ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax}; | |
5 | use rustc_ast::ast::{Attribute, GenericArg, MacArgs}; | |
6 | use rustc_ast::ast::{GenericBound, SelfKind, TraitBoundModifier}; | |
f9f354fc XL |
7 | use rustc_ast::ast::{InlineAsmOperand, InlineAsmRegOrRegClass}; |
8 | use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece}; | |
74b04a01 XL |
9 | use rustc_ast::attr; |
10 | use rustc_ast::ptr::P; | |
11 | use rustc_ast::token::{self, BinOpToken, DelimToken, Nonterminal, Token, TokenKind}; | |
f035d41b | 12 | use rustc_ast::tokenstream::{TokenStream, TokenTree}; |
74b04a01 XL |
13 | use rustc_ast::util::parser::{self, AssocOp, Fixity}; |
14 | use rustc_ast::util::{classify, comments}; | |
15 | use rustc_span::edition::Edition; | |
16 | use rustc_span::source_map::{SourceMap, Spanned}; | |
f9f354fc | 17 | use rustc_span::symbol::{kw, sym, Ident, IdentPrinter, Symbol}; |
dfeec247 | 18 | use rustc_span::{BytePos, FileName, Span}; |
1a4d82fc | 19 | |
a1dfa0c6 | 20 | use std::borrow::Cow; |
416331ca XL |
21 | |
22 | #[cfg(test)] | |
23 | mod tests; | |
24 | ||
25 | pub enum MacHeader<'a> { | |
26 | Path(&'a ast::Path), | |
27 | Keyword(&'static str), | |
28 | } | |
1a4d82fc JJ |
29 | |
30 | pub enum AnnNode<'a> { | |
f9f354fc XL |
31 | Ident(&'a Ident), |
32 | Name(&'a Symbol), | |
b7449926 XL |
33 | Block(&'a ast::Block), |
34 | Item(&'a ast::Item), | |
35 | SubItem(ast::NodeId), | |
36 | Expr(&'a ast::Expr), | |
37 | Pat(&'a ast::Pat), | |
e1599b0c | 38 | Crate(&'a ast::Crate), |
223e47cc LB |
39 | } |
40 | ||
1a4d82fc | 41 | pub trait PpAnn { |
dfeec247 XL |
42 | fn pre(&self, _state: &mut State<'_>, _node: AnnNode<'_>) {} |
43 | fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) {} | |
223e47cc LB |
44 | } |
45 | ||
c34b1796 | 46 | #[derive(Copy, Clone)] |
1a4d82fc JJ |
47 | pub struct NoAnn; |
48 | ||
49 | impl PpAnn for NoAnn {} | |
50 | ||
416331ca | 51 | pub struct Comments<'a> { |
74b04a01 | 52 | sm: &'a SourceMap, |
416331ca XL |
53 | comments: Vec<comments::Comment>, |
54 | current: usize, | |
223e47cc LB |
55 | } |
56 | ||
416331ca | 57 | impl<'a> Comments<'a> { |
74b04a01 XL |
58 | pub fn new(sm: &'a SourceMap, filename: FileName, input: String) -> Comments<'a> { |
59 | let comments = comments::gather_comments(sm, filename, input); | |
60 | Comments { sm, comments, current: 0 } | |
416331ca XL |
61 | } |
62 | ||
63 | pub fn next(&self) -> Option<comments::Comment> { | |
64 | self.comments.get(self.current).cloned() | |
65 | } | |
66 | ||
67 | pub fn trailing_comment( | |
68 | &mut self, | |
dfeec247 | 69 | span: rustc_span::Span, |
416331ca XL |
70 | next_pos: Option<BytePos>, |
71 | ) -> Option<comments::Comment> { | |
72 | if let Some(cmnt) = self.next() { | |
dfeec247 XL |
73 | if cmnt.style != comments::Trailing { |
74 | return None; | |
75 | } | |
74b04a01 XL |
76 | let span_line = self.sm.lookup_char_pos(span.hi()); |
77 | let comment_line = self.sm.lookup_char_pos(cmnt.pos); | |
416331ca XL |
78 | let next = next_pos.unwrap_or_else(|| cmnt.pos + BytePos(1)); |
79 | if span.hi() < cmnt.pos && cmnt.pos < next && span_line.line == comment_line.line { | |
80 | return Some(cmnt); | |
81 | } | |
82 | } | |
83 | ||
84 | None | |
1a4d82fc JJ |
85 | } |
86 | } | |
87 | ||
416331ca XL |
88 | pub struct State<'a> { |
89 | pub s: pp::Printer, | |
90 | comments: Option<Comments<'a>>, | |
dfeec247 XL |
91 | ann: &'a (dyn PpAnn + 'a), |
92 | is_expanded: bool, | |
416331ca | 93 | } |
1a4d82fc | 94 | |
416331ca | 95 | crate const INDENT_UNIT: usize = 4; |
1a4d82fc JJ |
96 | |
97 | /// Requires you to pass an input filename and reader so that | |
48663c56 | 98 | /// it can scan the input text for comments to copy forward. |
dfeec247 | 99 | pub fn print_crate<'a>( |
74b04a01 | 100 | sm: &'a SourceMap, |
dfeec247 XL |
101 | krate: &ast::Crate, |
102 | filename: FileName, | |
103 | input: String, | |
104 | ann: &'a dyn PpAnn, | |
105 | is_expanded: bool, | |
74b04a01 XL |
106 | edition: Edition, |
107 | has_injected_crate: bool, | |
dfeec247 | 108 | ) -> String { |
416331ca XL |
109 | let mut s = State { |
110 | s: pp::mk_printer(), | |
74b04a01 | 111 | comments: Some(Comments::new(sm, filename, input)), |
416331ca XL |
112 | ann, |
113 | is_expanded, | |
114 | }; | |
32a655c1 | 115 | |
74b04a01 | 116 | if is_expanded && has_injected_crate { |
85aaf69f SL |
117 | // We need to print `#![no_std]` (and its feature gate) so that |
118 | // compiling pretty-printed source won't inject libstd again. | |
e1599b0c | 119 | // However, we don't want these attributes in the AST because |
85aaf69f SL |
120 | // of the feature gate, so we fake them up here. |
121 | ||
e1599b0c | 122 | // `#![feature(prelude_import)]` |
f9f354fc XL |
123 | let pi_nested = attr::mk_nested_word_item(Ident::with_dummy_span(sym::prelude_import)); |
124 | let list = attr::mk_list_item(Ident::with_dummy_span(sym::feature), vec![pi_nested]); | |
416331ca XL |
125 | let fake_attr = attr::mk_attr_inner(list); |
126 | s.print_attribute(&fake_attr); | |
85aaf69f | 127 | |
e1599b0c XL |
128 | // Currently, in Rust 2018 we don't have `extern crate std;` at the crate |
129 | // root, so this is not needed, and actually breaks things. | |
74b04a01 | 130 | if edition == Edition::Edition2015 { |
e1599b0c | 131 | // `#![no_std]` |
f9f354fc | 132 | let no_std_meta = attr::mk_word_item(Ident::with_dummy_span(sym::no_std)); |
e1599b0c XL |
133 | let fake_attr = attr::mk_attr_inner(no_std_meta); |
134 | s.print_attribute(&fake_attr); | |
135 | } | |
85aaf69f SL |
136 | } |
137 | ||
416331ca XL |
138 | s.print_mod(&krate.module, &krate.attrs); |
139 | s.print_remaining_comments(); | |
e1599b0c | 140 | s.ann.post(&mut s, AnnNode::Crate(krate)); |
041b39d2 | 141 | s.s.eof() |
1a4d82fc JJ |
142 | } |
143 | ||
74b04a01 | 144 | pub fn to_string(f: impl FnOnce(&mut State<'_>)) -> String { |
dfeec247 XL |
145 | let mut printer = |
146 | State { s: pp::mk_printer(), comments: None, ann: &NoAnn, is_expanded: false }; | |
416331ca XL |
147 | f(&mut printer); |
148 | printer.s.eof() | |
149 | } | |
150 | ||
f035d41b XL |
151 | // This makes printed token streams look slightly nicer, |
152 | // and also addresses some specific regressions described in #63896 and #73345. | |
ba9703b0 | 153 | fn tt_prepend_space(tt: &TokenTree, prev: &TokenTree) -> bool { |
f035d41b XL |
154 | if let TokenTree::Token(token) = prev { |
155 | if let token::DocComment(s) = token.kind { | |
156 | return !s.as_str().starts_with("//"); | |
157 | } | |
158 | } | |
416331ca XL |
159 | match tt { |
160 | TokenTree::Token(token) => match token.kind { | |
161 | token::Comma => false, | |
162 | _ => true, | |
dfeec247 | 163 | }, |
ba9703b0 XL |
164 | TokenTree::Delimited(_, DelimToken::Paren, _) => match prev { |
165 | TokenTree::Token(token) => match token.kind { | |
166 | token::Ident(_, _) => false, | |
167 | _ => true, | |
168 | }, | |
169 | _ => true, | |
170 | }, | |
f035d41b XL |
171 | TokenTree::Delimited(_, DelimToken::Bracket, _) => match prev { |
172 | TokenTree::Token(token) => match token.kind { | |
173 | token::Pound => false, | |
174 | _ => true, | |
175 | }, | |
176 | _ => true, | |
177 | }, | |
178 | TokenTree::Delimited(..) => true, | |
d9579d0f | 179 | } |
1a4d82fc JJ |
180 | } |
181 | ||
041b39d2 | 182 | fn binop_to_string(op: BinOpToken) -> &'static str { |
1a4d82fc | 183 | match op { |
dfeec247 XL |
184 | token::Plus => "+", |
185 | token::Minus => "-", | |
186 | token::Star => "*", | |
187 | token::Slash => "/", | |
188 | token::Percent => "%", | |
189 | token::Caret => "^", | |
190 | token::And => "&", | |
191 | token::Or => "|", | |
192 | token::Shl => "<<", | |
193 | token::Shr => ">>", | |
1a4d82fc JJ |
194 | } |
195 | } | |
196 | ||
dc9dc135 XL |
197 | pub fn literal_to_string(lit: token::Lit) -> String { |
198 | let token::Lit { kind, symbol, suffix } = lit; | |
199 | let mut out = match kind { | |
dfeec247 XL |
200 | token::Byte => format!("b'{}'", symbol), |
201 | token::Char => format!("'{}'", symbol), | |
202 | token::Str => format!("\"{}\"", symbol), | |
203 | token::StrRaw(n) => { | |
204 | format!("r{delim}\"{string}\"{delim}", delim = "#".repeat(n as usize), string = symbol) | |
205 | } | |
206 | token::ByteStr => format!("b\"{}\"", symbol), | |
207 | token::ByteStrRaw(n) => { | |
208 | format!("br{delim}\"{string}\"{delim}", delim = "#".repeat(n as usize), string = symbol) | |
209 | } | |
210 | token::Integer | token::Float | token::Bool | token::Err => symbol.to_string(), | |
48663c56 XL |
211 | }; |
212 | ||
213 | if let Some(suffix) = suffix { | |
214 | out.push_str(&suffix.as_str()) | |
215 | } | |
216 | ||
217 | out | |
218 | } | |
219 | ||
416331ca | 220 | /// Print the token kind precisely, without converting `$crate` into its respective crate name. |
dc9dc135 | 221 | pub fn token_kind_to_string(tok: &TokenKind) -> String { |
416331ca XL |
222 | token_kind_to_string_ext(tok, None) |
223 | } | |
224 | ||
225 | fn token_kind_to_string_ext(tok: &TokenKind, convert_dollar_crate: Option<Span>) -> String { | |
1a4d82fc | 226 | match *tok { |
dfeec247 XL |
227 | token::Eq => "=".to_string(), |
228 | token::Lt => "<".to_string(), | |
229 | token::Le => "<=".to_string(), | |
230 | token::EqEq => "==".to_string(), | |
231 | token::Ne => "!=".to_string(), | |
232 | token::Ge => ">=".to_string(), | |
233 | token::Gt => ">".to_string(), | |
234 | token::Not => "!".to_string(), | |
235 | token::Tilde => "~".to_string(), | |
236 | token::OrOr => "||".to_string(), | |
237 | token::AndAnd => "&&".to_string(), | |
238 | token::BinOp(op) => binop_to_string(op).to_string(), | |
239 | token::BinOpEq(op) => format!("{}=", binop_to_string(op)), | |
1a4d82fc JJ |
240 | |
241 | /* Structural symbols */ | |
dfeec247 XL |
242 | token::At => "@".to_string(), |
243 | token::Dot => ".".to_string(), | |
244 | token::DotDot => "..".to_string(), | |
245 | token::DotDotDot => "...".to_string(), | |
246 | token::DotDotEq => "..=".to_string(), | |
247 | token::Comma => ",".to_string(), | |
248 | token::Semi => ";".to_string(), | |
249 | token::Colon => ":".to_string(), | |
250 | token::ModSep => "::".to_string(), | |
251 | token::RArrow => "->".to_string(), | |
252 | token::LArrow => "<-".to_string(), | |
253 | token::FatArrow => "=>".to_string(), | |
1a4d82fc JJ |
254 | token::OpenDelim(token::Paren) => "(".to_string(), |
255 | token::CloseDelim(token::Paren) => ")".to_string(), | |
256 | token::OpenDelim(token::Bracket) => "[".to_string(), | |
257 | token::CloseDelim(token::Bracket) => "]".to_string(), | |
258 | token::OpenDelim(token::Brace) => "{".to_string(), | |
259 | token::CloseDelim(token::Brace) => "}".to_string(), | |
f035d41b | 260 | token::OpenDelim(token::NoDelim) | token::CloseDelim(token::NoDelim) => "".to_string(), |
dfeec247 XL |
261 | token::Pound => "#".to_string(), |
262 | token::Dollar => "$".to_string(), | |
263 | token::Question => "?".to_string(), | |
264 | token::SingleQuote => "'".to_string(), | |
1a4d82fc JJ |
265 | |
266 | /* Literals */ | |
dc9dc135 | 267 | token::Literal(lit) => literal_to_string(lit), |
223e47cc | 268 | |
1a4d82fc | 269 | /* Name components */ |
74b04a01 | 270 | token::Ident(s, is_raw) => IdentPrinter::new(s, is_raw, convert_dollar_crate).to_string(), |
dfeec247 | 271 | token::Lifetime(s) => s.to_string(), |
223e47cc | 272 | |
1a4d82fc | 273 | /* Other */ |
dfeec247 XL |
274 | token::DocComment(s) => s.to_string(), |
275 | token::Eof => "<eof>".to_string(), | |
276 | token::Whitespace => " ".to_string(), | |
277 | token::Comment => "/* */".to_string(), | |
278 | token::Shebang(s) => format!("/* shebang: {}*/", s), | |
279 | token::Unknown(s) => s.to_string(), | |
223e47cc | 280 | |
9fa01778 XL |
281 | token::Interpolated(ref nt) => nonterminal_to_string(nt), |
282 | } | |
283 | } | |
284 | ||
416331ca | 285 | /// Print the token precisely, without converting `$crate` into its respective crate name. |
dc9dc135 | 286 | pub fn token_to_string(token: &Token) -> String { |
416331ca XL |
287 | token_to_string_ext(token, false) |
288 | } | |
289 | ||
290 | fn token_to_string_ext(token: &Token, convert_dollar_crate: bool) -> String { | |
60c5eb7d | 291 | let convert_dollar_crate = convert_dollar_crate.then_some(token.span); |
416331ca | 292 | token_kind_to_string_ext(&token.kind, convert_dollar_crate) |
dc9dc135 XL |
293 | } |
294 | ||
60c5eb7d | 295 | pub fn nonterminal_to_string(nt: &Nonterminal) -> String { |
9fa01778 | 296 | match *nt { |
dfeec247 XL |
297 | token::NtExpr(ref e) => expr_to_string(e), |
298 | token::NtMeta(ref e) => attr_item_to_string(e), | |
299 | token::NtTy(ref e) => ty_to_string(e), | |
300 | token::NtPath(ref e) => path_to_string(e), | |
301 | token::NtItem(ref e) => item_to_string(e), | |
302 | token::NtBlock(ref e) => block_to_string(e), | |
303 | token::NtStmt(ref e) => stmt_to_string(e), | |
304 | token::NtPat(ref e) => pat_to_string(e), | |
74b04a01 | 305 | token::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(e, is_raw).to_string(), |
dfeec247 XL |
306 | token::NtLifetime(e) => e.to_string(), |
307 | token::NtLiteral(ref e) => expr_to_string(e), | |
f035d41b | 308 | token::NtTT(ref tree) => tt_to_string(tree), |
dfeec247 | 309 | token::NtVis(ref e) => vis_to_string(e), |
1a4d82fc | 310 | } |
223e47cc LB |
311 | } |
312 | ||
1a4d82fc | 313 | pub fn ty_to_string(ty: &ast::Ty) -> String { |
d9579d0f | 314 | to_string(|s| s.print_type(ty)) |
223e47cc LB |
315 | } |
316 | ||
8faf50e0 XL |
317 | pub fn bounds_to_string(bounds: &[ast::GenericBound]) -> String { |
318 | to_string(|s| s.print_type_bounds("", bounds)) | |
223e47cc LB |
319 | } |
320 | ||
1a4d82fc | 321 | pub fn pat_to_string(pat: &ast::Pat) -> String { |
d9579d0f | 322 | to_string(|s| s.print_pat(pat)) |
223e47cc LB |
323 | } |
324 | ||
1a4d82fc | 325 | pub fn expr_to_string(e: &ast::Expr) -> String { |
d9579d0f | 326 | to_string(|s| s.print_expr(e)) |
223e47cc LB |
327 | } |
328 | ||
f035d41b | 329 | pub fn tt_to_string(tt: &TokenTree) -> String { |
416331ca | 330 | to_string(|s| s.print_tt(tt, false)) |
223e47cc LB |
331 | } |
332 | ||
f035d41b | 333 | pub fn tts_to_string(tokens: &TokenStream) -> String { |
416331ca | 334 | to_string(|s| s.print_tts(tokens, false)) |
cc61c64b XL |
335 | } |
336 | ||
1a4d82fc | 337 | pub fn stmt_to_string(stmt: &ast::Stmt) -> String { |
d9579d0f | 338 | to_string(|s| s.print_stmt(stmt)) |
223e47cc LB |
339 | } |
340 | ||
1a4d82fc | 341 | pub fn item_to_string(i: &ast::Item) -> String { |
d9579d0f | 342 | to_string(|s| s.print_item(i)) |
223e47cc LB |
343 | } |
344 | ||
ff7c6d11 XL |
345 | pub fn generic_params_to_string(generic_params: &[ast::GenericParam]) -> String { |
346 | to_string(|s| s.print_generic_params(generic_params)) | |
223e47cc LB |
347 | } |
348 | ||
1a4d82fc | 349 | pub fn path_to_string(p: &ast::Path) -> String { |
0531ce1d | 350 | to_string(|s| s.print_path(p, false, 0)) |
223e47cc LB |
351 | } |
352 | ||
041b39d2 XL |
353 | pub fn path_segment_to_string(p: &ast::PathSegment) -> String { |
354 | to_string(|s| s.print_path_segment(p, false)) | |
355 | } | |
356 | ||
cc61c64b XL |
357 | pub fn vis_to_string(v: &ast::Visibility) -> String { |
358 | to_string(|s| s.print_visibility(v)) | |
359 | } | |
360 | ||
416331ca | 361 | fn block_to_string(blk: &ast::Block) -> String { |
d9579d0f | 362 | to_string(|s| { |
e1599b0c | 363 | // Containing cbox, will be closed by `print_block` at `}`. |
416331ca | 364 | s.cbox(INDENT_UNIT); |
e1599b0c | 365 | // Head-ibox, will be closed by `print_block` after `{`. |
416331ca | 366 | s.ibox(0); |
1a4d82fc JJ |
367 | s.print_block(blk) |
368 | }) | |
223e47cc LB |
369 | } |
370 | ||
9e0c209e SL |
371 | pub fn meta_list_item_to_string(li: &ast::NestedMetaItem) -> String { |
372 | to_string(|s| s.print_meta_list_item(li)) | |
373 | } | |
374 | ||
e74abb32 XL |
375 | fn attr_item_to_string(ai: &ast::AttrItem) -> String { |
376 | to_string(|s| s.print_attr_item(ai, ai.path.span)) | |
223e47cc LB |
377 | } |
378 | ||
1a4d82fc | 379 | pub fn attribute_to_string(attr: &ast::Attribute) -> String { |
d9579d0f | 380 | to_string(|s| s.print_attribute(attr)) |
223e47cc LB |
381 | } |
382 | ||
e1599b0c XL |
383 | pub fn param_to_string(arg: &ast::Param) -> String { |
384 | to_string(|s| s.print_param(arg, false)) | |
223e47cc LB |
385 | } |
386 | ||
416331ca | 387 | fn visibility_qualified(vis: &ast::Visibility, s: &str) -> String { |
cc61c64b | 388 | format!("{}{}", to_string(|s| s.print_visibility(vis)), s) |
223e47cc LB |
389 | } |
390 | ||
416331ca XL |
391 | impl std::ops::Deref for State<'_> { |
392 | type Target = pp::Printer; | |
393 | fn deref(&self) -> &Self::Target { | |
394 | &self.s | |
1a4d82fc | 395 | } |
416331ca | 396 | } |
223e47cc | 397 | |
416331ca XL |
398 | impl std::ops::DerefMut for State<'_> { |
399 | fn deref_mut(&mut self) -> &mut Self::Target { | |
400 | &mut self.s | |
b039eaaf | 401 | } |
416331ca | 402 | } |
223e47cc | 403 | |
e1599b0c | 404 | pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::DerefMut { |
416331ca | 405 | fn comments(&mut self) -> &mut Option<Comments<'a>>; |
f9f354fc | 406 | fn print_ident(&mut self, ident: Ident); |
416331ca | 407 | fn print_generic_args(&mut self, args: &ast::GenericArgs, colons_before_params: bool); |
223e47cc | 408 | |
dfeec247 XL |
409 | fn strsep<T, F>( |
410 | &mut self, | |
411 | sep: &'static str, | |
412 | space_before: bool, | |
413 | b: Breaks, | |
414 | elts: &[T], | |
415 | mut op: F, | |
416 | ) where | |
417 | F: FnMut(&mut Self, &T), | |
b039eaaf | 418 | { |
416331ca | 419 | self.rbox(0, b); |
e1599b0c XL |
420 | if let Some((first, rest)) = elts.split_first() { |
421 | op(self, first); | |
422 | for elt in rest { | |
423 | if space_before { | |
424 | self.space(); | |
425 | } | |
426 | self.word_space(sep); | |
427 | op(self, elt); | |
428 | } | |
b039eaaf | 429 | } |
416331ca | 430 | self.end(); |
b039eaaf SL |
431 | } |
432 | ||
e1599b0c | 433 | fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], op: F) |
dfeec247 XL |
434 | where |
435 | F: FnMut(&mut Self, &T), | |
e1599b0c XL |
436 | { |
437 | self.strsep(",", false, b, elts, op) | |
438 | } | |
439 | ||
416331ca | 440 | fn maybe_print_comment(&mut self, pos: BytePos) { |
c30ab7b3 SL |
441 | while let Some(ref cmnt) = self.next_comment() { |
442 | if cmnt.pos < pos { | |
416331ca | 443 | self.print_comment(cmnt); |
c30ab7b3 | 444 | } else { |
dfeec247 | 445 | break; |
b039eaaf SL |
446 | } |
447 | } | |
b039eaaf SL |
448 | } |
449 | ||
dfeec247 | 450 | fn print_comment(&mut self, cmnt: &comments::Comment) { |
416331ca | 451 | match cmnt.style { |
b039eaaf SL |
452 | comments::Mixed => { |
453 | assert_eq!(cmnt.lines.len(), 1); | |
416331ca XL |
454 | self.zerobreak(); |
455 | self.word(cmnt.lines[0].clone()); | |
456 | self.zerobreak() | |
b039eaaf SL |
457 | } |
458 | comments::Isolated => { | |
416331ca | 459 | self.hardbreak_if_not_bol(); |
b039eaaf SL |
460 | for line in &cmnt.lines { |
461 | // Don't print empty lines because they will end up as trailing | |
e1599b0c | 462 | // whitespace. |
b039eaaf | 463 | if !line.is_empty() { |
416331ca | 464 | self.word(line.clone()); |
b039eaaf | 465 | } |
416331ca | 466 | self.hardbreak(); |
b039eaaf | 467 | } |
b039eaaf SL |
468 | } |
469 | comments::Trailing => { | |
416331ca XL |
470 | if !self.is_beginning_of_line() { |
471 | self.word(" "); | |
c30ab7b3 | 472 | } |
b039eaaf | 473 | if cmnt.lines.len() == 1 { |
416331ca XL |
474 | self.word(cmnt.lines[0].clone()); |
475 | self.hardbreak() | |
b039eaaf | 476 | } else { |
416331ca | 477 | self.ibox(0); |
b039eaaf SL |
478 | for line in &cmnt.lines { |
479 | if !line.is_empty() { | |
416331ca | 480 | self.word(line.clone()); |
b039eaaf | 481 | } |
416331ca | 482 | self.hardbreak(); |
b039eaaf | 483 | } |
416331ca | 484 | self.end(); |
b039eaaf SL |
485 | } |
486 | } | |
487 | comments::BlankLine => { | |
488 | // We need to do at least one, possibly two hardbreaks. | |
416331ca XL |
489 | let twice = match self.last_token() { |
490 | pp::Token::String(s) => ";" == s, | |
491 | pp::Token::Begin(_) => true, | |
492 | pp::Token::End => true, | |
dfeec247 | 493 | _ => false, |
b039eaaf | 494 | }; |
416331ca XL |
495 | if twice { |
496 | self.hardbreak(); | |
b039eaaf | 497 | } |
416331ca | 498 | self.hardbreak(); |
b039eaaf | 499 | } |
416331ca | 500 | } |
74b04a01 XL |
501 | if let Some(cmnts) = self.comments() { |
502 | cmnts.current += 1; | |
b039eaaf SL |
503 | } |
504 | } | |
505 | ||
506 | fn next_comment(&mut self) -> Option<comments::Comment> { | |
416331ca | 507 | self.comments().as_mut().and_then(|c| c.next()) |
b039eaaf SL |
508 | } |
509 | ||
416331ca XL |
510 | fn print_literal(&mut self, lit: &ast::Lit) { |
511 | self.maybe_print_comment(lit.span.lo()); | |
512 | self.word(lit.token.to_string()) | |
b039eaaf SL |
513 | } |
514 | ||
dfeec247 | 515 | fn print_string(&mut self, st: &str, style: ast::StrStyle) { |
b039eaaf | 516 | let st = match style { |
dfeec247 | 517 | ast::StrStyle::Cooked => (format!("\"{}\"", st.escape_debug())), |
7453a54e | 518 | ast::StrStyle::Raw(n) => { |
dfeec247 | 519 | format!("r{delim}\"{string}\"{delim}", delim = "#".repeat(n as usize), string = st) |
b039eaaf SL |
520 | } |
521 | }; | |
416331ca | 522 | self.word(st) |
b039eaaf SL |
523 | } |
524 | ||
dfeec247 | 525 | fn print_inner_attributes(&mut self, attrs: &[ast::Attribute]) { |
92a42be0 SL |
526 | self.print_either_attributes(attrs, ast::AttrStyle::Inner, false, true) |
527 | } | |
528 | ||
dfeec247 | 529 | fn print_inner_attributes_no_trailing_hardbreak(&mut self, attrs: &[ast::Attribute]) { |
92a42be0 | 530 | self.print_either_attributes(attrs, ast::AttrStyle::Inner, false, false) |
b039eaaf SL |
531 | } |
532 | ||
dfeec247 | 533 | fn print_outer_attributes(&mut self, attrs: &[ast::Attribute]) { |
92a42be0 SL |
534 | self.print_either_attributes(attrs, ast::AttrStyle::Outer, false, true) |
535 | } | |
536 | ||
dfeec247 | 537 | fn print_inner_attributes_inline(&mut self, attrs: &[ast::Attribute]) { |
92a42be0 SL |
538 | self.print_either_attributes(attrs, ast::AttrStyle::Inner, true, true) |
539 | } | |
540 | ||
dfeec247 | 541 | fn print_outer_attributes_inline(&mut self, attrs: &[ast::Attribute]) { |
92a42be0 SL |
542 | self.print_either_attributes(attrs, ast::AttrStyle::Outer, true, true) |
543 | } | |
544 | ||
dfeec247 XL |
545 | fn print_either_attributes( |
546 | &mut self, | |
547 | attrs: &[ast::Attribute], | |
548 | kind: ast::AttrStyle, | |
549 | is_inline: bool, | |
550 | trailing_hardbreak: bool, | |
551 | ) { | |
b039eaaf SL |
552 | let mut count = 0; |
553 | for attr in attrs { | |
476ff2be | 554 | if attr.style == kind { |
416331ca | 555 | self.print_attribute_inline(attr, is_inline); |
3157f602 | 556 | if is_inline { |
416331ca | 557 | self.nbsp(); |
3157f602 XL |
558 | } |
559 | count += 1; | |
b039eaaf SL |
560 | } |
561 | } | |
92a42be0 | 562 | if count > 0 && trailing_hardbreak && !is_inline { |
416331ca | 563 | self.hardbreak_if_not_bol(); |
83c7162d | 564 | } |
83c7162d XL |
565 | } |
566 | ||
416331ca | 567 | fn print_attribute(&mut self, attr: &ast::Attribute) { |
92a42be0 SL |
568 | self.print_attribute_inline(attr, false) |
569 | } | |
570 | ||
dfeec247 | 571 | fn print_attribute_inline(&mut self, attr: &ast::Attribute, is_inline: bool) { |
92a42be0 | 572 | if !is_inline { |
416331ca | 573 | self.hardbreak_if_not_bol(); |
92a42be0 | 574 | } |
416331ca | 575 | self.maybe_print_comment(attr.span.lo()); |
60c5eb7d XL |
576 | match attr.kind { |
577 | ast::AttrKind::Normal(ref item) => { | |
578 | match attr.style { | |
579 | ast::AttrStyle::Inner => self.word("#!["), | |
580 | ast::AttrStyle::Outer => self.word("#["), | |
581 | } | |
582 | self.print_attr_item(&item, attr.span); | |
583 | self.word("]"); | |
584 | } | |
585 | ast::AttrKind::DocComment(comment) => { | |
586 | self.word(comment.to_string()); | |
587 | self.hardbreak() | |
416331ca | 588 | } |
e74abb32 XL |
589 | } |
590 | } | |
591 | ||
592 | fn print_attr_item(&mut self, item: &ast::AttrItem, span: Span) { | |
593 | self.ibox(0); | |
60c5eb7d XL |
594 | match &item.args { |
595 | MacArgs::Delimited(_, delim, tokens) => self.print_mac_common( | |
596 | Some(MacHeader::Path(&item.path)), | |
597 | false, | |
598 | None, | |
599 | delim.to_token(), | |
f035d41b | 600 | tokens, |
60c5eb7d XL |
601 | true, |
602 | span, | |
603 | ), | |
604 | MacArgs::Empty | MacArgs::Eq(..) => { | |
e74abb32 | 605 | self.print_path(&item.path, false, 0); |
60c5eb7d | 606 | if let MacArgs::Eq(_, tokens) = &item.args { |
e74abb32 | 607 | self.space(); |
60c5eb7d | 608 | self.word_space("="); |
f035d41b | 609 | self.print_tts(tokens, true); |
416331ca | 610 | } |
cc61c64b | 611 | } |
b039eaaf | 612 | } |
e74abb32 | 613 | self.end(); |
b039eaaf | 614 | } |
1a4d82fc | 615 | |
416331ca | 616 | fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) { |
532ac7d7 | 617 | match item { |
dfeec247 XL |
618 | ast::NestedMetaItem::MetaItem(ref mi) => self.print_meta_item(mi), |
619 | ast::NestedMetaItem::Literal(ref lit) => self.print_literal(lit), | |
9e0c209e SL |
620 | } |
621 | } | |
622 | ||
416331ca XL |
623 | fn print_meta_item(&mut self, item: &ast::MetaItem) { |
624 | self.ibox(INDENT_UNIT); | |
e74abb32 | 625 | match item.kind { |
416331ca | 626 | ast::MetaItemKind::Word => self.print_path(&item.path, false, 0), |
476ff2be | 627 | ast::MetaItemKind::NameValue(ref value) => { |
416331ca XL |
628 | self.print_path(&item.path, false, 0); |
629 | self.space(); | |
630 | self.word_space("="); | |
631 | self.print_literal(value); | |
b039eaaf | 632 | } |
476ff2be | 633 | ast::MetaItemKind::List(ref items) => { |
416331ca XL |
634 | self.print_path(&item.path, false, 0); |
635 | self.popen(); | |
dfeec247 | 636 | self.commasep(Consistent, &items[..], |s, i| s.print_meta_list_item(i)); |
416331ca | 637 | self.pclose(); |
b039eaaf SL |
638 | } |
639 | } | |
416331ca | 640 | self.end(); |
b039eaaf | 641 | } |
92a42be0 | 642 | |
cc61c64b XL |
643 | /// This doesn't deserve to be called "pretty" printing, but it should be |
644 | /// meaning-preserving. A quick hack that might help would be to look at the | |
645 | /// spans embedded in the TTs to decide where to put spaces and newlines. | |
646 | /// But it'd be better to parse these according to the grammar of the | |
647 | /// appropriate macro, transcribe back into the grammar we just parsed from, | |
648 | /// and then pretty-print the resulting AST nodes (so, e.g., we print | |
649 | /// expression arguments as expressions). It can be done! I think. | |
f035d41b | 650 | fn print_tt(&mut self, tt: &TokenTree, convert_dollar_crate: bool) { |
cc61c64b | 651 | match tt { |
f035d41b | 652 | TokenTree::Token(token) => { |
416331ca | 653 | self.word(token_to_string_ext(&token, convert_dollar_crate)); |
ba9703b0 XL |
654 | if let token::DocComment(..) = token.kind { |
655 | self.hardbreak() | |
cc61c64b XL |
656 | } |
657 | } | |
416331ca XL |
658 | TokenTree::Delimited(dspan, delim, tts) => { |
659 | self.print_mac_common( | |
dfeec247 XL |
660 | None, |
661 | false, | |
662 | None, | |
f035d41b | 663 | *delim, |
dfeec247 XL |
664 | tts, |
665 | convert_dollar_crate, | |
666 | dspan.entire(), | |
416331ca XL |
667 | ); |
668 | } | |
cc61c64b XL |
669 | } |
670 | } | |
671 | ||
f035d41b XL |
672 | fn print_tts(&mut self, tts: &TokenStream, convert_dollar_crate: bool) { |
673 | let mut iter = tts.trees().peekable(); | |
ba9703b0 | 674 | while let Some(tt) = iter.next() { |
f035d41b XL |
675 | self.print_tt(&tt, convert_dollar_crate); |
676 | if let Some(next) = iter.peek() { | |
677 | if tt_prepend_space(next, &tt) { | |
678 | self.space(); | |
679 | } | |
cc61c64b | 680 | } |
cc61c64b | 681 | } |
cc61c64b XL |
682 | } |
683 | ||
416331ca XL |
684 | fn print_mac_common( |
685 | &mut self, | |
686 | header: Option<MacHeader<'_>>, | |
687 | has_bang: bool, | |
f9f354fc | 688 | ident: Option<Ident>, |
416331ca | 689 | delim: DelimToken, |
f035d41b | 690 | tts: &TokenStream, |
416331ca XL |
691 | convert_dollar_crate: bool, |
692 | span: Span, | |
693 | ) { | |
694 | if delim == DelimToken::Brace { | |
695 | self.cbox(INDENT_UNIT); | |
696 | } | |
697 | match header { | |
698 | Some(MacHeader::Path(path)) => self.print_path(path, false, 0), | |
699 | Some(MacHeader::Keyword(kw)) => self.word(kw), | |
700 | None => {} | |
701 | } | |
702 | if has_bang { | |
703 | self.word("!"); | |
704 | } | |
705 | if let Some(ident) = ident { | |
706 | self.nbsp(); | |
707 | self.print_ident(ident); | |
708 | } | |
709 | match delim { | |
710 | DelimToken::Brace => { | |
711 | if header.is_some() || has_bang || ident.is_some() { | |
712 | self.nbsp(); | |
713 | } | |
714 | self.word("{"); | |
715 | if !tts.is_empty() { | |
716 | self.space(); | |
717 | } | |
718 | } | |
719 | _ => self.word(token_kind_to_string(&token::OpenDelim(delim))), | |
720 | } | |
721 | self.ibox(0); | |
722 | self.print_tts(tts, convert_dollar_crate); | |
723 | self.end(); | |
724 | match delim { | |
725 | DelimToken::Brace => self.bclose(span), | |
726 | _ => self.word(token_kind_to_string(&token::CloseDelim(delim))), | |
ff7c6d11 | 727 | } |
b039eaaf SL |
728 | } |
729 | ||
416331ca XL |
730 | fn print_path(&mut self, path: &ast::Path, colons_before_params: bool, depth: usize) { |
731 | self.maybe_print_comment(path.span.lo()); | |
b039eaaf | 732 | |
416331ca XL |
733 | for (i, segment) in path.segments[..path.segments.len() - depth].iter().enumerate() { |
734 | if i > 0 { | |
735 | self.word("::") | |
736 | } | |
737 | self.print_path_segment(segment, colons_before_params); | |
738 | } | |
b039eaaf SL |
739 | } |
740 | ||
416331ca XL |
741 | fn print_path_segment(&mut self, segment: &ast::PathSegment, colons_before_params: bool) { |
742 | if segment.ident.name != kw::PathRoot { | |
743 | self.print_ident(segment.ident); | |
744 | if let Some(ref args) = segment.args { | |
745 | self.print_generic_args(args, colons_before_params); | |
746 | } | |
747 | } | |
b039eaaf | 748 | } |
1a4d82fc | 749 | |
416331ca | 750 | fn head<S: Into<Cow<'static, str>>>(&mut self, w: S) { |
a1dfa0c6 | 751 | let w = w.into(); |
e1599b0c | 752 | // Outer-box is consistent. |
416331ca | 753 | self.cbox(INDENT_UNIT); |
e1599b0c | 754 | // Head-box is inconsistent. |
416331ca | 755 | self.ibox(w.len() + 1); |
e1599b0c | 756 | // Keyword that starts the head. |
1a4d82fc | 757 | if !w.is_empty() { |
416331ca | 758 | self.word_nbsp(w); |
223e47cc | 759 | } |
223e47cc | 760 | } |
223e47cc | 761 | |
416331ca XL |
762 | fn bopen(&mut self) { |
763 | self.word("{"); | |
e1599b0c | 764 | self.end(); // Close the head-box. |
1a4d82fc JJ |
765 | } |
766 | ||
dfeec247 | 767 | fn bclose_maybe_open(&mut self, span: rustc_span::Span, close_box: bool) { |
416331ca XL |
768 | self.maybe_print_comment(span.hi()); |
769 | self.break_offset_if_not_bol(1, -(INDENT_UNIT as isize)); | |
770 | self.word("}"); | |
1a4d82fc | 771 | if close_box { |
e1599b0c | 772 | self.end(); // Close the outer-box. |
223e47cc | 773 | } |
223e47cc | 774 | } |
223e47cc | 775 | |
dfeec247 | 776 | fn bclose(&mut self, span: rustc_span::Span) { |
416331ca | 777 | self.bclose_maybe_open(span, true) |
223e47cc | 778 | } |
223e47cc | 779 | |
416331ca XL |
780 | fn break_offset_if_not_bol(&mut self, n: usize, off: isize) { |
781 | if !self.is_beginning_of_line() { | |
782 | self.break_offset(n, off) | |
1a4d82fc | 783 | } else { |
416331ca | 784 | if off != 0 && self.last_token().is_hardbreak_tok() { |
1a4d82fc JJ |
785 | // We do something pretty sketchy here: tuck the nonzero |
786 | // offset-adjustment we were going to deposit along with the | |
787 | // break into the previous hardbreak. | |
416331ca XL |
788 | self.replace_last_token(pp::Printer::hardbreak_tok_offset(off)); |
789 | } | |
790 | } | |
791 | } | |
792 | } | |
793 | ||
794 | impl<'a> PrintState<'a> for State<'a> { | |
795 | fn comments(&mut self) -> &mut Option<Comments<'a>> { | |
796 | &mut self.comments | |
797 | } | |
798 | ||
f9f354fc | 799 | fn print_ident(&mut self, ident: Ident) { |
74b04a01 | 800 | self.s.word(IdentPrinter::for_ast_ident(ident, ident.is_raw_guess()).to_string()); |
416331ca XL |
801 | self.ann.post(self, AnnNode::Ident(&ident)) |
802 | } | |
803 | ||
804 | fn print_generic_args(&mut self, args: &ast::GenericArgs, colons_before_params: bool) { | |
805 | if colons_before_params { | |
806 | self.s.word("::") | |
807 | } | |
808 | ||
809 | match *args { | |
810 | ast::GenericArgs::AngleBracketed(ref data) => { | |
811 | self.s.word("<"); | |
ba9703b0 XL |
812 | self.commasep(Inconsistent, &data.args, |s, arg| match arg { |
813 | ast::AngleBracketedArg::Arg(a) => s.print_generic_arg(a), | |
814 | ast::AngleBracketedArg::Constraint(c) => s.print_assoc_constraint(c), | |
416331ca | 815 | }); |
416331ca XL |
816 | self.s.word(">") |
817 | } | |
818 | ||
819 | ast::GenericArgs::Parenthesized(ref data) => { | |
820 | self.s.word("("); | |
dfeec247 | 821 | self.commasep(Inconsistent, &data.inputs, |s, ty| s.print_type(ty)); |
416331ca | 822 | self.s.word(")"); |
dfeec247 | 823 | self.print_fn_ret_ty(&data.output); |
223e47cc | 824 | } |
223e47cc LB |
825 | } |
826 | } | |
416331ca | 827 | } |
223e47cc | 828 | |
416331ca | 829 | impl<'a> State<'a> { |
1a4d82fc JJ |
830 | // Synthesizes a comment that was not textually present in the original source |
831 | // file. | |
416331ca XL |
832 | pub fn synth_comment(&mut self, text: String) { |
833 | self.s.word("/*"); | |
834 | self.s.space(); | |
835 | self.s.word(text); | |
836 | self.s.space(); | |
041b39d2 | 837 | self.s.word("*/") |
223e47cc | 838 | } |
223e47cc | 839 | |
dfeec247 XL |
840 | crate fn commasep_cmnt<T, F, G>(&mut self, b: Breaks, elts: &[T], mut op: F, mut get_span: G) |
841 | where | |
416331ca | 842 | F: FnMut(&mut State<'_>, &T), |
dfeec247 | 843 | G: FnMut(&T) -> rustc_span::Span, |
1a4d82fc | 844 | { |
416331ca | 845 | self.rbox(0, b); |
1a4d82fc | 846 | let len = elts.len(); |
85aaf69f SL |
847 | let mut i = 0; |
848 | for elt in elts { | |
416331ca XL |
849 | self.maybe_print_comment(get_span(elt).hi()); |
850 | op(self, elt); | |
85aaf69f | 851 | i += 1; |
1a4d82fc | 852 | if i < len { |
416331ca | 853 | self.s.word(","); |
dfeec247 | 854 | self.maybe_print_trailing_comment(get_span(elt), Some(get_span(&elts[i]).hi())); |
416331ca | 855 | self.space_if_not_bol(); |
1a4d82fc JJ |
856 | } |
857 | } | |
416331ca | 858 | self.end(); |
1a4d82fc | 859 | } |
223e47cc | 860 | |
dfeec247 | 861 | crate fn commasep_exprs(&mut self, b: Breaks, exprs: &[P<ast::Expr>]) { |
7cac9316 | 862 | self.commasep_cmnt(b, exprs, |s, e| s.print_expr(e), |e| e.span) |
1a4d82fc | 863 | } |
223e47cc | 864 | |
dfeec247 | 865 | pub fn print_mod(&mut self, _mod: &ast::Mod, attrs: &[ast::Attribute]) { |
416331ca | 866 | self.print_inner_attributes(attrs); |
85aaf69f | 867 | for item in &_mod.items { |
416331ca | 868 | self.print_item(item); |
1a4d82fc | 869 | } |
223e47cc | 870 | } |
223e47cc | 871 | |
74b04a01 | 872 | crate fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod, attrs: &[Attribute]) { |
416331ca | 873 | self.print_inner_attributes(attrs); |
85aaf69f | 874 | for item in &nmod.items { |
416331ca | 875 | self.print_foreign_item(item); |
1a4d82fc | 876 | } |
223e47cc | 877 | } |
223e47cc | 878 | |
60c5eb7d | 879 | pub fn print_opt_lifetime(&mut self, lifetime: &Option<ast::Lifetime>) { |
8faf50e0 | 880 | if let Some(lt) = *lifetime { |
416331ca XL |
881 | self.print_lifetime(lt); |
882 | self.nbsp(); | |
1a4d82fc | 883 | } |
223e47cc | 884 | } |
223e47cc | 885 | |
ba9703b0 XL |
886 | pub fn print_assoc_constraint(&mut self, constraint: &ast::AssocTyConstraint) { |
887 | self.print_ident(constraint.ident); | |
888 | self.s.space(); | |
889 | match &constraint.kind { | |
890 | ast::AssocTyConstraintKind::Equality { ty } => { | |
891 | self.word_space("="); | |
892 | self.print_type(ty); | |
893 | } | |
894 | ast::AssocTyConstraintKind::Bound { bounds } => { | |
895 | self.print_type_bounds(":", &*bounds); | |
896 | } | |
897 | } | |
898 | } | |
899 | ||
900 | pub fn print_generic_arg(&mut self, generic_arg: &GenericArg) { | |
8faf50e0 XL |
901 | match generic_arg { |
902 | GenericArg::Lifetime(lt) => self.print_lifetime(*lt), | |
903 | GenericArg::Type(ty) => self.print_type(ty), | |
9fa01778 | 904 | GenericArg::Const(ct) => self.print_expr(&ct.value), |
8faf50e0 XL |
905 | } |
906 | } | |
907 | ||
60c5eb7d | 908 | pub fn print_type(&mut self, ty: &ast::Ty) { |
416331ca XL |
909 | self.maybe_print_comment(ty.span.lo()); |
910 | self.ibox(0); | |
e74abb32 | 911 | match ty.kind { |
c30ab7b3 | 912 | ast::TyKind::Slice(ref ty) => { |
416331ca XL |
913 | self.s.word("["); |
914 | self.print_type(ty); | |
915 | self.s.word("]"); | |
1a4d82fc | 916 | } |
7453a54e | 917 | ast::TyKind::Ptr(ref mt) => { |
416331ca | 918 | self.s.word("*"); |
60c5eb7d | 919 | self.print_mt(mt, true); |
1a4d82fc | 920 | } |
7453a54e | 921 | ast::TyKind::Rptr(ref lifetime, ref mt) => { |
416331ca XL |
922 | self.s.word("&"); |
923 | self.print_opt_lifetime(lifetime); | |
60c5eb7d | 924 | self.print_mt(mt, false); |
1a4d82fc | 925 | } |
5bcae85e | 926 | ast::TyKind::Never => { |
416331ca | 927 | self.s.word("!"); |
dfeec247 | 928 | } |
7453a54e | 929 | ast::TyKind::Tup(ref elts) => { |
416331ca | 930 | self.popen(); |
dfeec247 | 931 | self.commasep(Inconsistent, &elts[..], |s, ty| s.print_type(ty)); |
1a4d82fc | 932 | if elts.len() == 1 { |
416331ca | 933 | self.s.word(","); |
1a4d82fc | 934 | } |
416331ca | 935 | self.pclose(); |
1a4d82fc | 936 | } |
7453a54e | 937 | ast::TyKind::Paren(ref typ) => { |
416331ca XL |
938 | self.popen(); |
939 | self.print_type(typ); | |
940 | self.pclose(); | |
1a4d82fc | 941 | } |
7453a54e | 942 | ast::TyKind::BareFn(ref f) => { |
dfeec247 | 943 | self.print_ty_fn(f.ext, f.unsafety, &f.decl, None, &f.generic_params); |
1a4d82fc | 944 | } |
7453a54e | 945 | ast::TyKind::Path(None, ref path) => { |
416331ca | 946 | self.print_path(path, false, 0); |
c34b1796 | 947 | } |
dfeec247 | 948 | ast::TyKind::Path(Some(ref qself), ref path) => self.print_qpath(path, qself, false), |
abe05a73 | 949 | ast::TyKind::TraitObject(ref bounds, syntax) => { |
ff7c6d11 | 950 | let prefix = if syntax == ast::TraitObjectSyntax::Dyn { "dyn" } else { "" }; |
416331ca | 951 | self.print_type_bounds(prefix, &bounds[..]); |
1a4d82fc | 952 | } |
8faf50e0 | 953 | ast::TyKind::ImplTrait(_, ref bounds) => { |
416331ca | 954 | self.print_type_bounds("impl", &bounds[..]); |
5bcae85e | 955 | } |
94b46f34 | 956 | ast::TyKind::Array(ref ty, ref length) => { |
416331ca XL |
957 | self.s.word("["); |
958 | self.print_type(ty); | |
959 | self.s.word("; "); | |
960 | self.print_expr(&length.value); | |
961 | self.s.word("]"); | |
1a4d82fc | 962 | } |
7453a54e | 963 | ast::TyKind::Typeof(ref e) => { |
416331ca XL |
964 | self.s.word("typeof("); |
965 | self.print_expr(&e.value); | |
966 | self.s.word(")"); | |
1a4d82fc | 967 | } |
7453a54e | 968 | ast::TyKind::Infer => { |
416331ca | 969 | self.s.word("_"); |
3157f602 | 970 | } |
cc61c64b | 971 | ast::TyKind::Err => { |
416331ca XL |
972 | self.popen(); |
973 | self.s.word("/*ERROR*/"); | |
974 | self.pclose(); | |
cc61c64b | 975 | } |
3157f602 | 976 | ast::TyKind::ImplicitSelf => { |
416331ca | 977 | self.s.word("Self"); |
1a4d82fc | 978 | } |
ba9703b0 | 979 | ast::TyKind::MacCall(ref m) => { |
416331ca | 980 | self.print_mac(m); |
e9174d1e | 981 | } |
532ac7d7 | 982 | ast::TyKind::CVarArgs => { |
416331ca | 983 | self.s.word("..."); |
532ac7d7 | 984 | } |
223e47cc | 985 | } |
416331ca | 986 | self.end(); |
1a4d82fc JJ |
987 | } |
988 | ||
dfeec247 | 989 | crate fn print_foreign_item(&mut self, item: &ast::ForeignItem) { |
74b04a01 XL |
990 | let ast::Item { id, span, ident, ref attrs, ref kind, ref vis, tokens: _ } = *item; |
991 | self.ann.pre(self, AnnNode::SubItem(id)); | |
416331ca | 992 | self.hardbreak_if_not_bol(); |
74b04a01 XL |
993 | self.maybe_print_comment(span.lo()); |
994 | self.print_outer_attributes(attrs); | |
995 | match kind { | |
996 | ast::ForeignItemKind::Fn(def, sig, gen, body) => { | |
997 | self.print_fn_full(sig, ident, gen, vis, *def, body.as_deref(), attrs); | |
1a4d82fc | 998 | } |
74b04a01 XL |
999 | ast::ForeignItemKind::Static(ty, mutbl, body) => { |
1000 | let def = ast::Defaultness::Final; | |
1001 | self.print_item_const(ident, Some(*mutbl), ty, body.as_deref(), vis, def); | |
1a4d82fc | 1002 | } |
74b04a01 XL |
1003 | ast::ForeignItemKind::TyAlias(def, generics, bounds, ty) => { |
1004 | self.print_associated_type(ident, generics, bounds, ty.as_deref(), vis, *def); | |
abe05a73 | 1005 | } |
ba9703b0 | 1006 | ast::ForeignItemKind::MacCall(m) => { |
416331ca | 1007 | self.print_mac(m); |
60c5eb7d XL |
1008 | if m.args.need_semicolon() { |
1009 | self.s.word(";"); | |
94b46f34 | 1010 | } |
83c7162d | 1011 | } |
223e47cc | 1012 | } |
74b04a01 | 1013 | self.ann.post(self, AnnNode::SubItem(id)) |
223e47cc | 1014 | } |
223e47cc | 1015 | |
74b04a01 | 1016 | fn print_item_const( |
dfeec247 | 1017 | &mut self, |
f9f354fc | 1018 | ident: Ident, |
74b04a01 | 1019 | mutbl: Option<ast::Mutability>, |
dfeec247 | 1020 | ty: &ast::Ty, |
74b04a01 | 1021 | body: Option<&ast::Expr>, |
dfeec247 | 1022 | vis: &ast::Visibility, |
74b04a01 | 1023 | defaultness: ast::Defaultness, |
dfeec247 | 1024 | ) { |
74b04a01 XL |
1025 | self.head(""); |
1026 | self.print_visibility(vis); | |
1027 | self.print_defaultness(defaultness); | |
1028 | let leading = match mutbl { | |
1029 | None => "const", | |
1030 | Some(ast::Mutability::Not) => "static", | |
1031 | Some(ast::Mutability::Mut) => "static mut", | |
1032 | }; | |
1033 | self.word_space(leading); | |
416331ca XL |
1034 | self.print_ident(ident); |
1035 | self.word_space(":"); | |
1036 | self.print_type(ty); | |
74b04a01 XL |
1037 | self.s.space(); |
1038 | self.end(); // end the head-ibox | |
1039 | if let Some(body) = body { | |
416331ca | 1040 | self.word_space("="); |
74b04a01 | 1041 | self.print_expr(body); |
d9579d0f | 1042 | } |
74b04a01 XL |
1043 | self.s.word(";"); |
1044 | self.end(); // end the outer cbox | |
d9579d0f AL |
1045 | } |
1046 | ||
dfeec247 XL |
1047 | fn print_associated_type( |
1048 | &mut self, | |
f9f354fc | 1049 | ident: Ident, |
74b04a01 | 1050 | generics: &ast::Generics, |
dfeec247 XL |
1051 | bounds: &ast::GenericBounds, |
1052 | ty: Option<&ast::Ty>, | |
74b04a01 XL |
1053 | vis: &ast::Visibility, |
1054 | defaultness: ast::Defaultness, | |
dfeec247 | 1055 | ) { |
74b04a01 XL |
1056 | self.head(""); |
1057 | self.print_visibility(vis); | |
1058 | self.print_defaultness(defaultness); | |
416331ca XL |
1059 | self.word_space("type"); |
1060 | self.print_ident(ident); | |
74b04a01 | 1061 | self.print_generic_params(&generics.params); |
dfeec247 | 1062 | self.print_type_bounds(":", bounds); |
74b04a01 | 1063 | self.print_where_clause(&generics.where_clause); |
c34b1796 | 1064 | if let Some(ty) = ty { |
416331ca XL |
1065 | self.s.space(); |
1066 | self.word_space("="); | |
1067 | self.print_type(ty); | |
c34b1796 | 1068 | } |
74b04a01 XL |
1069 | self.s.word(";"); |
1070 | self.end(); // end inner head-block | |
1071 | self.end(); // end outer head-block | |
1a4d82fc JJ |
1072 | } |
1073 | ||
e1599b0c | 1074 | /// Pretty-prints an item. |
416331ca XL |
1075 | crate fn print_item(&mut self, item: &ast::Item) { |
1076 | self.hardbreak_if_not_bol(); | |
1077 | self.maybe_print_comment(item.span.lo()); | |
1078 | self.print_outer_attributes(&item.attrs); | |
1079 | self.ann.pre(self, AnnNode::Item(item)); | |
e74abb32 | 1080 | match item.kind { |
0531ce1d | 1081 | ast::ItemKind::ExternCrate(orig_name) => { |
416331ca | 1082 | self.head(visibility_qualified(&item.vis, "extern crate")); |
0531ce1d | 1083 | if let Some(orig_name) = orig_name { |
416331ca XL |
1084 | self.print_name(orig_name); |
1085 | self.s.space(); | |
1086 | self.s.word("as"); | |
1087 | self.s.space(); | |
85aaf69f | 1088 | } |
416331ca XL |
1089 | self.print_ident(item.ident); |
1090 | self.s.word(";"); | |
1091 | self.end(); // end inner head-block | |
1092 | self.end(); // end outer head-block | |
85aaf69f | 1093 | } |
ff7c6d11 | 1094 | ast::ItemKind::Use(ref tree) => { |
416331ca XL |
1095 | self.head(visibility_qualified(&item.vis, "use")); |
1096 | self.print_use_tree(tree); | |
1097 | self.s.word(";"); | |
1098 | self.end(); // end inner head-block | |
1099 | self.end(); // end outer head-block | |
85aaf69f | 1100 | } |
74b04a01 XL |
1101 | ast::ItemKind::Static(ref ty, mutbl, ref body) => { |
1102 | let def = ast::Defaultness::Final; | |
1103 | self.print_item_const(item.ident, Some(mutbl), ty, body.as_deref(), &item.vis, def); | |
1a4d82fc | 1104 | } |
74b04a01 XL |
1105 | ast::ItemKind::Const(def, ref ty, ref body) => { |
1106 | self.print_item_const(item.ident, None, ty, body.as_deref(), &item.vis, def); | |
1a4d82fc | 1107 | } |
74b04a01 XL |
1108 | ast::ItemKind::Fn(def, ref sig, ref gen, ref body) => { |
1109 | let body = body.as_deref(); | |
1110 | self.print_fn_full(sig, item.ident, gen, &item.vis, def, body, &item.attrs); | |
1a4d82fc | 1111 | } |
7453a54e | 1112 | ast::ItemKind::Mod(ref _mod) => { |
416331ca XL |
1113 | self.head(visibility_qualified(&item.vis, "mod")); |
1114 | self.print_ident(item.ident); | |
0bf4aa26 XL |
1115 | |
1116 | if _mod.inline || self.is_expanded { | |
416331ca XL |
1117 | self.nbsp(); |
1118 | self.bopen(); | |
1119 | self.print_mod(_mod, &item.attrs); | |
1120 | self.bclose(item.span); | |
0bf4aa26 | 1121 | } else { |
416331ca XL |
1122 | self.s.word(";"); |
1123 | self.end(); // end inner head-block | |
1124 | self.end(); // end outer head-block | |
0bf4aa26 | 1125 | } |
1a4d82fc | 1126 | } |
7453a54e | 1127 | ast::ItemKind::ForeignMod(ref nmod) => { |
416331ca | 1128 | self.head("extern"); |
60c5eb7d XL |
1129 | if let Some(abi) = nmod.abi { |
1130 | self.print_literal(&abi.as_lit()); | |
1131 | self.nbsp(); | |
1132 | } | |
416331ca XL |
1133 | self.bopen(); |
1134 | self.print_foreign_mod(nmod, &item.attrs); | |
1135 | self.bclose(item.span); | |
1a4d82fc | 1136 | } |
cc61c64b | 1137 | ast::ItemKind::GlobalAsm(ref ga) => { |
416331ca | 1138 | self.head(visibility_qualified(&item.vis, "global_asm!")); |
60c5eb7d | 1139 | self.s.word(ga.asm.to_string()); |
416331ca XL |
1140 | self.end(); |
1141 | } | |
74b04a01 XL |
1142 | ast::ItemKind::TyAlias(def, ref generics, ref bounds, ref ty) => { |
1143 | let ty = ty.as_deref(); | |
1144 | self.print_associated_type(item.ident, generics, bounds, ty, &item.vis, def); | |
416331ca | 1145 | } |
7453a54e | 1146 | ast::ItemKind::Enum(ref enum_definition, ref params) => { |
dfeec247 | 1147 | self.print_enum_def(enum_definition, params, item.ident, item.span, &item.vis); |
1a4d82fc | 1148 | } |
7453a54e | 1149 | ast::ItemKind::Struct(ref struct_def, ref generics) => { |
416331ca XL |
1150 | self.head(visibility_qualified(&item.vis, "struct")); |
1151 | self.print_struct(struct_def, generics, item.ident, item.span, true); | |
1a4d82fc | 1152 | } |
9e0c209e | 1153 | ast::ItemKind::Union(ref struct_def, ref generics) => { |
416331ca XL |
1154 | self.head(visibility_qualified(&item.vis, "union")); |
1155 | self.print_struct(struct_def, generics, item.ident, item.span, true); | |
9e0c209e | 1156 | } |
dfeec247 XL |
1157 | ast::ItemKind::Impl { |
1158 | unsafety, | |
1159 | polarity, | |
1160 | defaultness, | |
1161 | constness, | |
1162 | ref generics, | |
1163 | ref of_trait, | |
1164 | ref self_ty, | |
1165 | ref items, | |
1166 | } => { | |
416331ca XL |
1167 | self.head(""); |
1168 | self.print_visibility(&item.vis); | |
1169 | self.print_defaultness(defaultness); | |
1170 | self.print_unsafety(unsafety); | |
1171 | self.word_nbsp("impl"); | |
dfeec247 | 1172 | self.print_constness(constness); |
1a4d82fc | 1173 | |
8faf50e0 | 1174 | if !generics.params.is_empty() { |
416331ca XL |
1175 | self.print_generic_params(&generics.params); |
1176 | self.s.space(); | |
1a4d82fc JJ |
1177 | } |
1178 | ||
ba9703b0 | 1179 | if let ast::ImplPolarity::Negative(_) = polarity { |
416331ca | 1180 | self.s.word("!"); |
1a4d82fc JJ |
1181 | } |
1182 | ||
dfeec247 | 1183 | if let Some(ref t) = *of_trait { |
416331ca XL |
1184 | self.print_trait_ref(t); |
1185 | self.s.space(); | |
1186 | self.word_space("for"); | |
1a4d82fc JJ |
1187 | } |
1188 | ||
dfeec247 | 1189 | self.print_type(self_ty); |
416331ca | 1190 | self.print_where_clause(&generics.where_clause); |
1a4d82fc | 1191 | |
416331ca XL |
1192 | self.s.space(); |
1193 | self.bopen(); | |
1194 | self.print_inner_attributes(&item.attrs); | |
dfeec247 XL |
1195 | for impl_item in items { |
1196 | self.print_assoc_item(impl_item); | |
1a4d82fc | 1197 | } |
416331ca | 1198 | self.bclose(item.span); |
1a4d82fc | 1199 | } |
abe05a73 | 1200 | ast::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref trait_items) => { |
416331ca XL |
1201 | self.head(""); |
1202 | self.print_visibility(&item.vis); | |
1203 | self.print_unsafety(unsafety); | |
1204 | self.print_is_auto(is_auto); | |
1205 | self.word_nbsp("trait"); | |
1206 | self.print_ident(item.ident); | |
1207 | self.print_generic_params(&generics.params); | |
1a4d82fc | 1208 | let mut real_bounds = Vec::with_capacity(bounds.len()); |
85aaf69f | 1209 | for b in bounds.iter() { |
8faf50e0 | 1210 | if let GenericBound::Trait(ref ptr, ast::TraitBoundModifier::Maybe) = *b { |
416331ca XL |
1211 | self.s.space(); |
1212 | self.word_space("for ?"); | |
1213 | self.print_trait_ref(&ptr.trait_ref); | |
1a4d82fc | 1214 | } else { |
85aaf69f | 1215 | real_bounds.push(b.clone()); |
1a4d82fc JJ |
1216 | } |
1217 | } | |
416331ca XL |
1218 | self.print_type_bounds(":", &real_bounds[..]); |
1219 | self.print_where_clause(&generics.where_clause); | |
1220 | self.s.word(" "); | |
1221 | self.bopen(); | |
74b04a01 | 1222 | self.print_inner_attributes(&item.attrs); |
c34b1796 | 1223 | for trait_item in trait_items { |
dfeec247 | 1224 | self.print_assoc_item(trait_item); |
1a4d82fc | 1225 | } |
416331ca | 1226 | self.bclose(item.span); |
1a4d82fc | 1227 | } |
ff7c6d11 | 1228 | ast::ItemKind::TraitAlias(ref generics, ref bounds) => { |
416331ca XL |
1229 | self.head(""); |
1230 | self.print_visibility(&item.vis); | |
1231 | self.word_nbsp("trait"); | |
1232 | self.print_ident(item.ident); | |
1233 | self.print_generic_params(&generics.params); | |
ff7c6d11 XL |
1234 | let mut real_bounds = Vec::with_capacity(bounds.len()); |
1235 | // FIXME(durka) this seems to be some quite outdated syntax | |
1236 | for b in bounds.iter() { | |
8faf50e0 | 1237 | if let GenericBound::Trait(ref ptr, ast::TraitBoundModifier::Maybe) = *b { |
416331ca XL |
1238 | self.s.space(); |
1239 | self.word_space("for ?"); | |
1240 | self.print_trait_ref(&ptr.trait_ref); | |
ff7c6d11 XL |
1241 | } else { |
1242 | real_bounds.push(b.clone()); | |
1243 | } | |
1244 | } | |
416331ca XL |
1245 | self.nbsp(); |
1246 | self.print_type_bounds("=", &real_bounds[..]); | |
1247 | self.print_where_clause(&generics.where_clause); | |
1248 | self.s.word(";"); | |
ff7c6d11 | 1249 | } |
ba9703b0 | 1250 | ast::ItemKind::MacCall(ref mac) => { |
416331ca | 1251 | self.print_mac(mac); |
60c5eb7d XL |
1252 | if mac.args.need_semicolon() { |
1253 | self.s.word(";"); | |
416331ca XL |
1254 | } |
1255 | } | |
1256 | ast::ItemKind::MacroDef(ref macro_def) => { | |
ba9703b0 | 1257 | let (kw, has_bang) = if macro_def.macro_rules { |
e1599b0c XL |
1258 | ("macro_rules", true) |
1259 | } else { | |
1260 | self.print_visibility(&item.vis); | |
1261 | ("macro", false) | |
1262 | }; | |
416331ca XL |
1263 | self.print_mac_common( |
1264 | Some(MacHeader::Keyword(kw)), | |
1265 | has_bang, | |
1266 | Some(item.ident), | |
60c5eb7d | 1267 | macro_def.body.delim(), |
f035d41b | 1268 | ¯o_def.body.inner_tokens(), |
416331ca XL |
1269 | true, |
1270 | item.span, | |
1271 | ); | |
1a4d82fc | 1272 | } |
223e47cc | 1273 | } |
b7449926 | 1274 | self.ann.post(self, AnnNode::Item(item)) |
223e47cc | 1275 | } |
223e47cc | 1276 | |
416331ca | 1277 | fn print_trait_ref(&mut self, t: &ast::TraitRef) { |
0531ce1d | 1278 | self.print_path(&t.path, false, 0) |
223e47cc | 1279 | } |
223e47cc | 1280 | |
dfeec247 | 1281 | fn print_formal_generic_params(&mut self, generic_params: &[ast::GenericParam]) { |
ff7c6d11 | 1282 | if !generic_params.is_empty() { |
416331ca XL |
1283 | self.s.word("for"); |
1284 | self.print_generic_params(generic_params); | |
1285 | self.nbsp(); | |
1a4d82fc | 1286 | } |
85aaf69f | 1287 | } |
1a4d82fc | 1288 | |
416331ca XL |
1289 | fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) { |
1290 | self.print_formal_generic_params(&t.bound_generic_params); | |
1a4d82fc JJ |
1291 | self.print_trait_ref(&t.trait_ref) |
1292 | } | |
1293 | ||
dfeec247 XL |
1294 | crate fn print_enum_def( |
1295 | &mut self, | |
1296 | enum_definition: &ast::EnumDef, | |
1297 | generics: &ast::Generics, | |
f9f354fc | 1298 | ident: Ident, |
dfeec247 XL |
1299 | span: rustc_span::Span, |
1300 | visibility: &ast::Visibility, | |
1301 | ) { | |
416331ca XL |
1302 | self.head(visibility_qualified(visibility, "enum")); |
1303 | self.print_ident(ident); | |
1304 | self.print_generic_params(&generics.params); | |
1305 | self.print_where_clause(&generics.where_clause); | |
1306 | self.s.space(); | |
85aaf69f | 1307 | self.print_variants(&enum_definition.variants, span) |
1a4d82fc JJ |
1308 | } |
1309 | ||
dfeec247 | 1310 | crate fn print_variants(&mut self, variants: &[ast::Variant], span: rustc_span::Span) { |
416331ca | 1311 | self.bopen(); |
85aaf69f | 1312 | for v in variants { |
416331ca XL |
1313 | self.space_if_not_bol(); |
1314 | self.maybe_print_comment(v.span.lo()); | |
e1599b0c | 1315 | self.print_outer_attributes(&v.attrs); |
416331ca XL |
1316 | self.ibox(INDENT_UNIT); |
1317 | self.print_variant(v); | |
1318 | self.s.word(","); | |
1319 | self.end(); | |
1320 | self.maybe_print_trailing_comment(v.span, None); | |
1a4d82fc JJ |
1321 | } |
1322 | self.bclose(span) | |
1323 | } | |
1324 | ||
416331ca | 1325 | crate fn print_visibility(&mut self, vis: &ast::Visibility) { |
0531ce1d XL |
1326 | match vis.node { |
1327 | ast::VisibilityKind::Public => self.word_nbsp("pub"), | |
1328 | ast::VisibilityKind::Crate(sugar) => match sugar { | |
abe05a73 | 1329 | ast::CrateSugar::PubCrate => self.word_nbsp("pub(crate)"), |
dfeec247 XL |
1330 | ast::CrateSugar::JustCrate => self.word_nbsp("crate"), |
1331 | }, | |
0531ce1d XL |
1332 | ast::VisibilityKind::Restricted { ref path, .. } => { |
1333 | let path = to_string(|s| s.print_path(path, false, 0)); | |
cc61c64b | 1334 | if path == "self" || path == "super" { |
a1dfa0c6 | 1335 | self.word_nbsp(format!("pub({})", path)) |
cc61c64b | 1336 | } else { |
a1dfa0c6 | 1337 | self.word_nbsp(format!("pub(in {})", path)) |
cc61c64b | 1338 | } |
32a655c1 | 1339 | } |
416331ca | 1340 | ast::VisibilityKind::Inherited => {} |
1a4d82fc JJ |
1341 | } |
1342 | } | |
1343 | ||
416331ca | 1344 | crate fn print_defaultness(&mut self, defaultness: ast::Defaultness) { |
74b04a01 | 1345 | if let ast::Defaultness::Default(_) = defaultness { |
416331ca | 1346 | self.word_nbsp("default"); |
7cac9316 | 1347 | } |
7cac9316 XL |
1348 | } |
1349 | ||
dfeec247 XL |
1350 | crate fn print_struct( |
1351 | &mut self, | |
1352 | struct_def: &ast::VariantData, | |
1353 | generics: &ast::Generics, | |
f9f354fc | 1354 | ident: Ident, |
dfeec247 XL |
1355 | span: rustc_span::Span, |
1356 | print_finalizer: bool, | |
1357 | ) { | |
416331ca XL |
1358 | self.print_ident(ident); |
1359 | self.print_generic_params(&generics.params); | |
532ac7d7 XL |
1360 | match struct_def { |
1361 | ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => { | |
1362 | if let ast::VariantData::Tuple(..) = struct_def { | |
416331ca | 1363 | self.popen(); |
dfeec247 XL |
1364 | self.commasep(Inconsistent, struct_def.fields(), |s, field| { |
1365 | s.maybe_print_comment(field.span.lo()); | |
1366 | s.print_outer_attributes(&field.attrs); | |
1367 | s.print_visibility(&field.vis); | |
1368 | s.print_type(&field.ty) | |
1369 | }); | |
416331ca | 1370 | self.pclose(); |
532ac7d7 | 1371 | } |
416331ca | 1372 | self.print_where_clause(&generics.where_clause); |
532ac7d7 | 1373 | if print_finalizer { |
416331ca | 1374 | self.s.word(";"); |
532ac7d7 | 1375 | } |
416331ca | 1376 | self.end(); |
e1599b0c | 1377 | self.end(); // Close the outer-box. |
b039eaaf | 1378 | } |
532ac7d7 | 1379 | ast::VariantData::Struct(..) => { |
416331ca XL |
1380 | self.print_where_clause(&generics.where_clause); |
1381 | self.nbsp(); | |
1382 | self.bopen(); | |
1383 | self.hardbreak_if_not_bol(); | |
223e47cc | 1384 | |
532ac7d7 | 1385 | for field in struct_def.fields() { |
416331ca XL |
1386 | self.hardbreak_if_not_bol(); |
1387 | self.maybe_print_comment(field.span.lo()); | |
1388 | self.print_outer_attributes(&field.attrs); | |
1389 | self.print_visibility(&field.vis); | |
1390 | self.print_ident(field.ident.unwrap()); | |
1391 | self.word_nbsp(":"); | |
1392 | self.print_type(&field.ty); | |
1393 | self.s.word(","); | |
532ac7d7 XL |
1394 | } |
1395 | ||
1396 | self.bclose(span) | |
1397 | } | |
223e47cc | 1398 | } |
1a4d82fc | 1399 | } |
223e47cc | 1400 | |
416331ca XL |
1401 | crate fn print_variant(&mut self, v: &ast::Variant) { |
1402 | self.head(""); | |
60c5eb7d | 1403 | self.print_visibility(&v.vis); |
9cc50fc6 | 1404 | let generics = ast::Generics::default(); |
e1599b0c | 1405 | self.print_struct(&v.data, &generics, v.ident, v.span, false); |
ba9703b0 XL |
1406 | if let Some(ref d) = v.disr_expr { |
1407 | self.s.space(); | |
1408 | self.word_space("="); | |
1409 | self.print_expr(&d.value) | |
1a4d82fc JJ |
1410 | } |
1411 | } | |
1412 | ||
dfeec247 | 1413 | crate fn print_assoc_item(&mut self, item: &ast::AssocItem) { |
74b04a01 XL |
1414 | let ast::Item { id, span, ident, ref attrs, ref kind, ref vis, tokens: _ } = *item; |
1415 | self.ann.pre(self, AnnNode::SubItem(id)); | |
416331ca | 1416 | self.hardbreak_if_not_bol(); |
74b04a01 XL |
1417 | self.maybe_print_comment(span.lo()); |
1418 | self.print_outer_attributes(attrs); | |
1419 | match kind { | |
1420 | ast::AssocItemKind::Fn(def, sig, gen, body) => { | |
1421 | self.print_fn_full(sig, ident, gen, vis, *def, body.as_deref(), attrs); | |
d9579d0f | 1422 | } |
74b04a01 XL |
1423 | ast::AssocItemKind::Const(def, ty, body) => { |
1424 | self.print_item_const(ident, None, ty, body.as_deref(), vis, *def); | |
c34b1796 | 1425 | } |
74b04a01 XL |
1426 | ast::AssocItemKind::TyAlias(def, generics, bounds, ty) => { |
1427 | self.print_associated_type(ident, generics, bounds, ty.as_deref(), vis, *def); | |
3157f602 | 1428 | } |
ba9703b0 | 1429 | ast::AssocItemKind::MacCall(m) => { |
74b04a01 XL |
1430 | self.print_mac(m); |
1431 | if m.args.need_semicolon() { | |
60c5eb7d | 1432 | self.s.word(";"); |
94b46f34 | 1433 | } |
c34b1796 | 1434 | } |
1a4d82fc | 1435 | } |
74b04a01 | 1436 | self.ann.post(self, AnnNode::SubItem(id)) |
223e47cc | 1437 | } |
223e47cc | 1438 | |
416331ca XL |
1439 | crate fn print_stmt(&mut self, st: &ast::Stmt) { |
1440 | self.maybe_print_comment(st.span.lo()); | |
e74abb32 | 1441 | match st.kind { |
3157f602 | 1442 | ast::StmtKind::Local(ref loc) => { |
416331ca XL |
1443 | self.print_outer_attributes(&loc.attrs); |
1444 | self.space_if_not_bol(); | |
1445 | self.ibox(INDENT_UNIT); | |
1446 | self.word_nbsp("let"); | |
1447 | ||
1448 | self.ibox(INDENT_UNIT); | |
1449 | self.print_local_decl(loc); | |
1450 | self.end(); | |
3157f602 | 1451 | if let Some(ref init) = loc.init { |
416331ca XL |
1452 | self.nbsp(); |
1453 | self.word_space("="); | |
1454 | self.print_expr(init); | |
3157f602 | 1455 | } |
416331ca XL |
1456 | self.s.word(";"); |
1457 | self.end(); | |
1a4d82fc | 1458 | } |
416331ca | 1459 | ast::StmtKind::Item(ref item) => self.print_item(item), |
3157f602 | 1460 | ast::StmtKind::Expr(ref expr) => { |
416331ca XL |
1461 | self.space_if_not_bol(); |
1462 | self.print_expr_outer_attr_style(expr, false); | |
60c5eb7d | 1463 | if classify::expr_requires_semi_to_be_stmt(expr) { |
416331ca | 1464 | self.s.word(";"); |
3157f602 | 1465 | } |
1a4d82fc | 1466 | } |
3157f602 | 1467 | ast::StmtKind::Semi(ref expr) => { |
74b04a01 XL |
1468 | self.space_if_not_bol(); |
1469 | self.print_expr_outer_attr_style(expr, false); | |
1470 | self.s.word(";"); | |
1471 | } | |
1472 | ast::StmtKind::Empty => { | |
1473 | self.space_if_not_bol(); | |
1474 | self.s.word(";"); | |
1a4d82fc | 1475 | } |
ba9703b0 | 1476 | ast::StmtKind::MacCall(ref mac) => { |
3157f602 | 1477 | let (ref mac, style, ref attrs) = **mac; |
416331ca XL |
1478 | self.space_if_not_bol(); |
1479 | self.print_outer_attributes(attrs); | |
1480 | self.print_mac(mac); | |
5bcae85e | 1481 | if style == ast::MacStmtStyle::Semicolon { |
416331ca | 1482 | self.s.word(";"); |
223e47cc LB |
1483 | } |
1484 | } | |
223e47cc | 1485 | } |
1a4d82fc | 1486 | self.maybe_print_trailing_comment(st.span, None) |
223e47cc | 1487 | } |
223e47cc | 1488 | |
416331ca | 1489 | crate fn print_block(&mut self, blk: &ast::Block) { |
1a4d82fc JJ |
1490 | self.print_block_with_attrs(blk, &[]) |
1491 | } | |
970d7e83 | 1492 | |
416331ca XL |
1493 | crate fn print_block_unclosed_indent(&mut self, blk: &ast::Block) { |
1494 | self.print_block_maybe_unclosed(blk, &[], false) | |
1a4d82fc | 1495 | } |
223e47cc | 1496 | |
dfeec247 | 1497 | crate fn print_block_with_attrs(&mut self, blk: &ast::Block, attrs: &[ast::Attribute]) { |
416331ca | 1498 | self.print_block_maybe_unclosed(blk, attrs, true) |
1a4d82fc | 1499 | } |
223e47cc | 1500 | |
dfeec247 XL |
1501 | crate fn print_block_maybe_unclosed( |
1502 | &mut self, | |
1503 | blk: &ast::Block, | |
1504 | attrs: &[ast::Attribute], | |
1505 | close_box: bool, | |
1506 | ) { | |
1a4d82fc | 1507 | match blk.rules { |
416331ca | 1508 | BlockCheckMode::Unsafe(..) => self.word_space("unsafe"), |
dfeec247 | 1509 | BlockCheckMode::Default => (), |
1a4d82fc | 1510 | } |
416331ca XL |
1511 | self.maybe_print_comment(blk.span.lo()); |
1512 | self.ann.pre(self, AnnNode::Block(blk)); | |
1513 | self.bopen(); | |
223e47cc | 1514 | |
416331ca | 1515 | self.print_inner_attributes(attrs); |
970d7e83 | 1516 | |
3157f602 | 1517 | for (i, st) in blk.stmts.iter().enumerate() { |
e74abb32 | 1518 | match st.kind { |
3157f602 | 1519 | ast::StmtKind::Expr(ref expr) if i == blk.stmts.len() - 1 => { |
416331ca XL |
1520 | self.maybe_print_comment(st.span.lo()); |
1521 | self.space_if_not_bol(); | |
1522 | self.print_expr_outer_attr_style(expr, false); | |
1523 | self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi())); | |
3157f602 | 1524 | } |
416331ca | 1525 | _ => self.print_stmt(st), |
1a4d82fc | 1526 | } |
1a4d82fc | 1527 | } |
3157f602 | 1528 | |
416331ca | 1529 | self.bclose_maybe_open(blk.span, close_box); |
b7449926 | 1530 | self.ann.post(self, AnnNode::Block(blk)) |
1a4d82fc JJ |
1531 | } |
1532 | ||
e1599b0c XL |
1533 | /// Print a `let pat = scrutinee` expression. |
1534 | crate fn print_let(&mut self, pat: &ast::Pat, scrutinee: &ast::Expr) { | |
416331ca | 1535 | self.s.word("let "); |
dc9dc135 | 1536 | |
e1599b0c | 1537 | self.print_pat(pat); |
416331ca | 1538 | self.s.space(); |
dc9dc135 | 1539 | |
416331ca | 1540 | self.word_space("="); |
dc9dc135 XL |
1541 | self.print_expr_cond_paren( |
1542 | scrutinee, | |
1543 | Self::cond_needs_par(scrutinee) | |
dfeec247 | 1544 | || parser::needs_par_as_let_scrutinee(scrutinee.precedence().order()), |
dc9dc135 XL |
1545 | ) |
1546 | } | |
1547 | ||
416331ca | 1548 | fn print_else(&mut self, els: Option<&ast::Expr>) { |
e74abb32 XL |
1549 | if let Some(_else) = els { |
1550 | match _else.kind { | |
1551 | // Another `else if` block. | |
1552 | ast::ExprKind::If(ref i, ref then, ref e) => { | |
1553 | self.cbox(INDENT_UNIT - 1); | |
1554 | self.ibox(0); | |
1555 | self.s.word(" else if "); | |
1556 | self.print_expr_as_cond(i); | |
1557 | self.s.space(); | |
1558 | self.print_block(then); | |
dfeec247 | 1559 | self.print_else(e.as_deref()) |
e74abb32 XL |
1560 | } |
1561 | // Final `else` block. | |
1562 | ast::ExprKind::Block(ref b, _) => { | |
1563 | self.cbox(INDENT_UNIT - 1); | |
1564 | self.ibox(0); | |
1565 | self.s.word(" else "); | |
1566 | self.print_block(b) | |
1567 | } | |
1568 | // Constraints would be great here! | |
1569 | _ => { | |
1570 | panic!("print_if saw if with weird alternative"); | |
1a4d82fc JJ |
1571 | } |
1572 | } | |
1a4d82fc JJ |
1573 | } |
1574 | } | |
1575 | ||
dfeec247 | 1576 | crate fn print_if(&mut self, test: &ast::Expr, blk: &ast::Block, elseopt: Option<&ast::Expr>) { |
416331ca | 1577 | self.head("if"); |
dc9dc135 | 1578 | |
416331ca XL |
1579 | self.print_expr_as_cond(test); |
1580 | self.s.space(); | |
1a4d82fc | 1581 | |
416331ca | 1582 | self.print_block(blk); |
1a4d82fc JJ |
1583 | self.print_else(elseopt) |
1584 | } | |
1585 | ||
ba9703b0 | 1586 | crate fn print_mac(&mut self, m: &ast::MacCall) { |
416331ca | 1587 | self.print_mac_common( |
e1599b0c | 1588 | Some(MacHeader::Path(&m.path)), |
416331ca XL |
1589 | true, |
1590 | None, | |
60c5eb7d | 1591 | m.args.delim(), |
f035d41b | 1592 | &m.args.inner_tokens(), |
416331ca | 1593 | true, |
60c5eb7d | 1594 | m.span(), |
416331ca | 1595 | ); |
223e47cc | 1596 | } |
223e47cc | 1597 | |
416331ca XL |
1598 | fn print_call_post(&mut self, args: &[P<ast::Expr>]) { |
1599 | self.popen(); | |
1600 | self.commasep_exprs(Inconsistent, args); | |
1a4d82fc | 1601 | self.pclose() |
223e47cc LB |
1602 | } |
1603 | ||
416331ca | 1604 | crate fn print_expr_maybe_paren(&mut self, expr: &ast::Expr, prec: i8) { |
dc9dc135 | 1605 | self.print_expr_cond_paren(expr, expr.precedence().order() < prec) |
e9174d1e SL |
1606 | } |
1607 | ||
e1599b0c | 1608 | /// Prints an expr using syntax that's acceptable in a condition position, such as the `cond` in |
ea8adc8c | 1609 | /// `if cond { ... }`. |
416331ca | 1610 | crate fn print_expr_as_cond(&mut self, expr: &ast::Expr) { |
dc9dc135 XL |
1611 | self.print_expr_cond_paren(expr, Self::cond_needs_par(expr)) |
1612 | } | |
1613 | ||
1614 | /// Does `expr` need parenthesis when printed in a condition position? | |
1615 | fn cond_needs_par(expr: &ast::Expr) -> bool { | |
e74abb32 | 1616 | match expr.kind { |
ea8adc8c XL |
1617 | // These cases need parens due to the parse error observed in #26461: `if return {}` |
1618 | // parses as the erroneous construct `if (return {})`, not `if (return) {}`. | |
dfeec247 | 1619 | ast::ExprKind::Closure(..) | ast::ExprKind::Ret(..) | ast::ExprKind::Break(..) => true, |
ea8adc8c XL |
1620 | |
1621 | _ => parser::contains_exterior_struct_lit(expr), | |
dc9dc135 XL |
1622 | } |
1623 | } | |
ea8adc8c | 1624 | |
e1599b0c | 1625 | /// Prints `expr` or `(expr)` when `needs_par` holds. |
416331ca | 1626 | fn print_expr_cond_paren(&mut self, expr: &ast::Expr, needs_par: bool) { |
1a4d82fc | 1627 | if needs_par { |
416331ca | 1628 | self.popen(); |
1a4d82fc | 1629 | } |
416331ca | 1630 | self.print_expr(expr); |
1a4d82fc | 1631 | if needs_par { |
416331ca | 1632 | self.pclose(); |
1a4d82fc | 1633 | } |
223e47cc LB |
1634 | } |
1635 | ||
dfeec247 | 1636 | fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>], attrs: &[Attribute]) { |
416331ca XL |
1637 | self.ibox(INDENT_UNIT); |
1638 | self.s.word("["); | |
1639 | self.print_inner_attributes_inline(attrs); | |
1640 | self.commasep_exprs(Inconsistent, &exprs[..]); | |
1641 | self.s.word("]"); | |
1642 | self.end(); | |
85aaf69f SL |
1643 | } |
1644 | ||
dfeec247 XL |
1645 | fn print_expr_repeat( |
1646 | &mut self, | |
1647 | element: &ast::Expr, | |
1648 | count: &ast::AnonConst, | |
1649 | attrs: &[Attribute], | |
1650 | ) { | |
416331ca XL |
1651 | self.ibox(INDENT_UNIT); |
1652 | self.s.word("["); | |
1653 | self.print_inner_attributes_inline(attrs); | |
1654 | self.print_expr(element); | |
1655 | self.word_space(";"); | |
1656 | self.print_expr(&count.value); | |
1657 | self.s.word("]"); | |
1658 | self.end(); | |
85aaf69f SL |
1659 | } |
1660 | ||
dfeec247 XL |
1661 | fn print_expr_struct( |
1662 | &mut self, | |
1663 | path: &ast::Path, | |
1664 | fields: &[ast::Field], | |
1665 | wth: &Option<P<ast::Expr>>, | |
1666 | attrs: &[Attribute], | |
1667 | ) { | |
416331ca XL |
1668 | self.print_path(path, true, 0); |
1669 | self.s.word("{"); | |
1670 | self.print_inner_attributes_inline(attrs); | |
32a655c1 | 1671 | self.commasep_cmnt( |
b039eaaf SL |
1672 | Consistent, |
1673 | &fields[..], | |
1674 | |s, field| { | |
74b04a01 | 1675 | s.print_outer_attributes(&field.attrs); |
416331ca | 1676 | s.ibox(INDENT_UNIT); |
c30ab7b3 | 1677 | if !field.is_shorthand { |
416331ca XL |
1678 | s.print_ident(field.ident); |
1679 | s.word_space(":"); | |
c30ab7b3 | 1680 | } |
416331ca XL |
1681 | s.print_expr(&field.expr); |
1682 | s.end(); | |
b039eaaf | 1683 | }, |
dfeec247 XL |
1684 | |f| f.span, |
1685 | ); | |
b039eaaf SL |
1686 | match *wth { |
1687 | Some(ref expr) => { | |
416331ca | 1688 | self.ibox(INDENT_UNIT); |
b039eaaf | 1689 | if !fields.is_empty() { |
416331ca XL |
1690 | self.s.word(","); |
1691 | self.s.space(); | |
85aaf69f | 1692 | } |
416331ca XL |
1693 | self.s.word(".."); |
1694 | self.print_expr(expr); | |
1695 | self.end(); | |
b039eaaf | 1696 | } |
dfeec247 XL |
1697 | _ => { |
1698 | if !fields.is_empty() { | |
1699 | self.s.word(",") | |
1700 | } | |
85aaf69f | 1701 | } |
85aaf69f | 1702 | } |
416331ca | 1703 | self.s.word("}"); |
85aaf69f SL |
1704 | } |
1705 | ||
dfeec247 | 1706 | fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>], attrs: &[Attribute]) { |
416331ca XL |
1707 | self.popen(); |
1708 | self.print_inner_attributes_inline(attrs); | |
1709 | self.commasep_exprs(Inconsistent, &exprs[..]); | |
85aaf69f | 1710 | if exprs.len() == 1 { |
416331ca | 1711 | self.s.word(","); |
85aaf69f SL |
1712 | } |
1713 | self.pclose() | |
1714 | } | |
1715 | ||
dfeec247 XL |
1716 | fn print_expr_call(&mut self, func: &ast::Expr, args: &[P<ast::Expr>]) { |
1717 | let prec = match func.kind { | |
1718 | ast::ExprKind::Field(..) => parser::PREC_FORCE_PAREN, | |
1719 | _ => parser::PREC_POSTFIX, | |
1720 | }; | |
ea8adc8c | 1721 | |
416331ca | 1722 | self.print_expr_maybe_paren(func, prec); |
85aaf69f SL |
1723 | self.print_call_post(args) |
1724 | } | |
1725 | ||
dfeec247 | 1726 | fn print_expr_method_call(&mut self, segment: &ast::PathSegment, args: &[P<ast::Expr>]) { |
85aaf69f | 1727 | let base_args = &args[1..]; |
416331ca XL |
1728 | self.print_expr_maybe_paren(&args[0], parser::PREC_POSTFIX); |
1729 | self.s.word("."); | |
1730 | self.print_ident(segment.ident); | |
8faf50e0 | 1731 | if let Some(ref args) = segment.args { |
416331ca | 1732 | self.print_generic_args(args, true); |
85aaf69f SL |
1733 | } |
1734 | self.print_call_post(base_args) | |
1735 | } | |
1736 | ||
dfeec247 | 1737 | fn print_expr_binary(&mut self, op: ast::BinOp, lhs: &ast::Expr, rhs: &ast::Expr) { |
ea8adc8c XL |
1738 | let assoc_op = AssocOp::from_ast_binop(op.node); |
1739 | let prec = assoc_op.precedence() as i8; | |
1740 | let fixity = assoc_op.fixity(); | |
1741 | ||
1742 | let (left_prec, right_prec) = match fixity { | |
1743 | Fixity::Left => (prec, prec + 1), | |
1744 | Fixity::Right => (prec + 1, prec), | |
1745 | Fixity::None => (prec + 1, prec + 1), | |
1746 | }; | |
1747 | ||
e74abb32 | 1748 | let left_prec = match (&lhs.kind, op.node) { |
abe05a73 XL |
1749 | // These cases need parens: `x as i32 < y` has the parser thinking that `i32 < y` is |
1750 | // the beginning of a path type. It starts trying to parse `x as (i32 < y ...` instead | |
1751 | // of `(x as i32) < ...`. We need to convince it _not_ to do that. | |
ba9703b0 XL |
1752 | (&ast::ExprKind::Cast { .. }, ast::BinOpKind::Lt | ast::BinOpKind::Shl) => { |
1753 | parser::PREC_FORCE_PAREN | |
1754 | } | |
dc9dc135 XL |
1755 | // We are given `(let _ = a) OP b`. |
1756 | // | |
1757 | // - When `OP <= LAnd` we should print `let _ = a OP b` to avoid redundant parens | |
1758 | // as the parser will interpret this as `(let _ = a) OP b`. | |
1759 | // | |
1760 | // - Otherwise, e.g. when we have `(let a = b) < c` in AST, | |
1761 | // parens are required since the parser would interpret `let a = b < c` as | |
1762 | // `let a = (b < c)`. To achieve this, we force parens. | |
1763 | (&ast::ExprKind::Let { .. }, _) if !parser::needs_par_as_let_scrutinee(prec) => { | |
1764 | parser::PREC_FORCE_PAREN | |
1765 | } | |
abe05a73 XL |
1766 | _ => left_prec, |
1767 | }; | |
1768 | ||
416331ca XL |
1769 | self.print_expr_maybe_paren(lhs, left_prec); |
1770 | self.s.space(); | |
1771 | self.word_space(op.node.to_string()); | |
ea8adc8c | 1772 | self.print_expr_maybe_paren(rhs, right_prec) |
85aaf69f SL |
1773 | } |
1774 | ||
dfeec247 | 1775 | fn print_expr_unary(&mut self, op: ast::UnOp, expr: &ast::Expr) { |
416331ca | 1776 | self.s.word(ast::UnOp::to_string(op)); |
ea8adc8c | 1777 | self.print_expr_maybe_paren(expr, parser::PREC_PREFIX) |
85aaf69f SL |
1778 | } |
1779 | ||
dfeec247 XL |
1780 | fn print_expr_addr_of( |
1781 | &mut self, | |
1782 | kind: ast::BorrowKind, | |
1783 | mutability: ast::Mutability, | |
1784 | expr: &ast::Expr, | |
1785 | ) { | |
416331ca | 1786 | self.s.word("&"); |
60c5eb7d XL |
1787 | match kind { |
1788 | ast::BorrowKind::Ref => self.print_mutability(mutability, false), | |
1789 | ast::BorrowKind::Raw => { | |
1790 | self.word_nbsp("raw"); | |
1791 | self.print_mutability(mutability, true); | |
1792 | } | |
1793 | } | |
ea8adc8c | 1794 | self.print_expr_maybe_paren(expr, parser::PREC_PREFIX) |
85aaf69f SL |
1795 | } |
1796 | ||
60c5eb7d | 1797 | pub fn print_expr(&mut self, expr: &ast::Expr) { |
92a42be0 SL |
1798 | self.print_expr_outer_attr_style(expr, true) |
1799 | } | |
1800 | ||
dfeec247 | 1801 | fn print_expr_outer_attr_style(&mut self, expr: &ast::Expr, is_inline: bool) { |
416331ca | 1802 | self.maybe_print_comment(expr.span.lo()); |
92a42be0 | 1803 | |
3157f602 | 1804 | let attrs = &expr.attrs; |
92a42be0 | 1805 | if is_inline { |
416331ca | 1806 | self.print_outer_attributes_inline(attrs); |
92a42be0 | 1807 | } else { |
416331ca | 1808 | self.print_outer_attributes(attrs); |
92a42be0 SL |
1809 | } |
1810 | ||
416331ca XL |
1811 | self.ibox(INDENT_UNIT); |
1812 | self.ann.pre(self, AnnNode::Expr(expr)); | |
e74abb32 | 1813 | match expr.kind { |
7453a54e | 1814 | ast::ExprKind::Box(ref expr) => { |
416331ca XL |
1815 | self.word_space("box"); |
1816 | self.print_expr_maybe_paren(expr, parser::PREC_PREFIX); | |
b039eaaf | 1817 | } |
32a655c1 | 1818 | ast::ExprKind::Array(ref exprs) => { |
416331ca | 1819 | self.print_expr_vec(&exprs[..], attrs); |
1a4d82fc | 1820 | } |
7453a54e | 1821 | ast::ExprKind::Repeat(ref element, ref count) => { |
416331ca | 1822 | self.print_expr_repeat(element, count, attrs); |
1a4d82fc | 1823 | } |
7453a54e | 1824 | ast::ExprKind::Struct(ref path, ref fields, ref wth) => { |
416331ca | 1825 | self.print_expr_struct(path, &fields[..], wth, attrs); |
1a4d82fc | 1826 | } |
7453a54e | 1827 | ast::ExprKind::Tup(ref exprs) => { |
416331ca | 1828 | self.print_expr_tup(&exprs[..], attrs); |
1a4d82fc | 1829 | } |
7453a54e | 1830 | ast::ExprKind::Call(ref func, ref args) => { |
416331ca | 1831 | self.print_expr_call(func, &args[..]); |
1a4d82fc | 1832 | } |
f035d41b | 1833 | ast::ExprKind::MethodCall(ref segment, ref args, _) => { |
416331ca | 1834 | self.print_expr_method_call(segment, &args[..]); |
1a4d82fc | 1835 | } |
7453a54e | 1836 | ast::ExprKind::Binary(op, ref lhs, ref rhs) => { |
416331ca | 1837 | self.print_expr_binary(op, lhs, rhs); |
1a4d82fc | 1838 | } |
7453a54e | 1839 | ast::ExprKind::Unary(op, ref expr) => { |
416331ca | 1840 | self.print_expr_unary(op, expr); |
1a4d82fc | 1841 | } |
60c5eb7d XL |
1842 | ast::ExprKind::AddrOf(k, m, ref expr) => { |
1843 | self.print_expr_addr_of(k, m, expr); | |
85aaf69f | 1844 | } |
7453a54e | 1845 | ast::ExprKind::Lit(ref lit) => { |
416331ca | 1846 | self.print_literal(lit); |
1a4d82fc | 1847 | } |
7453a54e | 1848 | ast::ExprKind::Cast(ref expr, ref ty) => { |
ea8adc8c | 1849 | let prec = AssocOp::As.precedence() as i8; |
416331ca XL |
1850 | self.print_expr_maybe_paren(expr, prec); |
1851 | self.s.space(); | |
1852 | self.word_space("as"); | |
1853 | self.print_type(ty); | |
1a4d82fc | 1854 | } |
7453a54e | 1855 | ast::ExprKind::Type(ref expr, ref ty) => { |
ea8adc8c | 1856 | let prec = AssocOp::Colon.precedence() as i8; |
416331ca XL |
1857 | self.print_expr_maybe_paren(expr, prec); |
1858 | self.word_space(":"); | |
1859 | self.print_type(ty); | |
9cc50fc6 | 1860 | } |
e1599b0c XL |
1861 | ast::ExprKind::Let(ref pat, ref scrutinee) => { |
1862 | self.print_let(pat, scrutinee); | |
dc9dc135 | 1863 | } |
7453a54e | 1864 | ast::ExprKind::If(ref test, ref blk, ref elseopt) => { |
dfeec247 | 1865 | self.print_if(test, blk, elseopt.as_deref()) |
1a4d82fc | 1866 | } |
2c00a5a8 XL |
1867 | ast::ExprKind::While(ref test, ref blk, opt_label) => { |
1868 | if let Some(label) = opt_label { | |
416331ca XL |
1869 | self.print_ident(label.ident); |
1870 | self.word_space(":"); | |
1a4d82fc | 1871 | } |
416331ca XL |
1872 | self.head("while"); |
1873 | self.print_expr_as_cond(test); | |
1874 | self.s.space(); | |
1875 | self.print_block_with_attrs(blk, attrs); | |
1a4d82fc | 1876 | } |
2c00a5a8 XL |
1877 | ast::ExprKind::ForLoop(ref pat, ref iter, ref blk, opt_label) => { |
1878 | if let Some(label) = opt_label { | |
416331ca XL |
1879 | self.print_ident(label.ident); |
1880 | self.word_space(":"); | |
1a4d82fc | 1881 | } |
416331ca XL |
1882 | self.head("for"); |
1883 | self.print_pat(pat); | |
1884 | self.s.space(); | |
1885 | self.word_space("in"); | |
1886 | self.print_expr_as_cond(iter); | |
1887 | self.s.space(); | |
1888 | self.print_block_with_attrs(blk, attrs); | |
1a4d82fc | 1889 | } |
2c00a5a8 XL |
1890 | ast::ExprKind::Loop(ref blk, opt_label) => { |
1891 | if let Some(label) = opt_label { | |
416331ca XL |
1892 | self.print_ident(label.ident); |
1893 | self.word_space(":"); | |
1a4d82fc | 1894 | } |
416331ca XL |
1895 | self.head("loop"); |
1896 | self.s.space(); | |
1897 | self.print_block_with_attrs(blk, attrs); | |
1a4d82fc | 1898 | } |
7453a54e | 1899 | ast::ExprKind::Match(ref expr, ref arms) => { |
416331ca XL |
1900 | self.cbox(INDENT_UNIT); |
1901 | self.ibox(INDENT_UNIT); | |
1902 | self.word_nbsp("match"); | |
1903 | self.print_expr_as_cond(expr); | |
1904 | self.s.space(); | |
1905 | self.bopen(); | |
1906 | self.print_inner_attributes_no_trailing_hardbreak(attrs); | |
85aaf69f | 1907 | for arm in arms { |
416331ca | 1908 | self.print_arm(arm); |
1a4d82fc | 1909 | } |
416331ca | 1910 | self.bclose(expr.span); |
1a4d82fc | 1911 | } |
8faf50e0 | 1912 | ast::ExprKind::Closure( |
dfeec247 XL |
1913 | capture_clause, |
1914 | asyncness, | |
1915 | movability, | |
1916 | ref decl, | |
1917 | ref body, | |
1918 | _, | |
1919 | ) => { | |
416331ca XL |
1920 | self.print_movability(movability); |
1921 | self.print_asyncness(asyncness); | |
1922 | self.print_capture_clause(capture_clause); | |
1a4d82fc | 1923 | |
dfeec247 | 1924 | self.print_fn_params_and_ret(decl, true); |
416331ca XL |
1925 | self.s.space(); |
1926 | self.print_expr(body); | |
1927 | self.end(); // need to close a box | |
3157f602 | 1928 | |
1a4d82fc JJ |
1929 | // a box will be closed by print_expr, but we didn't want an overall |
1930 | // wrapper so we closed the corresponding opening. so create an | |
1931 | // empty box to satisfy the close. | |
416331ca | 1932 | self.ibox(0); |
1a4d82fc | 1933 | } |
94b46f34 XL |
1934 | ast::ExprKind::Block(ref blk, opt_label) => { |
1935 | if let Some(label) = opt_label { | |
416331ca XL |
1936 | self.print_ident(label.ident); |
1937 | self.word_space(":"); | |
94b46f34 | 1938 | } |
1a4d82fc | 1939 | // containing cbox, will be closed by print-block at } |
416331ca | 1940 | self.cbox(INDENT_UNIT); |
1a4d82fc | 1941 | // head-box, will be closed by print-block after { |
416331ca XL |
1942 | self.ibox(0); |
1943 | self.print_block_with_attrs(blk, attrs); | |
1a4d82fc | 1944 | } |
8faf50e0 | 1945 | ast::ExprKind::Async(capture_clause, _, ref blk) => { |
416331ca XL |
1946 | self.word_nbsp("async"); |
1947 | self.print_capture_clause(capture_clause); | |
1948 | self.s.space(); | |
0bf4aa26 | 1949 | // cbox/ibox in analogy to the `ExprKind::Block` arm above |
416331ca XL |
1950 | self.cbox(INDENT_UNIT); |
1951 | self.ibox(0); | |
1952 | self.print_block_with_attrs(blk, attrs); | |
1953 | } | |
1954 | ast::ExprKind::Await(ref expr) => { | |
1955 | self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); | |
1956 | self.s.word(".await"); | |
48663c56 | 1957 | } |
dfeec247 | 1958 | ast::ExprKind::Assign(ref lhs, ref rhs, _) => { |
ea8adc8c | 1959 | let prec = AssocOp::Assign.precedence() as i8; |
416331ca XL |
1960 | self.print_expr_maybe_paren(lhs, prec + 1); |
1961 | self.s.space(); | |
1962 | self.word_space("="); | |
1963 | self.print_expr_maybe_paren(rhs, prec); | |
1a4d82fc | 1964 | } |
7453a54e | 1965 | ast::ExprKind::AssignOp(op, ref lhs, ref rhs) => { |
ea8adc8c | 1966 | let prec = AssocOp::Assign.precedence() as i8; |
416331ca XL |
1967 | self.print_expr_maybe_paren(lhs, prec + 1); |
1968 | self.s.space(); | |
1969 | self.s.word(op.node.to_string()); | |
1970 | self.word_space("="); | |
1971 | self.print_expr_maybe_paren(rhs, prec); | |
1a4d82fc | 1972 | } |
83c7162d | 1973 | ast::ExprKind::Field(ref expr, ident) => { |
416331ca XL |
1974 | self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); |
1975 | self.s.word("."); | |
1976 | self.print_ident(ident); | |
1a4d82fc | 1977 | } |
7453a54e | 1978 | ast::ExprKind::Index(ref expr, ref index) => { |
416331ca XL |
1979 | self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); |
1980 | self.s.word("["); | |
1981 | self.print_expr(index); | |
1982 | self.s.word("]"); | |
1a4d82fc | 1983 | } |
54a0048b | 1984 | ast::ExprKind::Range(ref start, ref end, limits) => { |
ea8adc8c XL |
1985 | // Special case for `Range`. `AssocOp` claims that `Range` has higher precedence |
1986 | // than `Assign`, but `x .. x = x` gives a parse error instead of `x .. (x = x)`. | |
1987 | // Here we use a fake precedence value so that any child with lower precedence than | |
1988 | // a "normal" binop gets parenthesized. (`LOr` is the lowest-precedence binop.) | |
1989 | let fake_prec = AssocOp::LOr.precedence() as i8; | |
7cac9316 | 1990 | if let Some(ref e) = *start { |
416331ca | 1991 | self.print_expr_maybe_paren(e, fake_prec); |
54a0048b SL |
1992 | } |
1993 | if limits == ast::RangeLimits::HalfOpen { | |
416331ca | 1994 | self.s.word(".."); |
54a0048b | 1995 | } else { |
416331ca | 1996 | self.s.word("..="); |
1a4d82fc | 1997 | } |
7cac9316 | 1998 | if let Some(ref e) = *end { |
416331ca | 1999 | self.print_expr_maybe_paren(e, fake_prec); |
1a4d82fc JJ |
2000 | } |
2001 | } | |
dfeec247 XL |
2002 | ast::ExprKind::Path(None, ref path) => self.print_path(path, true, 0), |
2003 | ast::ExprKind::Path(Some(ref qself), ref path) => self.print_qpath(path, qself, true), | |
2c00a5a8 | 2004 | ast::ExprKind::Break(opt_label, ref opt_expr) => { |
416331ca XL |
2005 | self.s.word("break"); |
2006 | self.s.space(); | |
2c00a5a8 | 2007 | if let Some(label) = opt_label { |
416331ca XL |
2008 | self.print_ident(label.ident); |
2009 | self.s.space(); | |
1a4d82fc | 2010 | } |
476ff2be | 2011 | if let Some(ref expr) = *opt_expr { |
416331ca XL |
2012 | self.print_expr_maybe_paren(expr, parser::PREC_JUMP); |
2013 | self.s.space(); | |
476ff2be | 2014 | } |
1a4d82fc | 2015 | } |
2c00a5a8 | 2016 | ast::ExprKind::Continue(opt_label) => { |
416331ca XL |
2017 | self.s.word("continue"); |
2018 | self.s.space(); | |
2c00a5a8 | 2019 | if let Some(label) = opt_label { |
416331ca XL |
2020 | self.print_ident(label.ident); |
2021 | self.s.space() | |
1a4d82fc JJ |
2022 | } |
2023 | } | |
7453a54e | 2024 | ast::ExprKind::Ret(ref result) => { |
416331ca | 2025 | self.s.word("return"); |
7cac9316 | 2026 | if let Some(ref expr) = *result { |
416331ca XL |
2027 | self.s.word(" "); |
2028 | self.print_expr_maybe_paren(expr, parser::PREC_JUMP); | |
1a4d82fc JJ |
2029 | } |
2030 | } | |
f9f354fc XL |
2031 | ast::ExprKind::InlineAsm(ref a) => { |
2032 | enum AsmArg<'a> { | |
2033 | Template(String), | |
2034 | Operand(&'a InlineAsmOperand), | |
2035 | Options(InlineAsmOptions), | |
2036 | } | |
2037 | ||
2038 | let mut args = vec![]; | |
2039 | args.push(AsmArg::Template(InlineAsmTemplatePiece::to_string(&a.template))); | |
2040 | args.extend(a.operands.iter().map(|(o, _)| AsmArg::Operand(o))); | |
2041 | if !a.options.is_empty() { | |
2042 | args.push(AsmArg::Options(a.options)); | |
2043 | } | |
2044 | ||
2045 | self.word("asm!"); | |
2046 | self.popen(); | |
2047 | self.commasep(Consistent, &args, |s, arg| match arg { | |
2048 | AsmArg::Template(template) => s.print_string(&template, ast::StrStyle::Cooked), | |
2049 | AsmArg::Operand(op) => { | |
2050 | let print_reg_or_class = |s: &mut Self, r: &InlineAsmRegOrRegClass| match r | |
2051 | { | |
2052 | InlineAsmRegOrRegClass::Reg(r) => { | |
2053 | s.print_string(&r.as_str(), ast::StrStyle::Cooked) | |
2054 | } | |
2055 | InlineAsmRegOrRegClass::RegClass(r) => s.word(r.to_string()), | |
2056 | }; | |
2057 | match op { | |
2058 | InlineAsmOperand::In { reg, expr } => { | |
2059 | s.word("in"); | |
2060 | s.popen(); | |
2061 | print_reg_or_class(s, reg); | |
2062 | s.pclose(); | |
2063 | s.space(); | |
2064 | s.print_expr(expr); | |
2065 | } | |
2066 | InlineAsmOperand::Out { reg, late, expr } => { | |
2067 | s.word(if *late { "lateout" } else { "out" }); | |
2068 | s.popen(); | |
2069 | print_reg_or_class(s, reg); | |
2070 | s.pclose(); | |
2071 | s.space(); | |
2072 | match expr { | |
2073 | Some(expr) => s.print_expr(expr), | |
2074 | None => s.word("_"), | |
2075 | } | |
2076 | } | |
2077 | InlineAsmOperand::InOut { reg, late, expr } => { | |
2078 | s.word(if *late { "inlateout" } else { "inout" }); | |
2079 | s.popen(); | |
2080 | print_reg_or_class(s, reg); | |
2081 | s.pclose(); | |
2082 | s.space(); | |
2083 | s.print_expr(expr); | |
2084 | } | |
2085 | InlineAsmOperand::SplitInOut { reg, late, in_expr, out_expr } => { | |
2086 | s.word(if *late { "inlateout" } else { "inout" }); | |
2087 | s.popen(); | |
2088 | print_reg_or_class(s, reg); | |
2089 | s.pclose(); | |
2090 | s.space(); | |
2091 | s.print_expr(in_expr); | |
2092 | s.space(); | |
2093 | s.word_space("=>"); | |
2094 | match out_expr { | |
2095 | Some(out_expr) => s.print_expr(out_expr), | |
2096 | None => s.word("_"), | |
2097 | } | |
2098 | } | |
2099 | InlineAsmOperand::Const { expr } => { | |
2100 | s.word("const"); | |
2101 | s.space(); | |
2102 | s.print_expr(expr); | |
2103 | } | |
2104 | InlineAsmOperand::Sym { expr } => { | |
2105 | s.word("sym"); | |
2106 | s.space(); | |
2107 | s.print_expr(expr); | |
2108 | } | |
2109 | } | |
2110 | } | |
2111 | AsmArg::Options(opts) => { | |
2112 | s.word("options"); | |
2113 | s.popen(); | |
2114 | let mut options = vec![]; | |
2115 | if opts.contains(InlineAsmOptions::PURE) { | |
2116 | options.push("pure"); | |
2117 | } | |
2118 | if opts.contains(InlineAsmOptions::NOMEM) { | |
2119 | options.push("nomem"); | |
2120 | } | |
2121 | if opts.contains(InlineAsmOptions::READONLY) { | |
2122 | options.push("readonly"); | |
2123 | } | |
2124 | if opts.contains(InlineAsmOptions::PRESERVES_FLAGS) { | |
2125 | options.push("preserves_flags"); | |
2126 | } | |
2127 | if opts.contains(InlineAsmOptions::NORETURN) { | |
2128 | options.push("noreturn"); | |
2129 | } | |
2130 | if opts.contains(InlineAsmOptions::NOSTACK) { | |
2131 | options.push("nostack"); | |
2132 | } | |
2133 | if opts.contains(InlineAsmOptions::ATT_SYNTAX) { | |
2134 | options.push("att_syntax"); | |
2135 | } | |
2136 | s.commasep(Inconsistent, &options, |s, &opt| { | |
2137 | s.word(opt); | |
2138 | }); | |
2139 | s.pclose(); | |
2140 | } | |
2141 | }); | |
2142 | self.pclose(); | |
2143 | } | |
ba9703b0 XL |
2144 | ast::ExprKind::LlvmInlineAsm(ref a) => { |
2145 | self.s.word("llvm_asm!"); | |
416331ca XL |
2146 | self.popen(); |
2147 | self.print_string(&a.asm.as_str(), a.asm_str_style); | |
2148 | self.word_space(":"); | |
1a4d82fc | 2149 | |
32a655c1 | 2150 | self.commasep(Inconsistent, &a.outputs, |s, out| { |
476ff2be SL |
2151 | let constraint = out.constraint.as_str(); |
2152 | let mut ch = constraint.chars(); | |
54a0048b SL |
2153 | match ch.next() { |
2154 | Some('=') if out.is_rw => { | |
dfeec247 | 2155 | s.print_string(&format!("+{}", ch.as_str()), ast::StrStyle::Cooked) |
1a4d82fc | 2156 | } |
dfeec247 | 2157 | _ => s.print_string(&constraint, ast::StrStyle::Cooked), |
1a4d82fc | 2158 | } |
416331ca XL |
2159 | s.popen(); |
2160 | s.print_expr(&out.expr); | |
2161 | s.pclose(); | |
2162 | }); | |
2163 | self.s.space(); | |
2164 | self.word_space(":"); | |
32a655c1 SL |
2165 | |
2166 | self.commasep(Inconsistent, &a.inputs, |s, &(co, ref o)| { | |
416331ca XL |
2167 | s.print_string(&co.as_str(), ast::StrStyle::Cooked); |
2168 | s.popen(); | |
2169 | s.print_expr(o); | |
2170 | s.pclose(); | |
2171 | }); | |
2172 | self.s.space(); | |
2173 | self.word_space(":"); | |
1a4d82fc | 2174 | |
dfeec247 | 2175 | self.commasep(Inconsistent, &a.clobbers, |s, co| { |
416331ca XL |
2176 | s.print_string(&co.as_str(), ast::StrStyle::Cooked); |
2177 | }); | |
1a4d82fc | 2178 | |
c30ab7b3 | 2179 | let mut options = vec![]; |
1a4d82fc JJ |
2180 | if a.volatile { |
2181 | options.push("volatile"); | |
2182 | } | |
2183 | if a.alignstack { | |
2184 | options.push("alignstack"); | |
2185 | } | |
ba9703b0 | 2186 | if a.dialect == ast::LlvmAsmDialect::Intel { |
1a4d82fc JJ |
2187 | options.push("intel"); |
2188 | } | |
223e47cc | 2189 | |
9346a6ac | 2190 | if !options.is_empty() { |
416331ca XL |
2191 | self.s.space(); |
2192 | self.word_space(":"); | |
dfeec247 XL |
2193 | self.commasep(Inconsistent, &options, |s, &co| { |
2194 | s.print_string(co, ast::StrStyle::Cooked); | |
2195 | }); | |
1a4d82fc | 2196 | } |
223e47cc | 2197 | |
416331ca | 2198 | self.pclose(); |
1a4d82fc | 2199 | } |
ba9703b0 | 2200 | ast::ExprKind::MacCall(ref m) => self.print_mac(m), |
7453a54e | 2201 | ast::ExprKind::Paren(ref e) => { |
416331ca XL |
2202 | self.popen(); |
2203 | self.print_inner_attributes_inline(attrs); | |
2204 | self.print_expr(e); | |
2205 | self.pclose(); | |
dfeec247 | 2206 | } |
ea8adc8c | 2207 | ast::ExprKind::Yield(ref e) => { |
416331ca | 2208 | self.s.word("yield"); |
ba9703b0 XL |
2209 | |
2210 | if let Some(ref expr) = *e { | |
2211 | self.s.space(); | |
2212 | self.print_expr_maybe_paren(expr, parser::PREC_JUMP); | |
ea8adc8c XL |
2213 | } |
2214 | } | |
54a0048b | 2215 | ast::ExprKind::Try(ref e) => { |
416331ca XL |
2216 | self.print_expr_maybe_paren(e, parser::PREC_POSTFIX); |
2217 | self.s.word("?") | |
1a4d82fc | 2218 | } |
b7449926 | 2219 | ast::ExprKind::TryBlock(ref blk) => { |
416331ca XL |
2220 | self.head("try"); |
2221 | self.s.space(); | |
2222 | self.print_block_with_attrs(blk, attrs) | |
cc61c64b | 2223 | } |
0731742a | 2224 | ast::ExprKind::Err => { |
416331ca XL |
2225 | self.popen(); |
2226 | self.s.word("/*ERROR*/"); | |
2227 | self.pclose() | |
0731742a | 2228 | } |
223e47cc | 2229 | } |
416331ca XL |
2230 | self.ann.post(self, AnnNode::Expr(expr)); |
2231 | self.end(); | |
1a4d82fc JJ |
2232 | } |
2233 | ||
416331ca XL |
2234 | crate fn print_local_decl(&mut self, loc: &ast::Local) { |
2235 | self.print_pat(&loc.pat); | |
1a4d82fc | 2236 | if let Some(ref ty) = loc.ty { |
416331ca XL |
2237 | self.word_space(":"); |
2238 | self.print_type(ty); | |
1a4d82fc | 2239 | } |
223e47cc | 2240 | } |
223e47cc | 2241 | |
60c5eb7d | 2242 | pub fn print_usize(&mut self, i: usize) { |
a1dfa0c6 | 2243 | self.s.word(i.to_string()) |
1a4d82fc JJ |
2244 | } |
2245 | ||
f9f354fc | 2246 | crate fn print_name(&mut self, name: Symbol) { |
60c5eb7d | 2247 | self.s.word(name.to_string()); |
b7449926 | 2248 | self.ann.post(self, AnnNode::Name(&name)) |
1a4d82fc JJ |
2249 | } |
2250 | ||
dfeec247 | 2251 | fn print_qpath(&mut self, path: &ast::Path, qself: &ast::QSelf, colons_before_params: bool) { |
416331ca XL |
2252 | self.s.word("<"); |
2253 | self.print_type(&qself.ty); | |
c34b1796 | 2254 | if qself.position > 0 { |
416331ca XL |
2255 | self.s.space(); |
2256 | self.word_space("as"); | |
c34b1796 | 2257 | let depth = path.segments.len() - qself.position; |
416331ca | 2258 | self.print_path(path, false, depth); |
c34b1796 | 2259 | } |
416331ca XL |
2260 | self.s.word(">"); |
2261 | self.s.word("::"); | |
c34b1796 | 2262 | let item_segment = path.segments.last().unwrap(); |
416331ca | 2263 | self.print_ident(item_segment.ident); |
ba9703b0 XL |
2264 | if let Some(ref args) = item_segment.args { |
2265 | self.print_generic_args(args, colons_before_params) | |
32a655c1 | 2266 | } |
85aaf69f SL |
2267 | } |
2268 | ||
416331ca XL |
2269 | crate fn print_pat(&mut self, pat: &ast::Pat) { |
2270 | self.maybe_print_comment(pat.span.lo()); | |
2271 | self.ann.pre(self, AnnNode::Pat(pat)); | |
1a4d82fc | 2272 | /* Pat isn't normalized, but the beauty of it |
dfeec247 | 2273 | is that it doesn't matter */ |
e74abb32 | 2274 | match pat.kind { |
416331ca | 2275 | PatKind::Wild => self.s.word("_"), |
83c7162d | 2276 | PatKind::Ident(binding_mode, ident, ref sub) => { |
1a4d82fc | 2277 | match binding_mode { |
9cc50fc6 | 2278 | ast::BindingMode::ByRef(mutbl) => { |
416331ca | 2279 | self.word_nbsp("ref"); |
60c5eb7d | 2280 | self.print_mutability(mutbl, false); |
1a4d82fc | 2281 | } |
dfeec247 XL |
2282 | ast::BindingMode::ByValue(ast::Mutability::Not) => {} |
2283 | ast::BindingMode::ByValue(ast::Mutability::Mut) => { | |
416331ca | 2284 | self.word_nbsp("mut"); |
1a4d82fc JJ |
2285 | } |
2286 | } | |
416331ca | 2287 | self.print_ident(ident); |
3157f602 | 2288 | if let Some(ref p) = *sub { |
e74abb32 XL |
2289 | self.s.space(); |
2290 | self.s.word_space("@"); | |
416331ca | 2291 | self.print_pat(p); |
3157f602 XL |
2292 | } |
2293 | } | |
416331ca XL |
2294 | PatKind::TupleStruct(ref path, ref elts) => { |
2295 | self.print_path(path, true, 0); | |
2296 | self.popen(); | |
2297 | self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p)); | |
2298 | self.pclose(); | |
1a4d82fc | 2299 | } |
e1599b0c XL |
2300 | PatKind::Or(ref pats) => { |
2301 | self.strsep("|", true, Inconsistent, &pats[..], |s, p| s.print_pat(p)); | |
2302 | } | |
3157f602 | 2303 | PatKind::Path(None, ref path) => { |
416331ca | 2304 | self.print_path(path, true, 0); |
7453a54e | 2305 | } |
3157f602 | 2306 | PatKind::Path(Some(ref qself), ref path) => { |
416331ca | 2307 | self.print_qpath(path, qself, false); |
d9579d0f | 2308 | } |
7453a54e | 2309 | PatKind::Struct(ref path, ref fields, etc) => { |
416331ca XL |
2310 | self.print_path(path, true, 0); |
2311 | self.nbsp(); | |
2312 | self.word_space("{"); | |
32a655c1 | 2313 | self.commasep_cmnt( |
dfeec247 XL |
2314 | Consistent, |
2315 | &fields[..], | |
1a4d82fc | 2316 | |s, f| { |
416331ca | 2317 | s.cbox(INDENT_UNIT); |
e1599b0c XL |
2318 | if !f.is_shorthand { |
2319 | s.print_ident(f.ident); | |
416331ca | 2320 | s.word_nbsp(":"); |
1a4d82fc | 2321 | } |
e1599b0c | 2322 | s.print_pat(&f.pat); |
416331ca | 2323 | s.end(); |
1a4d82fc | 2324 | }, |
dfeec247 XL |
2325 | |f| f.pat.span, |
2326 | ); | |
1a4d82fc | 2327 | if etc { |
dfeec247 XL |
2328 | if !fields.is_empty() { |
2329 | self.word_space(","); | |
2330 | } | |
416331ca XL |
2331 | self.s.word(".."); |
2332 | } | |
2333 | self.s.space(); | |
2334 | self.s.word("}"); | |
2335 | } | |
2336 | PatKind::Tuple(ref elts) => { | |
2337 | self.popen(); | |
2338 | self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p)); | |
2339 | if elts.len() == 1 { | |
2340 | self.s.word(","); | |
1a4d82fc | 2341 | } |
416331ca | 2342 | self.pclose(); |
1a4d82fc | 2343 | } |
7453a54e | 2344 | PatKind::Box(ref inner) => { |
416331ca XL |
2345 | self.s.word("box "); |
2346 | self.print_pat(inner); | |
1a4d82fc | 2347 | } |
7453a54e | 2348 | PatKind::Ref(ref inner, mutbl) => { |
416331ca | 2349 | self.s.word("&"); |
dfeec247 | 2350 | if mutbl == ast::Mutability::Mut { |
416331ca | 2351 | self.s.word("mut "); |
1a4d82fc | 2352 | } |
416331ca | 2353 | self.print_pat(inner); |
1a4d82fc | 2354 | } |
416331ca | 2355 | PatKind::Lit(ref e) => self.print_expr(&**e), |
8faf50e0 | 2356 | PatKind::Range(ref begin, ref end, Spanned { node: ref end_kind, .. }) => { |
dfeec247 XL |
2357 | if let Some(e) = begin { |
2358 | self.print_expr(e); | |
2359 | self.s.space(); | |
2360 | } | |
32a655c1 | 2361 | match *end_kind { |
416331ca XL |
2362 | RangeEnd::Included(RangeSyntax::DotDotDot) => self.s.word("..."), |
2363 | RangeEnd::Included(RangeSyntax::DotDotEq) => self.s.word("..="), | |
2364 | RangeEnd::Excluded => self.s.word(".."), | |
1a4d82fc | 2365 | } |
dfeec247 XL |
2366 | if let Some(e) = end { |
2367 | self.print_expr(e); | |
2368 | } | |
416331ca XL |
2369 | } |
2370 | PatKind::Slice(ref elts) => { | |
2371 | self.s.word("["); | |
2372 | self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p)); | |
2373 | self.s.word("]"); | |
1a4d82fc | 2374 | } |
416331ca | 2375 | PatKind::Rest => self.s.word(".."), |
0531ce1d | 2376 | PatKind::Paren(ref inner) => { |
416331ca XL |
2377 | self.popen(); |
2378 | self.print_pat(inner); | |
2379 | self.pclose(); | |
0531ce1d | 2380 | } |
ba9703b0 | 2381 | PatKind::MacCall(ref m) => self.print_mac(m), |
1a4d82fc | 2382 | } |
b7449926 | 2383 | self.ann.post(self, AnnNode::Pat(pat)) |
1a4d82fc | 2384 | } |
223e47cc | 2385 | |
416331ca | 2386 | fn print_arm(&mut self, arm: &ast::Arm) { |
e1599b0c | 2387 | // Note, I have no idea why this check is necessary, but here it is. |
1a4d82fc | 2388 | if arm.attrs.is_empty() { |
416331ca XL |
2389 | self.s.space(); |
2390 | } | |
2391 | self.cbox(INDENT_UNIT); | |
2392 | self.ibox(0); | |
e1599b0c | 2393 | self.maybe_print_comment(arm.pat.span.lo()); |
416331ca | 2394 | self.print_outer_attributes(&arm.attrs); |
e1599b0c | 2395 | self.print_pat(&arm.pat); |
416331ca | 2396 | self.s.space(); |
dc9dc135 | 2397 | if let Some(ref e) = arm.guard { |
416331ca XL |
2398 | self.word_space("if"); |
2399 | self.print_expr(e); | |
2400 | self.s.space(); | |
223e47cc | 2401 | } |
416331ca | 2402 | self.word_space("=>"); |
223e47cc | 2403 | |
e74abb32 | 2404 | match arm.body.kind { |
94b46f34 XL |
2405 | ast::ExprKind::Block(ref blk, opt_label) => { |
2406 | if let Some(label) = opt_label { | |
416331ca XL |
2407 | self.print_ident(label.ident); |
2408 | self.word_space(":"); | |
94b46f34 XL |
2409 | } |
2410 | ||
e1599b0c | 2411 | // The block will close the pattern's ibox. |
416331ca | 2412 | self.print_block_unclosed_indent(blk); |
1a4d82fc | 2413 | |
e1599b0c | 2414 | // If it is a user-provided unsafe block, print a comma after it. |
7453a54e | 2415 | if let BlockCheckMode::Unsafe(ast::UserProvided) = blk.rules { |
416331ca | 2416 | self.s.word(","); |
1a4d82fc JJ |
2417 | } |
2418 | } | |
2419 | _ => { | |
e1599b0c | 2420 | self.end(); // Close the ibox for the pattern. |
416331ca XL |
2421 | self.print_expr(&arm.body); |
2422 | self.s.word(","); | |
1a4d82fc | 2423 | } |
223e47cc | 2424 | } |
e1599b0c | 2425 | self.end(); // Close enclosing cbox. |
1a4d82fc | 2426 | } |
223e47cc | 2427 | |
416331ca | 2428 | fn print_explicit_self(&mut self, explicit_self: &ast::ExplicitSelf) { |
3157f602 XL |
2429 | match explicit_self.node { |
2430 | SelfKind::Value(m) => { | |
60c5eb7d | 2431 | self.print_mutability(m, false); |
041b39d2 | 2432 | self.s.word("self") |
1a4d82fc | 2433 | } |
3157f602 | 2434 | SelfKind::Region(ref lt, m) => { |
416331ca XL |
2435 | self.s.word("&"); |
2436 | self.print_opt_lifetime(lt); | |
60c5eb7d | 2437 | self.print_mutability(m, false); |
041b39d2 | 2438 | self.s.word("self") |
1a4d82fc | 2439 | } |
3157f602 | 2440 | SelfKind::Explicit(ref typ, m) => { |
60c5eb7d | 2441 | self.print_mutability(m, false); |
416331ca XL |
2442 | self.s.word("self"); |
2443 | self.word_space(":"); | |
7cac9316 | 2444 | self.print_type(typ) |
1a4d82fc JJ |
2445 | } |
2446 | } | |
223e47cc | 2447 | } |
223e47cc | 2448 | |
74b04a01 XL |
2449 | fn print_fn_full( |
2450 | &mut self, | |
2451 | sig: &ast::FnSig, | |
f9f354fc | 2452 | name: Ident, |
74b04a01 XL |
2453 | generics: &ast::Generics, |
2454 | vis: &ast::Visibility, | |
2455 | defaultness: ast::Defaultness, | |
2456 | body: Option<&ast::Block>, | |
2457 | attrs: &[ast::Attribute], | |
2458 | ) { | |
2459 | if body.is_some() { | |
2460 | self.head(""); | |
2461 | } | |
2462 | self.print_visibility(vis); | |
2463 | self.print_defaultness(defaultness); | |
2464 | self.print_fn(&sig.decl, sig.header, Some(name), generics); | |
2465 | if let Some(body) = body { | |
2466 | self.nbsp(); | |
2467 | self.print_block_with_attrs(body, attrs); | |
2468 | } else { | |
2469 | self.s.word(";"); | |
2470 | } | |
2471 | } | |
2472 | ||
dfeec247 XL |
2473 | crate fn print_fn( |
2474 | &mut self, | |
2475 | decl: &ast::FnDecl, | |
2476 | header: ast::FnHeader, | |
f9f354fc | 2477 | name: Option<Ident>, |
dfeec247 | 2478 | generics: &ast::Generics, |
dfeec247 | 2479 | ) { |
74b04a01 | 2480 | self.print_fn_header_info(header); |
c34b1796 | 2481 | if let Some(name) = name { |
416331ca XL |
2482 | self.nbsp(); |
2483 | self.print_ident(name); | |
c34b1796 | 2484 | } |
416331ca | 2485 | self.print_generic_params(&generics.params); |
dfeec247 | 2486 | self.print_fn_params_and_ret(decl, false); |
c34b1796 | 2487 | self.print_where_clause(&generics.where_clause) |
1a4d82fc JJ |
2488 | } |
2489 | ||
dfeec247 XL |
2490 | crate fn print_fn_params_and_ret(&mut self, decl: &ast::FnDecl, is_closure: bool) { |
2491 | let (open, close) = if is_closure { ("|", "|") } else { ("(", ")") }; | |
2492 | self.word(open); | |
2493 | self.commasep(Inconsistent, &decl.inputs, |s, param| s.print_param(param, is_closure)); | |
2494 | self.word(close); | |
2495 | self.print_fn_ret_ty(&decl.output) | |
223e47cc | 2496 | } |
223e47cc | 2497 | |
416331ca | 2498 | crate fn print_movability(&mut self, movability: ast::Movability) { |
2c00a5a8 XL |
2499 | match movability { |
2500 | ast::Movability::Static => self.word_space("static"), | |
dfeec247 | 2501 | ast::Movability::Movable => {} |
2c00a5a8 XL |
2502 | } |
2503 | } | |
2504 | ||
74b04a01 | 2505 | crate fn print_asyncness(&mut self, asyncness: ast::Async) { |
8faf50e0 | 2506 | if asyncness.is_async() { |
416331ca | 2507 | self.word_nbsp("async"); |
8faf50e0 | 2508 | } |
8faf50e0 XL |
2509 | } |
2510 | ||
416331ca | 2511 | crate fn print_capture_clause(&mut self, capture_clause: ast::CaptureBy) { |
1a4d82fc | 2512 | match capture_clause { |
7453a54e | 2513 | ast::CaptureBy::Value => self.word_space("move"), |
dfeec247 | 2514 | ast::CaptureBy::Ref => {} |
1a4d82fc | 2515 | } |
223e47cc | 2516 | } |
223e47cc | 2517 | |
60c5eb7d | 2518 | pub fn print_type_bounds(&mut self, prefix: &'static str, bounds: &[ast::GenericBound]) { |
1a4d82fc | 2519 | if !bounds.is_empty() { |
416331ca | 2520 | self.s.word(prefix); |
1a4d82fc | 2521 | let mut first = true; |
85aaf69f | 2522 | for bound in bounds { |
ff7c6d11 | 2523 | if !(first && prefix.is_empty()) { |
416331ca | 2524 | self.nbsp(); |
ff7c6d11 | 2525 | } |
1a4d82fc JJ |
2526 | if first { |
2527 | first = false; | |
2528 | } else { | |
416331ca | 2529 | self.word_space("+"); |
1a4d82fc JJ |
2530 | } |
2531 | ||
ff7c6d11 | 2532 | match bound { |
8faf50e0 | 2533 | GenericBound::Trait(tref, modifier) => { |
ff7c6d11 | 2534 | if modifier == &TraitBoundModifier::Maybe { |
416331ca | 2535 | self.s.word("?"); |
ff7c6d11 | 2536 | } |
416331ca | 2537 | self.print_poly_trait_ref(tref); |
1a4d82fc | 2538 | } |
416331ca | 2539 | GenericBound::Outlives(lt) => self.print_lifetime(*lt), |
ff7c6d11 | 2540 | } |
1a4d82fc | 2541 | } |
1a4d82fc JJ |
2542 | } |
2543 | } | |
223e47cc | 2544 | |
416331ca | 2545 | crate fn print_lifetime(&mut self, lifetime: ast::Lifetime) { |
7cac9316 | 2546 | self.print_name(lifetime.ident.name) |
223e47cc | 2547 | } |
223e47cc | 2548 | |
416331ca | 2549 | crate fn print_lifetime_bounds( |
dfeec247 XL |
2550 | &mut self, |
2551 | lifetime: ast::Lifetime, | |
2552 | bounds: &ast::GenericBounds, | |
2553 | ) { | |
416331ca | 2554 | self.print_lifetime(lifetime); |
3157f602 | 2555 | if !bounds.is_empty() { |
416331ca | 2556 | self.s.word(": "); |
3157f602 XL |
2557 | for (i, bound) in bounds.iter().enumerate() { |
2558 | if i != 0 { | |
416331ca | 2559 | self.s.word(" + "); |
3157f602 | 2560 | } |
8faf50e0 | 2561 | match bound { |
416331ca | 2562 | ast::GenericBound::Outlives(lt) => self.print_lifetime(*lt), |
8faf50e0 XL |
2563 | _ => panic!(), |
2564 | } | |
3157f602 | 2565 | } |
223e47cc LB |
2566 | } |
2567 | } | |
223e47cc | 2568 | |
416331ca | 2569 | crate fn print_generic_params(&mut self, generic_params: &[ast::GenericParam]) { |
ff7c6d11 | 2570 | if generic_params.is_empty() { |
416331ca | 2571 | return; |
1a4d82fc JJ |
2572 | } |
2573 | ||
416331ca | 2574 | self.s.word("<"); |
1a4d82fc | 2575 | |
ff7c6d11 | 2576 | self.commasep(Inconsistent, &generic_params, |s, param| { |
416331ca XL |
2577 | s.print_outer_attributes_inline(¶m.attrs); |
2578 | ||
8faf50e0 XL |
2579 | match param.kind { |
2580 | ast::GenericParamKind::Lifetime => { | |
8faf50e0 XL |
2581 | let lt = ast::Lifetime { id: param.id, ident: param.ident }; |
2582 | s.print_lifetime_bounds(lt, ¶m.bounds) | |
9fa01778 | 2583 | } |
8faf50e0 | 2584 | ast::GenericParamKind::Type { ref default } => { |
416331ca XL |
2585 | s.print_ident(param.ident); |
2586 | s.print_type_bounds(":", ¶m.bounds); | |
2587 | if let Some(ref default) = default { | |
2588 | s.s.space(); | |
2589 | s.word_space("="); | |
2590 | s.print_type(default) | |
8faf50e0 XL |
2591 | } |
2592 | } | |
f035d41b | 2593 | ast::GenericParamKind::Const { ref ty, kw_span: _ } => { |
416331ca XL |
2594 | s.word_space("const"); |
2595 | s.print_ident(param.ident); | |
2596 | s.s.space(); | |
2597 | s.word_space(":"); | |
2598 | s.print_type(ty); | |
9fa01778 XL |
2599 | s.print_type_bounds(":", ¶m.bounds) |
2600 | } | |
1a4d82fc | 2601 | } |
416331ca | 2602 | }); |
1a4d82fc | 2603 | |
416331ca | 2604 | self.s.word(">"); |
223e47cc | 2605 | } |
223e47cc | 2606 | |
416331ca | 2607 | crate fn print_where_clause(&mut self, where_clause: &ast::WhereClause) { |
f035d41b | 2608 | if where_clause.predicates.is_empty() && !where_clause.has_where_token { |
416331ca | 2609 | return; |
1a4d82fc JJ |
2610 | } |
2611 | ||
416331ca XL |
2612 | self.s.space(); |
2613 | self.word_space("where"); | |
1a4d82fc | 2614 | |
c34b1796 | 2615 | for (i, predicate) in where_clause.predicates.iter().enumerate() { |
1a4d82fc | 2616 | if i != 0 { |
416331ca | 2617 | self.word_space(","); |
1a4d82fc JJ |
2618 | } |
2619 | ||
92a42be0 | 2620 | match *predicate { |
ff7c6d11 XL |
2621 | ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate { |
2622 | ref bound_generic_params, | |
2623 | ref bounded_ty, | |
2624 | ref bounds, | |
2625 | .. | |
2626 | }) => { | |
416331ca XL |
2627 | self.print_formal_generic_params(bound_generic_params); |
2628 | self.print_type(bounded_ty); | |
2629 | self.print_type_bounds(":", bounds); | |
1a4d82fc | 2630 | } |
dfeec247 XL |
2631 | ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate { |
2632 | ref lifetime, | |
2633 | ref bounds, | |
2634 | .. | |
2635 | }) => { | |
416331ca | 2636 | self.print_lifetime_bounds(*lifetime, bounds); |
1a4d82fc | 2637 | } |
dfeec247 XL |
2638 | ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { |
2639 | ref lhs_ty, | |
2640 | ref rhs_ty, | |
2641 | .. | |
2642 | }) => { | |
416331ca XL |
2643 | self.print_type(lhs_ty); |
2644 | self.s.space(); | |
2645 | self.word_space("="); | |
2646 | self.print_type(rhs_ty); | |
1a4d82fc JJ |
2647 | } |
2648 | } | |
223e47cc | 2649 | } |
223e47cc | 2650 | } |
223e47cc | 2651 | |
416331ca | 2652 | crate fn print_use_tree(&mut self, tree: &ast::UseTree) { |
ff7c6d11 | 2653 | match tree.kind { |
94b46f34 | 2654 | ast::UseTreeKind::Simple(rename, ..) => { |
416331ca | 2655 | self.print_path(&tree.prefix, false, 0); |
0531ce1d | 2656 | if let Some(rename) = rename { |
416331ca XL |
2657 | self.s.space(); |
2658 | self.word_space("as"); | |
2659 | self.print_ident(rename); | |
1a4d82fc | 2660 | } |
1a4d82fc | 2661 | } |
ff7c6d11 XL |
2662 | ast::UseTreeKind::Glob => { |
2663 | if !tree.prefix.segments.is_empty() { | |
416331ca XL |
2664 | self.print_path(&tree.prefix, false, 0); |
2665 | self.s.word("::"); | |
ff7c6d11 | 2666 | } |
416331ca | 2667 | self.s.word("*"); |
1a4d82fc | 2668 | } |
ff7c6d11 XL |
2669 | ast::UseTreeKind::Nested(ref items) => { |
2670 | if tree.prefix.segments.is_empty() { | |
416331ca | 2671 | self.s.word("{"); |
1a4d82fc | 2672 | } else { |
416331ca XL |
2673 | self.print_path(&tree.prefix, false, 0); |
2674 | self.s.word("::{"); | |
1a4d82fc | 2675 | } |
ff7c6d11 XL |
2676 | self.commasep(Inconsistent, &items[..], |this, &(ref tree, _)| { |
2677 | this.print_use_tree(tree) | |
416331ca XL |
2678 | }); |
2679 | self.s.word("}"); | |
1a4d82fc JJ |
2680 | } |
2681 | } | |
223e47cc | 2682 | } |
223e47cc | 2683 | |
60c5eb7d | 2684 | pub fn print_mutability(&mut self, mutbl: ast::Mutability, print_const: bool) { |
1a4d82fc | 2685 | match mutbl { |
dfeec247 XL |
2686 | ast::Mutability::Mut => self.word_nbsp("mut"), |
2687 | ast::Mutability::Not => { | |
2688 | if print_const { | |
2689 | self.word_nbsp("const"); | |
2690 | } | |
2691 | } | |
1a4d82fc JJ |
2692 | } |
2693 | } | |
2694 | ||
60c5eb7d XL |
2695 | crate fn print_mt(&mut self, mt: &ast::MutTy, print_const: bool) { |
2696 | self.print_mutability(mt.mutbl, print_const); | |
7453a54e | 2697 | self.print_type(&mt.ty) |
223e47cc | 2698 | } |
223e47cc | 2699 | |
e1599b0c | 2700 | crate fn print_param(&mut self, input: &ast::Param, is_closure: bool) { |
416331ca XL |
2701 | self.ibox(INDENT_UNIT); |
2702 | ||
2703 | self.print_outer_attributes_inline(&input.attrs); | |
2704 | ||
e74abb32 | 2705 | match input.ty.kind { |
416331ca | 2706 | ast::TyKind::Infer if is_closure => self.print_pat(&input.pat), |
1a4d82fc | 2707 | _ => { |
a7813a04 | 2708 | if let Some(eself) = input.to_self() { |
416331ca | 2709 | self.print_explicit_self(&eself); |
a7813a04 | 2710 | } else { |
e74abb32 | 2711 | let invalid = if let PatKind::Ident(_, ident, _) = input.pat.kind { |
dc9dc135 | 2712 | ident.name == kw::Invalid |
3157f602 XL |
2713 | } else { |
2714 | false | |
2715 | }; | |
a7813a04 | 2716 | if !invalid { |
416331ca XL |
2717 | self.print_pat(&input.pat); |
2718 | self.s.word(":"); | |
2719 | self.s.space(); | |
1a4d82fc | 2720 | } |
416331ca | 2721 | self.print_type(&input.ty); |
1a4d82fc | 2722 | } |
1a4d82fc | 2723 | } |
223e47cc | 2724 | } |
416331ca | 2725 | self.end(); |
223e47cc | 2726 | } |
223e47cc | 2727 | |
74b04a01 XL |
2728 | crate fn print_fn_ret_ty(&mut self, fn_ret_ty: &ast::FnRetTy) { |
2729 | if let ast::FnRetTy::Ty(ty) = fn_ret_ty { | |
dfeec247 XL |
2730 | self.space_if_not_bol(); |
2731 | self.ibox(INDENT_UNIT); | |
2732 | self.word_space("->"); | |
2733 | self.print_type(ty); | |
2734 | self.end(); | |
2735 | self.maybe_print_comment(ty.span.lo()); | |
1a4d82fc JJ |
2736 | } |
2737 | } | |
2738 | ||
dfeec247 XL |
2739 | crate fn print_ty_fn( |
2740 | &mut self, | |
2741 | ext: ast::Extern, | |
74b04a01 | 2742 | unsafety: ast::Unsafe, |
dfeec247 | 2743 | decl: &ast::FnDecl, |
f9f354fc | 2744 | name: Option<Ident>, |
dfeec247 XL |
2745 | generic_params: &[ast::GenericParam], |
2746 | ) { | |
416331ca | 2747 | self.ibox(INDENT_UNIT); |
ff7c6d11 | 2748 | if !generic_params.is_empty() { |
416331ca XL |
2749 | self.s.word("for"); |
2750 | self.print_generic_params(generic_params); | |
c34b1796 AL |
2751 | } |
2752 | let generics = ast::Generics { | |
ff7c6d11 | 2753 | params: Vec::new(), |
f035d41b XL |
2754 | where_clause: ast::WhereClause { |
2755 | has_where_token: false, | |
2756 | predicates: Vec::new(), | |
2757 | span: rustc_span::DUMMY_SP, | |
2758 | }, | |
dfeec247 | 2759 | span: rustc_span::DUMMY_SP, |
c34b1796 | 2760 | }; |
74b04a01 XL |
2761 | let header = ast::FnHeader { unsafety, ext, ..ast::FnHeader::default() }; |
2762 | self.print_fn(decl, header, name, &generics); | |
416331ca | 2763 | self.end(); |
223e47cc LB |
2764 | } |
2765 | ||
dfeec247 XL |
2766 | crate fn maybe_print_trailing_comment( |
2767 | &mut self, | |
2768 | span: rustc_span::Span, | |
2769 | next_pos: Option<BytePos>, | |
2770 | ) { | |
416331ca XL |
2771 | if let Some(cmnts) = self.comments() { |
2772 | if let Some(cmnt) = cmnts.trailing_comment(span, next_pos) { | |
2773 | self.print_comment(&cmnt); | |
1a4d82fc | 2774 | } |
1a4d82fc | 2775 | } |
1a4d82fc | 2776 | } |
223e47cc | 2777 | |
416331ca | 2778 | crate fn print_remaining_comments(&mut self) { |
1a4d82fc JJ |
2779 | // If there aren't any remaining comments, then we need to manually |
2780 | // make sure there is a line break at the end. | |
2781 | if self.next_comment().is_none() { | |
416331ca | 2782 | self.s.hardbreak(); |
1a4d82fc | 2783 | } |
7cac9316 | 2784 | while let Some(ref cmnt) = self.next_comment() { |
416331ca | 2785 | self.print_comment(cmnt); |
1a4d82fc JJ |
2786 | } |
2787 | } | |
2788 | ||
74b04a01 XL |
2789 | crate fn print_fn_header_info(&mut self, header: ast::FnHeader) { |
2790 | self.print_constness(header.constness); | |
2791 | self.print_asyncness(header.asyncness); | |
416331ca | 2792 | self.print_unsafety(header.unsafety); |
b039eaaf | 2793 | |
60c5eb7d XL |
2794 | match header.ext { |
2795 | ast::Extern::None => {} | |
2796 | ast::Extern::Implicit => { | |
2797 | self.word_nbsp("extern"); | |
2798 | } | |
2799 | ast::Extern::Explicit(abi) => { | |
2800 | self.word_nbsp("extern"); | |
2801 | self.print_literal(&abi.as_lit()); | |
2802 | self.nbsp(); | |
2803 | } | |
1a4d82fc JJ |
2804 | } |
2805 | ||
041b39d2 | 2806 | self.s.word("fn") |
1a4d82fc JJ |
2807 | } |
2808 | ||
74b04a01 | 2809 | crate fn print_unsafety(&mut self, s: ast::Unsafe) { |
1a4d82fc | 2810 | match s { |
74b04a01 XL |
2811 | ast::Unsafe::No => {} |
2812 | ast::Unsafe::Yes(_) => self.word_nbsp("unsafe"), | |
1a4d82fc | 2813 | } |
223e47cc | 2814 | } |
abe05a73 | 2815 | |
74b04a01 | 2816 | crate fn print_constness(&mut self, s: ast::Const) { |
dfeec247 | 2817 | match s { |
74b04a01 XL |
2818 | ast::Const::No => {} |
2819 | ast::Const::Yes(_) => self.word_nbsp("const"), | |
dfeec247 XL |
2820 | } |
2821 | } | |
2822 | ||
416331ca | 2823 | crate fn print_is_auto(&mut self, s: ast::IsAuto) { |
abe05a73 XL |
2824 | match s { |
2825 | ast::IsAuto::Yes => self.word_nbsp("auto"), | |
416331ca | 2826 | ast::IsAuto::No => {} |
abe05a73 XL |
2827 | } |
2828 | } | |
223e47cc | 2829 | } |