]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/rust/ast/rust-ast-dump.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / rust / ast / rust-ast-dump.cc
1 // Copyright (C) 2020-2023 Free Software Foundation, Inc.
2
3 // This file is part of GCC.
4
5 // GCC is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation; either version 3, or (at your option) any later
8 // version.
9
10 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 // for more details.
14
15 // You should have received a copy of the GNU General Public License
16 // along with GCC; see the file COPYING3. If not see
17 // <http://www.gnu.org/licenses/>.
18
19 #include "rust-ast-dump.h"
20
21 namespace Rust {
22 namespace AST {
23
24 Indent::Indent () : tabs (0) {}
25
26 std::ostream &
27 operator<< (std::ostream &stream, const Indent &indent)
28 {
29 return stream << std::string (indent.tabs, '\t');
30 }
31
32 void
33 Indent::increment ()
34 {
35 tabs++;
36 }
37
38 void
39 Indent::decrement ()
40 {
41 rust_assert (tabs != 0);
42 tabs--;
43 }
44
45 Dump::Dump (std::ostream &stream) : stream (stream), indentation (Indent ()) {}
46
47 void
48 Dump::go (AST::Crate &crate)
49 {
50 for (auto &item : crate.items)
51 {
52 stream << indentation;
53 item->accept_vis (*this);
54 stream << "\n";
55 }
56 }
57
58 void
59 Dump::go (AST::Item &item)
60 {
61 item.accept_vis (*this);
62 }
63
64 void
65 Dump::format_function_param (FunctionParam &param)
66 {
67 param.get_pattern ()->accept_vis (*this);
68 stream << ": ";
69 param.get_type ()->accept_vis (*this);
70 }
71
72 void
73 Dump::emit_attrib (const Attribute &attrib)
74 {
75 stream << "#";
76 stream << "[";
77
78 for (size_t i = 0; i < attrib.get_path ().get_segments ().size (); i++)
79 {
80 const auto &seg = attrib.get_path ().get_segments ().at (i);
81 bool has_next = (i + 1) < attrib.get_path ().get_segments ().size ();
82
83 stream << seg.get_segment_name ();
84 if (has_next)
85 stream << "::";
86 }
87
88 if (attrib.has_attr_input ())
89 {
90 stream << " = ";
91
92 bool is_literal = attrib.get_attr_input ().get_attr_input_type ()
93 == AST::AttrInput::AttrInputType::LITERAL;
94 if (is_literal)
95 {
96 auto &literal
97 = static_cast<AST::AttrInputLiteral &> (attrib.get_attr_input ());
98 const auto &value = literal.get_literal ().as_string ();
99
100 stream << "\"" << value << "\"";
101 }
102 else
103 {
104 stream << "FIXME";
105 }
106 }
107
108 stream << "]";
109 }
110
111 void
112 Dump::visit (Token &tok)
113 {}
114
115 void
116 Dump::visit (DelimTokenTree &delim_tok_tree)
117 {}
118
119 void
120 Dump::visit (AttrInputMetaItemContainer &input)
121 {}
122
123 void
124 Dump::visit (IdentifierExpr &ident_expr)
125 {
126 stream << ident_expr.get_ident ();
127 }
128
129 void
130 Dump::visit (Lifetime &lifetime)
131 {}
132
133 void
134 Dump::visit (LifetimeParam &lifetime_param)
135 {}
136
137 void
138 Dump::visit (ConstGenericParam &lifetime_param)
139 {}
140
141 // rust-path.h
142 void
143 Dump::visit (PathInExpression &path)
144 {}
145
146 void
147 Dump::visit (TypePathSegment &segment)
148 {}
149
150 void
151 Dump::visit (TypePathSegmentGeneric &segment)
152 {}
153
154 void
155 Dump::visit (TypePathSegmentFunction &segment)
156 {}
157
158 void
159 Dump::visit (TypePath &path)
160 {
161 stream << path.as_string ();
162 }
163
164 void
165 Dump::visit (QualifiedPathInExpression &path)
166 {}
167
168 void
169 Dump::visit (QualifiedPathInType &path)
170 {}
171
172 // rust-expr.h
173 void
174 Dump::visit (LiteralExpr &expr)
175 {
176 stream << expr.as_string ();
177 }
178
179 void
180 Dump::visit (AttrInputLiteral &attr_input)
181 {}
182
183 void
184 Dump::visit (MetaItemLitExpr &meta_item)
185 {}
186
187 void
188 Dump::visit (MetaItemPathLit &meta_item)
189 {}
190
191 void
192 Dump::visit (BorrowExpr &expr)
193 {}
194
195 void
196 Dump::visit (DereferenceExpr &expr)
197 {}
198
199 void
200 Dump::visit (ErrorPropagationExpr &expr)
201 {}
202
203 void
204 Dump::visit (NegationExpr &expr)
205 {}
206
207 void
208 Dump::visit (ArithmeticOrLogicalExpr &expr)
209 {
210 expr.get_left_expr ()->accept_vis (*this);
211 stream << " ";
212
213 switch (expr.get_expr_type ())
214 {
215 case ArithmeticOrLogicalOperator::ADD:
216 stream << "+";
217 break;
218
219 case ArithmeticOrLogicalOperator::SUBTRACT:
220 stream << "-";
221 break;
222
223 case ArithmeticOrLogicalOperator::MULTIPLY:
224 stream << "*";
225 break;
226
227 case ArithmeticOrLogicalOperator::DIVIDE:
228 stream << "/";
229 break;
230
231 case ArithmeticOrLogicalOperator::MODULUS:
232 stream << "%";
233 break;
234
235 case ArithmeticOrLogicalOperator::BITWISE_AND:
236 stream << "&";
237 break;
238
239 case ArithmeticOrLogicalOperator::BITWISE_OR:
240 stream << "|";
241 break;
242
243 case ArithmeticOrLogicalOperator::BITWISE_XOR:
244 stream << "^";
245 break;
246
247 case ArithmeticOrLogicalOperator::LEFT_SHIFT:
248 stream << "<<";
249 break;
250
251 case ArithmeticOrLogicalOperator::RIGHT_SHIFT:
252 stream << ">>";
253 break;
254 }
255
256 stream << " ";
257 expr.get_right_expr ()->accept_vis (*this);
258 }
259
260 void
261 Dump::visit (ComparisonExpr &expr)
262 {}
263
264 void
265 Dump::visit (LazyBooleanExpr &expr)
266 {}
267
268 void
269 Dump::visit (TypeCastExpr &expr)
270 {}
271
272 void
273 Dump::visit (AssignmentExpr &expr)
274 {}
275
276 void
277 Dump::visit (CompoundAssignmentExpr &expr)
278 {}
279
280 void
281 Dump::visit (GroupedExpr &expr)
282 {}
283
284 void
285 Dump::visit (ArrayElemsValues &elems)
286 {}
287
288 void
289 Dump::visit (ArrayElemsCopied &elems)
290 {}
291
292 void
293 Dump::visit (ArrayExpr &expr)
294 {}
295
296 void
297 Dump::visit (ArrayIndexExpr &expr)
298 {}
299
300 void
301 Dump::visit (TupleExpr &expr)
302 {}
303
304 void
305 Dump::visit (TupleIndexExpr &expr)
306 {}
307
308 void
309 Dump::visit (StructExprStruct &expr)
310 {}
311
312 void
313 Dump::visit (StructExprFieldIdentifier &field)
314 {}
315
316 void
317 Dump::visit (StructExprFieldIdentifierValue &field)
318 {}
319
320 void
321 Dump::visit (StructExprFieldIndexValue &field)
322 {}
323
324 void
325 Dump::visit (StructExprStructFields &expr)
326 {}
327
328 void
329 Dump::visit (StructExprStructBase &expr)
330 {}
331
332 void
333 Dump::visit (CallExpr &expr)
334 {}
335
336 void
337 Dump::visit (MethodCallExpr &expr)
338 {}
339
340 void
341 Dump::visit (FieldAccessExpr &expr)
342 {}
343
344 void
345 Dump::visit (ClosureExprInner &expr)
346 {}
347
348 void
349 Dump::visit (BlockExpr &expr)
350 {
351 stream << "{\n";
352 indentation.increment ();
353
354 for (auto &stmt : expr.get_statements ())
355 {
356 stream << indentation;
357 stmt->accept_vis (*this);
358 stream << ";\n";
359 }
360
361 if (expr.has_tail_expr ())
362 {
363 stream << indentation;
364 expr.get_tail_expr ()->accept_vis (*this);
365 }
366
367 indentation.decrement ();
368 stream << "\n" << indentation << "}\n";
369 }
370
371 void
372 Dump::visit (ClosureExprInnerTyped &expr)
373 {}
374
375 void
376 Dump::visit (ContinueExpr &expr)
377 {}
378
379 void
380 Dump::visit (BreakExpr &expr)
381 {}
382
383 void
384 Dump::visit (RangeFromToExpr &expr)
385 {}
386
387 void
388 Dump::visit (RangeFromExpr &expr)
389 {}
390
391 void
392 Dump::visit (RangeToExpr &expr)
393 {}
394
395 void
396 Dump::visit (RangeFullExpr &expr)
397 {}
398
399 void
400 Dump::visit (RangeFromToInclExpr &expr)
401 {}
402
403 void
404 Dump::visit (RangeToInclExpr &expr)
405 {}
406
407 void
408 Dump::visit (ReturnExpr &expr)
409 {}
410
411 void
412 Dump::visit (UnsafeBlockExpr &expr)
413 {}
414
415 void
416 Dump::visit (LoopExpr &expr)
417 {}
418
419 void
420 Dump::visit (WhileLoopExpr &expr)
421 {}
422
423 void
424 Dump::visit (WhileLetLoopExpr &expr)
425 {}
426
427 void
428 Dump::visit (ForLoopExpr &expr)
429 {}
430
431 void
432 Dump::visit (IfExpr &expr)
433 {}
434
435 void
436 Dump::visit (IfExprConseqElse &expr)
437 {}
438
439 void
440 Dump::visit (IfExprConseqIf &expr)
441 {}
442
443 void
444 Dump::visit (IfExprConseqIfLet &expr)
445 {}
446
447 void
448 Dump::visit (IfLetExpr &expr)
449 {}
450
451 void
452 Dump::visit (IfLetExprConseqElse &expr)
453 {}
454
455 void
456 Dump::visit (IfLetExprConseqIf &expr)
457 {}
458
459 void
460 Dump::visit (IfLetExprConseqIfLet &expr)
461 {}
462
463 void
464 Dump::visit (MatchExpr &expr)
465 {}
466
467 void
468 Dump::visit (AwaitExpr &expr)
469 {}
470
471 void
472 Dump::visit (AsyncBlockExpr &expr)
473 {}
474
475 // rust-item.h
476 void
477 Dump::visit (TypeParam &param)
478 {
479 stream << param.get_type_representation ();
480 if (param.has_type ())
481 {
482 stream << " = ";
483 param.get_type ()->accept_vis (*this);
484 }
485 }
486
487 void
488 Dump::visit (LifetimeWhereClauseItem &item)
489 {}
490
491 void
492 Dump::visit (TypeBoundWhereClauseItem &item)
493 {}
494
495 void
496 Dump::visit (Method &method)
497 {
498 stream << indentation << "fn " << method.get_method_name () << '(';
499
500 auto &self = method.get_self_param ();
501 stream << self.as_string ();
502
503 auto &params = method.get_function_params ();
504 for (auto &param : params)
505 {
506 stream << ", ";
507 format_function_param (param);
508 }
509
510 stream << ") ";
511
512 if (method.has_return_type ())
513 {
514 stream << "-> ";
515 method.get_return_type ()->accept_vis (*this);
516 stream << " ";
517 }
518
519 auto &block = method.get_definition ();
520 if (!block)
521 stream << ';';
522 else
523 block->accept_vis (*this);
524
525 stream << '\n';
526 }
527
528 void
529 Dump::visit (Module &module)
530 {}
531
532 void
533 Dump::visit (ExternCrate &crate)
534 {}
535
536 void
537 Dump::visit (UseTreeGlob &use_tree)
538 {}
539
540 void
541 Dump::visit (UseTreeList &use_tree)
542 {}
543
544 void
545 Dump::visit (UseTreeRebind &use_tree)
546 {}
547
548 void
549 Dump::visit (UseDeclaration &use_decl)
550 {}
551
552 void
553 Dump::visit (Function &function)
554 {
555 stream << "fn " << function.get_function_name ();
556
557 if (function.has_generics ())
558 {
559 stream << "<";
560 for (size_t i = 0; i < function.get_generic_params ().size (); i++)
561 {
562 auto &param = function.get_generic_params ().at (i);
563 param->accept_vis (*this);
564
565 bool has_next = (i + 1) < function.get_generic_params ().size ();
566 if (has_next)
567 stream << ", ";
568 }
569 stream << ">";
570 }
571
572 stream << '(';
573 auto &params = function.get_function_params ();
574 if (params.size () >= 1)
575 {
576 format_function_param (params[0]);
577 for (size_t i = 1; i < params.size (); i++)
578 {
579 stream << ", ";
580 format_function_param (params[i]);
581 }
582 }
583
584 stream << ") ";
585
586 if (function.has_return_type ())
587 {
588 stream << "-> ";
589 function.get_return_type ()->accept_vis (*this);
590 stream << " ";
591 }
592
593 auto &block = function.get_definition ();
594 if (!block)
595 stream << ';';
596 else
597 block->accept_vis (*this);
598
599 stream << '\n';
600 }
601
602 void
603 Dump::visit (TypeAlias &type_alias)
604 {}
605
606 void
607 Dump::visit (StructStruct &struct_item)
608 {}
609
610 void
611 Dump::visit (TupleStruct &tuple_struct)
612 {}
613
614 void
615 Dump::visit (EnumItem &item)
616 {}
617
618 void
619 Dump::visit (EnumItemTuple &item)
620 {}
621
622 void
623 Dump::visit (EnumItemStruct &item)
624 {}
625
626 void
627 Dump::visit (EnumItemDiscriminant &item)
628 {}
629
630 void
631 Dump::visit (Enum &enum_item)
632 {}
633
634 void
635 Dump::visit (Union &union_item)
636 {}
637
638 void
639 Dump::visit (ConstantItem &const_item)
640 {}
641
642 void
643 Dump::visit (StaticItem &static_item)
644 {}
645
646 void
647 Dump::format_function_common (std::unique_ptr<Type> &return_type,
648 std::unique_ptr<BlockExpr> &block)
649 {
650 if (return_type)
651 {
652 stream << "-> ";
653 return_type->accept_vis (*this);
654 }
655
656 if (block)
657 {
658 if (return_type)
659 stream << ' ';
660 block->accept_vis (*this);
661 }
662 else
663 stream << ";\n";
664 }
665
666 void
667 Dump::visit (TraitItemFunc &item)
668 {
669 auto func = item.get_trait_function_decl ();
670 stream << indentation << "fn " << func.get_identifier () << '(';
671
672 auto &params = func.get_function_params ();
673 for (auto &param : params)
674 {
675 stream << ", ";
676 format_function_param (param);
677 }
678
679 stream << ") ";
680
681 format_function_common (func.get_return_type (), item.get_definition ());
682 }
683
684 void
685 Dump::visit (TraitItemMethod &item)
686 {
687 auto method = item.get_trait_method_decl ();
688 stream << indentation << "fn " << method.get_identifier () << '(';
689
690 auto &self = method.get_self_param ();
691 stream << self.as_string ();
692
693 auto &params = method.get_function_params ();
694 for (auto &param : params)
695 {
696 stream << ", ";
697 format_function_param (param);
698 }
699
700 stream << ") ";
701
702 format_function_common (method.get_return_type (), item.get_definition ());
703 }
704
705 void
706 Dump::visit (TraitItemConst &item)
707 {
708 stream << indentation << "const " << item.get_identifier () << ": ";
709 item.get_type ()->accept_vis (*this);
710 stream << ";\n";
711 }
712
713 void
714 Dump::visit (TraitItemType &item)
715 {
716 stream << indentation << "type " << item.get_identifier () << ";\n";
717 }
718
719 void
720 Dump::visit (Trait &trait)
721 {
722 for (const auto &attr : trait.get_outer_attrs ())
723 {
724 emit_attrib (attr);
725 stream << "\n" << indentation;
726 }
727
728 stream << "trait " << trait.get_identifier ();
729
730 // Traits actually have an implicit Self thrown at the start so we must expect
731 // the number of generic params to be > 1
732 if (trait.get_generic_params ().size () > 1)
733 {
734 stream << "<";
735 for (size_t i = 1; i < trait.get_generic_params ().size (); i++)
736 {
737 auto &param = trait.get_generic_params ().at (i);
738 param->accept_vis (*this);
739
740 bool has_next = (i + 1) < trait.get_generic_params ().size ();
741 if (has_next)
742 stream << ", ";
743 }
744 stream << ">";
745 }
746
747 stream << " {\n";
748
749 indentation.increment ();
750
751 for (auto &item : trait.get_trait_items ())
752 item->accept_vis (*this);
753
754 indentation.decrement ();
755 stream << "\n}\n";
756 }
757
758 void
759 Dump::visit (InherentImpl &impl)
760 {
761 stream << "impl ";
762
763 // FIXME: Handle generics
764
765 impl.get_type ()->accept_vis (*this);
766
767 // FIXME: Handle where-clause
768 // FIXME: Handle inner attributes
769
770 stream << " {\n";
771 indentation.increment ();
772
773 for (auto &item : impl.get_impl_items ())
774 item->accept_vis (*this);
775
776 indentation.decrement ();
777 stream << "\n}\n";
778 }
779
780 void
781 Dump::visit (TraitImpl &impl)
782 {
783 stream << "impl ";
784 impl.get_trait_path ().accept_vis (*this);
785 stream << " for ";
786 impl.get_type ()->accept_vis (*this);
787
788 stream << " {\n";
789 indentation.increment ();
790
791 for (auto &item : impl.get_impl_items ())
792 item->accept_vis (*this);
793
794 indentation.decrement ();
795 stream << "\n}\n";
796 }
797
798 void
799 Dump::visit (ExternalStaticItem &item)
800 {}
801
802 void
803 Dump::visit (ExternalFunctionItem &function)
804 {
805 stream << "fn " << function.get_identifier () << '(';
806
807 for (size_t i = 0; i < function.get_function_params ().size (); i++)
808 {
809 auto &param = function.get_function_params ().at (i);
810 bool has_next = (i + 1) < function.get_function_params ().size ();
811
812 stream << param.get_name () << ": ";
813 param.get_type ()->accept_vis (*this);
814
815 if (has_next)
816 stream << ", ";
817 }
818
819 stream << ')';
820 if (function.has_return_type ())
821 {
822 stream << "-> ";
823 function.get_return_type ()->accept_vis (*this);
824 }
825 }
826
827 void
828 Dump::visit (ExternBlock &block)
829 {
830 stream << "extern ";
831
832 if (block.has_abi ())
833 {
834 stream << "\"";
835 stream << block.get_abi ();
836 stream << "\" ";
837 }
838
839 stream << "{\n";
840 indentation.increment ();
841
842 for (auto &item : block.get_extern_items ())
843 {
844 stream << indentation;
845 item->accept_vis (*this);
846 stream << ";\n";
847 }
848
849 indentation.decrement ();
850 stream << "\n" << indentation << "}\n";
851 }
852
853 // rust-macro.h
854 void
855 Dump::visit (MacroMatchFragment &match)
856 {}
857
858 void
859 Dump::visit (MacroMatchRepetition &match)
860 {}
861
862 void
863 Dump::visit (MacroMatcher &matcher)
864 {}
865
866 void
867 Dump::visit (MacroRulesDefinition &rules_def)
868 {}
869
870 void
871 Dump::visit (MacroInvocation &macro_invoc)
872 {}
873
874 void
875 Dump::visit (MetaItemPath &meta_item)
876 {}
877
878 void
879 Dump::visit (MetaItemSeq &meta_item)
880 {}
881
882 void
883 Dump::visit (MetaWord &meta_item)
884 {}
885
886 void
887 Dump::visit (MetaNameValueStr &meta_item)
888 {}
889
890 void
891 Dump::visit (MetaListPaths &meta_item)
892 {}
893
894 void
895 Dump::visit (MetaListNameValueStr &meta_item)
896 {}
897
898 // rust-pattern.h
899 void
900 Dump::visit (LiteralPattern &pattern)
901 {}
902
903 void
904 Dump::visit (IdentifierPattern &pattern)
905 {
906 stream << pattern.get_ident ();
907 }
908
909 void
910 Dump::visit (WildcardPattern &pattern)
911 {}
912
913 // void Dump::visit(RangePatternBound& bound){}
914
915 void
916 Dump::visit (RangePatternBoundLiteral &bound)
917 {}
918
919 void
920 Dump::visit (RangePatternBoundPath &bound)
921 {}
922
923 void
924 Dump::visit (RangePatternBoundQualPath &bound)
925 {}
926
927 void
928 Dump::visit (RangePattern &pattern)
929 {}
930
931 void
932 Dump::visit (ReferencePattern &pattern)
933 {}
934
935 // void Dump::visit(StructPatternField& field){}
936
937 void
938 Dump::visit (StructPatternFieldTuplePat &field)
939 {}
940
941 void
942 Dump::visit (StructPatternFieldIdentPat &field)
943 {}
944
945 void
946 Dump::visit (StructPatternFieldIdent &field)
947 {}
948
949 void
950 Dump::visit (StructPattern &pattern)
951 {}
952
953 // void Dump::visit(TupleStructItems& tuple_items){}
954
955 void
956 Dump::visit (TupleStructItemsNoRange &tuple_items)
957 {}
958
959 void
960 Dump::visit (TupleStructItemsRange &tuple_items)
961 {}
962
963 void
964 Dump::visit (TupleStructPattern &pattern)
965 {}
966
967 // void Dump::visit(TuplePatternItems& tuple_items){}
968
969 void
970 Dump::visit (TuplePatternItemsMultiple &tuple_items)
971 {}
972
973 void
974 Dump::visit (TuplePatternItemsRanged &tuple_items)
975 {}
976
977 void
978 Dump::visit (TuplePattern &pattern)
979 {}
980
981 void
982 Dump::visit (GroupedPattern &pattern)
983 {}
984
985 void
986 Dump::visit (SlicePattern &pattern)
987 {}
988
989 // rust-stmt.h
990 void
991 Dump::visit (EmptyStmt &stmt)
992 {}
993
994 void
995 Dump::visit (LetStmt &stmt)
996 {
997 stream << "let ";
998 auto &pattern = stmt.get_pattern ();
999 if (pattern)
1000 pattern->accept_vis (*this);
1001
1002 if (stmt.has_type ())
1003 {
1004 stream << ": ";
1005 stmt.get_type ()->accept_vis (*this);
1006 }
1007
1008 if (stmt.has_init_expr ())
1009 {
1010 stream << " = ";
1011 stmt.get_init_expr ()->accept_vis (*this);
1012 }
1013 }
1014
1015 void
1016 Dump::visit (ExprStmtWithoutBlock &stmt)
1017 {}
1018
1019 void
1020 Dump::visit (ExprStmtWithBlock &stmt)
1021 {}
1022
1023 // rust-type.h
1024 void
1025 Dump::visit (TraitBound &bound)
1026 {}
1027
1028 void
1029 Dump::visit (ImplTraitType &type)
1030 {}
1031
1032 void
1033 Dump::visit (TraitObjectType &type)
1034 {}
1035
1036 void
1037 Dump::visit (ParenthesisedType &type)
1038 {}
1039
1040 void
1041 Dump::visit (ImplTraitTypeOneBound &type)
1042 {}
1043
1044 void
1045 Dump::visit (TraitObjectTypeOneBound &type)
1046 {}
1047
1048 void
1049 Dump::visit (TupleType &type)
1050 {}
1051
1052 void
1053 Dump::visit (NeverType &type)
1054 {}
1055
1056 void
1057 Dump::visit (RawPointerType &type)
1058 {}
1059
1060 void
1061 Dump::visit (ReferenceType &type)
1062 {
1063 type.get_type_referenced ()->accept_vis (*this);
1064 }
1065
1066 void
1067 Dump::visit (ArrayType &type)
1068 {
1069 type.get_elem_type ()->accept_vis (*this);
1070 }
1071
1072 void
1073 Dump::visit (SliceType &type)
1074 {
1075 type.get_elem_type ()->accept_vis (*this);
1076 }
1077
1078 void
1079 Dump::visit (InferredType &type)
1080 {
1081 stream << "_";
1082 }
1083
1084 void
1085 Dump::visit (BareFunctionType &type)
1086 {}
1087
1088 } // namespace AST
1089 } // namespace Rust