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
::codemap
::{CodeMap, Spanned}
;
16 use syntax
::parse
::token
::{self, keywords, BinOpToken}
;
17 use syntax
::parse
::lexer
::comments
;
18 use syntax
::print
::pp
::{self, break_offset, word, space, hardbreak}
;
19 use syntax
::print
::pp
::{Breaks, eof}
;
20 use syntax
::print
::pp
::Breaks
::{Consistent, Inconsistent}
;
21 use syntax
::print
::pprust
::{self as ast_pp, PrintState}
;
23 use syntax_pos
::{self, BytePos}
;
27 use hir
::{Crate, PatKind, RegionTyParamBound, SelfKind, TraitTyParamBound, TraitBoundModifier}
;
29 use std
::io
::{self, Write, Read}
;
31 pub enum AnnNode
<'a
> {
32 NodeName(&'a ast
::Name
),
33 NodeBlock(&'a hir
::Block
),
34 NodeItem(&'a hir
::Item
),
35 NodeSubItem(ast
::NodeId
),
36 NodeExpr(&'a hir
::Expr
),
37 NodePat(&'a hir
::Pat
),
41 fn pre(&self, _state
: &mut State
, _node
: AnnNode
) -> io
::Result
<()> {
44 fn post(&self, _state
: &mut State
, _node
: AnnNode
) -> io
::Result
<()> {
49 #[derive(Copy, Clone)]
52 impl PpAnn
for NoAnn {}
55 pub struct State
<'a
> {
56 krate
: Option
<&'a Crate
>,
57 pub s
: pp
::Printer
<'a
>,
58 cm
: Option
<&'a CodeMap
>,
59 comments
: Option
<Vec
<comments
::Comment
>>,
60 literals
: Option
<Vec
<comments
::Literal
>>,
61 cur_cmnt_and_lit
: ast_pp
::CurrentCommentAndLiteral
,
62 boxes
: Vec
<pp
::Breaks
>,
63 ann
: &'
a (PpAnn
+ 'a
),
66 impl<'a
> PrintState
<'a
> for State
<'a
> {
67 fn writer(&mut self) -> &mut pp
::Printer
<'a
> {
71 fn boxes(&mut self) -> &mut Vec
<pp
::Breaks
> {
75 fn comments(&mut self) -> &mut Option
<Vec
<comments
::Comment
>> {
79 fn cur_cmnt_and_lit(&mut self) -> &mut ast_pp
::CurrentCommentAndLiteral
{
80 &mut self.cur_cmnt_and_lit
83 fn literals(&self) -> &Option
<Vec
<comments
::Literal
>> {
88 pub fn rust_printer
<'a
>(writer
: Box
<Write
+ 'a
>, krate
: Option
<&'a Crate
>) -> State
<'a
> {
89 static NO_ANN
: NoAnn
= NoAnn
;
90 rust_printer_annotated(writer
, &NO_ANN
, krate
)
93 pub fn rust_printer_annotated
<'a
>(writer
: Box
<Write
+ 'a
>,
95 krate
: Option
<&'a Crate
>)
99 s
: pp
::mk_printer(writer
, default_columns
),
103 cur_cmnt_and_lit
: ast_pp
::CurrentCommentAndLiteral
{
112 #[allow(non_upper_case_globals)]
113 pub const indent_unit
: usize = 4;
115 #[allow(non_upper_case_globals)]
116 pub const default_columns
: usize = 78;
119 /// Requires you to pass an input filename and reader so that
120 /// it can scan the input text for comments and literals to
122 pub fn print_crate
<'a
>(cm
: &'a CodeMap
,
123 span_diagnostic
: &errors
::Handler
,
127 out
: Box
<Write
+ 'a
>,
131 let mut s
= State
::new_from_input(cm
, span_diagnostic
, filename
, input
,
132 out
, ann
, is_expanded
, Some(krate
));
134 // When printing the AST, we sometimes need to inject `#[no_std]` here.
135 // Since you can't compile the HIR, it's not necessary.
137 s
.print_mod(&krate
.module
, &krate
.attrs
)?
;
138 s
.print_remaining_comments()?
;
143 pub fn new_from_input(cm
: &'a CodeMap
,
144 span_diagnostic
: &errors
::Handler
,
147 out
: Box
<Write
+ 'a
>,
150 krate
: Option
<&'a Crate
>)
152 let (cmnts
, lits
) = comments
::gather_comments_and_literals(span_diagnostic
,
160 // If the code is post expansion, don't use the table of
161 // literals, since it doesn't correspond with the literals
162 // in the AST anymore.
171 pub fn new(cm
: &'a CodeMap
,
172 out
: Box
<Write
+ 'a
>,
174 comments
: Option
<Vec
<comments
::Comment
>>,
175 literals
: Option
<Vec
<comments
::Literal
>>,
176 krate
: Option
<&'a Crate
>)
180 s
: pp
::mk_printer(out
, default_columns
),
182 comments
: comments
.clone(),
183 literals
: literals
.clone(),
184 cur_cmnt_and_lit
: ast_pp
::CurrentCommentAndLiteral
{
194 pub fn to_string
<F
>(f
: F
) -> String
195 where F
: FnOnce(&mut State
) -> io
::Result
<()>
197 let mut wr
= Vec
::new();
199 let mut printer
= rust_printer(Box
::new(&mut wr
), None
);
200 f(&mut printer
).unwrap();
201 eof(&mut printer
.s
).unwrap();
203 String
::from_utf8(wr
).unwrap()
206 pub fn binop_to_string(op
: BinOpToken
) -> &'
static str {
212 token
::Percent
=> "%",
221 pub fn ty_to_string(ty
: &hir
::Ty
) -> String
{
222 to_string(|s
| s
.print_type(ty
))
225 pub fn bounds_to_string(bounds
: &[hir
::TyParamBound
]) -> String
{
226 to_string(|s
| s
.print_bounds("", bounds
))
229 pub fn pat_to_string(pat
: &hir
::Pat
) -> String
{
230 to_string(|s
| s
.print_pat(pat
))
233 pub fn arm_to_string(arm
: &hir
::Arm
) -> String
{
234 to_string(|s
| s
.print_arm(arm
))
237 pub fn expr_to_string(e
: &hir
::Expr
) -> String
{
238 to_string(|s
| s
.print_expr(e
))
241 pub fn lifetime_to_string(e
: &hir
::Lifetime
) -> String
{
242 to_string(|s
| s
.print_lifetime(e
))
245 pub fn stmt_to_string(stmt
: &hir
::Stmt
) -> String
{
246 to_string(|s
| s
.print_stmt(stmt
))
249 pub fn item_to_string(i
: &hir
::Item
) -> String
{
250 to_string(|s
| s
.print_item(i
))
253 pub fn impl_item_to_string(i
: &hir
::ImplItem
) -> String
{
254 to_string(|s
| s
.print_impl_item(i
))
257 pub fn trait_item_to_string(i
: &hir
::TraitItem
) -> String
{
258 to_string(|s
| s
.print_trait_item(i
))
261 pub fn generics_to_string(generics
: &hir
::Generics
) -> String
{
262 to_string(|s
| s
.print_generics(generics
))
265 pub fn where_clause_to_string(i
: &hir
::WhereClause
) -> String
{
266 to_string(|s
| s
.print_where_clause(i
))
269 pub fn fn_block_to_string(p
: &hir
::FnDecl
) -> String
{
270 to_string(|s
| s
.print_fn_block_args(p
))
273 pub fn path_to_string(p
: &hir
::Path
) -> String
{
274 to_string(|s
| s
.print_path(p
, false, 0))
277 pub fn name_to_string(name
: ast
::Name
) -> String
{
278 to_string(|s
| s
.print_name(name
))
281 pub fn fun_to_string(decl
: &hir
::FnDecl
,
282 unsafety
: hir
::Unsafety
,
283 constness
: hir
::Constness
,
285 generics
: &hir
::Generics
)
296 s
.end()?
; // Close the head box
297 s
.end() // Close the outer box
301 pub fn block_to_string(blk
: &hir
::Block
) -> String
{
303 // containing cbox, will be closed by print-block at }
304 s
.cbox(indent_unit
)?
;
305 // head-ibox, will be closed by print-block after {
311 pub fn variant_to_string(var
: &hir
::Variant
) -> String
{
312 to_string(|s
| s
.print_variant(var
))
315 pub fn arg_to_string(arg
: &hir
::Arg
) -> String
{
316 to_string(|s
| s
.print_arg(arg
, false))
319 pub fn visibility_qualified(vis
: &hir
::Visibility
, s
: &str) -> String
{
321 hir
::Public
=> format
!("pub {}", s
),
322 hir
::Visibility
::Crate
=> format
!("pub(crate) {}", s
),
323 hir
::Visibility
::Restricted { ref path, .. }
=> format
!("pub({}) {}", path
, s
),
324 hir
::Inherited
=> s
.to_string(),
328 fn needs_parentheses(expr
: &hir
::Expr
) -> bool
{
330 hir
::ExprAssign(..) |
331 hir
::ExprBinary(..) |
332 hir
::ExprClosure(..) |
333 hir
::ExprAssignOp(..) |
335 hir
::ExprType(..) => true,
341 pub fn cbox(&mut self, u
: usize) -> io
::Result
<()> {
342 self.boxes
.push(pp
::Breaks
::Consistent
);
343 pp
::cbox(&mut self.s
, u
)
346 pub fn nbsp(&mut self) -> io
::Result
<()> {
347 word(&mut self.s
, " ")
350 pub fn word_nbsp(&mut self, w
: &str) -> io
::Result
<()> {
351 word(&mut self.s
, w
)?
;
355 pub fn head(&mut self, w
: &str) -> io
::Result
<()> {
356 // outer-box is consistent
357 self.cbox(indent_unit
)?
;
358 // head-box is inconsistent
359 self.ibox(w
.len() + 1)?
;
360 // keyword that starts the head
367 pub fn bopen(&mut self) -> io
::Result
<()> {
368 word(&mut self.s
, "{")?
;
369 self.end() // close the head-box
372 pub fn bclose_(&mut self, span
: syntax_pos
::Span
, indented
: usize) -> io
::Result
<()> {
373 self.bclose_maybe_open(span
, indented
, true)
375 pub fn bclose_maybe_open(&mut self,
376 span
: syntax_pos
::Span
,
380 self.maybe_print_comment(span
.hi
)?
;
381 self.break_offset_if_not_bol(1, -(indented
as isize))?
;
382 word(&mut self.s
, "}")?
;
384 self.end()?
; // close the outer-box
388 pub fn bclose(&mut self, span
: syntax_pos
::Span
) -> io
::Result
<()> {
389 self.bclose_(span
, indent_unit
)
392 pub fn in_cbox(&self) -> bool
{
393 match self.boxes
.last() {
394 Some(&last_box
) => last_box
== pp
::Breaks
::Consistent
,
398 pub fn space_if_not_bol(&mut self) -> io
::Result
<()> {
404 pub fn break_offset_if_not_bol(&mut self, n
: usize, off
: isize) -> io
::Result
<()> {
406 break_offset(&mut self.s
, n
, off
)
408 if off
!= 0 && self.s
.last_token().is_hardbreak_tok() {
409 // We do something pretty sketchy here: tuck the nonzero
410 // offset-adjustment we were going to deposit along with the
411 // break into the previous hardbreak.
412 self.s
.replace_last_token(pp
::hardbreak_tok_offset(off
));
418 // Synthesizes a comment that was not textually present in the original source
420 pub fn synth_comment(&mut self, text
: String
) -> io
::Result
<()> {
421 word(&mut self.s
, "/*")?
;
423 word(&mut self.s
, &text
[..])?
;
425 word(&mut self.s
, "*/")
429 pub fn commasep_cmnt
<T
, F
, G
>(&mut self,
435 where F
: FnMut(&mut State
, &T
) -> io
::Result
<()>,
436 G
: FnMut(&T
) -> syntax_pos
::Span
439 let len
= elts
.len();
442 self.maybe_print_comment(get_span(elt
).hi
)?
;
446 word(&mut self.s
, ",")?
;
447 self.maybe_print_trailing_comment(get_span(elt
), Some(get_span(&elts
[i
]).hi
))?
;
448 self.space_if_not_bol()?
;
454 pub fn commasep_exprs(&mut self, b
: Breaks
, exprs
: &[P
<hir
::Expr
>]) -> io
::Result
<()> {
455 self.commasep_cmnt(b
, exprs
, |s
, e
| s
.print_expr(&e
), |e
| e
.span
)
458 pub fn print_mod(&mut self, _mod
: &hir
::Mod
, attrs
: &[ast
::Attribute
]) -> io
::Result
<()> {
459 self.print_inner_attributes(attrs
)?
;
460 for item_id
in &_mod
.item_ids
{
461 self.print_item_id(item_id
)?
;
466 pub fn print_foreign_mod(&mut self,
467 nmod
: &hir
::ForeignMod
,
468 attrs
: &[ast
::Attribute
])
470 self.print_inner_attributes(attrs
)?
;
471 for item
in &nmod
.items
{
472 self.print_foreign_item(item
)?
;
477 pub fn print_opt_lifetime(&mut self, lifetime
: &Option
<hir
::Lifetime
>) -> io
::Result
<()> {
478 if let Some(l
) = *lifetime
{
479 self.print_lifetime(&l
)?
;
485 pub fn print_type(&mut self, ty
: &hir
::Ty
) -> io
::Result
<()> {
486 self.maybe_print_comment(ty
.span
.lo
)?
;
489 hir
::TyVec(ref ty
) => {
490 word(&mut self.s
, "[")?
;
491 self.print_type(&ty
)?
;
492 word(&mut self.s
, "]")?
;
494 hir
::TyPtr(ref mt
) => {
495 word(&mut self.s
, "*")?
;
497 hir
::MutMutable
=> self.word_nbsp("mut")?
,
498 hir
::MutImmutable
=> self.word_nbsp("const")?
,
500 self.print_type(&mt
.ty
)?
;
502 hir
::TyRptr(ref lifetime
, ref mt
) => {
503 word(&mut self.s
, "&")?
;
504 self.print_opt_lifetime(lifetime
)?
;
508 word(&mut self.s
, "!")?
;
510 hir
::TyTup(ref elts
) => {
512 self.commasep(Inconsistent
, &elts
[..], |s
, ty
| s
.print_type(&ty
))?
;
514 word(&mut self.s
, ",")?
;
518 hir
::TyBareFn(ref f
) => {
519 let generics
= hir
::Generics
{
520 lifetimes
: f
.lifetimes
.clone(),
521 ty_params
: hir
::HirVec
::new(),
522 where_clause
: hir
::WhereClause
{
523 id
: ast
::DUMMY_NODE_ID
,
524 predicates
: hir
::HirVec
::new(),
526 span
: syntax_pos
::DUMMY_SP
,
528 self.print_ty_fn(f
.abi
, f
.unsafety
, &f
.decl
, None
, &generics
)?
;
530 hir
::TyPath(None
, ref path
) => {
531 self.print_path(path
, false, 0)?
;
533 hir
::TyPath(Some(ref qself
), ref path
) => {
534 self.print_qpath(path
, qself
, false)?
536 hir
::TyObjectSum(ref ty
, ref bounds
) => {
537 self.print_type(&ty
)?
;
538 self.print_bounds("+", &bounds
[..])?
;
540 hir
::TyPolyTraitRef(ref bounds
) => {
541 self.print_bounds("", &bounds
[..])?
;
543 hir
::TyImplTrait(ref bounds
) => {
544 self.print_bounds("impl ", &bounds
[..])?
;
546 hir
::TyFixedLengthVec(ref ty
, ref v
) => {
547 word(&mut self.s
, "[")?
;
548 self.print_type(&ty
)?
;
549 word(&mut self.s
, "; ")?
;
550 self.print_expr(&v
)?
;
551 word(&mut self.s
, "]")?
;
553 hir
::TyTypeof(ref e
) => {
554 word(&mut self.s
, "typeof(")?
;
555 self.print_expr(&e
)?
;
556 word(&mut self.s
, ")")?
;
559 word(&mut self.s
, "_")?
;
565 pub fn print_foreign_item(&mut self, item
: &hir
::ForeignItem
) -> io
::Result
<()> {
566 self.hardbreak_if_not_bol()?
;
567 self.maybe_print_comment(item
.span
.lo
)?
;
568 self.print_outer_attributes(&item
.attrs
)?
;
570 hir
::ForeignItemFn(ref decl
, ref generics
) => {
573 hir
::Unsafety
::Normal
,
574 hir
::Constness
::NotConst
,
579 self.end()?
; // end head-ibox
580 word(&mut self.s
, ";")?
;
581 self.end() // end the outer fn box
583 hir
::ForeignItemStatic(ref t
, m
) => {
584 self.head(&visibility_qualified(&item
.vis
, "static"))?
;
586 self.word_space("mut")?
;
588 self.print_name(item
.name
)?
;
589 self.word_space(":")?
;
590 self.print_type(&t
)?
;
591 word(&mut self.s
, ";")?
;
592 self.end()?
; // end the head-ibox
593 self.end() // end the outer cbox
598 fn print_associated_const(&mut self,
601 default: Option
<&hir
::Expr
>,
602 vis
: &hir
::Visibility
)
604 word(&mut self.s
, &visibility_qualified(vis
, ""))?
;
605 self.word_space("const")?
;
606 self.print_name(name
)?
;
607 self.word_space(":")?
;
608 self.print_type(ty
)?
;
609 if let Some(expr
) = default {
611 self.word_space("=")?
;
612 self.print_expr(expr
)?
;
614 word(&mut self.s
, ";")
617 fn print_associated_type(&mut self,
619 bounds
: Option
<&hir
::TyParamBounds
>,
620 ty
: Option
<&hir
::Ty
>)
622 self.word_space("type")?
;
623 self.print_name(name
)?
;
624 if let Some(bounds
) = bounds
{
625 self.print_bounds(":", bounds
)?
;
627 if let Some(ty
) = ty
{
629 self.word_space("=")?
;
630 self.print_type(ty
)?
;
632 word(&mut self.s
, ";")
635 pub fn print_item_id(&mut self, item_id
: &hir
::ItemId
) -> io
::Result
<()> {
636 if let Some(krate
) = self.krate
{
637 // skip nested items if krate context was not provided
638 let item
= &krate
.items
[&item_id
.id
];
639 self.print_item(item
)
645 /// Pretty-print an item
646 pub fn print_item(&mut self, item
: &hir
::Item
) -> io
::Result
<()> {
647 self.hardbreak_if_not_bol()?
;
648 self.maybe_print_comment(item
.span
.lo
)?
;
649 self.print_outer_attributes(&item
.attrs
)?
;
650 self.ann
.pre(self, NodeItem(item
))?
;
652 hir
::ItemExternCrate(ref optional_path
) => {
653 self.head(&visibility_qualified(&item
.vis
, "extern crate"))?
;
654 if let Some(p
) = *optional_path
{
655 let val
= p
.as_str();
656 if val
.contains("-") {
657 self.print_string(&val
, ast
::StrStyle
::Cooked
)?
;
662 word(&mut self.s
, "as")?
;
665 self.print_name(item
.name
)?
;
666 word(&mut self.s
, ";")?
;
667 self.end()?
; // end inner head-block
668 self.end()?
; // end outer head-block
670 hir
::ItemUse(ref vp
) => {
671 self.head(&visibility_qualified(&item
.vis
, "use"))?
;
672 self.print_view_path(&vp
)?
;
673 word(&mut self.s
, ";")?
;
674 self.end()?
; // end inner head-block
675 self.end()?
; // end outer head-block
677 hir
::ItemStatic(ref ty
, m
, ref expr
) => {
678 self.head(&visibility_qualified(&item
.vis
, "static"))?
;
679 if m
== hir
::MutMutable
{
680 self.word_space("mut")?
;
682 self.print_name(item
.name
)?
;
683 self.word_space(":")?
;
684 self.print_type(&ty
)?
;
686 self.end()?
; // end the head-ibox
688 self.word_space("=")?
;
689 self.print_expr(&expr
)?
;
690 word(&mut self.s
, ";")?
;
691 self.end()?
; // end the outer cbox
693 hir
::ItemConst(ref ty
, ref expr
) => {
694 self.head(&visibility_qualified(&item
.vis
, "const"))?
;
695 self.print_name(item
.name
)?
;
696 self.word_space(":")?
;
697 self.print_type(&ty
)?
;
699 self.end()?
; // end the head-ibox
701 self.word_space("=")?
;
702 self.print_expr(&expr
)?
;
703 word(&mut self.s
, ";")?
;
704 self.end()?
; // end the outer cbox
706 hir
::ItemFn(ref decl
, unsafety
, constness
, abi
, ref typarams
, ref body
) => {
715 word(&mut self.s
, " ")?
;
716 self.print_block_with_attrs(&body
, &item
.attrs
)?
;
718 hir
::ItemMod(ref _mod
) => {
719 self.head(&visibility_qualified(&item
.vis
, "mod"))?
;
720 self.print_name(item
.name
)?
;
723 self.print_mod(_mod
, &item
.attrs
)?
;
724 self.bclose(item
.span
)?
;
726 hir
::ItemForeignMod(ref nmod
) => {
727 self.head("extern")?
;
728 self.word_nbsp(&nmod
.abi
.to_string())?
;
730 self.print_foreign_mod(nmod
, &item
.attrs
)?
;
731 self.bclose(item
.span
)?
;
733 hir
::ItemTy(ref ty
, ref params
) => {
734 self.ibox(indent_unit
)?
;
736 self.word_nbsp(&visibility_qualified(&item
.vis
, "type"))?
;
737 self.print_name(item
.name
)?
;
738 self.print_generics(params
)?
;
739 self.end()?
; // end the inner ibox
741 self.print_where_clause(¶ms
.where_clause
)?
;
743 self.word_space("=")?
;
744 self.print_type(&ty
)?
;
745 word(&mut self.s
, ";")?
;
746 self.end()?
; // end the outer ibox
748 hir
::ItemEnum(ref enum_definition
, ref params
) => {
749 self.print_enum_def(enum_definition
, params
, item
.name
, item
.span
, &item
.vis
)?
;
751 hir
::ItemStruct(ref struct_def
, ref generics
) => {
752 self.head(&visibility_qualified(&item
.vis
, "struct"))?
;
753 self.print_struct(struct_def
, generics
, item
.name
, item
.span
, true)?
;
755 hir
::ItemUnion(ref struct_def
, ref generics
) => {
756 self.head(&visibility_qualified(&item
.vis
, "union"))?
;
757 self.print_struct(struct_def
, generics
, item
.name
, item
.span
, true)?
;
759 hir
::ItemDefaultImpl(unsafety
, ref trait_ref
) => {
761 self.print_visibility(&item
.vis
)?
;
762 self.print_unsafety(unsafety
)?
;
763 self.word_nbsp("impl")?
;
764 self.print_trait_ref(trait_ref
)?
;
766 self.word_space("for")?
;
767 self.word_space("..")?
;
769 self.bclose(item
.span
)?
;
771 hir
::ItemImpl(unsafety
,
778 self.print_visibility(&item
.vis
)?
;
779 self.print_unsafety(unsafety
)?
;
780 self.word_nbsp("impl")?
;
782 if generics
.is_parameterized() {
783 self.print_generics(generics
)?
;
788 hir
::ImplPolarity
::Negative
=> {
789 word(&mut self.s
, "!")?
;
796 self.print_trait_ref(t
)?
;
798 self.word_space("for")?
;
803 self.print_type(&ty
)?
;
804 self.print_where_clause(&generics
.where_clause
)?
;
808 self.print_inner_attributes(&item
.attrs
)?
;
809 for impl_item
in impl_items
{
810 self.print_impl_item(impl_item
)?
;
812 self.bclose(item
.span
)?
;
814 hir
::ItemTrait(unsafety
, ref generics
, ref bounds
, ref trait_items
) => {
816 self.print_visibility(&item
.vis
)?
;
817 self.print_unsafety(unsafety
)?
;
818 self.word_nbsp("trait")?
;
819 self.print_name(item
.name
)?
;
820 self.print_generics(generics
)?
;
821 let mut real_bounds
= Vec
::with_capacity(bounds
.len());
822 for b
in bounds
.iter() {
823 if let TraitTyParamBound(ref ptr
, hir
::TraitBoundModifier
::Maybe
) = *b
{
825 self.word_space("for ?")?
;
826 self.print_trait_ref(&ptr
.trait_ref
)?
;
828 real_bounds
.push(b
.clone());
831 self.print_bounds(":", &real_bounds
[..])?
;
832 self.print_where_clause(&generics
.where_clause
)?
;
833 word(&mut self.s
, " ")?
;
835 for trait_item
in trait_items
{
836 self.print_trait_item(trait_item
)?
;
838 self.bclose(item
.span
)?
;
841 self.ann
.post(self, NodeItem(item
))
844 fn print_trait_ref(&mut self, t
: &hir
::TraitRef
) -> io
::Result
<()> {
845 self.print_path(&t
.path
, false, 0)
848 fn print_formal_lifetime_list(&mut self, lifetimes
: &[hir
::LifetimeDef
]) -> io
::Result
<()> {
849 if !lifetimes
.is_empty() {
850 word(&mut self.s
, "for<")?
;
851 let mut comma
= false;
852 for lifetime_def
in lifetimes
{
854 self.word_space(",")?
856 self.print_lifetime_def(lifetime_def
)?
;
859 word(&mut self.s
, ">")?
;
864 fn print_poly_trait_ref(&mut self, t
: &hir
::PolyTraitRef
) -> io
::Result
<()> {
865 self.print_formal_lifetime_list(&t
.bound_lifetimes
)?
;
866 self.print_trait_ref(&t
.trait_ref
)
869 pub fn print_enum_def(&mut self,
870 enum_definition
: &hir
::EnumDef
,
871 generics
: &hir
::Generics
,
873 span
: syntax_pos
::Span
,
874 visibility
: &hir
::Visibility
)
876 self.head(&visibility_qualified(visibility
, "enum"))?
;
877 self.print_name(name
)?
;
878 self.print_generics(generics
)?
;
879 self.print_where_clause(&generics
.where_clause
)?
;
881 self.print_variants(&enum_definition
.variants
, span
)
884 pub fn print_variants(&mut self,
885 variants
: &[hir
::Variant
],
886 span
: syntax_pos
::Span
)
890 self.space_if_not_bol()?
;
891 self.maybe_print_comment(v
.span
.lo
)?
;
892 self.print_outer_attributes(&v
.node
.attrs
)?
;
893 self.ibox(indent_unit
)?
;
894 self.print_variant(v
)?
;
895 word(&mut self.s
, ",")?
;
897 self.maybe_print_trailing_comment(v
.span
, None
)?
;
902 pub fn print_visibility(&mut self, vis
: &hir
::Visibility
) -> io
::Result
<()> {
904 hir
::Public
=> self.word_nbsp("pub"),
905 hir
::Visibility
::Crate
=> self.word_nbsp("pub(crate)"),
906 hir
::Visibility
::Restricted { ref path, .. }
=>
907 self.word_nbsp(&format
!("pub({})", path
)),
908 hir
::Inherited
=> Ok(()),
912 pub fn print_struct(&mut self,
913 struct_def
: &hir
::VariantData
,
914 generics
: &hir
::Generics
,
916 span
: syntax_pos
::Span
,
917 print_finalizer
: bool
)
919 self.print_name(name
)?
;
920 self.print_generics(generics
)?
;
921 if !struct_def
.is_struct() {
922 if struct_def
.is_tuple() {
924 self.commasep(Inconsistent
, struct_def
.fields(), |s
, field
| {
925 s
.maybe_print_comment(field
.span
.lo
)?
;
926 s
.print_outer_attributes(&field
.attrs
)?
;
927 s
.print_visibility(&field
.vis
)?
;
928 s
.print_type(&field
.ty
)
932 self.print_where_clause(&generics
.where_clause
)?
;
934 word(&mut self.s
, ";")?
;
937 self.end() // close the outer-box
939 self.print_where_clause(&generics
.where_clause
)?
;
942 self.hardbreak_if_not_bol()?
;
944 for field
in struct_def
.fields() {
945 self.hardbreak_if_not_bol()?
;
946 self.maybe_print_comment(field
.span
.lo
)?
;
947 self.print_outer_attributes(&field
.attrs
)?
;
948 self.print_visibility(&field
.vis
)?
;
949 self.print_name(field
.name
)?
;
950 self.word_nbsp(":")?
;
951 self.print_type(&field
.ty
)?
;
952 word(&mut self.s
, ",")?
;
959 pub fn print_variant(&mut self, v
: &hir
::Variant
) -> io
::Result
<()> {
961 let generics
= hir
::Generics
::empty();
962 self.print_struct(&v
.node
.data
, &generics
, v
.node
.name
, v
.span
, false)?
;
963 match v
.node
.disr_expr
{
966 self.word_space("=")?
;
972 pub fn print_method_sig(&mut self,
975 vis
: &hir
::Visibility
)
977 self.print_fn(&m
.decl
,
986 pub fn print_trait_item(&mut self, ti
: &hir
::TraitItem
) -> io
::Result
<()> {
987 self.ann
.pre(self, NodeSubItem(ti
.id
))?
;
988 self.hardbreak_if_not_bol()?
;
989 self.maybe_print_comment(ti
.span
.lo
)?
;
990 self.print_outer_attributes(&ti
.attrs
)?
;
992 hir
::ConstTraitItem(ref ty
, ref default) => {
993 self.print_associated_const(ti
.name
,
995 default.as_ref().map(|expr
| &**expr
),
998 hir
::MethodTraitItem(ref sig
, ref body
) => {
1002 self.print_method_sig(ti
.name
, sig
, &hir
::Inherited
)?
;
1003 if let Some(ref body
) = *body
{
1005 self.print_block_with_attrs(body
, &ti
.attrs
)?
;
1007 word(&mut self.s
, ";")?
;
1010 hir
::TypeTraitItem(ref bounds
, ref default) => {
1011 self.print_associated_type(ti
.name
,
1013 default.as_ref().map(|ty
| &**ty
))?
;
1016 self.ann
.post(self, NodeSubItem(ti
.id
))
1019 pub fn print_impl_item(&mut self, ii
: &hir
::ImplItem
) -> io
::Result
<()> {
1020 self.ann
.pre(self, NodeSubItem(ii
.id
))?
;
1021 self.hardbreak_if_not_bol()?
;
1022 self.maybe_print_comment(ii
.span
.lo
)?
;
1023 self.print_outer_attributes(&ii
.attrs
)?
;
1025 if let hir
::Defaultness
::Default
= ii
.defaultness
{
1026 self.word_nbsp("default")?
;
1030 hir
::ImplItemKind
::Const(ref ty
, ref expr
) => {
1031 self.print_associated_const(ii
.name
, &ty
, Some(&expr
), &ii
.vis
)?
;
1033 hir
::ImplItemKind
::Method(ref sig
, ref body
) => {
1035 self.print_method_sig(ii
.name
, sig
, &ii
.vis
)?
;
1037 self.print_block_with_attrs(body
, &ii
.attrs
)?
;
1039 hir
::ImplItemKind
::Type(ref ty
) => {
1040 self.print_associated_type(ii
.name
, None
, Some(ty
))?
;
1043 self.ann
.post(self, NodeSubItem(ii
.id
))
1046 pub fn print_stmt(&mut self, st
: &hir
::Stmt
) -> io
::Result
<()> {
1047 self.maybe_print_comment(st
.span
.lo
)?
;
1049 hir
::StmtDecl(ref decl
, _
) => {
1050 self.print_decl(&decl
)?
;
1052 hir
::StmtExpr(ref expr
, _
) => {
1053 self.space_if_not_bol()?
;
1054 self.print_expr(&expr
)?
;
1056 hir
::StmtSemi(ref expr
, _
) => {
1057 self.space_if_not_bol()?
;
1058 self.print_expr(&expr
)?
;
1059 word(&mut self.s
, ";")?
;
1062 if stmt_ends_with_semi(&st
.node
) {
1063 word(&mut self.s
, ";")?
;
1065 self.maybe_print_trailing_comment(st
.span
, None
)
1068 pub fn print_block(&mut self, blk
: &hir
::Block
) -> io
::Result
<()> {
1069 self.print_block_with_attrs(blk
, &[])
1072 pub fn print_block_unclosed(&mut self, blk
: &hir
::Block
) -> io
::Result
<()> {
1073 self.print_block_unclosed_indent(blk
, indent_unit
)
1076 pub fn print_block_unclosed_indent(&mut self,
1080 self.print_block_maybe_unclosed(blk
, indented
, &[], false)
1083 pub fn print_block_with_attrs(&mut self,
1085 attrs
: &[ast
::Attribute
])
1087 self.print_block_maybe_unclosed(blk
, indent_unit
, attrs
, true)
1090 pub fn print_block_maybe_unclosed(&mut self,
1093 attrs
: &[ast
::Attribute
],
1097 hir
::UnsafeBlock(..) => self.word_space("unsafe")?
,
1098 hir
::PushUnsafeBlock(..) => self.word_space("push_unsafe")?
,
1099 hir
::PopUnsafeBlock(..) => self.word_space("pop_unsafe")?
,
1100 hir
::PushUnstableBlock
=> self.word_space("push_unstable")?
,
1101 hir
::PopUnstableBlock
=> self.word_space("pop_unstable")?
,
1102 hir
::DefaultBlock
=> (),
1104 self.maybe_print_comment(blk
.span
.lo
)?
;
1105 self.ann
.pre(self, NodeBlock(blk
))?
;
1108 self.print_inner_attributes(attrs
)?
;
1110 for st
in &blk
.stmts
{
1111 self.print_stmt(st
)?
;
1115 self.space_if_not_bol()?
;
1116 self.print_expr(&expr
)?
;
1117 self.maybe_print_trailing_comment(expr
.span
, Some(blk
.span
.hi
))?
;
1121 self.bclose_maybe_open(blk
.span
, indented
, close_box
)?
;
1122 self.ann
.post(self, NodeBlock(blk
))
1125 fn print_else(&mut self, els
: Option
<&hir
::Expr
>) -> io
::Result
<()> {
1129 // "another else-if"
1130 hir
::ExprIf(ref i
, ref then
, ref e
) => {
1131 self.cbox(indent_unit
- 1)?
;
1133 word(&mut self.s
, " else if ")?
;
1134 self.print_expr(&i
)?
;
1135 space(&mut self.s
)?
;
1136 self.print_block(&then
)?
;
1137 self.print_else(e
.as_ref().map(|e
| &**e
))
1140 hir
::ExprBlock(ref b
) => {
1141 self.cbox(indent_unit
- 1)?
;
1143 word(&mut self.s
, " else ")?
;
1144 self.print_block(&b
)
1146 // BLEAH, constraints would be great here
1148 panic
!("print_if saw if with weird alternative");
1156 pub fn print_if(&mut self,
1159 elseopt
: Option
<&hir
::Expr
>)
1162 self.print_expr(test
)?
;
1163 space(&mut self.s
)?
;
1164 self.print_block(blk
)?
;
1165 self.print_else(elseopt
)
1168 pub fn print_if_let(&mut self,
1172 elseopt
: Option
<&hir
::Expr
>)
1174 self.head("if let")?
;
1175 self.print_pat(pat
)?
;
1176 space(&mut self.s
)?
;
1177 self.word_space("=")?
;
1178 self.print_expr(expr
)?
;
1179 space(&mut self.s
)?
;
1180 self.print_block(blk
)?
;
1181 self.print_else(elseopt
)
1185 fn print_call_post(&mut self, args
: &[P
<hir
::Expr
>]) -> io
::Result
<()> {
1187 self.commasep_exprs(Inconsistent
, args
)?
;
1191 pub fn print_expr_maybe_paren(&mut self, expr
: &hir
::Expr
) -> io
::Result
<()> {
1192 let needs_par
= needs_parentheses(expr
);
1196 self.print_expr(expr
)?
;
1203 fn print_expr_vec(&mut self, exprs
: &[P
<hir
::Expr
>]) -> io
::Result
<()> {
1204 self.ibox(indent_unit
)?
;
1205 word(&mut self.s
, "[")?
;
1206 self.commasep_exprs(Inconsistent
, &exprs
[..])?
;
1207 word(&mut self.s
, "]")?
;
1211 fn print_expr_repeat(&mut self, element
: &hir
::Expr
, count
: &hir
::Expr
) -> io
::Result
<()> {
1212 self.ibox(indent_unit
)?
;
1213 word(&mut self.s
, "[")?
;
1214 self.print_expr(element
)?
;
1215 self.word_space(";")?
;
1216 self.print_expr(count
)?
;
1217 word(&mut self.s
, "]")?
;
1221 fn print_expr_struct(&mut self,
1223 fields
: &[hir
::Field
],
1224 wth
: &Option
<P
<hir
::Expr
>>)
1226 self.print_path(path
, true, 0)?
;
1227 word(&mut self.s
, "{")?
;
1228 self.commasep_cmnt(Consistent
,
1231 s
.ibox(indent_unit
)?
;
1232 s
.print_name(field
.name
.node
)?
;
1234 s
.print_expr(&field
.expr
)?
;
1240 self.ibox(indent_unit
)?
;
1241 if !fields
.is_empty() {
1242 word(&mut self.s
, ",")?
;
1243 space(&mut self.s
)?
;
1245 word(&mut self.s
, "..")?
;
1246 self.print_expr(&expr
)?
;
1249 _
=> if !fields
.is_empty() {
1250 word(&mut self.s
, ",")?
1253 word(&mut self.s
, "}")?
;
1257 fn print_expr_tup(&mut self, exprs
: &[P
<hir
::Expr
>]) -> io
::Result
<()> {
1259 self.commasep_exprs(Inconsistent
, &exprs
[..])?
;
1260 if exprs
.len() == 1 {
1261 word(&mut self.s
, ",")?
;
1266 fn print_expr_call(&mut self, func
: &hir
::Expr
, args
: &[P
<hir
::Expr
>]) -> io
::Result
<()> {
1267 self.print_expr_maybe_paren(func
)?
;
1268 self.print_call_post(args
)
1271 fn print_expr_method_call(&mut self,
1272 name
: Spanned
<ast
::Name
>,
1274 args
: &[P
<hir
::Expr
>])
1276 let base_args
= &args
[1..];
1277 self.print_expr(&args
[0])?
;
1278 word(&mut self.s
, ".")?
;
1279 self.print_name(name
.node
)?
;
1280 if !tys
.is_empty() {
1281 word(&mut self.s
, "::<")?
;
1282 self.commasep(Inconsistent
, tys
, |s
, ty
| s
.print_type(&ty
))?
;
1283 word(&mut self.s
, ">")?
;
1285 self.print_call_post(base_args
)
1288 fn print_expr_binary(&mut self,
1293 self.print_expr(lhs
)?
;
1294 space(&mut self.s
)?
;
1295 self.word_space(op
.node
.as_str())?
;
1296 self.print_expr(rhs
)
1299 fn print_expr_unary(&mut self, op
: hir
::UnOp
, expr
: &hir
::Expr
) -> io
::Result
<()> {
1300 word(&mut self.s
, op
.as_str())?
;
1301 self.print_expr_maybe_paren(expr
)
1304 fn print_expr_addr_of(&mut self,
1305 mutability
: hir
::Mutability
,
1308 word(&mut self.s
, "&")?
;
1309 self.print_mutability(mutability
)?
;
1310 self.print_expr_maybe_paren(expr
)
1313 pub fn print_expr(&mut self, expr
: &hir
::Expr
) -> io
::Result
<()> {
1314 self.maybe_print_comment(expr
.span
.lo
)?
;
1315 self.ibox(indent_unit
)?
;
1316 self.ann
.pre(self, NodeExpr(expr
))?
;
1318 hir
::ExprBox(ref expr
) => {
1319 self.word_space("box")?
;
1320 self.print_expr(expr
)?
;
1322 hir
::ExprVec(ref exprs
) => {
1323 self.print_expr_vec(&exprs
[..])?
;
1325 hir
::ExprRepeat(ref element
, ref count
) => {
1326 self.print_expr_repeat(&element
, &count
)?
;
1328 hir
::ExprStruct(ref path
, ref fields
, ref wth
) => {
1329 self.print_expr_struct(path
, &fields
[..], wth
)?
;
1331 hir
::ExprTup(ref exprs
) => {
1332 self.print_expr_tup(&exprs
[..])?
;
1334 hir
::ExprCall(ref func
, ref args
) => {
1335 self.print_expr_call(&func
, &args
[..])?
;
1337 hir
::ExprMethodCall(name
, ref tys
, ref args
) => {
1338 self.print_expr_method_call(name
, &tys
[..], &args
[..])?
;
1340 hir
::ExprBinary(op
, ref lhs
, ref rhs
) => {
1341 self.print_expr_binary(op
, &lhs
, &rhs
)?
;
1343 hir
::ExprUnary(op
, ref expr
) => {
1344 self.print_expr_unary(op
, &expr
)?
;
1346 hir
::ExprAddrOf(m
, ref expr
) => {
1347 self.print_expr_addr_of(m
, &expr
)?
;
1349 hir
::ExprLit(ref lit
) => {
1350 self.print_literal(&lit
)?
;
1352 hir
::ExprCast(ref expr
, ref ty
) => {
1353 self.print_expr(&expr
)?
;
1354 space(&mut self.s
)?
;
1355 self.word_space("as")?
;
1356 self.print_type(&ty
)?
;
1358 hir
::ExprType(ref expr
, ref ty
) => {
1359 self.print_expr(&expr
)?
;
1360 self.word_space(":")?
;
1361 self.print_type(&ty
)?
;
1363 hir
::ExprIf(ref test
, ref blk
, ref elseopt
) => {
1364 self.print_if(&test
, &blk
, elseopt
.as_ref().map(|e
| &**e
))?
;
1366 hir
::ExprWhile(ref test
, ref blk
, opt_sp_name
) => {
1367 if let Some(sp_name
) = opt_sp_name
{
1368 self.print_name(sp_name
.node
)?
;
1369 self.word_space(":")?
;
1371 self.head("while")?
;
1372 self.print_expr(&test
)?
;
1373 space(&mut self.s
)?
;
1374 self.print_block(&blk
)?
;
1376 hir
::ExprLoop(ref blk
, opt_sp_name
) => {
1377 if let Some(sp_name
) = opt_sp_name
{
1378 self.print_name(sp_name
.node
)?
;
1379 self.word_space(":")?
;
1382 space(&mut self.s
)?
;
1383 self.print_block(&blk
)?
;
1385 hir
::ExprMatch(ref expr
, ref arms
, _
) => {
1386 self.cbox(indent_unit
)?
;
1388 self.word_nbsp("match")?
;
1389 self.print_expr(&expr
)?
;
1390 space(&mut self.s
)?
;
1393 self.print_arm(arm
)?
;
1395 self.bclose_(expr
.span
, indent_unit
)?
;
1397 hir
::ExprClosure(capture_clause
, ref decl
, ref body
, _fn_decl_span
) => {
1398 self.print_capture_clause(capture_clause
)?
;
1400 self.print_fn_block_args(&decl
)?
;
1401 space(&mut self.s
)?
;
1403 let default_return
= match decl
.output
{
1404 hir
::DefaultReturn(..) => true,
1408 if !default_return
|| !body
.stmts
.is_empty() || body
.expr
.is_none() {
1409 self.print_block_unclosed(&body
)?
;
1411 // we extract the block, so as not to create another set of boxes
1412 match body
.expr
.as_ref().unwrap().node
{
1413 hir
::ExprBlock(ref blk
) => {
1414 self.print_block_unclosed(&blk
)?
;
1417 // this is a bare expression
1418 self.print_expr(body
.expr
.as_ref().map(|e
| &**e
).unwrap())?
;
1419 self.end()?
; // need to close a box
1423 // a box will be closed by print_expr, but we didn't want an overall
1424 // wrapper so we closed the corresponding opening. so create an
1425 // empty box to satisfy the close.
1428 hir
::ExprBlock(ref blk
) => {
1429 // containing cbox, will be closed by print-block at }
1430 self.cbox(indent_unit
)?
;
1431 // head-box, will be closed by print-block after {
1433 self.print_block(&blk
)?
;
1435 hir
::ExprAssign(ref lhs
, ref rhs
) => {
1436 self.print_expr(&lhs
)?
;
1437 space(&mut self.s
)?
;
1438 self.word_space("=")?
;
1439 self.print_expr(&rhs
)?
;
1441 hir
::ExprAssignOp(op
, ref lhs
, ref rhs
) => {
1442 self.print_expr(&lhs
)?
;
1443 space(&mut self.s
)?
;
1444 word(&mut self.s
, op
.node
.as_str())?
;
1445 self.word_space("=")?
;
1446 self.print_expr(&rhs
)?
;
1448 hir
::ExprField(ref expr
, name
) => {
1449 self.print_expr(&expr
)?
;
1450 word(&mut self.s
, ".")?
;
1451 self.print_name(name
.node
)?
;
1453 hir
::ExprTupField(ref expr
, id
) => {
1454 self.print_expr(&expr
)?
;
1455 word(&mut self.s
, ".")?
;
1456 self.print_usize(id
.node
)?
;
1458 hir
::ExprIndex(ref expr
, ref index
) => {
1459 self.print_expr(&expr
)?
;
1460 word(&mut self.s
, "[")?
;
1461 self.print_expr(&index
)?
;
1462 word(&mut self.s
, "]")?
;
1464 hir
::ExprPath(None
, ref path
) => {
1465 self.print_path(path
, true, 0)?
1467 hir
::ExprPath(Some(ref qself
), ref path
) => {
1468 self.print_qpath(path
, qself
, true)?
1470 hir
::ExprBreak(opt_name
) => {
1471 word(&mut self.s
, "break")?
;
1472 space(&mut self.s
)?
;
1473 if let Some(name
) = opt_name
{
1474 self.print_name(name
.node
)?
;
1475 space(&mut self.s
)?
;
1478 hir
::ExprAgain(opt_name
) => {
1479 word(&mut self.s
, "continue")?
;
1480 space(&mut self.s
)?
;
1481 if let Some(name
) = opt_name
{
1482 self.print_name(name
.node
)?
;
1486 hir
::ExprRet(ref result
) => {
1487 word(&mut self.s
, "return")?
;
1490 word(&mut self.s
, " ")?
;
1491 self.print_expr(&expr
)?
;
1496 hir
::ExprInlineAsm(ref a
, ref outputs
, ref inputs
) => {
1497 word(&mut self.s
, "asm!")?
;
1499 self.print_string(&a
.asm
, a
.asm_str_style
)?
;
1500 self.word_space(":")?
;
1502 let mut out_idx
= 0;
1503 self.commasep(Inconsistent
, &a
.outputs
, |s
, out
| {
1504 let mut ch
= out
.constraint
.chars();
1506 Some('
='
) if out
.is_rw
=> {
1507 s
.print_string(&format
!("+{}", ch
.as_str()),
1508 ast
::StrStyle
::Cooked
)?
1510 _
=> s
.print_string(&out
.constraint
,
1511 ast
::StrStyle
::Cooked
)?
,
1514 s
.print_expr(&outputs
[out_idx
])?
;
1519 space(&mut self.s
)?
;
1520 self.word_space(":")?
;
1523 self.commasep(Inconsistent
, &a
.inputs
, |s
, co
| {
1524 s
.print_string(&co
, ast
::StrStyle
::Cooked
)?
;
1526 s
.print_expr(&inputs
[in_idx
])?
;
1531 space(&mut self.s
)?
;
1532 self.word_space(":")?
;
1534 self.commasep(Inconsistent
, &a
.clobbers
, |s
, co
| {
1535 s
.print_string(&co
, ast
::StrStyle
::Cooked
)?
;
1539 let mut options
= vec
![];
1541 options
.push("volatile");
1544 options
.push("alignstack");
1546 if a
.dialect
== ast
::AsmDialect
::Intel
{
1547 options
.push("intel");
1550 if !options
.is_empty() {
1551 space(&mut self.s
)?
;
1552 self.word_space(":")?
;
1553 self.commasep(Inconsistent
, &options
, |s
, &co
| {
1554 s
.print_string(co
, ast
::StrStyle
::Cooked
)?
;
1562 self.ann
.post(self, NodeExpr(expr
))?
;
1566 pub fn print_local_decl(&mut self, loc
: &hir
::Local
) -> io
::Result
<()> {
1567 self.print_pat(&loc
.pat
)?
;
1568 if let Some(ref ty
) = loc
.ty
{
1569 self.word_space(":")?
;
1570 self.print_type(&ty
)?
;
1575 pub fn print_decl(&mut self, decl
: &hir
::Decl
) -> io
::Result
<()> {
1576 self.maybe_print_comment(decl
.span
.lo
)?
;
1578 hir
::DeclLocal(ref loc
) => {
1579 self.space_if_not_bol()?
;
1580 self.ibox(indent_unit
)?
;
1581 self.word_nbsp("let")?
;
1583 self.ibox(indent_unit
)?
;
1584 self.print_local_decl(&loc
)?
;
1586 if let Some(ref init
) = loc
.init
{
1588 self.word_space("=")?
;
1589 self.print_expr(&init
)?
;
1593 hir
::DeclItem(ref item
) => {
1594 self.print_item_id(item
)
1599 pub fn print_usize(&mut self, i
: usize) -> io
::Result
<()> {
1600 word(&mut self.s
, &i
.to_string())
1603 pub fn print_name(&mut self, name
: ast
::Name
) -> io
::Result
<()> {
1604 word(&mut self.s
, &name
.as_str())?
;
1605 self.ann
.post(self, NodeName(&name
))
1608 pub fn print_for_decl(&mut self, loc
: &hir
::Local
, coll
: &hir
::Expr
) -> io
::Result
<()> {
1609 self.print_local_decl(loc
)?
;
1610 space(&mut self.s
)?
;
1611 self.word_space("in")?
;
1612 self.print_expr(coll
)
1615 fn print_path(&mut self,
1617 colons_before_params
: bool
,
1620 self.maybe_print_comment(path
.span
.lo
)?
;
1622 let mut first
= !path
.global
;
1623 for segment
in &path
.segments
[..path
.segments
.len() - depth
] {
1627 word(&mut self.s
, "::")?
1630 self.print_name(segment
.name
)?
;
1632 self.print_path_parameters(&segment
.parameters
, colons_before_params
)?
;
1638 fn print_qpath(&mut self,
1641 colons_before_params
: bool
)
1643 word(&mut self.s
, "<")?
;
1644 self.print_type(&qself
.ty
)?
;
1645 if qself
.position
> 0 {
1646 space(&mut self.s
)?
;
1647 self.word_space("as")?
;
1648 let depth
= path
.segments
.len() - qself
.position
;
1649 self.print_path(&path
, false, depth
)?
;
1651 word(&mut self.s
, ">")?
;
1652 word(&mut self.s
, "::")?
;
1653 let item_segment
= path
.segments
.last().unwrap();
1654 self.print_name(item_segment
.name
)?
;
1655 self.print_path_parameters(&item_segment
.parameters
, colons_before_params
)
1658 fn print_path_parameters(&mut self,
1659 parameters
: &hir
::PathParameters
,
1660 colons_before_params
: bool
)
1662 if parameters
.is_empty() {
1666 if colons_before_params
{
1667 word(&mut self.s
, "::")?
1671 hir
::AngleBracketedParameters(ref data
) => {
1672 word(&mut self.s
, "<")?
;
1674 let mut comma
= false;
1675 for lifetime
in &data
.lifetimes
{
1677 self.word_space(",")?
1679 self.print_lifetime(lifetime
)?
;
1683 if !data
.types
.is_empty() {
1685 self.word_space(",")?
1687 self.commasep(Inconsistent
, &data
.types
, |s
, ty
| s
.print_type(&ty
))?
;
1691 for binding
in data
.bindings
.iter() {
1693 self.word_space(",")?
1695 self.print_name(binding
.name
)?
;
1696 space(&mut self.s
)?
;
1697 self.word_space("=")?
;
1698 self.print_type(&binding
.ty
)?
;
1702 word(&mut self.s
, ">")?
1705 hir
::ParenthesizedParameters(ref data
) => {
1706 word(&mut self.s
, "(")?
;
1707 self.commasep(Inconsistent
, &data
.inputs
, |s
, ty
| s
.print_type(&ty
))?
;
1708 word(&mut self.s
, ")")?
;
1710 if let Some(ref ty
) = data
.output
{
1711 self.space_if_not_bol()?
;
1712 self.word_space("->")?
;
1713 self.print_type(&ty
)?
;
1721 pub fn print_pat(&mut self, pat
: &hir
::Pat
) -> io
::Result
<()> {
1722 self.maybe_print_comment(pat
.span
.lo
)?
;
1723 self.ann
.pre(self, NodePat(pat
))?
;
1724 // Pat isn't normalized, but the beauty of it
1725 // is that it doesn't matter
1727 PatKind
::Wild
=> word(&mut self.s
, "_")?
,
1728 PatKind
::Binding(binding_mode
, ref path1
, ref sub
) => {
1729 match binding_mode
{
1730 hir
::BindByRef(mutbl
) => {
1731 self.word_nbsp("ref")?
;
1732 self.print_mutability(mutbl
)?
;
1734 hir
::BindByValue(hir
::MutImmutable
) => {}
1735 hir
::BindByValue(hir
::MutMutable
) => {
1736 self.word_nbsp("mut")?
;
1739 self.print_name(path1
.node
)?
;
1740 if let Some(ref p
) = *sub
{
1741 word(&mut self.s
, "@")?
;
1742 self.print_pat(&p
)?
;
1745 PatKind
::TupleStruct(ref path
, ref elts
, ddpos
) => {
1746 self.print_path(path
, true, 0)?
;
1748 if let Some(ddpos
) = ddpos
{
1749 self.commasep(Inconsistent
, &elts
[..ddpos
], |s
, p
| s
.print_pat(&p
))?
;
1751 self.word_space(",")?
;
1753 word(&mut self.s
, "..")?
;
1754 if ddpos
!= elts
.len() {
1755 word(&mut self.s
, ",")?
;
1756 self.commasep(Inconsistent
, &elts
[ddpos
..], |s
, p
| s
.print_pat(&p
))?
;
1759 self.commasep(Inconsistent
, &elts
[..], |s
, p
| s
.print_pat(&p
))?
;
1763 PatKind
::Path(None
, ref path
) => {
1764 self.print_path(path
, true, 0)?
;
1766 PatKind
::Path(Some(ref qself
), ref path
) => {
1767 self.print_qpath(path
, qself
, false)?
;
1769 PatKind
::Struct(ref path
, ref fields
, etc
) => {
1770 self.print_path(path
, true, 0)?
;
1772 self.word_space("{")?
;
1773 self.commasep_cmnt(Consistent
,
1776 s
.cbox(indent_unit
)?
;
1777 if !f
.node
.is_shorthand
{
1778 s
.print_name(f
.node
.name
)?
;
1781 s
.print_pat(&f
.node
.pat
)?
;
1784 |f
| f
.node
.pat
.span
)?
;
1786 if !fields
.is_empty() {
1787 self.word_space(",")?
;
1789 word(&mut self.s
, "..")?
;
1791 space(&mut self.s
)?
;
1792 word(&mut self.s
, "}")?
;
1794 PatKind
::Tuple(ref elts
, ddpos
) => {
1796 if let Some(ddpos
) = ddpos
{
1797 self.commasep(Inconsistent
, &elts
[..ddpos
], |s
, p
| s
.print_pat(&p
))?
;
1799 self.word_space(",")?
;
1801 word(&mut self.s
, "..")?
;
1802 if ddpos
!= elts
.len() {
1803 word(&mut self.s
, ",")?
;
1804 self.commasep(Inconsistent
, &elts
[ddpos
..], |s
, p
| s
.print_pat(&p
))?
;
1807 self.commasep(Inconsistent
, &elts
[..], |s
, p
| s
.print_pat(&p
))?
;
1808 if elts
.len() == 1 {
1809 word(&mut self.s
, ",")?
;
1814 PatKind
::Box(ref inner
) => {
1815 word(&mut self.s
, "box ")?
;
1816 self.print_pat(&inner
)?
;
1818 PatKind
::Ref(ref inner
, mutbl
) => {
1819 word(&mut self.s
, "&")?
;
1820 if mutbl
== hir
::MutMutable
{
1821 word(&mut self.s
, "mut ")?
;
1823 self.print_pat(&inner
)?
;
1825 PatKind
::Lit(ref e
) => self.print_expr(&e
)?
,
1826 PatKind
::Range(ref begin
, ref end
) => {
1827 self.print_expr(&begin
)?
;
1828 space(&mut self.s
)?
;
1829 word(&mut self.s
, "...")?
;
1830 self.print_expr(&end
)?
;
1832 PatKind
::Vec(ref before
, ref slice
, ref after
) => {
1833 word(&mut self.s
, "[")?
;
1834 self.commasep(Inconsistent
, &before
[..], |s
, p
| s
.print_pat(&p
))?
;
1835 if let Some(ref p
) = *slice
{
1836 if !before
.is_empty() {
1837 self.word_space(",")?
;
1839 if p
.node
!= PatKind
::Wild
{
1840 self.print_pat(&p
)?
;
1842 word(&mut self.s
, "..")?
;
1843 if !after
.is_empty() {
1844 self.word_space(",")?
;
1847 self.commasep(Inconsistent
, &after
[..], |s
, p
| s
.print_pat(&p
))?
;
1848 word(&mut self.s
, "]")?
;
1851 self.ann
.post(self, NodePat(pat
))
1854 fn print_arm(&mut self, arm
: &hir
::Arm
) -> io
::Result
<()> {
1855 // I have no idea why this check is necessary, but here it
1857 if arm
.attrs
.is_empty() {
1858 space(&mut self.s
)?
;
1860 self.cbox(indent_unit
)?
;
1862 self.print_outer_attributes(&arm
.attrs
)?
;
1863 let mut first
= true;
1864 for p
in &arm
.pats
{
1868 space(&mut self.s
)?
;
1869 self.word_space("|")?
;
1871 self.print_pat(&p
)?
;
1873 space(&mut self.s
)?
;
1874 if let Some(ref e
) = arm
.guard
{
1875 self.word_space("if")?
;
1876 self.print_expr(&e
)?
;
1877 space(&mut self.s
)?
;
1879 self.word_space("=>")?
;
1881 match arm
.body
.node
{
1882 hir
::ExprBlock(ref blk
) => {
1883 // the block will close the pattern's ibox
1884 self.print_block_unclosed_indent(&blk
, indent_unit
)?
;
1886 // If it is a user-provided unsafe block, print a comma after it
1887 if let hir
::UnsafeBlock(hir
::UserProvided
) = blk
.rules
{
1888 word(&mut self.s
, ",")?
;
1892 self.end()?
; // close the ibox for the pattern
1893 self.print_expr(&arm
.body
)?
;
1894 word(&mut self.s
, ",")?
;
1897 self.end() // close enclosing cbox
1900 fn print_explicit_self(&mut self, explicit_self
: &hir
::ExplicitSelf
) -> io
::Result
<()> {
1901 match explicit_self
.node
{
1902 SelfKind
::Value(m
) => {
1903 self.print_mutability(m
)?
;
1904 word(&mut self.s
, "self")
1906 SelfKind
::Region(ref lt
, m
) => {
1907 word(&mut self.s
, "&")?
;
1908 self.print_opt_lifetime(lt
)?
;
1909 self.print_mutability(m
)?
;
1910 word(&mut self.s
, "self")
1912 SelfKind
::Explicit(ref typ
, m
) => {
1913 self.print_mutability(m
)?
;
1914 word(&mut self.s
, "self")?
;
1915 self.word_space(":")?
;
1916 self.print_type(&typ
)
1921 pub fn print_fn(&mut self,
1923 unsafety
: hir
::Unsafety
,
1924 constness
: hir
::Constness
,
1926 name
: Option
<ast
::Name
>,
1927 generics
: &hir
::Generics
,
1928 vis
: &hir
::Visibility
)
1930 self.print_fn_header_info(unsafety
, constness
, abi
, vis
)?
;
1932 if let Some(name
) = name
{
1934 self.print_name(name
)?
;
1936 self.print_generics(generics
)?
;
1937 self.print_fn_args_and_ret(decl
)?
;
1938 self.print_where_clause(&generics
.where_clause
)
1941 pub fn print_fn_args_and_ret(&mut self, decl
: &hir
::FnDecl
) -> io
::Result
<()> {
1943 self.commasep(Inconsistent
, &decl
.inputs
, |s
, arg
| s
.print_arg(arg
, false))?
;
1945 word(&mut self.s
, ", ...")?
;
1949 self.print_fn_output(decl
)
1952 pub fn print_fn_block_args(&mut self, decl
: &hir
::FnDecl
) -> io
::Result
<()> {
1953 word(&mut self.s
, "|")?
;
1954 self.commasep(Inconsistent
, &decl
.inputs
, |s
, arg
| s
.print_arg(arg
, true))?
;
1955 word(&mut self.s
, "|")?
;
1957 if let hir
::DefaultReturn(..) = decl
.output
{
1961 self.space_if_not_bol()?
;
1962 self.word_space("->")?
;
1964 hir
::Return(ref ty
) => {
1965 self.print_type(&ty
)?
;
1966 self.maybe_print_comment(ty
.span
.lo
)
1968 hir
::DefaultReturn(..) => unreachable
!(),
1972 pub fn print_capture_clause(&mut self, capture_clause
: hir
::CaptureClause
) -> io
::Result
<()> {
1973 match capture_clause
{
1974 hir
::CaptureByValue
=> self.word_space("move"),
1975 hir
::CaptureByRef
=> Ok(()),
1979 pub fn print_bounds(&mut self, prefix
: &str, bounds
: &[hir
::TyParamBound
]) -> io
::Result
<()> {
1980 if !bounds
.is_empty() {
1981 word(&mut self.s
, prefix
)?
;
1982 let mut first
= true;
1983 for bound
in bounds
{
1988 self.word_space("+")?
;
1992 TraitTyParamBound(ref tref
, TraitBoundModifier
::None
) => {
1993 self.print_poly_trait_ref(tref
)
1995 TraitTyParamBound(ref tref
, TraitBoundModifier
::Maybe
) => {
1996 word(&mut self.s
, "?")?
;
1997 self.print_poly_trait_ref(tref
)
1999 RegionTyParamBound(ref lt
) => {
2000 self.print_lifetime(lt
)
2010 pub fn print_lifetime(&mut self, lifetime
: &hir
::Lifetime
) -> io
::Result
<()> {
2011 self.print_name(lifetime
.name
)
2014 pub fn print_lifetime_def(&mut self, lifetime
: &hir
::LifetimeDef
) -> io
::Result
<()> {
2015 self.print_lifetime(&lifetime
.lifetime
)?
;
2017 for v
in &lifetime
.bounds
{
2018 word(&mut self.s
, sep
)?
;
2019 self.print_lifetime(v
)?
;
2025 pub fn print_generics(&mut self, generics
: &hir
::Generics
) -> io
::Result
<()> {
2026 let total
= generics
.lifetimes
.len() + generics
.ty_params
.len();
2031 word(&mut self.s
, "<")?
;
2033 let mut ints
= Vec
::new();
2038 self.commasep(Inconsistent
, &ints
[..], |s
, &idx
| {
2039 if idx
< generics
.lifetimes
.len() {
2040 let lifetime
= &generics
.lifetimes
[idx
];
2041 s
.print_lifetime_def(lifetime
)
2043 let idx
= idx
- generics
.lifetimes
.len();
2044 let param
= &generics
.ty_params
[idx
];
2045 s
.print_ty_param(param
)
2049 word(&mut self.s
, ">")?
;
2053 pub fn print_ty_param(&mut self, param
: &hir
::TyParam
) -> io
::Result
<()> {
2054 self.print_name(param
.name
)?
;
2055 self.print_bounds(":", ¶m
.bounds
)?
;
2056 match param
.default {
2057 Some(ref default) => {
2058 space(&mut self.s
)?
;
2059 self.word_space("=")?
;
2060 self.print_type(&default)
2066 pub fn print_where_clause(&mut self, where_clause
: &hir
::WhereClause
) -> io
::Result
<()> {
2067 if where_clause
.predicates
.is_empty() {
2071 space(&mut self.s
)?
;
2072 self.word_space("where")?
;
2074 for (i
, predicate
) in where_clause
.predicates
.iter().enumerate() {
2076 self.word_space(",")?
;
2080 &hir
::WherePredicate
::BoundPredicate(hir
::WhereBoundPredicate
{ref bound_lifetimes
,
2084 self.print_formal_lifetime_list(bound_lifetimes
)?
;
2085 self.print_type(&bounded_ty
)?
;
2086 self.print_bounds(":", bounds
)?
;
2088 &hir
::WherePredicate
::RegionPredicate(hir
::WhereRegionPredicate
{ref lifetime
,
2091 self.print_lifetime(lifetime
)?
;
2092 word(&mut self.s
, ":")?
;
2094 for (i
, bound
) in bounds
.iter().enumerate() {
2095 self.print_lifetime(bound
)?
;
2098 word(&mut self.s
, ":")?
;
2102 &hir
::WherePredicate
::EqPredicate(hir
::WhereEqPredicate{ref path, ref ty, ..}
) => {
2103 self.print_path(path
, false, 0)?
;
2104 space(&mut self.s
)?
;
2105 self.word_space("=")?
;
2106 self.print_type(&ty
)?
;
2114 pub fn print_view_path(&mut self, vp
: &hir
::ViewPath
) -> io
::Result
<()> {
2116 hir
::ViewPathSimple(name
, ref path
) => {
2117 self.print_path(path
, false, 0)?
;
2119 if path
.segments
.last().unwrap().name
!= name
{
2120 space(&mut self.s
)?
;
2121 self.word_space("as")?
;
2122 self.print_name(name
)?
;
2128 hir
::ViewPathGlob(ref path
) => {
2129 self.print_path(path
, false, 0)?
;
2130 word(&mut self.s
, "::*")
2133 hir
::ViewPathList(ref path
, ref segments
) => {
2134 if path
.segments
.is_empty() {
2135 word(&mut self.s
, "{")?
;
2137 self.print_path(path
, false, 0)?
;
2138 word(&mut self.s
, "::{")?
;
2140 self.commasep(Inconsistent
, &segments
[..], |s
, w
| s
.print_name(w
.node
.name
))?
;
2141 word(&mut self.s
, "}")
2146 pub fn print_mutability(&mut self, mutbl
: hir
::Mutability
) -> io
::Result
<()> {
2148 hir
::MutMutable
=> self.word_nbsp("mut"),
2149 hir
::MutImmutable
=> Ok(()),
2153 pub fn print_mt(&mut self, mt
: &hir
::MutTy
) -> io
::Result
<()> {
2154 self.print_mutability(mt
.mutbl
)?
;
2155 self.print_type(&mt
.ty
)
2158 pub fn print_arg(&mut self, input
: &hir
::Arg
, is_closure
: bool
) -> io
::Result
<()> {
2159 self.ibox(indent_unit
)?
;
2160 match input
.ty
.node
{
2161 hir
::TyInfer
if is_closure
=> self.print_pat(&input
.pat
)?
,
2163 if let Some(eself
) = input
.to_self() {
2164 self.print_explicit_self(&eself
)?
;
2166 let invalid
= if let PatKind
::Binding(_
, name
, _
) = input
.pat
.node
{
2167 name
.node
== keywords
::Invalid
.name()
2172 self.print_pat(&input
.pat
)?
;
2173 word(&mut self.s
, ":")?
;
2174 space(&mut self.s
)?
;
2176 self.print_type(&input
.ty
)?
;
2183 pub fn print_fn_output(&mut self, decl
: &hir
::FnDecl
) -> io
::Result
<()> {
2184 if let hir
::DefaultReturn(..) = decl
.output
{
2188 self.space_if_not_bol()?
;
2189 self.ibox(indent_unit
)?
;
2190 self.word_space("->")?
;
2192 hir
::DefaultReturn(..) => unreachable
!(),
2193 hir
::Return(ref ty
) => self.print_type(&ty
)?
,
2198 hir
::Return(ref output
) => self.maybe_print_comment(output
.span
.lo
),
2203 pub fn print_ty_fn(&mut self,
2205 unsafety
: hir
::Unsafety
,
2207 name
: Option
<ast
::Name
>,
2208 generics
: &hir
::Generics
)
2210 self.ibox(indent_unit
)?
;
2211 if !generics
.lifetimes
.is_empty() || !generics
.ty_params
.is_empty() {
2212 word(&mut self.s
, "for")?
;
2213 self.print_generics(generics
)?
;
2215 let generics
= hir
::Generics
{
2216 lifetimes
: hir
::HirVec
::new(),
2217 ty_params
: hir
::HirVec
::new(),
2218 where_clause
: hir
::WhereClause
{
2219 id
: ast
::DUMMY_NODE_ID
,
2220 predicates
: hir
::HirVec
::new(),
2222 span
: syntax_pos
::DUMMY_SP
,
2226 hir
::Constness
::NotConst
,
2234 pub fn maybe_print_trailing_comment(&mut self,
2235 span
: syntax_pos
::Span
,
2236 next_pos
: Option
<BytePos
>)
2238 let cm
= match self.cm
{
2242 if let Some(ref cmnt
) = self.next_comment() {
2243 if (*cmnt
).style
!= comments
::Trailing
{
2246 let span_line
= cm
.lookup_char_pos(span
.hi
);
2247 let comment_line
= cm
.lookup_char_pos((*cmnt
).pos
);
2248 let mut next
= (*cmnt
).pos
+ BytePos(1);
2249 if let Some(p
) = next_pos
{
2252 if span
.hi
< (*cmnt
).pos
&& (*cmnt
).pos
< next
&&
2253 span_line
.line
== comment_line
.line
{
2254 self.print_comment(cmnt
)?
;
2255 self.cur_cmnt_and_lit
.cur_cmnt
+= 1;
2261 pub fn print_remaining_comments(&mut self) -> io
::Result
<()> {
2262 // If there aren't any remaining comments, then we need to manually
2263 // make sure there is a line break at the end.
2264 if self.next_comment().is_none() {
2265 hardbreak(&mut self.s
)?
;
2268 match self.next_comment() {
2270 self.print_comment(cmnt
)?
;
2271 self.cur_cmnt_and_lit
.cur_cmnt
+= 1;
2279 pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
2280 opt_abi
: Option
<Abi
>)
2283 Some(Abi
::Rust
) => Ok(()),
2285 self.word_nbsp("extern")?
;
2286 self.word_nbsp(&abi
.to_string())
2292 pub fn print_extern_opt_abi(&mut self, opt_abi
: Option
<Abi
>) -> io
::Result
<()> {
2295 self.word_nbsp("extern")?
;
2296 self.word_nbsp(&abi
.to_string())
2302 pub fn print_fn_header_info(&mut self,
2303 unsafety
: hir
::Unsafety
,
2304 constness
: hir
::Constness
,
2306 vis
: &hir
::Visibility
)
2308 word(&mut self.s
, &visibility_qualified(vis
, ""))?
;
2309 self.print_unsafety(unsafety
)?
;
2312 hir
::Constness
::NotConst
=> {}
2313 hir
::Constness
::Const
=> self.word_nbsp("const")?
,
2316 if abi
!= Abi
::Rust
{
2317 self.word_nbsp("extern")?
;
2318 self.word_nbsp(&abi
.to_string())?
;
2321 word(&mut self.s
, "fn")
2324 pub fn print_unsafety(&mut self, s
: hir
::Unsafety
) -> io
::Result
<()> {
2326 hir
::Unsafety
::Normal
=> Ok(()),
2327 hir
::Unsafety
::Unsafe
=> self.word_nbsp("unsafe"),
2332 // Dup'ed from parse::classify, but adapted for the HIR.
2333 /// Does this expression require a semicolon to be treated
2334 /// as a statement? The negation of this: 'can this expression
2335 /// be used as a statement without a semicolon' -- is used
2336 /// as an early-bail-out in the parser so that, for instance,
2337 /// if true {...} else {...}
2339 /// isn't parsed as (if true {...} else {...} | x) | 5
2340 fn expr_requires_semi_to_be_stmt(e
: &hir
::Expr
) -> bool
{
2343 hir
::ExprMatch(..) |
2345 hir
::ExprWhile(..) |
2346 hir
::ExprLoop(..) => false,
2351 /// this statement requires a semicolon after it.
2352 /// note that in one case (stmt_semi), we've already
2353 /// seen the semicolon, and thus don't need another.
2354 fn stmt_ends_with_semi(stmt
: &hir
::Stmt_
) -> bool
{
2356 hir
::StmtDecl(ref d
, _
) => {
2358 hir
::DeclLocal(_
) => true,
2359 hir
::DeclItem(_
) => false,
2362 hir
::StmtExpr(ref e
, _
) => {
2363 expr_requires_semi_to_be_stmt(&e
)
2365 hir
::StmtSemi(..) => {