1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 pub use self::AnnNode
::*;
15 use syntax
::owned_slice
::OwnedSlice
;
16 use syntax
::codemap
::{self, CodeMap, BytePos, Spanned}
;
17 use syntax
::diagnostic
;
18 use syntax
::parse
::token
::{self, BinOpToken}
;
19 use syntax
::parse
::lexer
::comments
;
21 use syntax
::print
::pp
::{self, break_offset, word, space, hardbreak}
;
22 use syntax
::print
::pp
::{Breaks, eof}
;
23 use syntax
::print
::pp
::Breaks
::{Consistent, Inconsistent}
;
24 use syntax
::print
::pprust
::{self as ast_pp, PrintState}
;
28 use hir
::{Crate, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}
;
30 use std
::io
::{self, Write, Read}
;
32 pub enum AnnNode
<'a
> {
33 NodeName(&'a ast
::Name
),
34 NodeBlock(&'a hir
::Block
),
35 NodeItem(&'a hir
::Item
),
36 NodeSubItem(ast
::NodeId
),
37 NodeExpr(&'a hir
::Expr
),
38 NodePat(&'a hir
::Pat
),
42 fn pre(&self, _state
: &mut State
, _node
: AnnNode
) -> io
::Result
<()> {
45 fn post(&self, _state
: &mut State
, _node
: AnnNode
) -> io
::Result
<()> {
50 #[derive(Copy, Clone)]
53 impl PpAnn
for NoAnn {}
56 pub struct State
<'a
> {
57 krate
: Option
<&'a Crate
>,
58 pub s
: pp
::Printer
<'a
>,
59 cm
: Option
<&'a CodeMap
>,
60 comments
: Option
<Vec
<comments
::Comment
>>,
61 literals
: Option
<Vec
<comments
::Literal
>>,
62 cur_cmnt_and_lit
: ast_pp
::CurrentCommentAndLiteral
,
63 boxes
: Vec
<pp
::Breaks
>,
64 ann
: &'
a (PpAnn
+ 'a
),
67 impl<'a
> PrintState
<'a
> for State
<'a
> {
68 fn writer(&mut self) -> &mut pp
::Printer
<'a
> {
72 fn boxes(&mut self) -> &mut Vec
<pp
::Breaks
> {
76 fn comments(&mut self) -> &mut Option
<Vec
<comments
::Comment
>> {
80 fn cur_cmnt_and_lit(&mut self) -> &mut ast_pp
::CurrentCommentAndLiteral
{
81 &mut self.cur_cmnt_and_lit
84 fn literals(&self) -> &Option
<Vec
<comments
::Literal
>> {
89 pub fn rust_printer
<'a
>(writer
: Box
<Write
+ 'a
>, krate
: Option
<&'a Crate
>) -> State
<'a
> {
90 static NO_ANN
: NoAnn
= NoAnn
;
91 rust_printer_annotated(writer
, &NO_ANN
, krate
)
94 pub fn rust_printer_annotated
<'a
>(writer
: Box
<Write
+ 'a
>,
96 krate
: Option
<&'a Crate
>)
100 s
: pp
::mk_printer(writer
, default_columns
),
104 cur_cmnt_and_lit
: ast_pp
::CurrentCommentAndLiteral
{
113 #[allow(non_upper_case_globals)]
114 pub const indent_unit
: usize = 4;
116 #[allow(non_upper_case_globals)]
117 pub const default_columns
: usize = 78;
120 /// Requires you to pass an input filename and reader so that
121 /// it can scan the input text for comments and literals to
123 pub fn print_crate
<'a
>(cm
: &'a CodeMap
,
124 span_diagnostic
: &diagnostic
::SpanHandler
,
128 out
: Box
<Write
+ 'a
>,
132 let mut s
= State
::new_from_input(cm
, span_diagnostic
, filename
, input
,
133 out
, ann
, is_expanded
, Some(krate
));
135 // When printing the AST, we sometimes need to inject `#[no_std]` here.
136 // Since you can't compile the HIR, it's not necessary.
138 try
!(s
.print_mod(&krate
.module
, &krate
.attrs
));
139 try
!(s
.print_remaining_comments());
144 pub fn new_from_input(cm
: &'a CodeMap
,
145 span_diagnostic
: &diagnostic
::SpanHandler
,
148 out
: Box
<Write
+ 'a
>,
151 krate
: Option
<&'a Crate
>)
153 let (cmnts
, lits
) = comments
::gather_comments_and_literals(span_diagnostic
,
161 // If the code is post expansion, don't use the table of
162 // literals, since it doesn't correspond with the literals
163 // in the AST anymore.
172 pub fn new(cm
: &'a CodeMap
,
173 out
: Box
<Write
+ 'a
>,
175 comments
: Option
<Vec
<comments
::Comment
>>,
176 literals
: Option
<Vec
<comments
::Literal
>>,
177 krate
: Option
<&'a Crate
>)
181 s
: pp
::mk_printer(out
, default_columns
),
183 comments
: comments
.clone(),
184 literals
: literals
.clone(),
185 cur_cmnt_and_lit
: ast_pp
::CurrentCommentAndLiteral
{
195 pub fn to_string
<F
>(f
: F
) -> String
196 where F
: FnOnce(&mut State
) -> io
::Result
<()>
198 let mut wr
= Vec
::new();
200 let mut printer
= rust_printer(Box
::new(&mut wr
), None
);
201 f(&mut printer
).unwrap();
202 eof(&mut printer
.s
).unwrap();
204 String
::from_utf8(wr
).unwrap()
207 pub fn binop_to_string(op
: BinOpToken
) -> &'
static str {
213 token
::Percent
=> "%",
222 pub fn ty_to_string(ty
: &hir
::Ty
) -> String
{
223 to_string(|s
| s
.print_type(ty
))
226 pub fn bounds_to_string(bounds
: &[hir
::TyParamBound
]) -> String
{
227 to_string(|s
| s
.print_bounds("", bounds
))
230 pub fn pat_to_string(pat
: &hir
::Pat
) -> String
{
231 to_string(|s
| s
.print_pat(pat
))
234 pub fn arm_to_string(arm
: &hir
::Arm
) -> String
{
235 to_string(|s
| s
.print_arm(arm
))
238 pub fn expr_to_string(e
: &hir
::Expr
) -> String
{
239 to_string(|s
| s
.print_expr(e
))
242 pub fn lifetime_to_string(e
: &hir
::Lifetime
) -> String
{
243 to_string(|s
| s
.print_lifetime(e
))
246 pub fn stmt_to_string(stmt
: &hir
::Stmt
) -> String
{
247 to_string(|s
| s
.print_stmt(stmt
))
250 pub fn item_to_string(i
: &hir
::Item
) -> String
{
251 to_string(|s
| s
.print_item(i
))
254 pub fn impl_item_to_string(i
: &hir
::ImplItem
) -> String
{
255 to_string(|s
| s
.print_impl_item(i
))
258 pub fn trait_item_to_string(i
: &hir
::TraitItem
) -> String
{
259 to_string(|s
| s
.print_trait_item(i
))
262 pub fn generics_to_string(generics
: &hir
::Generics
) -> String
{
263 to_string(|s
| s
.print_generics(generics
))
266 pub fn where_clause_to_string(i
: &hir
::WhereClause
) -> String
{
267 to_string(|s
| s
.print_where_clause(i
))
270 pub fn fn_block_to_string(p
: &hir
::FnDecl
) -> String
{
271 to_string(|s
| s
.print_fn_block_args(p
))
274 pub fn path_to_string(p
: &hir
::Path
) -> String
{
275 to_string(|s
| s
.print_path(p
, false, 0))
278 pub fn name_to_string(name
: ast
::Name
) -> String
{
279 to_string(|s
| s
.print_name(name
))
282 pub fn fun_to_string(decl
: &hir
::FnDecl
,
283 unsafety
: hir
::Unsafety
,
284 constness
: hir
::Constness
,
286 opt_explicit_self
: Option
<&hir
::ExplicitSelf_
>,
287 generics
: &hir
::Generics
)
291 try
!(s
.print_fn(decl
,
299 try
!(s
.end()); // Close the head box
300 s
.end() // Close the outer box
304 pub fn block_to_string(blk
: &hir
::Block
) -> String
{
306 // containing cbox, will be closed by print-block at }
307 try
!(s
.cbox(indent_unit
));
308 // head-ibox, will be closed by print-block after {
314 pub fn explicit_self_to_string(explicit_self
: &hir
::ExplicitSelf_
) -> String
{
315 to_string(|s
| s
.print_explicit_self(explicit_self
, hir
::MutImmutable
).map(|_
| {}
))
318 pub fn variant_to_string(var
: &hir
::Variant
) -> String
{
319 to_string(|s
| s
.print_variant(var
))
322 pub fn arg_to_string(arg
: &hir
::Arg
) -> String
{
323 to_string(|s
| s
.print_arg(arg
))
326 pub fn visibility_qualified(vis
: hir
::Visibility
, s
: &str) -> String
{
328 hir
::Public
=> format
!("pub {}", s
),
329 hir
::Inherited
=> s
.to_string(),
333 fn needs_parentheses(expr
: &hir
::Expr
) -> bool
{
335 hir
::ExprAssign(..) |
336 hir
::ExprBinary(..) |
337 hir
::ExprClosure(..) |
338 hir
::ExprAssignOp(..) |
339 hir
::ExprCast(..) => true,
345 pub fn cbox(&mut self, u
: usize) -> io
::Result
<()> {
346 self.boxes
.push(pp
::Breaks
::Consistent
);
347 pp
::cbox(&mut self.s
, u
)
350 pub fn nbsp(&mut self) -> io
::Result
<()> {
351 word(&mut self.s
, " ")
354 pub fn word_nbsp(&mut self, w
: &str) -> io
::Result
<()> {
355 try
!(word(&mut self.s
, w
));
359 pub fn head(&mut self, w
: &str) -> io
::Result
<()> {
360 // outer-box is consistent
361 try
!(self.cbox(indent_unit
));
362 // head-box is inconsistent
363 try
!(self.ibox(w
.len() + 1));
364 // keyword that starts the head
366 try
!(self.word_nbsp(w
));
371 pub fn bopen(&mut self) -> io
::Result
<()> {
372 try
!(word(&mut self.s
, "{"));
373 self.end() // close the head-box
376 pub fn bclose_(&mut self, span
: codemap
::Span
, indented
: usize) -> io
::Result
<()> {
377 self.bclose_maybe_open(span
, indented
, true)
379 pub fn bclose_maybe_open(&mut self,
384 try
!(self.maybe_print_comment(span
.hi
));
385 try
!(self.break_offset_if_not_bol(1, -(indented
as isize)));
386 try
!(word(&mut self.s
, "}"));
388 try
!(self.end()); // close the outer-box
392 pub fn bclose(&mut self, span
: codemap
::Span
) -> io
::Result
<()> {
393 self.bclose_(span
, indent_unit
)
396 pub fn in_cbox(&self) -> bool
{
397 match self.boxes
.last() {
398 Some(&last_box
) => last_box
== pp
::Breaks
::Consistent
,
402 pub fn space_if_not_bol(&mut self) -> io
::Result
<()> {
404 try
!(space(&mut self.s
));
408 pub fn break_offset_if_not_bol(&mut self, n
: usize, off
: isize) -> io
::Result
<()> {
410 break_offset(&mut self.s
, n
, off
)
412 if off
!= 0 && self.s
.last_token().is_hardbreak_tok() {
413 // We do something pretty sketchy here: tuck the nonzero
414 // offset-adjustment we were going to deposit along with the
415 // break into the previous hardbreak.
416 self.s
.replace_last_token(pp
::hardbreak_tok_offset(off
));
422 // Synthesizes a comment that was not textually present in the original source
424 pub fn synth_comment(&mut self, text
: String
) -> io
::Result
<()> {
425 try
!(word(&mut self.s
, "/*"));
426 try
!(space(&mut self.s
));
427 try
!(word(&mut self.s
, &text
[..]));
428 try
!(space(&mut self.s
));
429 word(&mut self.s
, "*/")
433 pub fn commasep_cmnt
<T
, F
, G
>(&mut self,
439 where F
: FnMut(&mut State
, &T
) -> io
::Result
<()>,
440 G
: FnMut(&T
) -> codemap
::Span
442 try
!(self.rbox(0, b
));
443 let len
= elts
.len();
446 try
!(self.maybe_print_comment(get_span(elt
).hi
));
450 try
!(word(&mut self.s
, ","));
451 try
!(self.maybe_print_trailing_comment(get_span(elt
), Some(get_span(&elts
[i
]).hi
)));
452 try
!(self.space_if_not_bol());
458 pub fn commasep_exprs(&mut self, b
: Breaks
, exprs
: &[P
<hir
::Expr
>]) -> io
::Result
<()> {
459 self.commasep_cmnt(b
, exprs
, |s
, e
| s
.print_expr(&**e
), |e
| e
.span
)
462 pub fn print_mod(&mut self, _mod
: &hir
::Mod
, attrs
: &[ast
::Attribute
]) -> io
::Result
<()> {
463 try
!(self.print_inner_attributes(attrs
));
464 for item_id
in &_mod
.item_ids
{
465 try
!(self.print_item_id(item_id
));
470 pub fn print_foreign_mod(&mut self,
471 nmod
: &hir
::ForeignMod
,
472 attrs
: &[ast
::Attribute
])
474 try
!(self.print_inner_attributes(attrs
));
475 for item
in &nmod
.items
{
476 try
!(self.print_foreign_item(item
));
481 pub fn print_opt_lifetime(&mut self, lifetime
: &Option
<hir
::Lifetime
>) -> io
::Result
<()> {
482 if let Some(l
) = *lifetime
{
483 try
!(self.print_lifetime(&l
));
489 pub fn print_type(&mut self, ty
: &hir
::Ty
) -> io
::Result
<()> {
490 try
!(self.maybe_print_comment(ty
.span
.lo
));
493 hir
::TyVec(ref ty
) => {
494 try
!(word(&mut self.s
, "["));
495 try
!(self.print_type(&**ty
));
496 try
!(word(&mut self.s
, "]"));
498 hir
::TyPtr(ref mt
) => {
499 try
!(word(&mut self.s
, "*"));
501 hir
::MutMutable
=> try
!(self.word_nbsp("mut")),
502 hir
::MutImmutable
=> try
!(self.word_nbsp("const")),
504 try
!(self.print_type(&*mt
.ty
));
506 hir
::TyRptr(ref lifetime
, ref mt
) => {
507 try
!(word(&mut self.s
, "&"));
508 try
!(self.print_opt_lifetime(lifetime
));
509 try
!(self.print_mt(mt
));
511 hir
::TyTup(ref elts
) => {
513 try
!(self.commasep(Inconsistent
, &elts
[..], |s
, ty
| s
.print_type(&**ty
)));
515 try
!(word(&mut self.s
, ","));
519 hir
::TyBareFn(ref f
) => {
520 let generics
= hir
::Generics
{
521 lifetimes
: f
.lifetimes
.clone(),
522 ty_params
: OwnedSlice
::empty(),
523 where_clause
: hir
::WhereClause
{
524 id
: ast
::DUMMY_NODE_ID
,
525 predicates
: Vec
::new(),
528 try
!(self.print_ty_fn(f
.abi
, f
.unsafety
, &*f
.decl
, None
, &generics
, None
));
530 hir
::TyPath(None
, ref path
) => {
531 try
!(self.print_path(path
, false, 0));
533 hir
::TyPath(Some(ref qself
), ref path
) => {
534 try
!(self.print_qpath(path
, qself
, false))
536 hir
::TyObjectSum(ref ty
, ref bounds
) => {
537 try
!(self.print_type(&**ty
));
538 try
!(self.print_bounds("+", &bounds
[..]));
540 hir
::TyPolyTraitRef(ref bounds
) => {
541 try
!(self.print_bounds("", &bounds
[..]));
543 hir
::TyFixedLengthVec(ref ty
, ref v
) => {
544 try
!(word(&mut self.s
, "["));
545 try
!(self.print_type(&**ty
));
546 try
!(word(&mut self.s
, "; "));
547 try
!(self.print_expr(&**v
));
548 try
!(word(&mut self.s
, "]"));
550 hir
::TyTypeof(ref e
) => {
551 try
!(word(&mut self.s
, "typeof("));
552 try
!(self.print_expr(&**e
));
553 try
!(word(&mut self.s
, ")"));
556 try
!(word(&mut self.s
, "_"));
562 pub fn print_foreign_item(&mut self, item
: &hir
::ForeignItem
) -> io
::Result
<()> {
563 try
!(self.hardbreak_if_not_bol());
564 try
!(self.maybe_print_comment(item
.span
.lo
));
565 try
!(self.print_outer_attributes(&item
.attrs
));
567 hir
::ForeignItemFn(ref decl
, ref generics
) => {
569 try
!(self.print_fn(decl
,
570 hir
::Unsafety
::Normal
,
571 hir
::Constness
::NotConst
,
577 try
!(self.end()); // end head-ibox
578 try
!(word(&mut self.s
, ";"));
579 self.end() // end the outer fn box
581 hir
::ForeignItemStatic(ref t
, m
) => {
582 try
!(self.head(&visibility_qualified(item
.vis
, "static")));
584 try
!(self.word_space("mut"));
586 try
!(self.print_name(item
.name
));
587 try
!(self.word_space(":"));
588 try
!(self.print_type(&**t
));
589 try
!(word(&mut self.s
, ";"));
590 try
!(self.end()); // end the head-ibox
591 self.end() // end the outer cbox
596 fn print_associated_const(&mut self,
599 default: Option
<&hir
::Expr
>,
600 vis
: hir
::Visibility
)
602 try
!(word(&mut self.s
, &visibility_qualified(vis
, "")));
603 try
!(self.word_space("const"));
604 try
!(self.print_name(name
));
605 try
!(self.word_space(":"));
606 try
!(self.print_type(ty
));
607 if let Some(expr
) = default {
608 try
!(space(&mut self.s
));
609 try
!(self.word_space("="));
610 try
!(self.print_expr(expr
));
612 word(&mut self.s
, ";")
615 fn print_associated_type(&mut self,
617 bounds
: Option
<&hir
::TyParamBounds
>,
618 ty
: Option
<&hir
::Ty
>)
620 try
!(self.word_space("type"));
621 try
!(self.print_name(name
));
622 if let Some(bounds
) = bounds
{
623 try
!(self.print_bounds(":", bounds
));
625 if let Some(ty
) = ty
{
626 try
!(space(&mut self.s
));
627 try
!(self.word_space("="));
628 try
!(self.print_type(ty
));
630 word(&mut self.s
, ";")
633 pub fn print_item_id(&mut self, item_id
: &hir
::ItemId
) -> io
::Result
<()> {
634 if let Some(krate
) = self.krate
{
635 // skip nested items if krate context was not provided
636 let item
= &krate
.items
[&item_id
.id
];
637 self.print_item(item
)
643 /// Pretty-print an item
644 pub fn print_item(&mut self, item
: &hir
::Item
) -> io
::Result
<()> {
645 try
!(self.hardbreak_if_not_bol());
646 try
!(self.maybe_print_comment(item
.span
.lo
));
647 try
!(self.print_outer_attributes(&item
.attrs
));
648 try
!(self.ann
.pre(self, NodeItem(item
)));
650 hir
::ItemExternCrate(ref optional_path
) => {
651 try
!(self.head(&visibility_qualified(item
.vis
, "extern crate")));
652 if let Some(p
) = *optional_path
{
653 let val
= p
.as_str();
654 if val
.contains("-") {
655 try
!(self.print_string(&val
, ast
::CookedStr
));
657 try
!(self.print_name(p
));
659 try
!(space(&mut self.s
));
660 try
!(word(&mut self.s
, "as"));
661 try
!(space(&mut self.s
));
663 try
!(self.print_name(item
.name
));
664 try
!(word(&mut self.s
, ";"));
665 try
!(self.end()); // end inner head-block
666 try
!(self.end()); // end outer head-block
668 hir
::ItemUse(ref vp
) => {
669 try
!(self.head(&visibility_qualified(item
.vis
, "use")));
670 try
!(self.print_view_path(&**vp
));
671 try
!(word(&mut self.s
, ";"));
672 try
!(self.end()); // end inner head-block
673 try
!(self.end()); // end outer head-block
675 hir
::ItemStatic(ref ty
, m
, ref expr
) => {
676 try
!(self.head(&visibility_qualified(item
.vis
, "static")));
677 if m
== hir
::MutMutable
{
678 try
!(self.word_space("mut"));
680 try
!(self.print_name(item
.name
));
681 try
!(self.word_space(":"));
682 try
!(self.print_type(&**ty
));
683 try
!(space(&mut self.s
));
684 try
!(self.end()); // end the head-ibox
686 try
!(self.word_space("="));
687 try
!(self.print_expr(&**expr
));
688 try
!(word(&mut self.s
, ";"));
689 try
!(self.end()); // end the outer cbox
691 hir
::ItemConst(ref ty
, ref expr
) => {
692 try
!(self.head(&visibility_qualified(item
.vis
, "const")));
693 try
!(self.print_name(item
.name
));
694 try
!(self.word_space(":"));
695 try
!(self.print_type(&**ty
));
696 try
!(space(&mut self.s
));
697 try
!(self.end()); // end the head-ibox
699 try
!(self.word_space("="));
700 try
!(self.print_expr(&**expr
));
701 try
!(word(&mut self.s
, ";"));
702 try
!(self.end()); // end the outer cbox
704 hir
::ItemFn(ref decl
, unsafety
, constness
, abi
, ref typarams
, ref body
) => {
706 try
!(self.print_fn(decl
,
714 try
!(word(&mut self.s
, " "));
715 try
!(self.print_block_with_attrs(&**body
, &item
.attrs
));
717 hir
::ItemMod(ref _mod
) => {
718 try
!(self.head(&visibility_qualified(item
.vis
, "mod")));
719 try
!(self.print_name(item
.name
));
722 try
!(self.print_mod(_mod
, &item
.attrs
));
723 try
!(self.bclose(item
.span
));
725 hir
::ItemForeignMod(ref nmod
) => {
726 try
!(self.head("extern"));
727 try
!(self.word_nbsp(&nmod
.abi
.to_string()));
729 try
!(self.print_foreign_mod(nmod
, &item
.attrs
));
730 try
!(self.bclose(item
.span
));
732 hir
::ItemTy(ref ty
, ref params
) => {
733 try
!(self.ibox(indent_unit
));
735 try
!(self.word_nbsp(&visibility_qualified(item
.vis
, "type")));
736 try
!(self.print_name(item
.name
));
737 try
!(self.print_generics(params
));
738 try
!(self.end()); // end the inner ibox
740 try
!(self.print_where_clause(¶ms
.where_clause
));
741 try
!(space(&mut self.s
));
742 try
!(self.word_space("="));
743 try
!(self.print_type(&**ty
));
744 try
!(word(&mut self.s
, ";"));
745 try
!(self.end()); // end the outer ibox
747 hir
::ItemEnum(ref enum_definition
, ref params
) => {
748 try
!(self.print_enum_def(enum_definition
, params
, item
.name
, item
.span
, item
.vis
));
750 hir
::ItemStruct(ref struct_def
, ref generics
) => {
751 try
!(self.head(&visibility_qualified(item
.vis
, "struct")));
752 try
!(self.print_struct(struct_def
, generics
, item
.name
, item
.span
, true));
755 hir
::ItemDefaultImpl(unsafety
, ref trait_ref
) => {
757 try
!(self.print_visibility(item
.vis
));
758 try
!(self.print_unsafety(unsafety
));
759 try
!(self.word_nbsp("impl"));
760 try
!(self.print_trait_ref(trait_ref
));
761 try
!(space(&mut self.s
));
762 try
!(self.word_space("for"));
763 try
!(self.word_space(".."));
765 try
!(self.bclose(item
.span
));
767 hir
::ItemImpl(unsafety
,
774 try
!(self.print_visibility(item
.vis
));
775 try
!(self.print_unsafety(unsafety
));
776 try
!(self.word_nbsp("impl"));
778 if generics
.is_parameterized() {
779 try
!(self.print_generics(generics
));
780 try
!(space(&mut self.s
));
784 hir
::ImplPolarity
::Negative
=> {
785 try
!(word(&mut self.s
, "!"));
792 try
!(self.print_trait_ref(t
));
793 try
!(space(&mut self.s
));
794 try
!(self.word_space("for"));
799 try
!(self.print_type(&**ty
));
800 try
!(self.print_where_clause(&generics
.where_clause
));
802 try
!(space(&mut self.s
));
804 try
!(self.print_inner_attributes(&item
.attrs
));
805 for impl_item
in impl_items
{
806 try
!(self.print_impl_item(impl_item
));
808 try
!(self.bclose(item
.span
));
810 hir
::ItemTrait(unsafety
, ref generics
, ref bounds
, ref trait_items
) => {
812 try
!(self.print_visibility(item
.vis
));
813 try
!(self.print_unsafety(unsafety
));
814 try
!(self.word_nbsp("trait"));
815 try
!(self.print_name(item
.name
));
816 try
!(self.print_generics(generics
));
817 let mut real_bounds
= Vec
::with_capacity(bounds
.len());
818 for b
in bounds
.iter() {
819 if let TraitTyParamBound(ref ptr
, hir
::TraitBoundModifier
::Maybe
) = *b
{
820 try
!(space(&mut self.s
));
821 try
!(self.word_space("for ?"));
822 try
!(self.print_trait_ref(&ptr
.trait_ref
));
824 real_bounds
.push(b
.clone());
827 try
!(self.print_bounds(":", &real_bounds
[..]));
828 try
!(self.print_where_clause(&generics
.where_clause
));
829 try
!(word(&mut self.s
, " "));
831 for trait_item
in trait_items
{
832 try
!(self.print_trait_item(trait_item
));
834 try
!(self.bclose(item
.span
));
837 self.ann
.post(self, NodeItem(item
))
840 fn print_trait_ref(&mut self, t
: &hir
::TraitRef
) -> io
::Result
<()> {
841 self.print_path(&t
.path
, false, 0)
844 fn print_formal_lifetime_list(&mut self, lifetimes
: &[hir
::LifetimeDef
]) -> io
::Result
<()> {
845 if !lifetimes
.is_empty() {
846 try
!(word(&mut self.s
, "for<"));
847 let mut comma
= false;
848 for lifetime_def
in lifetimes
{
850 try
!(self.word_space(","))
852 try
!(self.print_lifetime_def(lifetime_def
));
855 try
!(word(&mut self.s
, ">"));
860 fn print_poly_trait_ref(&mut self, t
: &hir
::PolyTraitRef
) -> io
::Result
<()> {
861 try
!(self.print_formal_lifetime_list(&t
.bound_lifetimes
));
862 self.print_trait_ref(&t
.trait_ref
)
865 pub fn print_enum_def(&mut self,
866 enum_definition
: &hir
::EnumDef
,
867 generics
: &hir
::Generics
,
870 visibility
: hir
::Visibility
)
872 try
!(self.head(&visibility_qualified(visibility
, "enum")));
873 try
!(self.print_name(name
));
874 try
!(self.print_generics(generics
));
875 try
!(self.print_where_clause(&generics
.where_clause
));
876 try
!(space(&mut self.s
));
877 self.print_variants(&enum_definition
.variants
, span
)
880 pub fn print_variants(&mut self,
881 variants
: &[hir
::Variant
],
886 try
!(self.space_if_not_bol());
887 try
!(self.maybe_print_comment(v
.span
.lo
));
888 try
!(self.print_outer_attributes(&v
.node
.attrs
));
889 try
!(self.ibox(indent_unit
));
890 try
!(self.print_variant(v
));
891 try
!(word(&mut self.s
, ","));
893 try
!(self.maybe_print_trailing_comment(v
.span
, None
));
898 pub fn print_visibility(&mut self, vis
: hir
::Visibility
) -> io
::Result
<()> {
900 hir
::Public
=> self.word_nbsp("pub"),
901 hir
::Inherited
=> Ok(()),
905 pub fn print_struct(&mut self,
906 struct_def
: &hir
::VariantData
,
907 generics
: &hir
::Generics
,
910 print_finalizer
: bool
)
912 try
!(self.print_name(name
));
913 try
!(self.print_generics(generics
));
914 if !struct_def
.is_struct() {
915 if struct_def
.is_tuple() {
917 try
!(self.commasep(Inconsistent
, struct_def
.fields(), |s
, field
| {
918 match field
.node
.kind
{
919 hir
::NamedField(..) => panic
!("unexpected named field"),
920 hir
::UnnamedField(vis
) => {
921 try
!(s
.print_visibility(vis
));
922 try
!(s
.maybe_print_comment(field
.span
.lo
));
923 s
.print_type(&*field
.node
.ty
)
929 try
!(self.print_where_clause(&generics
.where_clause
));
931 try
!(word(&mut self.s
, ";"));
934 self.end() // close the outer-box
936 try
!(self.print_where_clause(&generics
.where_clause
));
939 try
!(self.hardbreak_if_not_bol());
941 for field
in struct_def
.fields() {
942 match field
.node
.kind
{
943 hir
::UnnamedField(..) => panic
!("unexpected unnamed field"),
944 hir
::NamedField(name
, visibility
) => {
945 try
!(self.hardbreak_if_not_bol());
946 try
!(self.maybe_print_comment(field
.span
.lo
));
947 try
!(self.print_outer_attributes(&field
.node
.attrs
));
948 try
!(self.print_visibility(visibility
));
949 try
!(self.print_name(name
));
950 try
!(self.word_nbsp(":"));
951 try
!(self.print_type(&*field
.node
.ty
));
952 try
!(word(&mut self.s
, ","));
961 pub fn print_variant(&mut self, v
: &hir
::Variant
) -> io
::Result
<()> {
963 let generics
= ::util
::empty_generics();
964 try
!(self.print_struct(&v
.node
.data
, &generics
, v
.node
.name
, v
.span
, false));
965 match v
.node
.disr_expr
{
967 try
!(space(&mut self.s
));
968 try
!(self.word_space("="));
969 self.print_expr(&**d
)
975 pub fn print_method_sig(&mut self,
978 vis
: hir
::Visibility
)
980 self.print_fn(&m
.decl
,
986 Some(&m
.explicit_self
.node
),
990 pub fn print_trait_item(&mut self, ti
: &hir
::TraitItem
) -> io
::Result
<()> {
991 try
!(self.ann
.pre(self, NodeSubItem(ti
.id
)));
992 try
!(self.hardbreak_if_not_bol());
993 try
!(self.maybe_print_comment(ti
.span
.lo
));
994 try
!(self.print_outer_attributes(&ti
.attrs
));
996 hir
::ConstTraitItem(ref ty
, ref default) => {
997 try
!(self.print_associated_const(ti
.name
,
999 default.as_ref().map(|expr
| &**expr
),
1002 hir
::MethodTraitItem(ref sig
, ref body
) => {
1004 try
!(self.head(""));
1006 try
!(self.print_method_sig(ti
.name
, sig
, hir
::Inherited
));
1007 if let Some(ref body
) = *body
{
1009 try
!(self.print_block_with_attrs(body
, &ti
.attrs
));
1011 try
!(word(&mut self.s
, ";"));
1014 hir
::TypeTraitItem(ref bounds
, ref default) => {
1015 try
!(self.print_associated_type(ti
.name
,
1017 default.as_ref().map(|ty
| &**ty
)));
1020 self.ann
.post(self, NodeSubItem(ti
.id
))
1023 pub fn print_impl_item(&mut self, ii
: &hir
::ImplItem
) -> io
::Result
<()> {
1024 try
!(self.ann
.pre(self, NodeSubItem(ii
.id
)));
1025 try
!(self.hardbreak_if_not_bol());
1026 try
!(self.maybe_print_comment(ii
.span
.lo
));
1027 try
!(self.print_outer_attributes(&ii
.attrs
));
1029 hir
::ImplItemKind
::Const(ref ty
, ref expr
) => {
1030 try
!(self.print_associated_const(ii
.name
, &ty
, Some(&expr
), ii
.vis
));
1032 hir
::ImplItemKind
::Method(ref sig
, ref body
) => {
1033 try
!(self.head(""));
1034 try
!(self.print_method_sig(ii
.name
, sig
, ii
.vis
));
1036 try
!(self.print_block_with_attrs(body
, &ii
.attrs
));
1038 hir
::ImplItemKind
::Type(ref ty
) => {
1039 try
!(self.print_associated_type(ii
.name
, None
, Some(ty
)));
1042 self.ann
.post(self, NodeSubItem(ii
.id
))
1045 pub fn print_stmt(&mut self, st
: &hir
::Stmt
) -> io
::Result
<()> {
1046 try
!(self.maybe_print_comment(st
.span
.lo
));
1048 hir
::StmtDecl(ref decl
, _
) => {
1049 try
!(self.print_decl(&**decl
));
1051 hir
::StmtExpr(ref expr
, _
) => {
1052 try
!(self.space_if_not_bol());
1053 try
!(self.print_expr(&**expr
));
1055 hir
::StmtSemi(ref expr
, _
) => {
1056 try
!(self.space_if_not_bol());
1057 try
!(self.print_expr(&**expr
));
1058 try
!(word(&mut self.s
, ";"));
1061 if stmt_ends_with_semi(&st
.node
) {
1062 try
!(word(&mut self.s
, ";"));
1064 self.maybe_print_trailing_comment(st
.span
, None
)
1067 pub fn print_block(&mut self, blk
: &hir
::Block
) -> io
::Result
<()> {
1068 self.print_block_with_attrs(blk
, &[])
1071 pub fn print_block_unclosed(&mut self, blk
: &hir
::Block
) -> io
::Result
<()> {
1072 self.print_block_unclosed_indent(blk
, indent_unit
)
1075 pub fn print_block_unclosed_indent(&mut self,
1079 self.print_block_maybe_unclosed(blk
, indented
, &[], false)
1082 pub fn print_block_with_attrs(&mut self,
1084 attrs
: &[ast
::Attribute
])
1086 self.print_block_maybe_unclosed(blk
, indent_unit
, attrs
, true)
1089 pub fn print_block_maybe_unclosed(&mut self,
1092 attrs
: &[ast
::Attribute
],
1096 hir
::UnsafeBlock(..) => try
!(self.word_space("unsafe")),
1097 hir
::PushUnsafeBlock(..) => try
!(self.word_space("push_unsafe")),
1098 hir
::PopUnsafeBlock(..) => try
!(self.word_space("pop_unsafe")),
1099 hir
::PushUnstableBlock
=> try
!(self.word_space("push_unstable")),
1100 hir
::PopUnstableBlock
=> try
!(self.word_space("pop_unstable")),
1101 hir
::DefaultBlock
=> (),
1103 try
!(self.maybe_print_comment(blk
.span
.lo
));
1104 try
!(self.ann
.pre(self, NodeBlock(blk
)));
1107 try
!(self.print_inner_attributes(attrs
));
1109 for st
in &blk
.stmts
{
1110 try
!(self.print_stmt(st
));
1114 try
!(self.space_if_not_bol());
1115 try
!(self.print_expr(&**expr
));
1116 try
!(self.maybe_print_trailing_comment(expr
.span
, Some(blk
.span
.hi
)));
1120 try
!(self.bclose_maybe_open(blk
.span
, indented
, close_box
));
1121 self.ann
.post(self, NodeBlock(blk
))
1124 fn print_else(&mut self, els
: Option
<&hir
::Expr
>) -> io
::Result
<()> {
1128 // "another else-if"
1129 hir
::ExprIf(ref i
, ref then
, ref e
) => {
1130 try
!(self.cbox(indent_unit
- 1));
1132 try
!(word(&mut self.s
, " else if "));
1133 try
!(self.print_expr(&**i
));
1134 try
!(space(&mut self.s
));
1135 try
!(self.print_block(&**then
));
1136 self.print_else(e
.as_ref().map(|e
| &**e
))
1139 hir
::ExprBlock(ref b
) => {
1140 try
!(self.cbox(indent_unit
- 1));
1142 try
!(word(&mut self.s
, " else "));
1143 self.print_block(&**b
)
1145 // BLEAH, constraints would be great here
1147 panic
!("print_if saw if with weird alternative");
1155 pub fn print_if(&mut self,
1158 elseopt
: Option
<&hir
::Expr
>)
1160 try
!(self.head("if"));
1161 try
!(self.print_expr(test
));
1162 try
!(space(&mut self.s
));
1163 try
!(self.print_block(blk
));
1164 self.print_else(elseopt
)
1167 pub fn print_if_let(&mut self,
1171 elseopt
: Option
<&hir
::Expr
>)
1173 try
!(self.head("if let"));
1174 try
!(self.print_pat(pat
));
1175 try
!(space(&mut self.s
));
1176 try
!(self.word_space("="));
1177 try
!(self.print_expr(expr
));
1178 try
!(space(&mut self.s
));
1179 try
!(self.print_block(blk
));
1180 self.print_else(elseopt
)
1184 fn print_call_post(&mut self, args
: &[P
<hir
::Expr
>]) -> io
::Result
<()> {
1186 try
!(self.commasep_exprs(Inconsistent
, args
));
1190 pub fn print_expr_maybe_paren(&mut self, expr
: &hir
::Expr
) -> io
::Result
<()> {
1191 let needs_par
= needs_parentheses(expr
);
1195 try
!(self.print_expr(expr
));
1197 try
!(self.pclose());
1202 fn print_expr_vec(&mut self, exprs
: &[P
<hir
::Expr
>]) -> io
::Result
<()> {
1203 try
!(self.ibox(indent_unit
));
1204 try
!(word(&mut self.s
, "["));
1205 try
!(self.commasep_exprs(Inconsistent
, &exprs
[..]));
1206 try
!(word(&mut self.s
, "]"));
1210 fn print_expr_repeat(&mut self, element
: &hir
::Expr
, count
: &hir
::Expr
) -> io
::Result
<()> {
1211 try
!(self.ibox(indent_unit
));
1212 try
!(word(&mut self.s
, "["));
1213 try
!(self.print_expr(element
));
1214 try
!(self.word_space(";"));
1215 try
!(self.print_expr(count
));
1216 try
!(word(&mut self.s
, "]"));
1220 fn print_expr_struct(&mut self,
1222 fields
: &[hir
::Field
],
1223 wth
: &Option
<P
<hir
::Expr
>>)
1225 try
!(self.print_path(path
, true, 0));
1226 try
!(word(&mut self.s
, "{"));
1227 try
!(self.commasep_cmnt(Consistent
,
1230 try
!(s
.ibox(indent_unit
));
1231 try
!(s
.print_name(field
.name
.node
));
1232 try
!(s
.word_space(":"));
1233 try
!(s
.print_expr(&*field
.expr
));
1239 try
!(self.ibox(indent_unit
));
1240 if !fields
.is_empty() {
1241 try
!(word(&mut self.s
, ","));
1242 try
!(space(&mut self.s
));
1244 try
!(word(&mut self.s
, ".."));
1245 try
!(self.print_expr(&**expr
));
1248 _
=> if !fields
.is_empty() {
1249 try
!(word(&mut self.s
, ","))
1252 try
!(word(&mut self.s
, "}"));
1256 fn print_expr_tup(&mut self, exprs
: &[P
<hir
::Expr
>]) -> io
::Result
<()> {
1258 try
!(self.commasep_exprs(Inconsistent
, &exprs
[..]));
1259 if exprs
.len() == 1 {
1260 try
!(word(&mut self.s
, ","));
1265 fn print_expr_call(&mut self, func
: &hir
::Expr
, args
: &[P
<hir
::Expr
>]) -> io
::Result
<()> {
1266 try
!(self.print_expr_maybe_paren(func
));
1267 self.print_call_post(args
)
1270 fn print_expr_method_call(&mut self,
1271 name
: Spanned
<ast
::Name
>,
1273 args
: &[P
<hir
::Expr
>])
1275 let base_args
= &args
[1..];
1276 try
!(self.print_expr(&*args
[0]));
1277 try
!(word(&mut self.s
, "."));
1278 try
!(self.print_name(name
.node
));
1279 if !tys
.is_empty() {
1280 try
!(word(&mut self.s
, "::<"));
1281 try
!(self.commasep(Inconsistent
, tys
, |s
, ty
| s
.print_type(&**ty
)));
1282 try
!(word(&mut self.s
, ">"));
1284 self.print_call_post(base_args
)
1287 fn print_expr_binary(&mut self,
1292 try
!(self.print_expr(lhs
));
1293 try
!(space(&mut self.s
));
1294 try
!(self.word_space(::util
::binop_to_string(op
.node
)));
1295 self.print_expr(rhs
)
1298 fn print_expr_unary(&mut self, op
: hir
::UnOp
, expr
: &hir
::Expr
) -> io
::Result
<()> {
1299 try
!(word(&mut self.s
, ::util
::unop_to_string(op
)));
1300 self.print_expr_maybe_paren(expr
)
1303 fn print_expr_addr_of(&mut self,
1304 mutability
: hir
::Mutability
,
1307 try
!(word(&mut self.s
, "&"));
1308 try
!(self.print_mutability(mutability
));
1309 self.print_expr_maybe_paren(expr
)
1312 pub fn print_expr(&mut self, expr
: &hir
::Expr
) -> io
::Result
<()> {
1313 try
!(self.maybe_print_comment(expr
.span
.lo
));
1314 try
!(self.ibox(indent_unit
));
1315 try
!(self.ann
.pre(self, NodeExpr(expr
)));
1317 hir
::ExprBox(ref expr
) => {
1318 try
!(self.word_space("box"));
1319 try
!(self.print_expr(expr
));
1321 hir
::ExprVec(ref exprs
) => {
1322 try
!(self.print_expr_vec(&exprs
[..]));
1324 hir
::ExprRepeat(ref element
, ref count
) => {
1325 try
!(self.print_expr_repeat(&**element
, &**count
));
1327 hir
::ExprStruct(ref path
, ref fields
, ref wth
) => {
1328 try
!(self.print_expr_struct(path
, &fields
[..], wth
));
1330 hir
::ExprTup(ref exprs
) => {
1331 try
!(self.print_expr_tup(&exprs
[..]));
1333 hir
::ExprCall(ref func
, ref args
) => {
1334 try
!(self.print_expr_call(&**func
, &args
[..]));
1336 hir
::ExprMethodCall(name
, ref tys
, ref args
) => {
1337 try
!(self.print_expr_method_call(name
, &tys
[..], &args
[..]));
1339 hir
::ExprBinary(op
, ref lhs
, ref rhs
) => {
1340 try
!(self.print_expr_binary(op
, &**lhs
, &**rhs
));
1342 hir
::ExprUnary(op
, ref expr
) => {
1343 try
!(self.print_expr_unary(op
, &**expr
));
1345 hir
::ExprAddrOf(m
, ref expr
) => {
1346 try
!(self.print_expr_addr_of(m
, &**expr
));
1348 hir
::ExprLit(ref lit
) => {
1349 try
!(self.print_literal(&**lit
));
1351 hir
::ExprCast(ref expr
, ref ty
) => {
1352 try
!(self.print_expr(&**expr
));
1353 try
!(space(&mut self.s
));
1354 try
!(self.word_space("as"));
1355 try
!(self.print_type(&**ty
));
1357 hir
::ExprIf(ref test
, ref blk
, ref elseopt
) => {
1358 try
!(self.print_if(&**test
, &**blk
, elseopt
.as_ref().map(|e
| &**e
)));
1360 hir
::ExprWhile(ref test
, ref blk
, opt_ident
) => {
1361 if let Some(ident
) = opt_ident
{
1362 try
!(self.print_name(ident
.name
));
1363 try
!(self.word_space(":"));
1365 try
!(self.head("while"));
1366 try
!(self.print_expr(&**test
));
1367 try
!(space(&mut self.s
));
1368 try
!(self.print_block(&**blk
));
1370 hir
::ExprLoop(ref blk
, opt_ident
) => {
1371 if let Some(ident
) = opt_ident
{
1372 try
!(self.print_name(ident
.name
));
1373 try
!(self.word_space(":"));
1375 try
!(self.head("loop"));
1376 try
!(space(&mut self.s
));
1377 try
!(self.print_block(&**blk
));
1379 hir
::ExprMatch(ref expr
, ref arms
, _
) => {
1380 try
!(self.cbox(indent_unit
));
1382 try
!(self.word_nbsp("match"));
1383 try
!(self.print_expr(&**expr
));
1384 try
!(space(&mut self.s
));
1387 try
!(self.print_arm(arm
));
1389 try
!(self.bclose_(expr
.span
, indent_unit
));
1391 hir
::ExprClosure(capture_clause
, ref decl
, ref body
) => {
1392 try
!(self.print_capture_clause(capture_clause
));
1394 try
!(self.print_fn_block_args(&**decl
));
1395 try
!(space(&mut self.s
));
1397 let default_return
= match decl
.output
{
1398 hir
::DefaultReturn(..) => true,
1402 if !default_return
|| !body
.stmts
.is_empty() || body
.expr
.is_none() {
1403 try
!(self.print_block_unclosed(&**body
));
1405 // we extract the block, so as not to create another set of boxes
1406 match body
.expr
.as_ref().unwrap().node
{
1407 hir
::ExprBlock(ref blk
) => {
1408 try
!(self.print_block_unclosed(&**blk
));
1411 // this is a bare expression
1412 try
!(self.print_expr(body
.expr
.as_ref().map(|e
| &**e
).unwrap()));
1413 try
!(self.end()); // need to close a box
1417 // a box will be closed by print_expr, but we didn't want an overall
1418 // wrapper so we closed the corresponding opening. so create an
1419 // empty box to satisfy the close.
1422 hir
::ExprBlock(ref blk
) => {
1423 // containing cbox, will be closed by print-block at }
1424 try
!(self.cbox(indent_unit
));
1425 // head-box, will be closed by print-block after {
1427 try
!(self.print_block(&**blk
));
1429 hir
::ExprAssign(ref lhs
, ref rhs
) => {
1430 try
!(self.print_expr(&**lhs
));
1431 try
!(space(&mut self.s
));
1432 try
!(self.word_space("="));
1433 try
!(self.print_expr(&**rhs
));
1435 hir
::ExprAssignOp(op
, ref lhs
, ref rhs
) => {
1436 try
!(self.print_expr(&**lhs
));
1437 try
!(space(&mut self.s
));
1438 try
!(word(&mut self.s
, ::util
::binop_to_string(op
.node
)));
1439 try
!(self.word_space("="));
1440 try
!(self.print_expr(&**rhs
));
1442 hir
::ExprField(ref expr
, name
) => {
1443 try
!(self.print_expr(&**expr
));
1444 try
!(word(&mut self.s
, "."));
1445 try
!(self.print_name(name
.node
));
1447 hir
::ExprTupField(ref expr
, id
) => {
1448 try
!(self.print_expr(&**expr
));
1449 try
!(word(&mut self.s
, "."));
1450 try
!(self.print_usize(id
.node
));
1452 hir
::ExprIndex(ref expr
, ref index
) => {
1453 try
!(self.print_expr(&**expr
));
1454 try
!(word(&mut self.s
, "["));
1455 try
!(self.print_expr(&**index
));
1456 try
!(word(&mut self.s
, "]"));
1458 hir
::ExprRange(ref start
, ref end
) => {
1459 if let &Some(ref e
) = start
{
1460 try
!(self.print_expr(&**e
));
1462 try
!(word(&mut self.s
, ".."));
1463 if let &Some(ref e
) = end
{
1464 try
!(self.print_expr(&**e
));
1467 hir
::ExprPath(None
, ref path
) => {
1468 try
!(self.print_path(path
, true, 0))
1470 hir
::ExprPath(Some(ref qself
), ref path
) => {
1471 try
!(self.print_qpath(path
, qself
, true))
1473 hir
::ExprBreak(opt_ident
) => {
1474 try
!(word(&mut self.s
, "break"));
1475 try
!(space(&mut self.s
));
1476 if let Some(ident
) = opt_ident
{
1477 try
!(self.print_name(ident
.node
.name
));
1478 try
!(space(&mut self.s
));
1481 hir
::ExprAgain(opt_ident
) => {
1482 try
!(word(&mut self.s
, "continue"));
1483 try
!(space(&mut self.s
));
1484 if let Some(ident
) = opt_ident
{
1485 try
!(self.print_name(ident
.node
.name
));
1486 try
!(space(&mut self.s
))
1489 hir
::ExprRet(ref result
) => {
1490 try
!(word(&mut self.s
, "return"));
1493 try
!(word(&mut self.s
, " "));
1494 try
!(self.print_expr(&**expr
));
1499 hir
::ExprInlineAsm(ref a
) => {
1500 try
!(word(&mut self.s
, "asm!"));
1502 try
!(self.print_string(&a
.asm
, a
.asm_str_style
));
1503 try
!(self.word_space(":"));
1505 try
!(self.commasep(Inconsistent
, &a
.outputs
, |s
, &(ref co
, ref o
, is_rw
)| {
1506 match co
.slice_shift_char() {
1507 Some(('
='
, operand
)) if is_rw
=> {
1508 try
!(s
.print_string(&format
!("+{}", operand
), ast
::CookedStr
))
1510 _
=> try
!(s
.print_string(&co
, ast
::CookedStr
)),
1513 try
!(s
.print_expr(&**o
));
1517 try
!(space(&mut self.s
));
1518 try
!(self.word_space(":"));
1520 try
!(self.commasep(Inconsistent
, &a
.inputs
, |s
, &(ref co
, ref o
)| {
1521 try
!(s
.print_string(&co
, ast
::CookedStr
));
1523 try
!(s
.print_expr(&**o
));
1527 try
!(space(&mut self.s
));
1528 try
!(self.word_space(":"));
1530 try
!(self.commasep(Inconsistent
, &a
.clobbers
, |s
, co
| {
1531 try
!(s
.print_string(&co
, ast
::CookedStr
));
1535 let mut options
= vec
![];
1537 options
.push("volatile");
1540 options
.push("alignstack");
1542 if a
.dialect
== ast
::AsmDialect
::Intel
{
1543 options
.push("intel");
1546 if !options
.is_empty() {
1547 try
!(space(&mut self.s
));
1548 try
!(self.word_space(":"));
1549 try
!(self.commasep(Inconsistent
, &*options
, |s
, &co
| {
1550 try
!(s
.print_string(co
, ast
::CookedStr
));
1555 try
!(self.pclose());
1558 try
!(self.ann
.post(self, NodeExpr(expr
)));
1562 pub fn print_local_decl(&mut self, loc
: &hir
::Local
) -> io
::Result
<()> {
1563 try
!(self.print_pat(&*loc
.pat
));
1564 if let Some(ref ty
) = loc
.ty
{
1565 try
!(self.word_space(":"));
1566 try
!(self.print_type(&**ty
));
1571 pub fn print_decl(&mut self, decl
: &hir
::Decl
) -> io
::Result
<()> {
1572 try
!(self.maybe_print_comment(decl
.span
.lo
));
1574 hir
::DeclLocal(ref loc
) => {
1575 try
!(self.space_if_not_bol());
1576 try
!(self.ibox(indent_unit
));
1577 try
!(self.word_nbsp("let"));
1579 try
!(self.ibox(indent_unit
));
1580 try
!(self.print_local_decl(&**loc
));
1582 if let Some(ref init
) = loc
.init
{
1584 try
!(self.word_space("="));
1585 try
!(self.print_expr(&**init
));
1589 hir
::DeclItem(ref item
) => {
1590 self.print_item_id(item
)
1595 pub fn print_usize(&mut self, i
: usize) -> io
::Result
<()> {
1596 word(&mut self.s
, &i
.to_string())
1599 pub fn print_name(&mut self, name
: ast
::Name
) -> io
::Result
<()> {
1600 try
!(word(&mut self.s
, &name
.as_str()));
1601 self.ann
.post(self, NodeName(&name
))
1604 pub fn print_for_decl(&mut self, loc
: &hir
::Local
, coll
: &hir
::Expr
) -> io
::Result
<()> {
1605 try
!(self.print_local_decl(loc
));
1606 try
!(space(&mut self.s
));
1607 try
!(self.word_space("in"));
1608 self.print_expr(coll
)
1611 fn print_path(&mut self,
1613 colons_before_params
: bool
,
1616 try
!(self.maybe_print_comment(path
.span
.lo
));
1618 let mut first
= !path
.global
;
1619 for segment
in &path
.segments
[..path
.segments
.len() - depth
] {
1623 try
!(word(&mut self.s
, "::"))
1626 try
!(self.print_name(segment
.identifier
.name
));
1628 try
!(self.print_path_parameters(&segment
.parameters
, colons_before_params
));
1634 fn print_qpath(&mut self,
1637 colons_before_params
: bool
)
1639 try
!(word(&mut self.s
, "<"));
1640 try
!(self.print_type(&qself
.ty
));
1641 if qself
.position
> 0 {
1642 try
!(space(&mut self.s
));
1643 try
!(self.word_space("as"));
1644 let depth
= path
.segments
.len() - qself
.position
;
1645 try
!(self.print_path(&path
, false, depth
));
1647 try
!(word(&mut self.s
, ">"));
1648 try
!(word(&mut self.s
, "::"));
1649 let item_segment
= path
.segments
.last().unwrap();
1650 try
!(self.print_name(item_segment
.identifier
.name
));
1651 self.print_path_parameters(&item_segment
.parameters
, colons_before_params
)
1654 fn print_path_parameters(&mut self,
1655 parameters
: &hir
::PathParameters
,
1656 colons_before_params
: bool
)
1658 if parameters
.is_empty() {
1662 if colons_before_params
{
1663 try
!(word(&mut self.s
, "::"))
1667 hir
::AngleBracketedParameters(ref data
) => {
1668 try
!(word(&mut self.s
, "<"));
1670 let mut comma
= false;
1671 for lifetime
in &data
.lifetimes
{
1673 try
!(self.word_space(","))
1675 try
!(self.print_lifetime(lifetime
));
1679 if !data
.types
.is_empty() {
1681 try
!(self.word_space(","))
1683 try
!(self.commasep(Inconsistent
, &data
.types
, |s
, ty
| s
.print_type(&**ty
)));
1687 for binding
in data
.bindings
.iter() {
1689 try
!(self.word_space(","))
1691 try
!(self.print_name(binding
.name
));
1692 try
!(space(&mut self.s
));
1693 try
!(self.word_space("="));
1694 try
!(self.print_type(&*binding
.ty
));
1698 try
!(word(&mut self.s
, ">"))
1701 hir
::ParenthesizedParameters(ref data
) => {
1702 try
!(word(&mut self.s
, "("));
1703 try
!(self.commasep(Inconsistent
, &data
.inputs
, |s
, ty
| s
.print_type(&**ty
)));
1704 try
!(word(&mut self.s
, ")"));
1709 try
!(self.space_if_not_bol());
1710 try
!(self.word_space("->"));
1711 try
!(self.print_type(&**ty
));
1720 pub fn print_pat(&mut self, pat
: &hir
::Pat
) -> io
::Result
<()> {
1721 try
!(self.maybe_print_comment(pat
.span
.lo
));
1722 try
!(self.ann
.pre(self, NodePat(pat
)));
1723 // Pat isn't normalized, but the beauty of it
1724 // is that it doesn't matter
1726 hir
::PatWild
=> try
!(word(&mut self.s
, "_")),
1727 hir
::PatIdent(binding_mode
, ref path1
, ref sub
) => {
1728 match binding_mode
{
1729 hir
::BindByRef(mutbl
) => {
1730 try
!(self.word_nbsp("ref"));
1731 try
!(self.print_mutability(mutbl
));
1733 hir
::BindByValue(hir
::MutImmutable
) => {}
1734 hir
::BindByValue(hir
::MutMutable
) => {
1735 try
!(self.word_nbsp("mut"));
1738 try
!(self.print_name(path1
.node
.name
));
1741 try
!(word(&mut self.s
, "@"));
1742 try
!(self.print_pat(&**p
));
1747 hir
::PatEnum(ref path
, ref args_
) => {
1748 try
!(self.print_path(path
, true, 0));
1750 None
=> try
!(word(&mut self.s
, "(..)")),
1752 if !args
.is_empty() {
1754 try
!(self.commasep(Inconsistent
, &args
[..], |s
, p
| s
.print_pat(&**p
)));
1755 try
!(self.pclose());
1760 hir
::PatQPath(ref qself
, ref path
) => {
1761 try
!(self.print_qpath(path
, qself
, false));
1763 hir
::PatStruct(ref path
, ref fields
, etc
) => {
1764 try
!(self.print_path(path
, true, 0));
1766 try
!(self.word_space("{"));
1767 try
!(self.commasep_cmnt(Consistent
,
1770 try
!(s
.cbox(indent_unit
));
1771 if !f
.node
.is_shorthand
{
1772 try
!(s
.print_name(f
.node
.name
));
1773 try
!(s
.word_nbsp(":"));
1775 try
!(s
.print_pat(&*f
.node
.pat
));
1778 |f
| f
.node
.pat
.span
));
1780 if !fields
.is_empty() {
1781 try
!(self.word_space(","));
1783 try
!(word(&mut self.s
, ".."));
1785 try
!(space(&mut self.s
));
1786 try
!(word(&mut self.s
, "}"));
1788 hir
::PatTup(ref elts
) => {
1790 try
!(self.commasep(Inconsistent
, &elts
[..], |s
, p
| s
.print_pat(&**p
)));
1791 if elts
.len() == 1 {
1792 try
!(word(&mut self.s
, ","));
1794 try
!(self.pclose());
1796 hir
::PatBox(ref inner
) => {
1797 try
!(word(&mut self.s
, "box "));
1798 try
!(self.print_pat(&**inner
));
1800 hir
::PatRegion(ref inner
, mutbl
) => {
1801 try
!(word(&mut self.s
, "&"));
1802 if mutbl
== hir
::MutMutable
{
1803 try
!(word(&mut self.s
, "mut "));
1805 try
!(self.print_pat(&**inner
));
1807 hir
::PatLit(ref e
) => try
!(self.print_expr(&**e
)),
1808 hir
::PatRange(ref begin
, ref end
) => {
1809 try
!(self.print_expr(&**begin
));
1810 try
!(space(&mut self.s
));
1811 try
!(word(&mut self.s
, "..."));
1812 try
!(self.print_expr(&**end
));
1814 hir
::PatVec(ref before
, ref slice
, ref after
) => {
1815 try
!(word(&mut self.s
, "["));
1816 try
!(self.commasep(Inconsistent
, &before
[..], |s
, p
| s
.print_pat(&**p
)));
1817 if let Some(ref p
) = *slice
{
1818 if !before
.is_empty() {
1819 try
!(self.word_space(","));
1821 if p
.node
!= hir
::PatWild
{
1822 try
!(self.print_pat(&**p
));
1824 try
!(word(&mut self.s
, ".."));
1825 if !after
.is_empty() {
1826 try
!(self.word_space(","));
1829 try
!(self.commasep(Inconsistent
, &after
[..], |s
, p
| s
.print_pat(&**p
)));
1830 try
!(word(&mut self.s
, "]"));
1833 self.ann
.post(self, NodePat(pat
))
1836 fn print_arm(&mut self, arm
: &hir
::Arm
) -> io
::Result
<()> {
1837 // I have no idea why this check is necessary, but here it
1839 if arm
.attrs
.is_empty() {
1840 try
!(space(&mut self.s
));
1842 try
!(self.cbox(indent_unit
));
1844 try
!(self.print_outer_attributes(&arm
.attrs
));
1845 let mut first
= true;
1846 for p
in &arm
.pats
{
1850 try
!(space(&mut self.s
));
1851 try
!(self.word_space("|"));
1853 try
!(self.print_pat(&**p
));
1855 try
!(space(&mut self.s
));
1856 if let Some(ref e
) = arm
.guard
{
1857 try
!(self.word_space("if"));
1858 try
!(self.print_expr(&**e
));
1859 try
!(space(&mut self.s
));
1861 try
!(self.word_space("=>"));
1863 match arm
.body
.node
{
1864 hir
::ExprBlock(ref blk
) => {
1865 // the block will close the pattern's ibox
1866 try
!(self.print_block_unclosed_indent(&**blk
, indent_unit
));
1868 // If it is a user-provided unsafe block, print a comma after it
1869 if let hir
::UnsafeBlock(hir
::UserProvided
) = blk
.rules
{
1870 try
!(word(&mut self.s
, ","));
1874 try
!(self.end()); // close the ibox for the pattern
1875 try
!(self.print_expr(&*arm
.body
));
1876 try
!(word(&mut self.s
, ","));
1879 self.end() // close enclosing cbox
1882 // Returns whether it printed anything
1883 fn print_explicit_self(&mut self,
1884 explicit_self
: &hir
::ExplicitSelf_
,
1885 mutbl
: hir
::Mutability
)
1886 -> io
::Result
<bool
> {
1887 try
!(self.print_mutability(mutbl
));
1888 match *explicit_self
{
1889 hir
::SelfStatic
=> {
1892 hir
::SelfValue(_
) => {
1893 try
!(word(&mut self.s
, "self"));
1895 hir
::SelfRegion(ref lt
, m
, _
) => {
1896 try
!(word(&mut self.s
, "&"));
1897 try
!(self.print_opt_lifetime(lt
));
1898 try
!(self.print_mutability(m
));
1899 try
!(word(&mut self.s
, "self"));
1901 hir
::SelfExplicit(ref typ
, _
) => {
1902 try
!(word(&mut self.s
, "self"));
1903 try
!(self.word_space(":"));
1904 try
!(self.print_type(&**typ
));
1910 pub fn print_fn(&mut self,
1912 unsafety
: hir
::Unsafety
,
1913 constness
: hir
::Constness
,
1915 name
: Option
<ast
::Name
>,
1916 generics
: &hir
::Generics
,
1917 opt_explicit_self
: Option
<&hir
::ExplicitSelf_
>,
1918 vis
: hir
::Visibility
)
1920 try
!(self.print_fn_header_info(unsafety
, constness
, abi
, vis
));
1922 if let Some(name
) = name
{
1924 try
!(self.print_name(name
));
1926 try
!(self.print_generics(generics
));
1927 try
!(self.print_fn_args_and_ret(decl
, opt_explicit_self
));
1928 self.print_where_clause(&generics
.where_clause
)
1931 pub fn print_fn_args(&mut self,
1933 opt_explicit_self
: Option
<&hir
::ExplicitSelf_
>)
1935 // It is unfortunate to duplicate the commasep logic, but we want the
1936 // self type and the args all in the same box.
1937 try
!(self.rbox(0, Inconsistent
));
1938 let mut first
= true;
1939 if let Some(explicit_self
) = opt_explicit_self
{
1940 let m
= match explicit_self
{
1941 &hir
::SelfStatic
=> hir
::MutImmutable
,
1942 _
=> match decl
.inputs
[0].pat
.node
{
1943 hir
::PatIdent(hir
::BindByValue(m
), _
, _
) => m
,
1944 _
=> hir
::MutImmutable
,
1947 first
= !try
!(self.print_explicit_self(explicit_self
, m
));
1950 // HACK(eddyb) ignore the separately printed self argument.
1951 let args
= if first
{
1961 try
!(self.word_space(","));
1963 try
!(self.print_arg(arg
));
1969 pub fn print_fn_args_and_ret(&mut self,
1971 opt_explicit_self
: Option
<&hir
::ExplicitSelf_
>)
1974 try
!(self.print_fn_args(decl
, opt_explicit_self
));
1976 try
!(word(&mut self.s
, ", ..."));
1978 try
!(self.pclose());
1980 self.print_fn_output(decl
)
1983 pub fn print_fn_block_args(&mut self, decl
: &hir
::FnDecl
) -> io
::Result
<()> {
1984 try
!(word(&mut self.s
, "|"));
1985 try
!(self.print_fn_args(decl
, None
));
1986 try
!(word(&mut self.s
, "|"));
1988 if let hir
::DefaultReturn(..) = decl
.output
{
1992 try
!(self.space_if_not_bol());
1993 try
!(self.word_space("->"));
1995 hir
::Return(ref ty
) => {
1996 try
!(self.print_type(&**ty
));
1997 self.maybe_print_comment(ty
.span
.lo
)
1999 hir
::DefaultReturn(..) => unreachable
!(),
2000 hir
::NoReturn(span
) => {
2001 try
!(self.word_nbsp("!"));
2002 self.maybe_print_comment(span
.lo
)
2007 pub fn print_capture_clause(&mut self, capture_clause
: hir
::CaptureClause
) -> io
::Result
<()> {
2008 match capture_clause
{
2009 hir
::CaptureByValue
=> self.word_space("move"),
2010 hir
::CaptureByRef
=> Ok(()),
2014 pub fn print_bounds(&mut self, prefix
: &str, bounds
: &[hir
::TyParamBound
]) -> io
::Result
<()> {
2015 if !bounds
.is_empty() {
2016 try
!(word(&mut self.s
, prefix
));
2017 let mut first
= true;
2018 for bound
in bounds
{
2023 try
!(self.word_space("+"));
2027 TraitTyParamBound(ref tref
, TraitBoundModifier
::None
) => {
2028 self.print_poly_trait_ref(tref
)
2030 TraitTyParamBound(ref tref
, TraitBoundModifier
::Maybe
) => {
2031 try
!(word(&mut self.s
, "?"));
2032 self.print_poly_trait_ref(tref
)
2034 RegionTyParamBound(ref lt
) => {
2035 self.print_lifetime(lt
)
2045 pub fn print_lifetime(&mut self, lifetime
: &hir
::Lifetime
) -> io
::Result
<()> {
2046 self.print_name(lifetime
.name
)
2049 pub fn print_lifetime_def(&mut self, lifetime
: &hir
::LifetimeDef
) -> io
::Result
<()> {
2050 try
!(self.print_lifetime(&lifetime
.lifetime
));
2052 for v
in &lifetime
.bounds
{
2053 try
!(word(&mut self.s
, sep
));
2054 try
!(self.print_lifetime(v
));
2060 pub fn print_generics(&mut self, generics
: &hir
::Generics
) -> io
::Result
<()> {
2061 let total
= generics
.lifetimes
.len() + generics
.ty_params
.len();
2066 try
!(word(&mut self.s
, "<"));
2068 let mut ints
= Vec
::new();
2073 try
!(self.commasep(Inconsistent
, &ints
[..], |s
, &idx
| {
2074 if idx
< generics
.lifetimes
.len() {
2075 let lifetime
= &generics
.lifetimes
[idx
];
2076 s
.print_lifetime_def(lifetime
)
2078 let idx
= idx
- generics
.lifetimes
.len();
2079 let param
= &generics
.ty_params
[idx
];
2080 s
.print_ty_param(param
)
2084 try
!(word(&mut self.s
, ">"));
2088 pub fn print_ty_param(&mut self, param
: &hir
::TyParam
) -> io
::Result
<()> {
2089 try
!(self.print_name(param
.name
));
2090 try
!(self.print_bounds(":", ¶m
.bounds
));
2091 match param
.default {
2092 Some(ref default) => {
2093 try
!(space(&mut self.s
));
2094 try
!(self.word_space("="));
2095 self.print_type(&**default)
2101 pub fn print_where_clause(&mut self, where_clause
: &hir
::WhereClause
) -> io
::Result
<()> {
2102 if where_clause
.predicates
.is_empty() {
2106 try
!(space(&mut self.s
));
2107 try
!(self.word_space("where"));
2109 for (i
, predicate
) in where_clause
.predicates
.iter().enumerate() {
2111 try
!(self.word_space(","));
2115 &hir
::WherePredicate
::BoundPredicate(hir
::WhereBoundPredicate
{ref bound_lifetimes
,
2119 try
!(self.print_formal_lifetime_list(bound_lifetimes
));
2120 try
!(self.print_type(&**bounded_ty
));
2121 try
!(self.print_bounds(":", bounds
));
2123 &hir
::WherePredicate
::RegionPredicate(hir
::WhereRegionPredicate
{ref lifetime
,
2126 try
!(self.print_lifetime(lifetime
));
2127 try
!(word(&mut self.s
, ":"));
2129 for (i
, bound
) in bounds
.iter().enumerate() {
2130 try
!(self.print_lifetime(bound
));
2133 try
!(word(&mut self.s
, ":"));
2137 &hir
::WherePredicate
::EqPredicate(hir
::WhereEqPredicate{ref path, ref ty, ..}
) => {
2138 try
!(self.print_path(path
, false, 0));
2139 try
!(space(&mut self.s
));
2140 try
!(self.word_space("="));
2141 try
!(self.print_type(&**ty
));
2149 pub fn print_view_path(&mut self, vp
: &hir
::ViewPath
) -> io
::Result
<()> {
2151 hir
::ViewPathSimple(name
, ref path
) => {
2152 try
!(self.print_path(path
, false, 0));
2154 if path
.segments
.last().unwrap().identifier
.name
!= name
{
2155 try
!(space(&mut self.s
));
2156 try
!(self.word_space("as"));
2157 try
!(self.print_name(name
));
2163 hir
::ViewPathGlob(ref path
) => {
2164 try
!(self.print_path(path
, false, 0));
2165 word(&mut self.s
, "::*")
2168 hir
::ViewPathList(ref path
, ref segments
) => {
2169 if path
.segments
.is_empty() {
2170 try
!(word(&mut self.s
, "{"));
2172 try
!(self.print_path(path
, false, 0));
2173 try
!(word(&mut self.s
, "::{"));
2175 try
!(self.commasep(Inconsistent
, &segments
[..], |s
, w
| {
2177 hir
::PathListIdent { name, .. }
=> {
2180 hir
::PathListMod { .. }
=> {
2181 word(&mut s
.s
, "self")
2185 word(&mut self.s
, "}")
2190 pub fn print_mutability(&mut self, mutbl
: hir
::Mutability
) -> io
::Result
<()> {
2192 hir
::MutMutable
=> self.word_nbsp("mut"),
2193 hir
::MutImmutable
=> Ok(()),
2197 pub fn print_mt(&mut self, mt
: &hir
::MutTy
) -> io
::Result
<()> {
2198 try
!(self.print_mutability(mt
.mutbl
));
2199 self.print_type(&*mt
.ty
)
2202 pub fn print_arg(&mut self, input
: &hir
::Arg
) -> io
::Result
<()> {
2203 try
!(self.ibox(indent_unit
));
2204 match input
.ty
.node
{
2205 hir
::TyInfer
=> try
!(self.print_pat(&*input
.pat
)),
2207 match input
.pat
.node
{
2208 hir
::PatIdent(_
, ref path1
, _
) if
2210 parse
::token
::special_idents
::invalid
.name
=> {
2214 try
!(self.print_pat(&*input
.pat
));
2215 try
!(word(&mut self.s
, ":"));
2216 try
!(space(&mut self.s
));
2219 try
!(self.print_type(&*input
.ty
));
2225 pub fn print_fn_output(&mut self, decl
: &hir
::FnDecl
) -> io
::Result
<()> {
2226 if let hir
::DefaultReturn(..) = decl
.output
{
2230 try
!(self.space_if_not_bol());
2231 try
!(self.ibox(indent_unit
));
2232 try
!(self.word_space("->"));
2234 hir
::NoReturn(_
) => try
!(self.word_nbsp("!")),
2235 hir
::DefaultReturn(..) => unreachable
!(),
2236 hir
::Return(ref ty
) => try
!(self.print_type(&**ty
)),
2241 hir
::Return(ref output
) => self.maybe_print_comment(output
.span
.lo
),
2246 pub fn print_ty_fn(&mut self,
2248 unsafety
: hir
::Unsafety
,
2250 name
: Option
<ast
::Name
>,
2251 generics
: &hir
::Generics
,
2252 opt_explicit_self
: Option
<&hir
::ExplicitSelf_
>)
2254 try
!(self.ibox(indent_unit
));
2255 if !generics
.lifetimes
.is_empty() || !generics
.ty_params
.is_empty() {
2256 try
!(word(&mut self.s
, "for"));
2257 try
!(self.print_generics(generics
));
2259 let generics
= hir
::Generics
{
2260 lifetimes
: Vec
::new(),
2261 ty_params
: OwnedSlice
::empty(),
2262 where_clause
: hir
::WhereClause
{
2263 id
: ast
::DUMMY_NODE_ID
,
2264 predicates
: Vec
::new(),
2267 try
!(self.print_fn(decl
,
2269 hir
::Constness
::NotConst
,
2278 pub fn maybe_print_trailing_comment(&mut self,
2279 span
: codemap
::Span
,
2280 next_pos
: Option
<BytePos
>)
2282 let cm
= match self.cm
{
2286 match self.next_comment() {
2288 if (*cmnt
).style
!= comments
::Trailing
{
2291 let span_line
= cm
.lookup_char_pos(span
.hi
);
2292 let comment_line
= cm
.lookup_char_pos((*cmnt
).pos
);
2293 let mut next
= (*cmnt
).pos
+ BytePos(1);
2296 Some(p
) => next
= p
,
2298 if span
.hi
< (*cmnt
).pos
&& (*cmnt
).pos
< next
&&
2299 span_line
.line
== comment_line
.line
{
2300 try
!(self.print_comment(cmnt
));
2301 self.cur_cmnt_and_lit
.cur_cmnt
+= 1;
2309 pub fn print_remaining_comments(&mut self) -> io
::Result
<()> {
2310 // If there aren't any remaining comments, then we need to manually
2311 // make sure there is a line break at the end.
2312 if self.next_comment().is_none() {
2313 try
!(hardbreak(&mut self.s
));
2316 match self.next_comment() {
2318 try
!(self.print_comment(cmnt
));
2319 self.cur_cmnt_and_lit
.cur_cmnt
+= 1;
2327 pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
2328 opt_abi
: Option
<abi
::Abi
>)
2331 Some(abi
::Rust
) => Ok(()),
2333 try
!(self.word_nbsp("extern"));
2334 self.word_nbsp(&abi
.to_string())
2340 pub fn print_extern_opt_abi(&mut self, opt_abi
: Option
<abi
::Abi
>) -> io
::Result
<()> {
2343 try
!(self.word_nbsp("extern"));
2344 self.word_nbsp(&abi
.to_string())
2350 pub fn print_fn_header_info(&mut self,
2351 unsafety
: hir
::Unsafety
,
2352 constness
: hir
::Constness
,
2354 vis
: hir
::Visibility
)
2356 try
!(word(&mut self.s
, &visibility_qualified(vis
, "")));
2357 try
!(self.print_unsafety(unsafety
));
2360 hir
::Constness
::NotConst
=> {}
2361 hir
::Constness
::Const
=> try
!(self.word_nbsp("const")),
2364 if abi
!= abi
::Rust
{
2365 try
!(self.word_nbsp("extern"));
2366 try
!(self.word_nbsp(&abi
.to_string()));
2369 word(&mut self.s
, "fn")
2372 pub fn print_unsafety(&mut self, s
: hir
::Unsafety
) -> io
::Result
<()> {
2374 hir
::Unsafety
::Normal
=> Ok(()),
2375 hir
::Unsafety
::Unsafe
=> self.word_nbsp("unsafe"),
2380 // Dup'ed from parse::classify, but adapted for the HIR.
2381 /// Does this expression require a semicolon to be treated
2382 /// as a statement? The negation of this: 'can this expression
2383 /// be used as a statement without a semicolon' -- is used
2384 /// as an early-bail-out in the parser so that, for instance,
2385 /// if true {...} else {...}
2387 /// isn't parsed as (if true {...} else {...} | x) | 5
2388 fn expr_requires_semi_to_be_stmt(e
: &hir
::Expr
) -> bool
{
2391 hir
::ExprMatch(..) |
2393 hir
::ExprWhile(..) |
2394 hir
::ExprLoop(..) => false,
2399 /// this statement requires a semicolon after it.
2400 /// note that in one case (stmt_semi), we've already
2401 /// seen the semicolon, and thus don't need another.
2402 fn stmt_ends_with_semi(stmt
: &hir
::Stmt_
) -> bool
{
2404 hir
::StmtDecl(ref d
, _
) => {
2406 hir
::DeclLocal(_
) => true,
2407 hir
::DeclItem(_
) => false,
2410 hir
::StmtExpr(ref e
, _
) => {
2411 expr_requires_semi_to_be_stmt(&**e
)
2413 hir
::StmtSemi(..) => {