1 #![feature(or_patterns)]
2 #![recursion_limit = "256"]
5 use rustc_ast
::util
::parser
::{self, AssocOp, Fixity}
;
6 use rustc_ast_pretty
::pp
::Breaks
::{Consistent, Inconsistent}
;
7 use rustc_ast_pretty
::pp
::{self, Breaks}
;
8 use rustc_ast_pretty
::pprust
::{Comments, PrintState}
;
10 use rustc_hir
::{GenericArg, GenericParam, GenericParamKind, Node}
;
11 use rustc_hir
::{GenericBound, PatKind, RangeEnd, TraitBoundModifier}
;
12 use rustc_span
::source_map
::{SourceMap, Spanned}
;
13 use rustc_span
::symbol
::{kw, Ident, IdentPrinter, Symbol}
;
14 use rustc_span
::{self, BytePos, FileName}
;
15 use rustc_target
::spec
::abi
::Abi
;
21 pub fn id_to_string(map
: &dyn rustc_hir
::intravisit
::Map
<'_
>, hir_id
: hir
::HirId
) -> String
{
22 to_string(&map
, |s
| s
.print_node(map
.find(hir_id
).unwrap()))
25 pub enum AnnNode
<'a
> {
27 Block(&'a hir
::Block
<'a
>),
28 Item(&'a hir
::Item
<'a
>),
30 Expr(&'a hir
::Expr
<'a
>),
31 Pat(&'a hir
::Pat
<'a
>),
32 Arm(&'a hir
::Arm
<'a
>),
37 TraitItem(hir
::TraitItemId
),
38 ImplItem(hir
::ImplItemId
),
39 ForeignItem(hir
::ForeignItemId
),
41 BodyParamPat(hir
::BodyId
, usize),
45 fn nested(&self, _state
: &mut State
<'_
>, _nested
: Nested
) {}
46 fn pre(&self, _state
: &mut State
<'_
>, _node
: AnnNode
<'_
>) {}
47 fn post(&self, _state
: &mut State
<'_
>, _node
: AnnNode
<'_
>) {}
51 impl PpAnn
for NoAnn {}
52 pub const NO_ANN
: &dyn PpAnn
= &NoAnn
;
54 impl PpAnn
for hir
::Crate
<'_
> {
55 fn nested(&self, state
: &mut State
<'_
>, nested
: Nested
) {
57 Nested
::Item(id
) => state
.print_item(self.item(id
.id
)),
58 Nested
::TraitItem(id
) => state
.print_trait_item(self.trait_item(id
)),
59 Nested
::ImplItem(id
) => state
.print_impl_item(self.impl_item(id
)),
60 Nested
::ForeignItem(id
) => state
.print_foreign_item(self.foreign_item(id
)),
61 Nested
::Body(id
) => state
.print_expr(&self.body(id
).value
),
62 Nested
::BodyParamPat(id
, i
) => state
.print_pat(&self.body(id
).params
[i
].pat
),
67 /// Identical to the `PpAnn` implementation for `hir::Crate`,
68 /// except it avoids creating a dependency on the whole crate.
69 impl PpAnn
for &dyn rustc_hir
::intravisit
::Map
<'_
> {
70 fn nested(&self, state
: &mut State
<'_
>, nested
: Nested
) {
72 Nested
::Item(id
) => state
.print_item(self.item(id
.id
)),
73 Nested
::TraitItem(id
) => state
.print_trait_item(self.trait_item(id
)),
74 Nested
::ImplItem(id
) => state
.print_impl_item(self.impl_item(id
)),
75 Nested
::ForeignItem(id
) => state
.print_foreign_item(self.foreign_item(id
)),
76 Nested
::Body(id
) => state
.print_expr(&self.body(id
).value
),
77 Nested
::BodyParamPat(id
, i
) => state
.print_pat(&self.body(id
).params
[i
].pat
),
82 pub struct State
<'a
> {
84 comments
: Option
<Comments
<'a
>>,
85 ann
: &'
a (dyn PpAnn
+ 'a
),
89 pub fn print_node(&mut self, node
: Node
<'_
>) {
91 Node
::Param(a
) => self.print_param(&a
),
92 Node
::Item(a
) => self.print_item(&a
),
93 Node
::ForeignItem(a
) => self.print_foreign_item(&a
),
94 Node
::TraitItem(a
) => self.print_trait_item(a
),
95 Node
::ImplItem(a
) => self.print_impl_item(a
),
96 Node
::Variant(a
) => self.print_variant(&a
),
97 Node
::AnonConst(a
) => self.print_anon_const(&a
),
98 Node
::Expr(a
) => self.print_expr(&a
),
99 Node
::Stmt(a
) => self.print_stmt(&a
),
100 Node
::PathSegment(a
) => self.print_path_segment(&a
),
101 Node
::Ty(a
) => self.print_type(&a
),
102 Node
::TraitRef(a
) => self.print_trait_ref(&a
),
103 Node
::Binding(a
) | Node
::Pat(a
) => self.print_pat(&a
),
104 Node
::Arm(a
) => self.print_arm(&a
),
106 // Containing cbox, will be closed by print-block at `}`.
107 self.cbox(INDENT_UNIT
);
108 // Head-ibox, will be closed by print-block after `{`.
112 Node
::Lifetime(a
) => self.print_lifetime(&a
),
113 Node
::Visibility(a
) => self.print_visibility(&a
),
114 Node
::GenericParam(_
) => panic
!("cannot print Node::GenericParam"),
115 Node
::Field(_
) => panic
!("cannot print StructField"),
116 // These cases do not carry enough information in the
117 // `hir_map` to reconstruct their full structure for pretty
119 Node
::Ctor(..) => panic
!("cannot print isolated Ctor"),
120 Node
::Local(a
) => self.print_local_decl(&a
),
121 Node
::MacroDef(_
) => panic
!("cannot print MacroDef"),
122 Node
::Crate(..) => panic
!("cannot print Crate"),
127 impl std
::ops
::Deref
for State
<'_
> {
128 type Target
= pp
::Printer
;
129 fn deref(&self) -> &Self::Target
{
134 impl std
::ops
::DerefMut
for State
<'_
> {
135 fn deref_mut(&mut self) -> &mut Self::Target
{
140 impl<'a
> PrintState
<'a
> for State
<'a
> {
141 fn comments(&mut self) -> &mut Option
<Comments
<'a
>> {
145 fn print_ident(&mut self, ident
: Ident
) {
146 self.s
.word(IdentPrinter
::for_ast_ident(ident
, ident
.is_raw_guess()).to_string());
147 self.ann
.post(self, AnnNode
::Name(&ident
.name
))
150 fn print_generic_args(&mut self, _
: &ast
::GenericArgs
, _colons_before_params
: bool
) {
151 panic
!("AST generic args printed by HIR pretty-printer");
155 pub const INDENT_UNIT
: usize = 4;
157 /// Requires you to pass an input filename and reader so that
158 /// it can scan the input text for comments to copy forward.
159 pub fn print_crate
<'a
>(
161 krate
: &hir
::Crate
<'_
>,
166 let mut s
= State
::new_from_input(sm
, filename
, input
, ann
);
168 // When printing the AST, we sometimes need to inject `#[no_std]` here.
169 // Since you can't compile the HIR, it's not necessary.
171 s
.print_mod(&krate
.item
.module
, &krate
.item
.attrs
);
172 s
.print_remaining_comments();
177 pub fn new_from_input(
183 State { s: pp::mk_printer(), comments: Some(Comments::new(sm, filename, input)), ann }
187 pub fn to_string
<F
>(ann
: &dyn PpAnn
, f
: F
) -> String
189 F
: FnOnce(&mut State
<'_
>),
191 let mut printer
= State { s: pp::mk_printer(), comments: None, ann }
;
196 pub fn visibility_qualified
<S
: Into
<Cow
<'
static, str>>>(vis
: &hir
::Visibility
<'_
>, w
: S
) -> String
{
197 to_string(NO_ANN
, |s
| {
198 s
.print_visibility(vis
);
203 pub fn generic_params_to_string(generic_params
: &[GenericParam
<'_
>]) -> String
{
204 to_string(NO_ANN
, |s
| s
.print_generic_params(generic_params
))
207 pub fn bounds_to_string
<'b
>(bounds
: impl IntoIterator
<Item
= &'b hir
::GenericBound
<'b
>>) -> String
{
208 to_string(NO_ANN
, |s
| s
.print_bounds("", bounds
))
211 pub fn param_to_string(arg
: &hir
::Param
<'_
>) -> String
{
212 to_string(NO_ANN
, |s
| s
.print_param(arg
))
215 pub fn ty_to_string(ty
: &hir
::Ty
<'_
>) -> String
{
216 to_string(NO_ANN
, |s
| s
.print_type(ty
))
219 pub fn path_segment_to_string(segment
: &hir
::PathSegment
<'_
>) -> String
{
220 to_string(NO_ANN
, |s
| s
.print_path_segment(segment
))
223 pub fn path_to_string(segment
: &hir
::Path
<'_
>) -> String
{
224 to_string(NO_ANN
, |s
| s
.print_path(segment
, false))
228 decl
: &hir
::FnDecl
<'_
>,
229 header
: hir
::FnHeader
,
230 name
: Option
<Symbol
>,
231 generics
: &hir
::Generics
<'_
>,
232 vis
: &hir
::Visibility
<'_
>,
234 body_id
: Option
<hir
::BodyId
>,
236 to_string(NO_ANN
, |s
| s
.print_fn(decl
, header
, name
, generics
, vis
, arg_names
, body_id
))
239 pub fn enum_def_to_string(
240 enum_definition
: &hir
::EnumDef
<'_
>,
241 generics
: &hir
::Generics
<'_
>,
243 span
: rustc_span
::Span
,
244 visibility
: &hir
::Visibility
<'_
>,
246 to_string(NO_ANN
, |s
| s
.print_enum_def(enum_definition
, generics
, name
, span
, visibility
))
250 pub fn cbox(&mut self, u
: usize) {
254 pub fn nbsp(&mut self) {
258 pub fn word_nbsp
<S
: Into
<Cow
<'
static, str>>>(&mut self, w
: S
) {
263 pub fn head
<S
: Into
<Cow
<'
static, str>>>(&mut self, w
: S
) {
265 // outer-box is consistent
266 self.cbox(INDENT_UNIT
);
267 // head-box is inconsistent
268 self.ibox(w
.len() + 1);
269 // keyword that starts the head
275 pub fn bopen(&mut self) {
277 self.end(); // close the head-box
280 pub fn bclose_maybe_open(&mut self, span
: rustc_span
::Span
, close_box
: bool
) {
281 self.maybe_print_comment(span
.hi());
282 self.break_offset_if_not_bol(1, -(INDENT_UNIT
as isize));
285 self.end(); // close the outer-box
289 pub fn bclose(&mut self, span
: rustc_span
::Span
) {
290 self.bclose_maybe_open(span
, true)
293 pub fn space_if_not_bol(&mut self) {
294 if !self.s
.is_beginning_of_line() {
299 pub fn break_offset_if_not_bol(&mut self, n
: usize, off
: isize) {
300 if !self.s
.is_beginning_of_line() {
301 self.s
.break_offset(n
, off
)
302 } else if off
!= 0 && self.s
.last_token().is_hardbreak_tok() {
303 // We do something pretty sketchy here: tuck the nonzero
304 // offset-adjustment we were going to deposit along with the
305 // break into the previous hardbreak.
306 self.s
.replace_last_token(pp
::Printer
::hardbreak_tok_offset(off
));
310 // Synthesizes a comment that was not textually present in the original source
312 pub fn synth_comment(&mut self, text
: String
) {
320 pub fn commasep_cmnt
<T
, F
, G
>(&mut self, b
: Breaks
, elts
: &[T
], mut op
: F
, mut get_span
: G
)
322 F
: FnMut(&mut State
<'_
>, &T
),
323 G
: FnMut(&T
) -> rustc_span
::Span
,
326 let len
= elts
.len();
329 self.maybe_print_comment(get_span(elt
).hi());
334 self.maybe_print_trailing_comment(get_span(elt
), Some(get_span(&elts
[i
]).hi()));
335 self.space_if_not_bol();
341 pub fn commasep_exprs(&mut self, b
: Breaks
, exprs
: &[hir
::Expr
<'_
>]) {
342 self.commasep_cmnt(b
, exprs
, |s
, e
| s
.print_expr(&e
), |e
| e
.span
)
345 pub fn print_mod(&mut self, _mod
: &hir
::Mod
<'_
>, attrs
: &[ast
::Attribute
]) {
346 self.print_inner_attributes(attrs
);
347 for &item_id
in _mod
.item_ids
{
348 self.ann
.nested(self, Nested
::Item(item_id
));
352 pub fn print_opt_lifetime(&mut self, lifetime
: &hir
::Lifetime
) {
353 if !lifetime
.is_elided() {
354 self.print_lifetime(lifetime
);
359 pub fn print_type(&mut self, ty
: &hir
::Ty
<'_
>) {
360 self.maybe_print_comment(ty
.span
.lo());
363 hir
::TyKind
::Slice(ref ty
) => {
365 self.print_type(&ty
);
368 hir
::TyKind
::Ptr(ref mt
) => {
370 self.print_mt(mt
, true);
372 hir
::TyKind
::Rptr(ref lifetime
, ref mt
) => {
374 self.print_opt_lifetime(lifetime
);
375 self.print_mt(mt
, false);
377 hir
::TyKind
::Never
=> {
380 hir
::TyKind
::Tup(ref elts
) => {
382 self.commasep(Inconsistent
, &elts
[..], |s
, ty
| s
.print_type(&ty
));
388 hir
::TyKind
::BareFn(ref f
) => {
398 hir
::TyKind
::OpaqueDef(..) => self.s
.word("/*impl Trait*/"),
399 hir
::TyKind
::Path(ref qpath
) => self.print_qpath(qpath
, false),
400 hir
::TyKind
::TraitObject(bounds
, ref lifetime
) => {
401 let mut first
= true;
402 for bound
in bounds
{
407 self.word_space("+");
409 self.print_poly_trait_ref(bound
);
411 if !lifetime
.is_elided() {
413 self.word_space("+");
414 self.print_lifetime(lifetime
);
417 hir
::TyKind
::Array(ref ty
, ref length
) => {
419 self.print_type(&ty
);
421 self.print_anon_const(length
);
424 hir
::TyKind
::Typeof(ref e
) => {
425 self.s
.word("typeof(");
426 self.print_anon_const(e
);
429 hir
::TyKind
::Infer
=> {
432 hir
::TyKind
::Err
=> {
434 self.s
.word("/*ERROR*/");
441 pub fn print_foreign_item(&mut self, item
: &hir
::ForeignItem
<'_
>) {
442 self.hardbreak_if_not_bol();
443 self.maybe_print_comment(item
.span
.lo());
444 self.print_outer_attributes(&item
.attrs
);
446 hir
::ForeignItemKind
::Fn(ref decl
, ref arg_names
, ref generics
) => {
451 unsafety
: hir
::Unsafety
::Normal
,
452 constness
: hir
::Constness
::NotConst
,
454 asyncness
: hir
::IsAsync
::NotAsync
,
456 Some(item
.ident
.name
),
462 self.end(); // end head-ibox
464 self.end() // end the outer fn box
466 hir
::ForeignItemKind
::Static(ref t
, m
) => {
467 self.head(visibility_qualified(&item
.vis
, "static"));
468 if m
== hir
::Mutability
::Mut
{
469 self.word_space("mut");
471 self.print_ident(item
.ident
);
472 self.word_space(":");
475 self.end(); // end the head-ibox
476 self.end() // end the outer cbox
478 hir
::ForeignItemKind
::Type
=> {
479 self.head(visibility_qualified(&item
.vis
, "type"));
480 self.print_ident(item
.ident
);
482 self.end(); // end the head-ibox
483 self.end() // end the outer cbox
488 fn print_associated_const(
492 default: Option
<hir
::BodyId
>,
493 vis
: &hir
::Visibility
<'_
>,
495 self.s
.word(visibility_qualified(vis
, ""));
496 self.word_space("const");
497 self.print_ident(ident
);
498 self.word_space(":");
500 if let Some(expr
) = default {
502 self.word_space("=");
503 self.ann
.nested(self, Nested
::Body(expr
));
508 fn print_associated_type(
511 generics
: &hir
::Generics
<'_
>,
512 bounds
: Option
<hir
::GenericBounds
<'_
>>,
513 ty
: Option
<&hir
::Ty
<'_
>>,
515 self.word_space("type");
516 self.print_ident(ident
);
517 self.print_generic_params(&generics
.params
);
518 if let Some(bounds
) = bounds
{
519 self.print_bounds(":", bounds
);
521 self.print_where_clause(&generics
.where_clause
);
522 if let Some(ty
) = ty
{
524 self.word_space("=");
532 item
: &hir
::Item
<'_
>,
533 generics
: &hir
::Generics
<'_
>,
534 inner
: impl Fn(&mut Self),
536 self.head(visibility_qualified(&item
.vis
, "type"));
537 self.print_ident(item
.ident
);
538 self.print_generic_params(&generics
.params
);
539 self.end(); // end the inner ibox
541 self.print_where_clause(&generics
.where_clause
);
545 self.end(); // end the outer ibox
548 /// Pretty-print an item
549 pub fn print_item(&mut self, item
: &hir
::Item
<'_
>) {
550 self.hardbreak_if_not_bol();
551 self.maybe_print_comment(item
.span
.lo());
552 self.print_outer_attributes(&item
.attrs
);
553 self.ann
.pre(self, AnnNode
::Item(item
));
555 hir
::ItemKind
::ExternCrate(orig_name
) => {
556 self.head(visibility_qualified(&item
.vis
, "extern crate"));
557 if let Some(orig_name
) = orig_name
{
558 self.print_name(orig_name
);
563 self.print_ident(item
.ident
);
565 self.end(); // end inner head-block
566 self.end(); // end outer head-block
568 hir
::ItemKind
::Use(ref path
, kind
) => {
569 self.head(visibility_qualified(&item
.vis
, "use"));
570 self.print_path(path
, false);
573 hir
::UseKind
::Single
=> {
574 if path
.segments
.last().unwrap().ident
!= item
.ident
{
576 self.word_space("as");
577 self.print_ident(item
.ident
);
581 hir
::UseKind
::Glob
=> self.s
.word("::*;"),
582 hir
::UseKind
::ListStem
=> self.s
.word("::{};"),
584 self.end(); // end inner head-block
585 self.end(); // end outer head-block
587 hir
::ItemKind
::Static(ref ty
, m
, expr
) => {
588 self.head(visibility_qualified(&item
.vis
, "static"));
589 if m
== hir
::Mutability
::Mut
{
590 self.word_space("mut");
592 self.print_ident(item
.ident
);
593 self.word_space(":");
594 self.print_type(&ty
);
596 self.end(); // end the head-ibox
598 self.word_space("=");
599 self.ann
.nested(self, Nested
::Body(expr
));
601 self.end(); // end the outer cbox
603 hir
::ItemKind
::Const(ref ty
, expr
) => {
604 self.head(visibility_qualified(&item
.vis
, "const"));
605 self.print_ident(item
.ident
);
606 self.word_space(":");
607 self.print_type(&ty
);
609 self.end(); // end the head-ibox
611 self.word_space("=");
612 self.ann
.nested(self, Nested
::Body(expr
));
614 self.end(); // end the outer cbox
616 hir
::ItemKind
::Fn(ref sig
, ref param_names
, body
) => {
621 Some(item
.ident
.name
),
628 self.end(); // need to close a box
629 self.end(); // need to close a box
630 self.ann
.nested(self, Nested
::Body(body
));
632 hir
::ItemKind
::Mod(ref _mod
) => {
633 self.head(visibility_qualified(&item
.vis
, "mod"));
634 self.print_ident(item
.ident
);
637 self.print_mod(_mod
, &item
.attrs
);
638 self.bclose(item
.span
);
640 hir
::ItemKind
::ForeignMod { abi, items }
=> {
642 self.word_nbsp(abi
.to_string());
644 self.print_inner_attributes(item
.attrs
);
646 self.ann
.nested(self, Nested
::ForeignItem(item
.id
));
648 self.bclose(item
.span
);
650 hir
::ItemKind
::GlobalAsm(ref ga
) => {
651 self.head(visibility_qualified(&item
.vis
, "global asm"));
652 self.s
.word(ga
.asm
.to_string());
655 hir
::ItemKind
::TyAlias(ref ty
, ref generics
) => {
656 self.print_item_type(item
, &generics
, |state
| {
657 state
.word_space("=");
658 state
.print_type(&ty
);
661 hir
::ItemKind
::OpaqueTy(ref opaque_ty
) => {
662 self.print_item_type(item
, &opaque_ty
.generics
, |state
| {
663 let mut real_bounds
= Vec
::with_capacity(opaque_ty
.bounds
.len());
664 for b
in opaque_ty
.bounds
.iter() {
665 if let GenericBound
::Trait(ref ptr
, hir
::TraitBoundModifier
::Maybe
) = *b
{
667 state
.word_space("for ?");
668 state
.print_trait_ref(&ptr
.trait_ref
);
673 state
.print_bounds("= impl", real_bounds
);
676 hir
::ItemKind
::Enum(ref enum_definition
, ref params
) => {
677 self.print_enum_def(enum_definition
, params
, item
.ident
.name
, item
.span
, &item
.vis
);
679 hir
::ItemKind
::Struct(ref struct_def
, ref generics
) => {
680 self.head(visibility_qualified(&item
.vis
, "struct"));
681 self.print_struct(struct_def
, generics
, item
.ident
.name
, item
.span
, true);
683 hir
::ItemKind
::Union(ref struct_def
, ref generics
) => {
684 self.head(visibility_qualified(&item
.vis
, "union"));
685 self.print_struct(struct_def
, generics
, item
.ident
.name
, item
.span
, true);
687 hir
::ItemKind
::Impl(hir
::Impl
{
699 self.print_visibility(&item
.vis
);
700 self.print_defaultness(defaultness
);
701 self.print_unsafety(unsafety
);
702 self.word_nbsp("impl");
704 if !generics
.params
.is_empty() {
705 self.print_generic_params(&generics
.params
);
709 if constness
== hir
::Constness
::Const
{
710 self.word_nbsp("const");
713 if let hir
::ImplPolarity
::Negative(_
) = polarity
{
717 if let Some(ref t
) = of_trait
{
718 self.print_trait_ref(t
);
720 self.word_space("for");
723 self.print_type(&self_ty
);
724 self.print_where_clause(&generics
.where_clause
);
728 self.print_inner_attributes(&item
.attrs
);
729 for impl_item
in items
{
730 self.ann
.nested(self, Nested
::ImplItem(impl_item
.id
));
732 self.bclose(item
.span
);
734 hir
::ItemKind
::Trait(is_auto
, unsafety
, ref generics
, ref bounds
, trait_items
) => {
736 self.print_visibility(&item
.vis
);
737 self.print_is_auto(is_auto
);
738 self.print_unsafety(unsafety
);
739 self.word_nbsp("trait");
740 self.print_ident(item
.ident
);
741 self.print_generic_params(&generics
.params
);
742 let mut real_bounds
= Vec
::with_capacity(bounds
.len());
743 for b
in bounds
.iter() {
744 if let GenericBound
::Trait(ref ptr
, hir
::TraitBoundModifier
::Maybe
) = *b
{
746 self.word_space("for ?");
747 self.print_trait_ref(&ptr
.trait_ref
);
752 self.print_bounds(":", real_bounds
);
753 self.print_where_clause(&generics
.where_clause
);
756 for trait_item
in trait_items
{
757 self.ann
.nested(self, Nested
::TraitItem(trait_item
.id
));
759 self.bclose(item
.span
);
761 hir
::ItemKind
::TraitAlias(ref generics
, ref bounds
) => {
763 self.print_visibility(&item
.vis
);
764 self.word_nbsp("trait");
765 self.print_ident(item
.ident
);
766 self.print_generic_params(&generics
.params
);
767 let mut real_bounds
= Vec
::with_capacity(bounds
.len());
768 // FIXME(durka) this seems to be some quite outdated syntax
769 for b
in bounds
.iter() {
770 if let GenericBound
::Trait(ref ptr
, hir
::TraitBoundModifier
::Maybe
) = *b
{
772 self.word_space("for ?");
773 self.print_trait_ref(&ptr
.trait_ref
);
779 self.print_bounds("=", real_bounds
);
780 self.print_where_clause(&generics
.where_clause
);
784 self.ann
.post(self, AnnNode
::Item(item
))
787 pub fn print_trait_ref(&mut self, t
: &hir
::TraitRef
<'_
>) {
788 self.print_path(&t
.path
, false)
791 fn print_formal_generic_params(&mut self, generic_params
: &[hir
::GenericParam
<'_
>]) {
792 if !generic_params
.is_empty() {
794 self.print_generic_params(generic_params
);
799 fn print_poly_trait_ref(&mut self, t
: &hir
::PolyTraitRef
<'_
>) {
800 self.print_formal_generic_params(&t
.bound_generic_params
);
801 self.print_trait_ref(&t
.trait_ref
)
804 pub fn print_enum_def(
806 enum_definition
: &hir
::EnumDef
<'_
>,
807 generics
: &hir
::Generics
<'_
>,
809 span
: rustc_span
::Span
,
810 visibility
: &hir
::Visibility
<'_
>,
812 self.head(visibility_qualified(visibility
, "enum"));
813 self.print_name(name
);
814 self.print_generic_params(&generics
.params
);
815 self.print_where_clause(&generics
.where_clause
);
817 self.print_variants(&enum_definition
.variants
, span
)
820 pub fn print_variants(&mut self, variants
: &[hir
::Variant
<'_
>], span
: rustc_span
::Span
) {
823 self.space_if_not_bol();
824 self.maybe_print_comment(v
.span
.lo());
825 self.print_outer_attributes(&v
.attrs
);
826 self.ibox(INDENT_UNIT
);
827 self.print_variant(v
);
830 self.maybe_print_trailing_comment(v
.span
, None
);
835 pub fn print_visibility(&mut self, vis
: &hir
::Visibility
<'_
>) {
837 hir
::VisibilityKind
::Public
=> self.word_nbsp("pub"),
838 hir
::VisibilityKind
::Crate(ast
::CrateSugar
::JustCrate
) => self.word_nbsp("crate"),
839 hir
::VisibilityKind
::Crate(ast
::CrateSugar
::PubCrate
) => self.word_nbsp("pub(crate)"),
840 hir
::VisibilityKind
::Restricted { ref path, .. }
=> {
842 if path
.segments
.len() == 1 && path
.segments
[0].ident
.name
== kw
::Super
{
843 // Special case: `super` can print like `pub(super)`.
844 self.s
.word("super");
846 // Everything else requires `in` at present.
847 self.word_nbsp("in");
848 self.print_path(path
, false);
852 hir
::VisibilityKind
::Inherited
=> (),
856 pub fn print_defaultness(&mut self, defaultness
: hir
::Defaultness
) {
858 hir
::Defaultness
::Default { .. }
=> self.word_nbsp("default"),
859 hir
::Defaultness
::Final
=> (),
865 struct_def
: &hir
::VariantData
<'_
>,
866 generics
: &hir
::Generics
<'_
>,
868 span
: rustc_span
::Span
,
869 print_finalizer
: bool
,
871 self.print_name(name
);
872 self.print_generic_params(&generics
.params
);
874 hir
::VariantData
::Tuple(..) | hir
::VariantData
::Unit(..) => {
875 if let hir
::VariantData
::Tuple(..) = struct_def
{
877 self.commasep(Inconsistent
, struct_def
.fields(), |s
, field
| {
878 s
.maybe_print_comment(field
.span
.lo());
879 s
.print_outer_attributes(&field
.attrs
);
880 s
.print_visibility(&field
.vis
);
881 s
.print_type(&field
.ty
)
885 self.print_where_clause(&generics
.where_clause
);
890 self.end() // close the outer-box
892 hir
::VariantData
::Struct(..) => {
893 self.print_where_clause(&generics
.where_clause
);
896 self.hardbreak_if_not_bol();
898 for field
in struct_def
.fields() {
899 self.hardbreak_if_not_bol();
900 self.maybe_print_comment(field
.span
.lo());
901 self.print_outer_attributes(&field
.attrs
);
902 self.print_visibility(&field
.vis
);
903 self.print_ident(field
.ident
);
905 self.print_type(&field
.ty
);
914 pub fn print_variant(&mut self, v
: &hir
::Variant
<'_
>) {
916 let generics
= hir
::Generics
::empty();
917 self.print_struct(&v
.data
, &generics
, v
.ident
.name
, v
.span
, false);
918 if let Some(ref d
) = v
.disr_expr
{
920 self.word_space("=");
921 self.print_anon_const(d
);
924 pub fn print_method_sig(
928 generics
: &hir
::Generics
<'_
>,
929 vis
: &hir
::Visibility
<'_
>,
931 body_id
: Option
<hir
::BodyId
>,
933 self.print_fn(&m
.decl
, m
.header
, Some(ident
.name
), generics
, vis
, arg_names
, body_id
)
936 pub fn print_trait_item(&mut self, ti
: &hir
::TraitItem
<'_
>) {
937 self.ann
.pre(self, AnnNode
::SubItem(ti
.hir_id
));
938 self.hardbreak_if_not_bol();
939 self.maybe_print_comment(ti
.span
.lo());
940 self.print_outer_attributes(&ti
.attrs
);
942 hir
::TraitItemKind
::Const(ref ty
, default) => {
944 Spanned { span: rustc_span::DUMMY_SP, node: hir::VisibilityKind::Inherited }
;
945 self.print_associated_const(ti
.ident
, &ty
, default, &vis
);
947 hir
::TraitItemKind
::Fn(ref sig
, hir
::TraitFn
::Required(ref arg_names
)) => {
949 Spanned { span: rustc_span::DUMMY_SP, node: hir::VisibilityKind::Inherited }
;
950 self.print_method_sig(ti
.ident
, sig
, &ti
.generics
, &vis
, arg_names
, None
);
953 hir
::TraitItemKind
::Fn(ref sig
, hir
::TraitFn
::Provided(body
)) => {
955 Spanned { span: rustc_span::DUMMY_SP, node: hir::VisibilityKind::Inherited }
;
957 self.print_method_sig(ti
.ident
, sig
, &ti
.generics
, &vis
, &[], Some(body
));
959 self.end(); // need to close a box
960 self.end(); // need to close a box
961 self.ann
.nested(self, Nested
::Body(body
));
963 hir
::TraitItemKind
::Type(ref bounds
, ref default) => {
964 self.print_associated_type(
968 default.as_ref().map(|ty
| &**ty
),
972 self.ann
.post(self, AnnNode
::SubItem(ti
.hir_id
))
975 pub fn print_impl_item(&mut self, ii
: &hir
::ImplItem
<'_
>) {
976 self.ann
.pre(self, AnnNode
::SubItem(ii
.hir_id
));
977 self.hardbreak_if_not_bol();
978 self.maybe_print_comment(ii
.span
.lo());
979 self.print_outer_attributes(&ii
.attrs
);
980 self.print_defaultness(ii
.defaultness
);
983 hir
::ImplItemKind
::Const(ref ty
, expr
) => {
984 self.print_associated_const(ii
.ident
, &ty
, Some(expr
), &ii
.vis
);
986 hir
::ImplItemKind
::Fn(ref sig
, body
) => {
988 self.print_method_sig(ii
.ident
, sig
, &ii
.generics
, &ii
.vis
, &[], Some(body
));
990 self.end(); // need to close a box
991 self.end(); // need to close a box
992 self.ann
.nested(self, Nested
::Body(body
));
994 hir
::ImplItemKind
::TyAlias(ref ty
) => {
995 self.print_associated_type(ii
.ident
, &ii
.generics
, None
, Some(ty
));
998 self.ann
.post(self, AnnNode
::SubItem(ii
.hir_id
))
1001 pub fn print_local(&mut self, init
: Option
<&hir
::Expr
<'_
>>, decl
: impl Fn(&mut Self)) {
1002 self.space_if_not_bol();
1003 self.ibox(INDENT_UNIT
);
1004 self.word_nbsp("let");
1006 self.ibox(INDENT_UNIT
);
1010 if let Some(ref init
) = init
{
1012 self.word_space("=");
1013 self.print_expr(&init
);
1018 pub fn print_stmt(&mut self, st
: &hir
::Stmt
<'_
>) {
1019 self.maybe_print_comment(st
.span
.lo());
1021 hir
::StmtKind
::Local(ref loc
) => {
1022 self.print_local(loc
.init
.as_deref(), |this
| this
.print_local_decl(&loc
));
1024 hir
::StmtKind
::Item(item
) => self.ann
.nested(self, Nested
::Item(item
)),
1025 hir
::StmtKind
::Expr(ref expr
) => {
1026 self.space_if_not_bol();
1027 self.print_expr(&expr
);
1029 hir
::StmtKind
::Semi(ref expr
) => {
1030 self.space_if_not_bol();
1031 self.print_expr(&expr
);
1035 if stmt_ends_with_semi(&st
.kind
) {
1038 self.maybe_print_trailing_comment(st
.span
, None
)
1041 pub fn print_block(&mut self, blk
: &hir
::Block
<'_
>) {
1042 self.print_block_with_attrs(blk
, &[])
1045 pub fn print_block_unclosed(&mut self, blk
: &hir
::Block
<'_
>) {
1046 self.print_block_maybe_unclosed(blk
, &[], false)
1049 pub fn print_block_with_attrs(&mut self, blk
: &hir
::Block
<'_
>, attrs
: &[ast
::Attribute
]) {
1050 self.print_block_maybe_unclosed(blk
, attrs
, true)
1053 pub fn print_block_maybe_unclosed(
1055 blk
: &hir
::Block
<'_
>,
1056 attrs
: &[ast
::Attribute
],
1060 hir
::BlockCheckMode
::UnsafeBlock(..) => self.word_space("unsafe"),
1061 hir
::BlockCheckMode
::PushUnsafeBlock(..) => self.word_space("push_unsafe"),
1062 hir
::BlockCheckMode
::PopUnsafeBlock(..) => self.word_space("pop_unsafe"),
1063 hir
::BlockCheckMode
::DefaultBlock
=> (),
1065 self.maybe_print_comment(blk
.span
.lo());
1066 self.ann
.pre(self, AnnNode
::Block(blk
));
1069 self.print_inner_attributes(attrs
);
1071 for st
in blk
.stmts
{
1072 self.print_stmt(st
);
1074 if let Some(ref expr
) = blk
.expr
{
1075 self.space_if_not_bol();
1076 self.print_expr(&expr
);
1077 self.maybe_print_trailing_comment(expr
.span
, Some(blk
.span
.hi()));
1079 self.bclose_maybe_open(blk
.span
, close_box
);
1080 self.ann
.post(self, AnnNode
::Block(blk
))
1083 fn print_else(&mut self, els
: Option
<&hir
::Expr
<'_
>>) {
1087 // "another else-if"
1088 hir
::ExprKind
::If(ref i
, ref then
, ref e
) => {
1089 self.cbox(INDENT_UNIT
- 1);
1091 self.s
.word(" else if ");
1092 self.print_expr_as_cond(&i
);
1094 self.print_expr(&then
);
1095 self.print_else(e
.as_ref().map(|e
| &**e
))
1098 hir
::ExprKind
::Block(ref b
, _
) => {
1099 self.cbox(INDENT_UNIT
- 1);
1101 self.s
.word(" else ");
1102 self.print_block(&b
)
1104 // BLEAH, constraints would be great here
1106 panic
!("print_if saw if with weird alternative");
1116 test
: &hir
::Expr
<'_
>,
1117 blk
: &hir
::Expr
<'_
>,
1118 elseopt
: Option
<&hir
::Expr
<'_
>>,
1121 self.print_expr_as_cond(test
);
1123 self.print_expr(blk
);
1124 self.print_else(elseopt
)
1127 pub fn print_anon_const(&mut self, constant
: &hir
::AnonConst
) {
1128 self.ann
.nested(self, Nested
::Body(constant
.body
))
1131 fn print_call_post(&mut self, args
: &[hir
::Expr
<'_
>]) {
1133 self.commasep_exprs(Inconsistent
, args
);
1137 pub fn print_expr_maybe_paren(&mut self, expr
: &hir
::Expr
<'_
>, prec
: i8) {
1138 let needs_par
= expr
.precedence().order() < prec
;
1142 self.print_expr(expr
);
1148 /// Print an expr using syntax that's acceptable in a condition position, such as the `cond` in
1149 /// `if cond { ... }`.
1150 pub fn print_expr_as_cond(&mut self, expr
: &hir
::Expr
<'_
>) {
1151 let needs_par
= match expr
.kind
{
1152 // These cases need parens due to the parse error observed in #26461: `if return {}`
1153 // parses as the erroneous construct `if (return {})`, not `if (return) {}`.
1154 hir
::ExprKind
::Closure(..) | hir
::ExprKind
::Ret(..) | hir
::ExprKind
::Break(..) => true,
1156 _
=> contains_exterior_struct_lit(expr
),
1162 self.print_expr(expr
);
1168 fn print_expr_vec(&mut self, exprs
: &[hir
::Expr
<'_
>]) {
1169 self.ibox(INDENT_UNIT
);
1171 self.commasep_exprs(Inconsistent
, exprs
);
1176 fn print_expr_anon_const(&mut self, anon_const
: &hir
::AnonConst
) {
1177 self.ibox(INDENT_UNIT
);
1178 self.s
.word_space("const");
1179 self.print_anon_const(anon_const
);
1183 fn print_expr_repeat(&mut self, element
: &hir
::Expr
<'_
>, count
: &hir
::AnonConst
) {
1184 self.ibox(INDENT_UNIT
);
1186 self.print_expr(element
);
1187 self.word_space(";");
1188 self.print_anon_const(count
);
1193 fn print_expr_struct(
1195 qpath
: &hir
::QPath
<'_
>,
1196 fields
: &[hir
::Field
<'_
>],
1197 wth
: &Option
<&hir
::Expr
<'_
>>,
1199 self.print_qpath(qpath
, true);
1205 s
.ibox(INDENT_UNIT
);
1206 if !field
.is_shorthand
{
1207 s
.print_ident(field
.ident
);
1210 s
.print_expr(&field
.expr
);
1217 self.ibox(INDENT_UNIT
);
1218 if !fields
.is_empty() {
1223 self.print_expr(&expr
);
1227 if !fields
.is_empty() {
1235 fn print_expr_tup(&mut self, exprs
: &[hir
::Expr
<'_
>]) {
1237 self.commasep_exprs(Inconsistent
, exprs
);
1238 if exprs
.len() == 1 {
1244 fn print_expr_call(&mut self, func
: &hir
::Expr
<'_
>, args
: &[hir
::Expr
<'_
>]) {
1245 let prec
= match func
.kind
{
1246 hir
::ExprKind
::Field(..) => parser
::PREC_FORCE_PAREN
,
1247 _
=> parser
::PREC_POSTFIX
,
1250 self.print_expr_maybe_paren(func
, prec
);
1251 self.print_call_post(args
)
1254 fn print_expr_method_call(&mut self, segment
: &hir
::PathSegment
<'_
>, args
: &[hir
::Expr
<'_
>]) {
1255 let base_args
= &args
[1..];
1256 self.print_expr_maybe_paren(&args
[0], parser
::PREC_POSTFIX
);
1258 self.print_ident(segment
.ident
);
1260 let generic_args
= segment
.args();
1261 if !generic_args
.args
.is_empty() || !generic_args
.bindings
.is_empty() {
1262 self.print_generic_args(generic_args
, segment
.infer_args
, true);
1265 self.print_call_post(base_args
)
1268 fn print_expr_binary(&mut self, op
: hir
::BinOp
, lhs
: &hir
::Expr
<'_
>, rhs
: &hir
::Expr
<'_
>) {
1269 let assoc_op
= bin_op_to_assoc_op(op
.node
);
1270 let prec
= assoc_op
.precedence() as i8;
1271 let fixity
= assoc_op
.fixity();
1273 let (left_prec
, right_prec
) = match fixity
{
1274 Fixity
::Left
=> (prec
, prec
+ 1),
1275 Fixity
::Right
=> (prec
+ 1, prec
),
1276 Fixity
::None
=> (prec
+ 1, prec
+ 1),
1279 let left_prec
= match (&lhs
.kind
, op
.node
) {
1280 // These cases need parens: `x as i32 < y` has the parser thinking that `i32 < y` is
1281 // the beginning of a path type. It starts trying to parse `x as (i32 < y ...` instead
1282 // of `(x as i32) < ...`. We need to convince it _not_ to do that.
1283 (&hir
::ExprKind
::Cast { .. }
, hir
::BinOpKind
::Lt
| hir
::BinOpKind
::Shl
) => {
1284 parser
::PREC_FORCE_PAREN
1289 self.print_expr_maybe_paren(lhs
, left_prec
);
1291 self.word_space(op
.node
.as_str());
1292 self.print_expr_maybe_paren(rhs
, right_prec
)
1295 fn print_expr_unary(&mut self, op
: hir
::UnOp
, expr
: &hir
::Expr
<'_
>) {
1296 self.s
.word(op
.as_str());
1297 self.print_expr_maybe_paren(expr
, parser
::PREC_PREFIX
)
1300 fn print_expr_addr_of(
1302 kind
: hir
::BorrowKind
,
1303 mutability
: hir
::Mutability
,
1304 expr
: &hir
::Expr
<'_
>,
1308 hir
::BorrowKind
::Ref
=> self.print_mutability(mutability
, false),
1309 hir
::BorrowKind
::Raw
=> {
1310 self.word_nbsp("raw");
1311 self.print_mutability(mutability
, true);
1314 self.print_expr_maybe_paren(expr
, parser
::PREC_PREFIX
)
1317 fn print_literal(&mut self, lit
: &hir
::Lit
) {
1318 self.maybe_print_comment(lit
.span
.lo());
1319 self.word(lit
.node
.to_lit_token().to_string())
1322 pub fn print_expr(&mut self, expr
: &hir
::Expr
<'_
>) {
1323 self.maybe_print_comment(expr
.span
.lo());
1324 self.print_outer_attributes(&expr
.attrs
);
1325 self.ibox(INDENT_UNIT
);
1326 self.ann
.pre(self, AnnNode
::Expr(expr
));
1328 hir
::ExprKind
::Box(ref expr
) => {
1329 self.word_space("box");
1330 self.print_expr_maybe_paren(expr
, parser
::PREC_PREFIX
);
1332 hir
::ExprKind
::Array(ref exprs
) => {
1333 self.print_expr_vec(exprs
);
1335 hir
::ExprKind
::ConstBlock(ref anon_const
) => {
1336 self.print_expr_anon_const(anon_const
);
1338 hir
::ExprKind
::Repeat(ref element
, ref count
) => {
1339 self.print_expr_repeat(&element
, count
);
1341 hir
::ExprKind
::Struct(ref qpath
, fields
, ref wth
) => {
1342 self.print_expr_struct(qpath
, fields
, wth
);
1344 hir
::ExprKind
::Tup(ref exprs
) => {
1345 self.print_expr_tup(exprs
);
1347 hir
::ExprKind
::Call(ref func
, ref args
) => {
1348 self.print_expr_call(&func
, args
);
1350 hir
::ExprKind
::MethodCall(ref segment
, _
, ref args
, _
) => {
1351 self.print_expr_method_call(segment
, args
);
1353 hir
::ExprKind
::Binary(op
, ref lhs
, ref rhs
) => {
1354 self.print_expr_binary(op
, &lhs
, &rhs
);
1356 hir
::ExprKind
::Unary(op
, ref expr
) => {
1357 self.print_expr_unary(op
, &expr
);
1359 hir
::ExprKind
::AddrOf(k
, m
, ref expr
) => {
1360 self.print_expr_addr_of(k
, m
, &expr
);
1362 hir
::ExprKind
::Lit(ref lit
) => {
1363 self.print_literal(&lit
);
1365 hir
::ExprKind
::Cast(ref expr
, ref ty
) => {
1366 let prec
= AssocOp
::As
.precedence() as i8;
1367 self.print_expr_maybe_paren(&expr
, prec
);
1369 self.word_space("as");
1370 self.print_type(&ty
);
1372 hir
::ExprKind
::Type(ref expr
, ref ty
) => {
1373 let prec
= AssocOp
::Colon
.precedence() as i8;
1374 self.print_expr_maybe_paren(&expr
, prec
);
1375 self.word_space(":");
1376 self.print_type(&ty
);
1378 hir
::ExprKind
::DropTemps(ref init
) => {
1380 self.cbox(INDENT_UNIT
);
1384 // Print `let _t = $init;`:
1385 let temp
= Ident
::from_str("_t");
1386 self.print_local(Some(init
), |this
| this
.print_ident(temp
));
1390 self.space_if_not_bol();
1391 self.print_ident(temp
);
1394 self.bclose_maybe_open(expr
.span
, true);
1396 hir
::ExprKind
::If(ref test
, ref blk
, ref elseopt
) => {
1397 self.print_if(&test
, &blk
, elseopt
.as_ref().map(|e
| &**e
));
1399 hir
::ExprKind
::Loop(ref blk
, opt_label
, _
, _
) => {
1400 if let Some(label
) = opt_label
{
1401 self.print_ident(label
.ident
);
1402 self.word_space(":");
1406 self.print_block(&blk
);
1408 hir
::ExprKind
::Match(ref expr
, arms
, _
) => {
1409 self.cbox(INDENT_UNIT
);
1410 self.ibox(INDENT_UNIT
);
1411 self.word_nbsp("match");
1412 self.print_expr_as_cond(&expr
);
1416 self.print_arm(arm
);
1418 self.bclose(expr
.span
);
1420 hir
::ExprKind
::Closure(capture_clause
, ref decl
, body
, _fn_decl_span
, _gen
) => {
1421 self.print_capture_clause(capture_clause
);
1423 self.print_closure_params(&decl
, body
);
1426 // This is a bare expression.
1427 self.ann
.nested(self, Nested
::Body(body
));
1428 self.end(); // need to close a box
1430 // A box will be closed by `print_expr`, but we didn't want an overall
1431 // wrapper so we closed the corresponding opening. so create an
1432 // empty box to satisfy the close.
1435 hir
::ExprKind
::Block(ref blk
, opt_label
) => {
1436 if let Some(label
) = opt_label
{
1437 self.print_ident(label
.ident
);
1438 self.word_space(":");
1440 // containing cbox, will be closed by print-block at `}`
1441 self.cbox(INDENT_UNIT
);
1442 // head-box, will be closed by print-block after `{`
1444 self.print_block(&blk
);
1446 hir
::ExprKind
::Assign(ref lhs
, ref rhs
, _
) => {
1447 let prec
= AssocOp
::Assign
.precedence() as i8;
1448 self.print_expr_maybe_paren(&lhs
, prec
+ 1);
1450 self.word_space("=");
1451 self.print_expr_maybe_paren(&rhs
, prec
);
1453 hir
::ExprKind
::AssignOp(op
, ref lhs
, ref rhs
) => {
1454 let prec
= AssocOp
::Assign
.precedence() as i8;
1455 self.print_expr_maybe_paren(&lhs
, prec
+ 1);
1457 self.s
.word(op
.node
.as_str());
1458 self.word_space("=");
1459 self.print_expr_maybe_paren(&rhs
, prec
);
1461 hir
::ExprKind
::Field(ref expr
, ident
) => {
1462 self.print_expr_maybe_paren(expr
, parser
::PREC_POSTFIX
);
1464 self.print_ident(ident
);
1466 hir
::ExprKind
::Index(ref expr
, ref index
) => {
1467 self.print_expr_maybe_paren(&expr
, parser
::PREC_POSTFIX
);
1469 self.print_expr(&index
);
1472 hir
::ExprKind
::Path(ref qpath
) => self.print_qpath(qpath
, true),
1473 hir
::ExprKind
::Break(destination
, ref opt_expr
) => {
1474 self.s
.word("break");
1476 if let Some(label
) = destination
.label
{
1477 self.print_ident(label
.ident
);
1480 if let Some(ref expr
) = *opt_expr
{
1481 self.print_expr_maybe_paren(expr
, parser
::PREC_JUMP
);
1485 hir
::ExprKind
::Continue(destination
) => {
1486 self.s
.word("continue");
1488 if let Some(label
) = destination
.label
{
1489 self.print_ident(label
.ident
);
1493 hir
::ExprKind
::Ret(ref result
) => {
1494 self.s
.word("return");
1495 if let Some(ref expr
) = *result
{
1497 self.print_expr_maybe_paren(&expr
, parser
::PREC_JUMP
);
1500 hir
::ExprKind
::InlineAsm(ref a
) => {
1503 Operand(&'a hir
::InlineAsmOperand
<'a
>),
1504 Options(ast
::InlineAsmOptions
),
1507 let mut args
= vec
![];
1508 args
.push(AsmArg
::Template(ast
::InlineAsmTemplatePiece
::to_string(&a
.template
)));
1509 args
.extend(a
.operands
.iter().map(|(o
, _
)| AsmArg
::Operand(o
)));
1510 if !a
.options
.is_empty() {
1511 args
.push(AsmArg
::Options(a
.options
));
1516 self.commasep(Consistent
, &args
, |s
, arg
| match arg
{
1517 AsmArg
::Template(template
) => s
.print_string(&template
, ast
::StrStyle
::Cooked
),
1518 AsmArg
::Operand(op
) => match op
{
1519 hir
::InlineAsmOperand
::In { reg, expr }
=> {
1522 s
.word(format
!("{}", reg
));
1527 hir
::InlineAsmOperand
::Out { reg, late, expr }
=> {
1528 s
.word(if *late { "lateout" }
else { "out" }
);
1530 s
.word(format
!("{}", reg
));
1534 Some(expr
) => s
.print_expr(expr
),
1535 None
=> s
.word("_"),
1538 hir
::InlineAsmOperand
::InOut { reg, late, expr }
=> {
1539 s
.word(if *late { "inlateout" }
else { "inout" }
);
1541 s
.word(format
!("{}", reg
));
1546 hir
::InlineAsmOperand
::SplitInOut { reg, late, in_expr, out_expr }
=> {
1547 s
.word(if *late { "inlateout" }
else { "inout" }
);
1549 s
.word(format
!("{}", reg
));
1552 s
.print_expr(in_expr
);
1556 Some(out_expr
) => s
.print_expr(out_expr
),
1557 None
=> s
.word("_"),
1560 hir
::InlineAsmOperand
::Const { expr }
=> {
1565 hir
::InlineAsmOperand
::Sym { expr }
=> {
1571 AsmArg
::Options(opts
) => {
1574 let mut options
= vec
![];
1575 if opts
.contains(ast
::InlineAsmOptions
::PURE
) {
1576 options
.push("pure");
1578 if opts
.contains(ast
::InlineAsmOptions
::NOMEM
) {
1579 options
.push("nomem");
1581 if opts
.contains(ast
::InlineAsmOptions
::READONLY
) {
1582 options
.push("readonly");
1584 if opts
.contains(ast
::InlineAsmOptions
::PRESERVES_FLAGS
) {
1585 options
.push("preserves_flags");
1587 if opts
.contains(ast
::InlineAsmOptions
::NORETURN
) {
1588 options
.push("noreturn");
1590 if opts
.contains(ast
::InlineAsmOptions
::NOSTACK
) {
1591 options
.push("nostack");
1593 if opts
.contains(ast
::InlineAsmOptions
::ATT_SYNTAX
) {
1594 options
.push("att_syntax");
1596 s
.commasep(Inconsistent
, &options
, |s
, &opt
| {
1604 hir
::ExprKind
::LlvmInlineAsm(ref a
) => {
1606 self.s
.word("llvm_asm!");
1608 self.print_symbol(i
.asm
, i
.asm_str_style
);
1609 self.word_space(":");
1611 let mut out_idx
= 0;
1612 self.commasep(Inconsistent
, &i
.outputs
, |s
, out
| {
1613 let constraint
= out
.constraint
.as_str();
1614 let mut ch
= constraint
.chars();
1616 Some('
='
) if out
.is_rw
=> {
1617 s
.print_string(&format
!("+{}", ch
.as_str()), ast
::StrStyle
::Cooked
)
1619 _
=> s
.print_string(&constraint
, ast
::StrStyle
::Cooked
),
1622 s
.print_expr(&a
.outputs_exprs
[out_idx
]);
1627 self.word_space(":");
1630 self.commasep(Inconsistent
, &i
.inputs
, |s
, &co
| {
1631 s
.print_symbol(co
, ast
::StrStyle
::Cooked
);
1633 s
.print_expr(&a
.inputs_exprs
[in_idx
]);
1638 self.word_space(":");
1640 self.commasep(Inconsistent
, &i
.clobbers
, |s
, &co
| {
1641 s
.print_symbol(co
, ast
::StrStyle
::Cooked
);
1644 let mut options
= vec
![];
1646 options
.push("volatile");
1649 options
.push("alignstack");
1651 if i
.dialect
== ast
::LlvmAsmDialect
::Intel
{
1652 options
.push("intel");
1655 if !options
.is_empty() {
1657 self.word_space(":");
1658 self.commasep(Inconsistent
, &options
, |s
, &co
| {
1659 s
.print_string(co
, ast
::StrStyle
::Cooked
);
1665 hir
::ExprKind
::Yield(ref expr
, _
) => {
1666 self.word_space("yield");
1667 self.print_expr_maybe_paren(&expr
, parser
::PREC_JUMP
);
1669 hir
::ExprKind
::Err
=> {
1671 self.s
.word("/*ERROR*/");
1675 self.ann
.post(self, AnnNode
::Expr(expr
));
1679 pub fn print_local_decl(&mut self, loc
: &hir
::Local
<'_
>) {
1680 self.print_pat(&loc
.pat
);
1681 if let Some(ref ty
) = loc
.ty
{
1682 self.word_space(":");
1683 self.print_type(&ty
);
1687 pub fn print_usize(&mut self, i
: usize) {
1688 self.s
.word(i
.to_string())
1691 pub fn print_name(&mut self, name
: Symbol
) {
1692 self.print_ident(Ident
::with_dummy_span(name
))
1695 pub fn print_for_decl(&mut self, loc
: &hir
::Local
<'_
>, coll
: &hir
::Expr
<'_
>) {
1696 self.print_local_decl(loc
);
1698 self.word_space("in");
1699 self.print_expr(coll
)
1702 pub fn print_path(&mut self, path
: &hir
::Path
<'_
>, colons_before_params
: bool
) {
1703 self.maybe_print_comment(path
.span
.lo());
1705 for (i
, segment
) in path
.segments
.iter().enumerate() {
1709 if segment
.ident
.name
!= kw
::PathRoot
{
1710 self.print_ident(segment
.ident
);
1711 self.print_generic_args(segment
.args(), segment
.infer_args
, colons_before_params
);
1716 pub fn print_path_segment(&mut self, segment
: &hir
::PathSegment
<'_
>) {
1717 if segment
.ident
.name
!= kw
::PathRoot
{
1718 self.print_ident(segment
.ident
);
1719 self.print_generic_args(segment
.args(), segment
.infer_args
, false);
1723 pub fn print_qpath(&mut self, qpath
: &hir
::QPath
<'_
>, colons_before_params
: bool
) {
1725 hir
::QPath
::Resolved(None
, ref path
) => self.print_path(path
, colons_before_params
),
1726 hir
::QPath
::Resolved(Some(ref qself
), ref path
) => {
1728 self.print_type(qself
);
1730 self.word_space("as");
1732 for (i
, segment
) in path
.segments
[..path
.segments
.len() - 1].iter().enumerate() {
1736 if segment
.ident
.name
!= kw
::PathRoot
{
1737 self.print_ident(segment
.ident
);
1738 self.print_generic_args(
1741 colons_before_params
,
1748 let item_segment
= path
.segments
.last().unwrap();
1749 self.print_ident(item_segment
.ident
);
1750 self.print_generic_args(
1751 item_segment
.args(),
1752 item_segment
.infer_args
,
1753 colons_before_params
,
1756 hir
::QPath
::TypeRelative(ref qself
, ref item_segment
) => {
1757 // If we've got a compound-qualified-path, let's push an additional pair of angle
1758 // brackets, so that we pretty-print `<<A::B>::C>` as `<A::B>::C`, instead of just
1759 // `A::B::C` (since the latter could be ambiguous to the user)
1760 if let hir
::TyKind
::Path(hir
::QPath
::Resolved(None
, _
)) = &qself
.kind
{
1761 self.print_type(qself
);
1764 self.print_type(qself
);
1769 self.print_ident(item_segment
.ident
);
1770 self.print_generic_args(
1771 item_segment
.args(),
1772 item_segment
.infer_args
,
1773 colons_before_params
,
1776 hir
::QPath
::LangItem(lang_item
, span
) => {
1777 self.s
.word("#[lang = \"");
1778 self.print_ident(Ident
::new(lang_item
.name(), span
));
1784 fn print_generic_args(
1786 generic_args
: &hir
::GenericArgs
<'_
>,
1788 colons_before_params
: bool
,
1790 if generic_args
.parenthesized
{
1792 self.commasep(Inconsistent
, generic_args
.inputs(), |s
, ty
| s
.print_type(&ty
));
1795 self.space_if_not_bol();
1796 self.word_space("->");
1797 self.print_type(generic_args
.bindings
[0].ty());
1799 let start
= if colons_before_params { "::<" }
else { "<" }
;
1800 let empty
= Cell
::new(true);
1801 let start_or_comma
= |this
: &mut Self| {
1806 this
.word_space(",")
1810 let mut nonelided_generic_args
: bool
= false;
1811 let elide_lifetimes
= generic_args
.args
.iter().all(|arg
| match arg
{
1812 GenericArg
::Lifetime(lt
) => lt
.is_elided(),
1814 nonelided_generic_args
= true;
1819 if nonelided_generic_args
{
1820 start_or_comma(self);
1824 |s
, generic_arg
| match generic_arg
{
1825 GenericArg
::Lifetime(lt
) if !elide_lifetimes
=> s
.print_lifetime(lt
),
1826 GenericArg
::Lifetime(_
) => {}
1827 GenericArg
::Type(ty
) => s
.print_type(ty
),
1828 GenericArg
::Const(ct
) => s
.print_anon_const(&ct
.value
),
1833 // FIXME(eddyb): this would leak into error messages (e.g.,
1834 // "non-exhaustive patterns: `Some::<..>(_)` not covered").
1835 if infer_args
&& false {
1836 start_or_comma(self);
1840 for binding
in generic_args
.bindings
.iter() {
1841 start_or_comma(self);
1842 self.print_ident(binding
.ident
);
1843 self.print_generic_args(binding
.gen_args
, false, false);
1845 match generic_args
.bindings
[0].kind
{
1846 hir
::TypeBindingKind
::Equality { ref ty }
=> {
1847 self.word_space("=");
1848 self.print_type(ty
);
1850 hir
::TypeBindingKind
::Constraint { bounds }
=> {
1851 self.print_bounds(":", bounds
);
1862 pub fn print_pat(&mut self, pat
: &hir
::Pat
<'_
>) {
1863 self.maybe_print_comment(pat
.span
.lo());
1864 self.ann
.pre(self, AnnNode
::Pat(pat
));
1865 // Pat isn't normalized, but the beauty of it
1866 // is that it doesn't matter
1868 PatKind
::Wild
=> self.s
.word("_"),
1869 PatKind
::Binding(binding_mode
, _
, ident
, ref sub
) => {
1870 match binding_mode
{
1871 hir
::BindingAnnotation
::Ref
=> {
1872 self.word_nbsp("ref");
1873 self.print_mutability(hir
::Mutability
::Not
, false);
1875 hir
::BindingAnnotation
::RefMut
=> {
1876 self.word_nbsp("ref");
1877 self.print_mutability(hir
::Mutability
::Mut
, false);
1879 hir
::BindingAnnotation
::Unannotated
=> {}
1880 hir
::BindingAnnotation
::Mutable
=> {
1881 self.word_nbsp("mut");
1884 self.print_ident(ident
);
1885 if let Some(ref p
) = *sub
{
1890 PatKind
::TupleStruct(ref qpath
, ref elts
, ddpos
) => {
1891 self.print_qpath(qpath
, true);
1893 if let Some(ddpos
) = ddpos
{
1894 self.commasep(Inconsistent
, &elts
[..ddpos
], |s
, p
| s
.print_pat(&p
));
1896 self.word_space(",");
1899 if ddpos
!= elts
.len() {
1901 self.commasep(Inconsistent
, &elts
[ddpos
..], |s
, p
| s
.print_pat(&p
));
1904 self.commasep(Inconsistent
, &elts
[..], |s
, p
| s
.print_pat(&p
));
1908 PatKind
::Path(ref qpath
) => {
1909 self.print_qpath(qpath
, true);
1911 PatKind
::Struct(ref qpath
, ref fields
, etc
) => {
1912 self.print_qpath(qpath
, true);
1914 self.word_space("{");
1919 s
.cbox(INDENT_UNIT
);
1920 if !f
.is_shorthand
{
1921 s
.print_ident(f
.ident
);
1924 s
.print_pat(&f
.pat
);
1930 if !fields
.is_empty() {
1931 self.word_space(",");
1938 PatKind
::Or(ref pats
) => {
1939 self.strsep("|", true, Inconsistent
, &pats
[..], |s
, p
| s
.print_pat(&p
));
1941 PatKind
::Tuple(ref elts
, ddpos
) => {
1943 if let Some(ddpos
) = ddpos
{
1944 self.commasep(Inconsistent
, &elts
[..ddpos
], |s
, p
| s
.print_pat(&p
));
1946 self.word_space(",");
1949 if ddpos
!= elts
.len() {
1951 self.commasep(Inconsistent
, &elts
[ddpos
..], |s
, p
| s
.print_pat(&p
));
1954 self.commasep(Inconsistent
, &elts
[..], |s
, p
| s
.print_pat(&p
));
1955 if elts
.len() == 1 {
1961 PatKind
::Box(ref inner
) => {
1962 let is_range_inner
= matches
!(inner
.kind
, PatKind
::Range(..));
1963 self.s
.word("box ");
1967 self.print_pat(&inner
);
1972 PatKind
::Ref(ref inner
, mutbl
) => {
1973 let is_range_inner
= matches
!(inner
.kind
, PatKind
::Range(..));
1975 self.s
.word(mutbl
.prefix_str());
1979 self.print_pat(&inner
);
1984 PatKind
::Lit(ref e
) => self.print_expr(&e
),
1985 PatKind
::Range(ref begin
, ref end
, ref end_kind
) => {
1986 if let Some(expr
) = begin
{
1987 self.print_expr(expr
);
1991 RangeEnd
::Included
=> self.s
.word("..."),
1992 RangeEnd
::Excluded
=> self.s
.word(".."),
1994 if let Some(expr
) = end
{
1995 self.print_expr(expr
);
1998 PatKind
::Slice(ref before
, ref slice
, ref after
) => {
2000 self.commasep(Inconsistent
, &before
[..], |s
, p
| s
.print_pat(&p
));
2001 if let Some(ref p
) = *slice
{
2002 if !before
.is_empty() {
2003 self.word_space(",");
2005 if let PatKind
::Wild
= p
.kind
{
2011 if !after
.is_empty() {
2012 self.word_space(",");
2015 self.commasep(Inconsistent
, &after
[..], |s
, p
| s
.print_pat(&p
));
2019 self.ann
.post(self, AnnNode
::Pat(pat
))
2022 pub fn print_param(&mut self, arg
: &hir
::Param
<'_
>) {
2023 self.print_outer_attributes(&arg
.attrs
);
2024 self.print_pat(&arg
.pat
);
2027 pub fn print_arm(&mut self, arm
: &hir
::Arm
<'_
>) {
2028 // I have no idea why this check is necessary, but here it
2030 if arm
.attrs
.is_empty() {
2033 self.cbox(INDENT_UNIT
);
2034 self.ann
.pre(self, AnnNode
::Arm(arm
));
2036 self.print_outer_attributes(&arm
.attrs
);
2037 self.print_pat(&arm
.pat
);
2039 if let Some(ref g
) = arm
.guard
{
2041 hir
::Guard
::If(e
) => {
2042 self.word_space("if");
2043 self.print_expr(&e
);
2046 hir
::Guard
::IfLet(pat
, e
) => {
2047 self.word_nbsp("if");
2048 self.word_nbsp("let");
2049 self.print_pat(&pat
);
2051 self.word_space("=");
2052 self.print_expr(&e
);
2057 self.word_space("=>");
2059 match arm
.body
.kind
{
2060 hir
::ExprKind
::Block(ref blk
, opt_label
) => {
2061 if let Some(label
) = opt_label
{
2062 self.print_ident(label
.ident
);
2063 self.word_space(":");
2065 // the block will close the pattern's ibox
2066 self.print_block_unclosed(&blk
);
2068 // If it is a user-provided unsafe block, print a comma after it
2069 if let hir
::BlockCheckMode
::UnsafeBlock(hir
::UnsafeSource
::UserProvided
) = blk
.rules
2075 self.end(); // close the ibox for the pattern
2076 self.print_expr(&arm
.body
);
2080 self.ann
.post(self, AnnNode
::Arm(arm
));
2081 self.end() // close enclosing cbox
2086 decl
: &hir
::FnDecl
<'_
>,
2087 header
: hir
::FnHeader
,
2088 name
: Option
<Symbol
>,
2089 generics
: &hir
::Generics
<'_
>,
2090 vis
: &hir
::Visibility
<'_
>,
2091 arg_names
: &[Ident
],
2092 body_id
: Option
<hir
::BodyId
>,
2094 self.print_fn_header_info(header
, vis
);
2096 if let Some(name
) = name
{
2098 self.print_name(name
);
2100 self.print_generic_params(&generics
.params
);
2104 // Make sure we aren't supplied *both* `arg_names` and `body_id`.
2105 assert
!(arg_names
.is_empty() || body_id
.is_none());
2106 self.commasep(Inconsistent
, &decl
.inputs
, |s
, ty
| {
2107 s
.ibox(INDENT_UNIT
);
2108 if let Some(arg_name
) = arg_names
.get(i
) {
2109 s
.s
.word(arg_name
.to_string());
2112 } else if let Some(body_id
) = body_id
{
2113 s
.ann
.nested(s
, Nested
::BodyParamPat(body_id
, i
));
2121 if decl
.c_variadic
{
2122 self.s
.word(", ...");
2126 self.print_fn_output(decl
);
2127 self.print_where_clause(&generics
.where_clause
)
2130 fn print_closure_params(&mut self, decl
: &hir
::FnDecl
<'_
>, body_id
: hir
::BodyId
) {
2133 self.commasep(Inconsistent
, &decl
.inputs
, |s
, ty
| {
2134 s
.ibox(INDENT_UNIT
);
2136 s
.ann
.nested(s
, Nested
::BodyParamPat(body_id
, i
));
2139 if let hir
::TyKind
::Infer
= ty
.kind
{
2150 if let hir
::FnRetTy
::DefaultReturn(..) = decl
.output
{
2154 self.space_if_not_bol();
2155 self.word_space("->");
2157 hir
::FnRetTy
::Return(ref ty
) => {
2158 self.print_type(&ty
);
2159 self.maybe_print_comment(ty
.span
.lo())
2161 hir
::FnRetTy
::DefaultReturn(..) => unreachable
!(),
2165 pub fn print_capture_clause(&mut self, capture_clause
: hir
::CaptureBy
) {
2166 match capture_clause
{
2167 hir
::CaptureBy
::Value
=> self.word_space("move"),
2168 hir
::CaptureBy
::Ref
=> {}
2172 pub fn print_bounds
<'b
>(
2174 prefix
: &'
static str,
2175 bounds
: impl IntoIterator
<Item
= &'b hir
::GenericBound
<'b
>>,
2177 let mut first
= true;
2178 for bound
in bounds
{
2180 self.s
.word(prefix
);
2182 if !(first
&& prefix
.is_empty()) {
2188 self.word_space("+");
2192 GenericBound
::Trait(tref
, modifier
) => {
2193 if modifier
== &TraitBoundModifier
::Maybe
{
2196 self.print_poly_trait_ref(tref
);
2198 GenericBound
::LangItemTrait(lang_item
, span
, ..) => {
2199 self.s
.word("#[lang = \"");
2200 self.print_ident(Ident
::new(lang_item
.name(), *span
));
2203 GenericBound
::Outlives(lt
) => {
2204 self.print_lifetime(lt
);
2210 pub fn print_generic_params(&mut self, generic_params
: &[GenericParam
<'_
>]) {
2211 if !generic_params
.is_empty() {
2214 self.commasep(Inconsistent
, generic_params
, |s
, param
| s
.print_generic_param(param
));
2220 pub fn print_generic_param(&mut self, param
: &GenericParam
<'_
>) {
2221 if let GenericParamKind
::Const { .. }
= param
.kind
{
2222 self.word_space("const");
2225 self.print_ident(param
.name
.ident());
2228 GenericParamKind
::Lifetime { .. }
=> {
2230 for bound
in param
.bounds
{
2232 GenericBound
::Outlives(ref lt
) => {
2234 self.print_lifetime(lt
);
2241 GenericParamKind
::Type { ref default, .. }
=> {
2242 self.print_bounds(":", param
.bounds
);
2243 if let Some(default) = default {
2245 self.word_space("=");
2246 self.print_type(&default)
2249 GenericParamKind
::Const { ref ty, ref default }
=> {
2250 self.word_space(":");
2251 self.print_type(ty
);
2252 if let Some(ref _default
) = default {
2253 // FIXME(const_generics_defaults): print the `default` value here
2259 pub fn print_lifetime(&mut self, lifetime
: &hir
::Lifetime
) {
2260 self.print_ident(lifetime
.name
.ident())
2263 pub fn print_where_clause(&mut self, where_clause
: &hir
::WhereClause
<'_
>) {
2264 if where_clause
.predicates
.is_empty() {
2269 self.word_space("where");
2271 for (i
, predicate
) in where_clause
.predicates
.iter().enumerate() {
2273 self.word_space(",");
2277 hir
::WherePredicate
::BoundPredicate(hir
::WhereBoundPredicate
{
2278 bound_generic_params
,
2283 self.print_formal_generic_params(bound_generic_params
);
2284 self.print_type(&bounded_ty
);
2285 self.print_bounds(":", *bounds
);
2287 hir
::WherePredicate
::RegionPredicate(hir
::WhereRegionPredicate
{
2292 self.print_lifetime(lifetime
);
2295 for (i
, bound
) in bounds
.iter().enumerate() {
2297 GenericBound
::Outlives(lt
) => {
2298 self.print_lifetime(lt
);
2308 hir
::WherePredicate
::EqPredicate(hir
::WhereEqPredicate
{
2311 self.print_type(lhs_ty
);
2313 self.word_space("=");
2314 self.print_type(rhs_ty
);
2320 pub fn print_mutability(&mut self, mutbl
: hir
::Mutability
, print_const
: bool
) {
2322 hir
::Mutability
::Mut
=> self.word_nbsp("mut"),
2323 hir
::Mutability
::Not
=> {
2325 self.word_nbsp("const")
2331 pub fn print_mt(&mut self, mt
: &hir
::MutTy
<'_
>, print_const
: bool
) {
2332 self.print_mutability(mt
.mutbl
, print_const
);
2333 self.print_type(&mt
.ty
)
2336 pub fn print_fn_output(&mut self, decl
: &hir
::FnDecl
<'_
>) {
2337 if let hir
::FnRetTy
::DefaultReturn(..) = decl
.output
{
2341 self.space_if_not_bol();
2342 self.ibox(INDENT_UNIT
);
2343 self.word_space("->");
2345 hir
::FnRetTy
::DefaultReturn(..) => unreachable
!(),
2346 hir
::FnRetTy
::Return(ref ty
) => self.print_type(&ty
),
2350 if let hir
::FnRetTy
::Return(ref output
) = decl
.output
{
2351 self.maybe_print_comment(output
.span
.lo())
2358 unsafety
: hir
::Unsafety
,
2359 decl
: &hir
::FnDecl
<'_
>,
2360 name
: Option
<Symbol
>,
2361 generic_params
: &[hir
::GenericParam
<'_
>],
2362 arg_names
: &[Ident
],
2364 self.ibox(INDENT_UNIT
);
2365 if !generic_params
.is_empty() {
2367 self.print_generic_params(generic_params
);
2369 let generics
= hir
::Generics
{
2371 where_clause
: hir
::WhereClause { predicates: &[], span: rustc_span::DUMMY_SP }
,
2372 span
: rustc_span
::DUMMY_SP
,
2379 constness
: hir
::Constness
::NotConst
,
2380 asyncness
: hir
::IsAsync
::NotAsync
,
2384 &Spanned { span: rustc_span::DUMMY_SP, node: hir::VisibilityKind::Inherited }
,
2391 pub fn maybe_print_trailing_comment(
2393 span
: rustc_span
::Span
,
2394 next_pos
: Option
<BytePos
>,
2396 if let Some(cmnts
) = self.comments() {
2397 if let Some(cmnt
) = cmnts
.trailing_comment(span
, next_pos
) {
2398 self.print_comment(&cmnt
);
2403 pub fn print_remaining_comments(&mut self) {
2404 // If there aren't any remaining comments, then we need to manually
2405 // make sure there is a line break at the end.
2406 if self.next_comment().is_none() {
2409 while let Some(ref cmnt
) = self.next_comment() {
2410 self.print_comment(cmnt
)
2414 pub fn print_opt_abi_and_extern_if_nondefault(&mut self, opt_abi
: Option
<Abi
>) {
2416 Some(Abi
::Rust
) => {}
2418 self.word_nbsp("extern");
2419 self.word_nbsp(abi
.to_string())
2425 pub fn print_extern_opt_abi(&mut self, opt_abi
: Option
<Abi
>) {
2426 if let Some(abi
) = opt_abi
{
2427 self.word_nbsp("extern");
2428 self.word_nbsp(abi
.to_string())
2432 pub fn print_fn_header_info(&mut self, header
: hir
::FnHeader
, vis
: &hir
::Visibility
<'_
>) {
2433 self.s
.word(visibility_qualified(vis
, ""));
2435 match header
.constness
{
2436 hir
::Constness
::NotConst
=> {}
2437 hir
::Constness
::Const
=> self.word_nbsp("const"),
2440 match header
.asyncness
{
2441 hir
::IsAsync
::NotAsync
=> {}
2442 hir
::IsAsync
::Async
=> self.word_nbsp("async"),
2445 self.print_unsafety(header
.unsafety
);
2447 if header
.abi
!= Abi
::Rust
{
2448 self.word_nbsp("extern");
2449 self.word_nbsp(header
.abi
.to_string());
2455 pub fn print_unsafety(&mut self, s
: hir
::Unsafety
) {
2457 hir
::Unsafety
::Normal
=> {}
2458 hir
::Unsafety
::Unsafe
=> self.word_nbsp("unsafe"),
2462 pub fn print_is_auto(&mut self, s
: hir
::IsAuto
) {
2464 hir
::IsAuto
::Yes
=> self.word_nbsp("auto"),
2465 hir
::IsAuto
::No
=> {}
2470 /// Does this expression require a semicolon to be treated
2471 /// as a statement? The negation of this: 'can this expression
2472 /// be used as a statement without a semicolon' -- is used
2473 /// as an early-bail-out in the parser so that, for instance,
2474 /// if true {...} else {...}
2476 /// isn't parsed as (if true {...} else {...} | x) | 5
2478 // Duplicated from `parse::classify`, but adapted for the HIR.
2479 fn expr_requires_semi_to_be_stmt(e
: &hir
::Expr
<'_
>) -> bool
{
2482 hir
::ExprKind
::If(..)
2483 | hir
::ExprKind
::Match(..)
2484 | hir
::ExprKind
::Block(..)
2485 | hir
::ExprKind
::Loop(..)
2489 /// This statement requires a semicolon after it.
2490 /// note that in one case (stmt_semi), we've already
2491 /// seen the semicolon, and thus don't need another.
2492 fn stmt_ends_with_semi(stmt
: &hir
::StmtKind
<'_
>) -> bool
{
2494 hir
::StmtKind
::Local(_
) => true,
2495 hir
::StmtKind
::Item(_
) => false,
2496 hir
::StmtKind
::Expr(ref e
) => expr_requires_semi_to_be_stmt(&e
),
2497 hir
::StmtKind
::Semi(..) => false,
2501 fn bin_op_to_assoc_op(op
: hir
::BinOpKind
) -> AssocOp
{
2502 use crate::hir
::BinOpKind
::*;
2504 Add
=> AssocOp
::Add
,
2505 Sub
=> AssocOp
::Subtract
,
2506 Mul
=> AssocOp
::Multiply
,
2507 Div
=> AssocOp
::Divide
,
2508 Rem
=> AssocOp
::Modulus
,
2510 And
=> AssocOp
::LAnd
,
2513 BitXor
=> AssocOp
::BitXor
,
2514 BitAnd
=> AssocOp
::BitAnd
,
2515 BitOr
=> AssocOp
::BitOr
,
2516 Shl
=> AssocOp
::ShiftLeft
,
2517 Shr
=> AssocOp
::ShiftRight
,
2519 Eq
=> AssocOp
::Equal
,
2520 Lt
=> AssocOp
::Less
,
2521 Le
=> AssocOp
::LessEqual
,
2522 Ne
=> AssocOp
::NotEqual
,
2523 Ge
=> AssocOp
::GreaterEqual
,
2524 Gt
=> AssocOp
::Greater
,
2528 /// Expressions that syntactically contain an "exterior" struct literal, i.e., not surrounded by any
2529 /// parens or other delimiters, e.g., `X { y: 1 }`, `X { y: 1 }.method()`, `foo == X { y: 1 }` and
2530 /// `X { y: 1 } == foo` all do, but `(X { y: 1 }) == foo` does not.
2531 fn contains_exterior_struct_lit(value
: &hir
::Expr
<'_
>) -> bool
{
2533 hir
::ExprKind
::Struct(..) => true,
2535 hir
::ExprKind
::Assign(ref lhs
, ref rhs
, _
)
2536 | hir
::ExprKind
::AssignOp(_
, ref lhs
, ref rhs
)
2537 | hir
::ExprKind
::Binary(_
, ref lhs
, ref rhs
) => {
2538 // `X { y: 1 } + X { y: 2 }`
2539 contains_exterior_struct_lit(&lhs
) || contains_exterior_struct_lit(&rhs
)
2541 hir
::ExprKind
::Unary(_
, ref x
)
2542 | hir
::ExprKind
::Cast(ref x
, _
)
2543 | hir
::ExprKind
::Type(ref x
, _
)
2544 | hir
::ExprKind
::Field(ref x
, _
)
2545 | hir
::ExprKind
::Index(ref x
, _
) => {
2546 // `&X { y: 1 }, X { y: 1 }.y`
2547 contains_exterior_struct_lit(&x
)
2550 hir
::ExprKind
::MethodCall(.., ref exprs
, _
) => {
2551 // `X { y: 1 }.bar(...)`
2552 contains_exterior_struct_lit(&exprs
[0])