Line data Source code
1 : /* General AST-related method implementations for Rust frontend.
2 : Copyright (C) 2009-2026 Free Software Foundation, Inc.
3 :
4 : This file is part of GCC.
5 :
6 : GCC is free software; you can redistribute it and/or modify it under
7 : the terms of the GNU General Public License as published by the Free
8 : Software Foundation; either version 3, or (at your option) any later
9 : version.
10 :
11 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with GCC; see the file COPYING3. If not see
18 : <http://www.gnu.org/licenses/>. */
19 :
20 : #include "rust-ast.h"
21 : #include "optional.h"
22 : #include "rust-builtin-ast-nodes.h"
23 : #include "rust-common.h"
24 : #include "rust-expr.h"
25 : #include "rust-system.h"
26 : #include "rust-ast-full.h"
27 : #include "rust-diagnostics.h"
28 : #include "rust-ast-visitor.h"
29 : #include "rust-macro.h"
30 : #include "rust-session-manager.h"
31 : #include "rust-lex.h"
32 : #include "rust-parse.h"
33 : #include "rust-operators.h"
34 : #include "rust-dir-owner.h"
35 : #include "rust-attribute-values.h"
36 : #include "rust-macro-invoc-lexer.h"
37 :
38 : /* Compilation unit used for various AST-related functions that would make
39 : * the headers too long if they were defined inline and don't receive any
40 : * benefits from being defined inline because they are virtual. Also used
41 : * for various other stuff. */
42 :
43 : namespace Rust {
44 : namespace AST {
45 :
46 23258 : SingleASTNode::SingleASTNode (SingleASTNode const &other)
47 : {
48 23258 : kind = other.kind;
49 23258 : switch (kind)
50 : {
51 10374 : case Kind::Expr:
52 10374 : expr = other.expr->clone_expr ();
53 10374 : break;
54 :
55 10376 : case Kind::Item:
56 10376 : item = other.item->clone_item ();
57 10376 : break;
58 :
59 1918 : case Kind::Stmt:
60 1918 : stmt = other.stmt->clone_stmt ();
61 1918 : break;
62 :
63 12 : case Kind::Extern:
64 12 : external_item = other.external_item->clone_external_item ();
65 12 : break;
66 :
67 428 : case Kind::Assoc:
68 428 : assoc_item = other.assoc_item->clone_associated_item ();
69 428 : break;
70 :
71 145 : case Kind::Type:
72 145 : type = other.type->clone_type ();
73 145 : break;
74 :
75 5 : case Kind::Pattern:
76 5 : pattern = other.pattern->clone_pattern ();
77 5 : break;
78 : }
79 23258 : }
80 :
81 : SingleASTNode
82 0 : SingleASTNode::operator= (SingleASTNode const &other)
83 : {
84 0 : kind = other.kind;
85 0 : switch (kind)
86 : {
87 0 : case Kind::Expr:
88 0 : expr = other.expr->clone_expr ();
89 0 : break;
90 :
91 0 : case Kind::Item:
92 0 : item = other.item->clone_item ();
93 0 : break;
94 :
95 0 : case Kind::Stmt:
96 0 : stmt = other.stmt->clone_stmt ();
97 0 : break;
98 :
99 0 : case Kind::Extern:
100 0 : external_item = other.external_item->clone_external_item ();
101 0 : break;
102 :
103 0 : case Kind::Assoc:
104 0 : assoc_item = other.assoc_item->clone_associated_item ();
105 0 : break;
106 :
107 0 : case Kind::Type:
108 0 : type = other.type->clone_type ();
109 0 : break;
110 :
111 0 : case Kind::Pattern:
112 0 : pattern = other.pattern->clone_pattern ();
113 0 : break;
114 : }
115 0 : return *this;
116 : }
117 :
118 : void
119 0 : SingleASTNode::accept_vis (ASTVisitor &vis)
120 : {
121 0 : switch (kind)
122 : {
123 0 : case Kind::Expr:
124 0 : expr->accept_vis (vis);
125 0 : break;
126 :
127 0 : case Kind::Item:
128 0 : item->accept_vis (vis);
129 0 : break;
130 :
131 0 : case Kind::Stmt:
132 0 : stmt->accept_vis (vis);
133 0 : break;
134 :
135 0 : case Kind::Extern:
136 0 : external_item->accept_vis (vis);
137 0 : break;
138 :
139 0 : case Kind::Assoc:
140 0 : assoc_item->accept_vis (vis);
141 0 : break;
142 :
143 0 : case Kind::Type:
144 0 : type->accept_vis (vis);
145 0 : break;
146 :
147 0 : case Kind::Pattern:
148 0 : pattern->accept_vis (vis);
149 0 : break;
150 : }
151 0 : }
152 :
153 : bool
154 8254 : SingleASTNode::is_error ()
155 : {
156 8254 : switch (kind)
157 : {
158 1917 : case Kind::Expr:
159 1917 : return expr == nullptr;
160 5182 : case Kind::Item:
161 5182 : return item == nullptr;
162 905 : case Kind::Stmt:
163 905 : return stmt == nullptr;
164 6 : case Kind::Extern:
165 6 : return external_item == nullptr;
166 214 : case Kind::Assoc:
167 214 : return assoc_item == nullptr;
168 29 : case Kind::Type:
169 29 : return type == nullptr;
170 1 : case Kind::Pattern:
171 1 : return pattern == nullptr;
172 : }
173 :
174 0 : rust_unreachable ();
175 : return true;
176 : }
177 :
178 : std::string
179 0 : SingleASTNode::as_string () const
180 : {
181 0 : switch (kind)
182 : {
183 0 : case Kind::Expr:
184 0 : return "Expr: " + expr->as_string ();
185 0 : case Kind::Item:
186 0 : return "Item: " + item->as_string ();
187 0 : case Kind::Stmt:
188 0 : return "Stmt: " + stmt->as_string ();
189 0 : case Kind::Extern:
190 0 : return "External Item: " + external_item->as_string ();
191 0 : case Kind::Assoc:
192 0 : return "Associated Item: " + assoc_item->as_string ();
193 0 : case Kind::Type:
194 0 : return "Type: " + type->as_string ();
195 0 : case Kind::Pattern:
196 0 : return "Pattern: " + pattern->as_string ();
197 : }
198 :
199 0 : rust_unreachable ();
200 : return "";
201 : }
202 :
203 : std::string
204 0 : Crate::as_string () const
205 : {
206 0 : rust_debug ("beginning crate recursive as-string");
207 :
208 0 : std::string str ("Crate: ");
209 :
210 : // inner attributes
211 0 : str += append_attributes (inner_attrs, INNER);
212 :
213 : // items
214 0 : str += "\n items: ";
215 0 : if (items.empty ())
216 : {
217 0 : str += "none";
218 : }
219 : else
220 : {
221 0 : for (const auto &item : items)
222 : {
223 : // DEBUG: null pointer check
224 0 : if (item == nullptr)
225 : {
226 0 : rust_debug ("something really terrible has gone wrong - "
227 : "null pointer item in crate.");
228 0 : return "NULL_POINTER_MARK";
229 : }
230 :
231 0 : str += "\n " + item->as_string ();
232 : }
233 : }
234 :
235 0 : return str + "\n";
236 0 : }
237 :
238 : void
239 0 : Crate::inject_extern_crate (std::string name)
240 : {
241 0 : items.push_back (std::make_unique<AST::ExternCrate> (
242 0 : AST::ExternCrate (name, AST::Visibility::create_public (UNKNOWN_LOCATION),
243 0 : {}, UNKNOWN_LOCATION)));
244 0 : }
245 :
246 : void
247 1 : Crate::inject_inner_attribute (Attribute attribute)
248 : {
249 1 : inner_attrs.push_back (attribute);
250 1 : }
251 :
252 : std::string
253 11480 : Attribute::as_string () const
254 : {
255 11480 : std::string path_str = path.as_string ();
256 11480 : if (attr_input == nullptr)
257 4670 : return path_str;
258 : else
259 6810 : return path_str + attr_input->as_string ();
260 11480 : }
261 :
262 : void
263 0 : Attribute::accept_vis (ASTVisitor &vis)
264 : {
265 0 : vis.visit (*this);
266 0 : }
267 :
268 : bool
269 83871 : Attribute::is_derive () const
270 : {
271 152322 : return has_attr_input () && get_path () == Values::Attributes::DERIVE_ATTR;
272 : }
273 :
274 : /**
275 : * Returns a list of traits to derive from within a given attribute.
276 : *
277 : * @param attrs The attributes on the item to derive
278 : */
279 : std::vector<std::reference_wrapper<AST::SimplePath>>
280 338 : Attribute::get_traits_to_derive ()
281 : {
282 338 : rust_assert (this->is_derive ());
283 :
284 338 : this->parse_attr_to_meta_item ();
285 338 : std::vector<std::reference_wrapper<AST::SimplePath>> result;
286 338 : auto &input = get_attr_input ();
287 338 : switch (input.get_attr_input_type ())
288 : {
289 338 : case AST::AttrInput::META_ITEM:
290 338 : {
291 338 : auto &meta = static_cast<AST::AttrInputMetaItemContainer &> (input);
292 946 : for (auto ¤t : meta.get_items ())
293 : {
294 : // HACK: Find a better way to achieve the downcast.
295 608 : switch (current->get_kind ())
296 : {
297 608 : case AST::MetaItemInner::Kind::MetaItem:
298 608 : {
299 : // Let raw pointer go out of scope without freeing, it doesn't
300 : // own the data anyway
301 608 : auto meta_item
302 608 : = static_cast<AST::MetaItem *> (current.get ());
303 608 : switch (meta_item->get_item_kind ())
304 : {
305 304 : case AST::MetaItem::ItemKind::Path:
306 304 : {
307 304 : auto path
308 : = static_cast<AST::MetaItemPath *> (meta_item);
309 304 : result.push_back (path->get_path ());
310 : }
311 304 : break;
312 304 : case AST::MetaItem::ItemKind::Word:
313 304 : {
314 304 : auto word = static_cast<AST::MetaWord *> (meta_item);
315 : // Convert current word to path
316 304 : current = std::make_unique<AST::MetaItemPath> (
317 608 : AST::MetaItemPath (AST::SimplePath::from_str (
318 304 : word->get_ident ().as_string (),
319 608 : word->get_locus ())));
320 304 : auto path
321 304 : = static_cast<AST::MetaItemPath *> (current.get ());
322 :
323 304 : result.push_back (path->get_path ());
324 : }
325 304 : break;
326 0 : case AST::MetaItem::ItemKind::ListPaths:
327 0 : case AST::MetaItem::ItemKind::NameValueStr:
328 0 : case AST::MetaItem::ItemKind::PathExpr:
329 0 : case AST::MetaItem::ItemKind::Seq:
330 0 : case AST::MetaItem::ItemKind::ListNameValueStr:
331 0 : default:
332 0 : gcc_unreachable ();
333 608 : break;
334 : }
335 : }
336 608 : break;
337 0 : case AST::MetaItemInner::Kind::LitExpr:
338 0 : default:
339 0 : gcc_unreachable ();
340 608 : break;
341 : }
342 : }
343 : }
344 : break;
345 0 : case AST::AttrInput::TOKEN_TREE:
346 0 : case AST::AttrInput::LITERAL:
347 0 : case AST::AttrInput::EXPR:
348 0 : rust_unreachable ();
349 338 : break;
350 : }
351 338 : return result;
352 : }
353 :
354 : // Copy constructor must deep copy attr_input as unique pointer
355 129034 : Attribute::Attribute (Attribute const &other)
356 129034 : : path (other.path), locus (other.locus),
357 129034 : inner_attribute (other.inner_attribute)
358 : {
359 : // guard to protect from null pointer dereference
360 129034 : if (other.attr_input != nullptr)
361 109254 : attr_input = other.attr_input->clone_attr_input ();
362 129034 : }
363 :
364 : // overload assignment operator to use custom clone method
365 : Attribute &
366 65 : Attribute::operator= (Attribute const &other)
367 : {
368 65 : path = other.path;
369 65 : locus = other.locus;
370 65 : inner_attribute = other.inner_attribute;
371 : // guard to protect from null pointer dereference
372 65 : if (other.attr_input != nullptr)
373 58 : attr_input = other.attr_input->clone_attr_input ();
374 : else
375 7 : attr_input = nullptr;
376 :
377 65 : return *this;
378 : }
379 :
380 : std::string
381 4694 : DelimTokenTree::as_string () const
382 : {
383 4694 : std::string start_delim;
384 4694 : std::string end_delim;
385 4694 : switch (delim_type)
386 : {
387 4694 : case PARENS:
388 4694 : start_delim = "(";
389 4694 : end_delim = ")";
390 4694 : break;
391 0 : case SQUARE:
392 0 : start_delim = "[";
393 0 : end_delim = "]";
394 0 : break;
395 0 : case CURLY:
396 0 : start_delim = "{";
397 0 : end_delim = "}";
398 0 : break;
399 0 : default:
400 0 : rust_debug ("Invalid delimiter type, "
401 : "Should be PARENS, SQUARE, or CURLY.");
402 0 : return "Invalid delimiter type";
403 : }
404 9388 : std::string str = start_delim;
405 4694 : if (!token_trees.empty ())
406 : {
407 18802 : for (const auto &tree : token_trees)
408 : {
409 : // DEBUG: null pointer check
410 14108 : if (tree == nullptr)
411 : {
412 0 : rust_debug (
413 : "something really terrible has gone wrong - null pointer "
414 : "token tree in delim token tree.");
415 0 : return "NULL_POINTER_MARK";
416 : }
417 :
418 28216 : str += tree->as_string ();
419 : }
420 : }
421 4694 : str += end_delim;
422 :
423 4694 : return str;
424 4694 : }
425 :
426 : std::string
427 147574 : Token::as_string () const
428 : {
429 147574 : if (tok_ref->should_have_str ())
430 : {
431 42610 : std::string str = tok_ref->get_str ();
432 :
433 42610 : std::string quote = is_string_lit () ? "\"" : "";
434 42610 : return quote + str + quote;
435 42610 : }
436 : else
437 : {
438 104964 : return tok_ref->get_token_description ();
439 : }
440 : }
441 :
442 : std::string
443 817154 : SimplePathSegment::as_string () const
444 : {
445 817154 : return segment_name;
446 : }
447 :
448 : const std::string
449 318818 : SimplePath::as_string () const
450 : {
451 318818 : std::string path;
452 318818 : if (opening_scope_resolution)
453 0 : path = "::";
454 :
455 : // crappy hack because doing proper for loop would be more code
456 318818 : bool first_time = true;
457 637672 : for (const auto &segment : segments)
458 : {
459 318854 : if (first_time)
460 : {
461 637636 : path += segment.as_string ();
462 318818 : first_time = false;
463 : }
464 : else
465 : {
466 72 : path += "::" + segment.as_string ();
467 : }
468 :
469 : // DEBUG: remove later. Checks for path error.
470 318854 : if (segment.is_error ())
471 : {
472 0 : rust_debug ("segment in path is error - this should've been filtered "
473 : "out. first segment "
474 : "was '%s'",
475 : segments.at (0).as_string ().c_str ());
476 : }
477 : }
478 :
479 318818 : return path;
480 : }
481 :
482 : std::string
483 10 : Visibility::as_string () const
484 : {
485 10 : switch (vis_type)
486 : {
487 0 : case PRIV:
488 0 : return std::string ("");
489 10 : case PUB:
490 10 : return std::string ("pub");
491 0 : case PUB_CRATE:
492 0 : return std::string ("pub(crate)");
493 0 : case PUB_SELF:
494 0 : return std::string ("pub(self)");
495 0 : case PUB_SUPER:
496 0 : return std::string ("pub(super)");
497 0 : case PUB_IN_PATH:
498 0 : return std::string ("pub(in ") + in_path.as_string () + std::string (")");
499 0 : default:
500 0 : rust_unreachable ();
501 : }
502 : }
503 :
504 : // Creates a string that reflects the visibility stored.
505 : std::string
506 0 : VisItem::as_string () const
507 : {
508 : // FIXME: can't do formatting on string to make identation occur.
509 0 : std::string str;
510 :
511 0 : if (!outer_attrs.empty ())
512 : {
513 0 : for (const auto &attr : outer_attrs)
514 0 : str += attr.as_string () + "\n";
515 : }
516 :
517 0 : if (has_visibility ())
518 0 : str += visibility.as_string () + " ";
519 :
520 0 : return str;
521 : }
522 :
523 : std::string
524 0 : Module::as_string () const
525 : {
526 0 : std::string str = VisItem::as_string () + "mod " + module_name.as_string ();
527 :
528 : // Return early if we're dealing with an unloaded module as their body resides
529 : // in a different file
530 0 : if (kind == ModuleKind::UNLOADED)
531 0 : return str + "\n no body (reference to external file)\n";
532 :
533 : // inner attributes
534 0 : str += append_attributes (inner_attrs, INNER);
535 :
536 : // items
537 0 : str += "\n items: ";
538 :
539 : // This can still happen if the module is loaded but empty, i.e. `mod foo {}`
540 0 : if (items.empty ())
541 : {
542 0 : str += "none";
543 : }
544 : else
545 : {
546 0 : for (const auto &item : items)
547 : {
548 : // DEBUG: null pointer check
549 0 : if (item == nullptr)
550 : {
551 0 : rust_debug ("something really terrible has gone wrong - "
552 : "null pointer item in crate.");
553 0 : return "NULL_POINTER_MARK";
554 : }
555 :
556 0 : str += "\n " + item->as_string ();
557 : }
558 : }
559 :
560 0 : return str + "\n";
561 0 : }
562 :
563 : std::string
564 0 : StaticItem::as_string () const
565 : {
566 0 : std::string str = VisItem::as_string ();
567 :
568 0 : str += indent_spaces (stay) + "static";
569 :
570 0 : if (has_mut)
571 0 : str += " mut";
572 :
573 0 : str += " " + name.as_string ();
574 :
575 : // DEBUG: null pointer check
576 0 : if (type == nullptr)
577 : {
578 0 : rust_debug ("something really terrible has gone wrong - null "
579 : "pointer type in static item.");
580 0 : return "NULL_POINTER_MARK";
581 : }
582 0 : str += "\n" + indent_spaces (stay) + "Type: " + type->as_string ();
583 :
584 : // DEBUG: null pointer check
585 0 : if (expr == nullptr)
586 : {
587 0 : rust_debug ("something really terrible has gone wrong - null "
588 : "pointer expr in static item.");
589 0 : return "NULL_POINTER_MARK";
590 : }
591 0 : str += "\n" + indent_spaces (stay) + "Expression: " + expr->as_string ();
592 :
593 0 : return str + "\n";
594 0 : }
595 :
596 : std::string
597 0 : ExternCrate::as_string () const
598 : {
599 0 : std::string str = VisItem::as_string ();
600 :
601 0 : str += "extern crate " + referenced_crate;
602 :
603 0 : if (has_as_clause ())
604 0 : str += " as " + as_clause_name;
605 :
606 0 : return str;
607 : }
608 :
609 : std::string
610 0 : TupleStruct::as_string () const
611 : {
612 0 : std::string str = VisItem::as_string ();
613 :
614 0 : str += "struct " + struct_name.as_string ();
615 :
616 : // generic params
617 0 : str += "\n Generic params: ";
618 0 : if (generic_params.empty ())
619 : {
620 0 : str += "none";
621 : }
622 : else
623 : {
624 0 : for (const auto ¶m : generic_params)
625 : {
626 : // DEBUG: null pointer check
627 0 : if (param == nullptr)
628 : {
629 0 : rust_debug (
630 : "something really terrible has gone wrong - null pointer "
631 : "generic param in enum.");
632 0 : return "NULL_POINTER_MARK";
633 : }
634 :
635 0 : str += "\n " + param->as_string ();
636 : }
637 : }
638 :
639 : // tuple fields
640 0 : str += "\n Tuple fields: ";
641 0 : if (fields.empty ())
642 : {
643 0 : str += "none";
644 : }
645 : else
646 : {
647 0 : for (const auto &field : fields)
648 0 : str += "\n " + field.as_string ();
649 : }
650 :
651 0 : str += "\n Where clause: ";
652 0 : if (has_where_clause ())
653 0 : str += where_clause.as_string ();
654 : else
655 0 : str += "none";
656 :
657 0 : return str;
658 0 : }
659 :
660 : std::string
661 0 : ConstantItem::as_string () const
662 : {
663 0 : std::string str = VisItem::as_string ();
664 :
665 0 : str += "const " + identifier.as_string ();
666 :
667 : // DEBUG: null pointer check
668 0 : if (type == nullptr)
669 : {
670 0 : rust_debug ("something really terrible has gone wrong - null "
671 : "pointer type in const item.");
672 0 : return "NULL_POINTER_MARK";
673 : }
674 0 : str += "\n Type: " + type->as_string ();
675 :
676 0 : if (has_expr ())
677 0 : str += "\n Expression: " + const_expr->as_string ();
678 :
679 0 : return str + "\n";
680 0 : }
681 :
682 : std::string
683 0 : InherentImpl::as_string () const
684 : {
685 0 : std::string str = VisItem::as_string ();
686 :
687 0 : str += "impl ";
688 :
689 : // generic params
690 0 : str += "\n Generic params: ";
691 0 : if (generic_params.empty ())
692 : {
693 0 : str += "none";
694 : }
695 : else
696 : {
697 0 : for (const auto ¶m : generic_params)
698 : {
699 : // DEBUG: null pointer check
700 0 : if (param == nullptr)
701 : {
702 0 : rust_debug (
703 : "something really terrible has gone wrong - null pointer "
704 : "generic param in inherent impl.");
705 0 : return "NULL_POINTER_MARK";
706 : }
707 :
708 0 : str += "\n " + param->as_string ();
709 : }
710 : }
711 :
712 0 : str += "\n Type: " + trait_type->as_string ();
713 :
714 0 : str += "\n Where clause: ";
715 0 : if (has_where_clause ())
716 0 : str += where_clause.as_string ();
717 : else
718 0 : str += "none";
719 :
720 : // inner attributes
721 0 : str += append_attributes (inner_attrs, INNER);
722 :
723 : // inherent impl items
724 0 : str += "\n Inherent impl items: ";
725 0 : if (!has_impl_items ())
726 : {
727 0 : str += "none";
728 : }
729 : else
730 : {
731 0 : for (const auto &item : impl_items)
732 0 : str += "\n " + item->as_string ();
733 : }
734 :
735 0 : return str;
736 0 : }
737 :
738 : std::string
739 0 : StructStruct::as_string () const
740 : {
741 0 : std::string str = VisItem::as_string ();
742 :
743 0 : str += "struct " + struct_name.as_string ();
744 :
745 : // generic params
746 0 : str += "\n Generic params: ";
747 0 : if (generic_params.empty ())
748 : {
749 0 : str += "none";
750 : }
751 : else
752 : {
753 0 : for (const auto ¶m : generic_params)
754 : {
755 : // DEBUG: null pointer check
756 0 : if (param == nullptr)
757 : {
758 0 : rust_debug (
759 : "something really terrible has gone wrong - null pointer "
760 : "generic param in enum.");
761 0 : return "NULL_POINTER_MARK";
762 : }
763 :
764 0 : str += "\n " + param->as_string ();
765 : }
766 : }
767 :
768 0 : str += "\n Where clause: ";
769 0 : if (has_where_clause ())
770 0 : str += where_clause.as_string ();
771 : else
772 0 : str += "none";
773 :
774 : // struct fields
775 0 : str += "\n Struct fields: ";
776 0 : if (is_unit)
777 : {
778 0 : str += "none (unit)";
779 : }
780 0 : else if (fields.empty ())
781 : {
782 0 : str += "none (non-unit)";
783 : }
784 : else
785 : {
786 0 : for (const auto &field : fields)
787 0 : str += "\n " + field.as_string ();
788 : }
789 :
790 0 : return str;
791 0 : }
792 :
793 : std::string
794 0 : UseDeclaration::as_string () const
795 : {
796 0 : std::string str = VisItem::as_string ();
797 :
798 : // DEBUG: null pointer check
799 0 : if (use_tree == nullptr)
800 : {
801 0 : rust_debug (
802 : "something really terrible has gone wrong - null pointer use tree in "
803 : "use declaration.");
804 0 : return "NULL_POINTER_MARK";
805 : }
806 :
807 0 : str += "use " + use_tree->as_string ();
808 :
809 0 : return str;
810 0 : }
811 :
812 : std::string
813 0 : UseTreeGlob::as_string () const
814 : {
815 0 : switch (glob_type)
816 : {
817 0 : case NO_PATH:
818 0 : return "*";
819 0 : case GLOBAL:
820 0 : return "::*";
821 0 : case PATH_PREFIXED:
822 0 : {
823 0 : std::string path_str = path.as_string ();
824 0 : return path_str + "::*";
825 0 : }
826 0 : default:
827 : // some kind of error
828 0 : return "ERROR-PATH";
829 : }
830 : rust_unreachable ();
831 : }
832 :
833 : std::string
834 0 : UseTreeList::as_string () const
835 : {
836 0 : std::string path_str;
837 0 : switch (path_type)
838 : {
839 0 : case NO_PATH:
840 0 : path_str = "{";
841 0 : break;
842 0 : case GLOBAL:
843 0 : path_str = "::{";
844 0 : break;
845 0 : case PATH_PREFIXED:
846 0 : {
847 0 : path_str = path.as_string () + "::{";
848 0 : break;
849 : }
850 0 : default:
851 : // some kind of error
852 0 : return "ERROR-PATH-LIST";
853 : }
854 :
855 0 : if (has_trees ())
856 : {
857 0 : auto i = trees.begin ();
858 0 : auto e = trees.end ();
859 :
860 : // DEBUG: null pointer check
861 0 : if (*i == nullptr)
862 : {
863 0 : rust_debug ("something really terrible has gone wrong - null pointer "
864 : "tree in use tree list.");
865 0 : return "NULL_POINTER_MARK";
866 : }
867 :
868 0 : for (; i != e; i++)
869 : {
870 0 : path_str += (*i)->as_string ();
871 0 : if (e != i + 1)
872 0 : path_str += ", ";
873 : }
874 : }
875 : else
876 : {
877 0 : path_str += "none";
878 : }
879 :
880 0 : return path_str + "}";
881 0 : }
882 :
883 : std::string
884 0 : UseTreeRebind::as_string () const
885 : {
886 0 : std::string path_str = path.as_string ();
887 :
888 0 : switch (bind_type)
889 : {
890 : case NONE:
891 : // nothing to add, just path
892 : break;
893 0 : case IDENTIFIER:
894 0 : path_str += " as " + identifier.as_string ();
895 0 : break;
896 0 : case WILDCARD:
897 0 : path_str += " as _";
898 0 : break;
899 0 : default:
900 : // error
901 0 : return "ERROR-PATH-REBIND";
902 : }
903 :
904 0 : return path_str;
905 0 : }
906 :
907 : std::string
908 0 : Enum::as_string () const
909 : {
910 0 : std::string str = VisItem::as_string ();
911 0 : str += enum_name.as_string ();
912 :
913 : // generic params
914 0 : str += "\n Generic params: ";
915 0 : if (generic_params.empty ())
916 : {
917 0 : str += "none";
918 : }
919 : else
920 : {
921 0 : for (const auto ¶m : generic_params)
922 : {
923 : // DEBUG: null pointer check
924 0 : if (param == nullptr)
925 : {
926 0 : rust_debug (
927 : "something really terrible has gone wrong - null pointer "
928 : "generic param in enum.");
929 0 : return "NULL_POINTER_MARK";
930 : }
931 :
932 0 : str += "\n " + param->as_string ();
933 : }
934 : }
935 :
936 0 : str += "\n Where clause: ";
937 0 : if (has_where_clause ())
938 0 : str += where_clause.as_string ();
939 : else
940 0 : str += "none";
941 :
942 : // items
943 0 : str += "\n Items: ";
944 0 : if (items.empty ())
945 : {
946 0 : str += "none";
947 : }
948 : else
949 : {
950 0 : for (const auto &item : items)
951 : {
952 : // DEBUG: null pointer check
953 0 : if (item == nullptr)
954 : {
955 0 : rust_debug (
956 : "something really terrible has gone wrong - null pointer "
957 : "enum item in enum.");
958 0 : return "NULL_POINTER_MARK";
959 : }
960 :
961 0 : str += "\n " + item->as_string ();
962 : }
963 : }
964 :
965 0 : return str;
966 0 : }
967 :
968 : std::string
969 0 : Trait::as_string () const
970 : {
971 0 : std::string str = VisItem::as_string ();
972 :
973 0 : if (has_unsafe)
974 0 : str += "unsafe ";
975 :
976 0 : str += "trait " + name.as_string ();
977 :
978 : // generic params
979 0 : str += "\n Generic params: ";
980 0 : if (generic_params.empty ())
981 : {
982 0 : str += "none";
983 : }
984 : else
985 : {
986 0 : for (const auto ¶m : generic_params)
987 : {
988 : // DEBUG: null pointer check
989 0 : if (param == nullptr)
990 : {
991 0 : rust_debug (
992 : "something really terrible has gone wrong - null pointer "
993 : "generic param in trait.");
994 0 : return "NULL_POINTER_MARK";
995 : }
996 :
997 0 : str += "\n " + param->as_string ();
998 : }
999 : }
1000 :
1001 0 : str += "\n Type param bounds: ";
1002 0 : if (!has_type_param_bounds ())
1003 : {
1004 0 : str += "none";
1005 : }
1006 : else
1007 : {
1008 0 : for (const auto &bound : type_param_bounds)
1009 : {
1010 : // DEBUG: null pointer check
1011 0 : if (bound == nullptr)
1012 : {
1013 0 : rust_debug (
1014 : "something really terrible has gone wrong - null pointer "
1015 : "type param bound in trait.");
1016 0 : return "NULL_POINTER_MARK";
1017 : }
1018 :
1019 0 : str += "\n " + bound->as_string ();
1020 : }
1021 : }
1022 :
1023 0 : str += "\n Where clause: ";
1024 0 : if (!has_where_clause ())
1025 0 : str += "none";
1026 : else
1027 0 : str += where_clause.as_string ();
1028 :
1029 0 : str += "\n Trait items: ";
1030 0 : if (!has_trait_items ())
1031 : {
1032 0 : str += "none";
1033 : }
1034 : else
1035 : {
1036 0 : for (const auto &item : trait_items)
1037 : {
1038 : // DEBUG: null pointer check
1039 0 : if (item == nullptr)
1040 : {
1041 0 : rust_debug (
1042 : "something really terrible has gone wrong - null pointer "
1043 : "trait item in trait.");
1044 0 : return "NULL_POINTER_MARK";
1045 : }
1046 :
1047 0 : str += "\n " + item->as_string ();
1048 : }
1049 : }
1050 :
1051 0 : return str;
1052 0 : }
1053 :
1054 : std::string
1055 0 : Union::as_string () const
1056 : {
1057 0 : std::string str = VisItem::as_string ();
1058 :
1059 0 : str += "union " + union_name.as_string ();
1060 :
1061 : // generic params
1062 0 : str += "\n Generic params: ";
1063 0 : if (generic_params.empty ())
1064 : {
1065 0 : str += "none";
1066 : }
1067 : else
1068 : {
1069 0 : for (const auto ¶m : generic_params)
1070 : {
1071 : // DEBUG: null pointer check
1072 0 : if (param == nullptr)
1073 : {
1074 0 : rust_debug (
1075 : "something really terrible has gone wrong - null pointer "
1076 : "generic param in union.");
1077 0 : return "NULL_POINTER_MARK";
1078 : }
1079 :
1080 0 : str += "\n " + param->as_string ();
1081 : }
1082 : }
1083 :
1084 0 : str += "\n Where clause: ";
1085 0 : if (has_where_clause ())
1086 0 : str += where_clause.as_string ();
1087 : else
1088 0 : str += "none";
1089 :
1090 : // struct fields
1091 0 : str += "\n Struct fields (variants): ";
1092 0 : if (variants.empty ())
1093 : {
1094 0 : str += "none";
1095 : }
1096 : else
1097 : {
1098 0 : for (const auto &field : variants)
1099 0 : str += "\n " + field.as_string ();
1100 : }
1101 :
1102 0 : return str;
1103 0 : }
1104 :
1105 44333 : Function::Function (Function const &other)
1106 44333 : : VisItem (other), ExternalItem (other.get_node_id ()),
1107 44333 : qualifiers (other.qualifiers), function_name (other.function_name),
1108 44333 : where_clause (other.where_clause), locus (other.locus),
1109 88666 : is_external_function (other.is_external_function)
1110 : {
1111 : // guard to prevent null dereference (always required)
1112 44333 : if (other.return_type != nullptr)
1113 36248 : return_type = other.return_type->clone_type ();
1114 :
1115 : // guard to prevent null dereference (only required if error state)
1116 44333 : if (other.has_body ())
1117 34621 : function_body = other.function_body.value ()->clone_block_expr ();
1118 : else
1119 9712 : function_body = tl::nullopt;
1120 :
1121 44333 : generic_params.reserve (other.generic_params.size ());
1122 48172 : for (const auto &e : other.generic_params)
1123 3839 : generic_params.push_back (e->clone_generic_param ());
1124 :
1125 44333 : function_params.reserve (other.function_params.size ());
1126 102266 : for (const auto &e : other.function_params)
1127 57933 : function_params.push_back (e->clone_param ());
1128 44333 : }
1129 :
1130 : Function &
1131 0 : Function::operator= (Function const &other)
1132 : {
1133 0 : VisItem::operator= (other);
1134 0 : function_name = other.function_name;
1135 0 : qualifiers = other.qualifiers;
1136 0 : where_clause = other.where_clause;
1137 : // visibility = other.visibility->clone_visibility();
1138 : // outer_attrs = other.outer_attrs;
1139 0 : locus = other.locus;
1140 0 : is_external_function = other.is_external_function;
1141 :
1142 : // guard to prevent null dereference (always required)
1143 0 : if (other.return_type != nullptr)
1144 0 : return_type = other.return_type->clone_type ();
1145 : else
1146 0 : return_type = nullptr;
1147 :
1148 : // guard to prevent null dereference (only required if error state)
1149 0 : if (other.has_body ())
1150 0 : function_body = other.function_body.value ()->clone_block_expr ();
1151 : else
1152 0 : function_body = tl::nullopt;
1153 :
1154 0 : generic_params.reserve (other.generic_params.size ());
1155 0 : for (const auto &e : other.generic_params)
1156 0 : generic_params.push_back (e->clone_generic_param ());
1157 :
1158 0 : function_params.reserve (other.function_params.size ());
1159 0 : for (const auto &e : other.function_params)
1160 0 : function_params.push_back (e->clone_param ());
1161 :
1162 0 : return *this;
1163 : }
1164 : std::string
1165 0 : Function::as_string () const
1166 : {
1167 0 : std::string str = VisItem::as_string () + "\n";
1168 0 : std::string qstr = qualifiers.as_string ();
1169 0 : if ("" != qstr)
1170 0 : str += qstr + " ";
1171 :
1172 0 : if (has_return_type ())
1173 : {
1174 : // DEBUG: null pointer check
1175 0 : if (return_type == nullptr)
1176 : {
1177 : rust_debug (
1178 : "something really terrible has gone wrong - null pointer return "
1179 : "type in function.");
1180 : return "NULL_POINTER_MARK";
1181 : }
1182 :
1183 0 : str += return_type->as_string () + " ";
1184 : }
1185 : else
1186 : {
1187 0 : str += "void ";
1188 : }
1189 :
1190 0 : str += function_name.as_string ();
1191 :
1192 0 : if (has_generics ())
1193 : {
1194 0 : str += "<";
1195 :
1196 0 : auto i = generic_params.begin ();
1197 0 : auto e = generic_params.end ();
1198 :
1199 : // DEBUG: null pointer check
1200 0 : if (i == e)
1201 : {
1202 0 : rust_debug ("something really terrible has gone wrong - null pointer "
1203 : "generic param in function item.");
1204 0 : return "NULL_POINTER_MARK";
1205 : }
1206 :
1207 0 : for (; i != e; i++)
1208 : {
1209 0 : str += (*i)->as_string ();
1210 0 : if (e != i + 1)
1211 0 : str += ", ";
1212 : }
1213 0 : str += ">";
1214 : }
1215 :
1216 0 : if (has_function_params ())
1217 : {
1218 0 : auto i = function_params.begin ();
1219 0 : auto e = function_params.end ();
1220 0 : str += "(";
1221 0 : for (; i != e; i++)
1222 : {
1223 0 : str += (*i)->as_string ();
1224 0 : if (e != i + 1)
1225 0 : str += ", ";
1226 : }
1227 0 : str += ")";
1228 : }
1229 : else
1230 : {
1231 0 : str += "()";
1232 : }
1233 :
1234 0 : if (has_where_clause ())
1235 0 : str += " where " + where_clause.as_string ();
1236 :
1237 0 : str += "\n";
1238 :
1239 0 : if (has_body ())
1240 0 : str += function_body.value ()->as_string () + "\n";
1241 :
1242 0 : return str;
1243 0 : }
1244 :
1245 : std::string
1246 0 : WhereClause::as_string () const
1247 : {
1248 : // just print where clause items, don't mention "where" or "where clause"
1249 0 : std::string str;
1250 :
1251 0 : if (where_clause_items.empty ())
1252 : {
1253 0 : str = "none";
1254 : }
1255 : else
1256 : {
1257 0 : for (const auto &item : where_clause_items)
1258 0 : str += "\n " + item->as_string ();
1259 : }
1260 :
1261 0 : return str;
1262 : }
1263 :
1264 : std::string
1265 0 : BlockExpr::as_string () const
1266 : {
1267 0 : std::string istr = indent_spaces (enter);
1268 0 : std::string str = istr + "BlockExpr:\n" + istr;
1269 :
1270 : // get outer attributes
1271 0 : str += append_attributes (outer_attrs, OUTER);
1272 :
1273 : // inner attributes
1274 0 : str += append_attributes (inner_attrs, INNER);
1275 :
1276 : // statements
1277 0 : str += "\n" + indent_spaces (stay) + "statements: ";
1278 0 : if (statements.empty ())
1279 : {
1280 0 : str += "none";
1281 : }
1282 : else
1283 : {
1284 0 : for (const auto &stmt : statements)
1285 : {
1286 : // DEBUG: null pointer check
1287 0 : if (stmt == nullptr)
1288 : {
1289 0 : rust_debug (
1290 : "something really terrible has gone wrong - null pointer "
1291 : "stmt in block expr.");
1292 0 : return "NULL_POINTER_MARK";
1293 : }
1294 :
1295 0 : str += "\n" + indent_spaces (stay) + stmt->as_string ();
1296 : }
1297 : }
1298 :
1299 : // final expression
1300 0 : str += "\n" + indent_spaces (stay) + "final expression: ";
1301 0 : if (expr == nullptr)
1302 0 : str += "none";
1303 : else
1304 0 : str += "\n" + expr->as_string ();
1305 :
1306 0 : str += "\n" + indent_spaces (out);
1307 0 : return str;
1308 0 : }
1309 :
1310 : std::string
1311 0 : AnonConst::as_string () const
1312 : {
1313 0 : std::string str = "AnonConst: ";
1314 :
1315 0 : if (kind == AnonConst::Kind::DeferredInference)
1316 0 : str += "_";
1317 : else
1318 0 : str += expr.value ()->as_string ();
1319 :
1320 0 : return str;
1321 : }
1322 :
1323 : std::string
1324 0 : ConstBlock::as_string () const
1325 : {
1326 0 : return "ConstBlock: " + expr.as_string ();
1327 : }
1328 :
1329 : std::string
1330 0 : TraitImpl::as_string () const
1331 : {
1332 0 : std::string str = VisItem::as_string ();
1333 :
1334 0 : if (has_unsafe)
1335 0 : str += "unsafe ";
1336 :
1337 0 : str += "impl ";
1338 :
1339 : // generic params
1340 0 : str += "\n Generic params: ";
1341 0 : if (!has_generics ())
1342 : {
1343 0 : str += "none";
1344 : }
1345 : else
1346 : {
1347 0 : for (const auto ¶m : generic_params)
1348 0 : str += "\n " + param->as_string ();
1349 : }
1350 :
1351 0 : str += "\n Has exclam: ";
1352 0 : if (has_exclam)
1353 0 : str += "true";
1354 : else
1355 0 : str += "false";
1356 :
1357 0 : str += "\n TypePath (to trait): " + trait_path.as_string ();
1358 :
1359 0 : str += "\n Type (struct to impl on): " + trait_type->as_string ();
1360 :
1361 0 : str += "\n Where clause: ";
1362 0 : if (!has_where_clause ())
1363 0 : str += "none";
1364 : else
1365 0 : str += where_clause.as_string ();
1366 :
1367 : // inner attributes
1368 0 : str += append_attributes (inner_attrs, INNER);
1369 :
1370 0 : str += "\n trait impl items: ";
1371 0 : if (!has_impl_items ())
1372 : {
1373 0 : str += "none";
1374 : }
1375 : else
1376 : {
1377 0 : for (const auto &item : impl_items)
1378 0 : str += "\n " + item->as_string ();
1379 : }
1380 :
1381 0 : return str;
1382 : }
1383 :
1384 : std::string
1385 0 : TypeAlias::as_string () const
1386 : {
1387 0 : std::string str = VisItem::as_string ();
1388 :
1389 0 : str += " " + new_type_name.as_string ();
1390 :
1391 : // generic params
1392 0 : str += "\n Generic params: ";
1393 0 : if (!has_generics ())
1394 : {
1395 0 : str += "none";
1396 : }
1397 : else
1398 : {
1399 : auto i = generic_params.begin ();
1400 : auto e = generic_params.end ();
1401 :
1402 0 : for (; i != e; i++)
1403 : {
1404 0 : str += (*i)->as_string ();
1405 0 : if (e != i + 1)
1406 0 : str += ", ";
1407 : }
1408 : }
1409 :
1410 0 : str += "\n Where clause: ";
1411 0 : if (!has_where_clause ())
1412 0 : str += "none";
1413 : else
1414 0 : str += where_clause.as_string ();
1415 :
1416 0 : str += "\n Type: " + existing_type->as_string ();
1417 :
1418 0 : return str;
1419 : }
1420 :
1421 : std::string
1422 0 : ExternBlock::as_string () const
1423 : {
1424 0 : std::string str = VisItem::as_string ();
1425 :
1426 0 : str += "extern ";
1427 0 : if (has_abi ())
1428 0 : str += "\"" + abi + "\" ";
1429 :
1430 0 : str += append_attributes (inner_attrs, INNER);
1431 :
1432 0 : str += "\n external items: ";
1433 0 : if (!has_extern_items ())
1434 : {
1435 0 : str += "none";
1436 : }
1437 : else
1438 : {
1439 0 : for (const auto &item : extern_items)
1440 0 : str += "\n " + item->as_string ();
1441 : }
1442 :
1443 0 : return str;
1444 : }
1445 :
1446 : std::string
1447 0 : MacroRule::as_string () const
1448 : {
1449 0 : std::string str ("Macro rule: ");
1450 :
1451 0 : str += "\n Matcher: \n ";
1452 0 : str += matcher.as_string ();
1453 :
1454 0 : str += "\n Transcriber: \n ";
1455 0 : str += transcriber.as_string ();
1456 :
1457 0 : return str;
1458 : }
1459 :
1460 : std::string
1461 0 : MacroRulesDefinition::as_string () const
1462 : {
1463 0 : std::string str;
1464 :
1465 : // get outer attrs
1466 0 : str += append_attributes (outer_attrs, OUTER);
1467 :
1468 : // TODO: deal with macro_2_0
1469 0 : str += "macro_rules!";
1470 :
1471 0 : str += rule_name.as_string ();
1472 :
1473 0 : str += "\n Macro rules: ";
1474 0 : if (rules.empty ())
1475 : {
1476 0 : str += "none";
1477 : }
1478 : else
1479 : {
1480 0 : for (const auto &rule : rules)
1481 0 : str += "\n " + rule.as_string ();
1482 : }
1483 :
1484 0 : str += "\n Delim type: ";
1485 0 : switch (delim_type)
1486 : {
1487 0 : case PARENS:
1488 0 : str += "parentheses";
1489 0 : break;
1490 0 : case SQUARE:
1491 0 : str += "square";
1492 0 : break;
1493 0 : case CURLY:
1494 0 : str += "curly";
1495 0 : break;
1496 0 : default:
1497 0 : return "ERROR_MARK_STRING - delim type in macro invocation";
1498 : }
1499 :
1500 0 : return str;
1501 0 : }
1502 :
1503 : std::string
1504 0 : MacroInvocation::as_string () const
1505 : {
1506 0 : std::string str = "MacroInvocation: ";
1507 0 : auto is_builtin = kind == InvocKind::Builtin;
1508 :
1509 0 : if (is_builtin)
1510 0 : str += "[builtin] ";
1511 : else
1512 0 : str += "[regular] ";
1513 :
1514 0 : str += append_attributes (outer_attrs, OUTER);
1515 :
1516 0 : str += "\n " + invoc_data.as_string ();
1517 :
1518 0 : str += "\n has semicolon: ";
1519 0 : str += has_semicolon () ? "true" : "false";
1520 :
1521 0 : if (is_builtin)
1522 : {
1523 0 : str += "[PENDING EAGER INVOCATIONS]: ";
1524 0 : for (auto &pending : pending_eager_invocs)
1525 : {
1526 0 : str += pending->as_string ();
1527 0 : str += "\n";
1528 : }
1529 : }
1530 :
1531 0 : return str;
1532 : }
1533 :
1534 : std::string
1535 0 : MacroInvocData::as_string () const
1536 : {
1537 0 : return path.as_string () + "!" + token_tree.as_string ();
1538 : }
1539 :
1540 : std::string
1541 0 : ExprStmt::as_string () const
1542 : {
1543 0 : std::string str = indent_spaces (enter) + "ExprStmt: \n";
1544 :
1545 0 : if (expr == nullptr)
1546 : {
1547 0 : str += "none (this should not happen and is an error)";
1548 : }
1549 : else
1550 : {
1551 0 : indent_spaces (enter);
1552 0 : str += expr->as_string ();
1553 0 : if (semicolon_followed)
1554 0 : str += ";";
1555 0 : indent_spaces (out);
1556 : }
1557 :
1558 0 : indent_spaces (out);
1559 0 : return str;
1560 : }
1561 :
1562 : std::string
1563 0 : ClosureParam::as_string () const
1564 : {
1565 0 : std::string str (pattern->as_string ());
1566 :
1567 0 : if (has_type_given ())
1568 0 : str += " : " + type->as_string ();
1569 :
1570 0 : return str;
1571 : }
1572 :
1573 : std::string
1574 0 : ClosureExpr::as_string () const
1575 : {
1576 0 : std::string str = "ClosureExpr:";
1577 :
1578 0 : str += append_attributes (outer_attrs, OUTER);
1579 :
1580 0 : str += "\n Has move: ";
1581 0 : if (has_move)
1582 0 : str += "true";
1583 : else
1584 0 : str += "false";
1585 :
1586 0 : str += "\n Params: ";
1587 0 : if (params.empty ())
1588 : {
1589 0 : str += "none";
1590 : }
1591 : else
1592 : {
1593 0 : for (const auto ¶m : params)
1594 0 : str += "\n " + param.as_string ();
1595 : }
1596 :
1597 0 : return str;
1598 : }
1599 :
1600 : std::string
1601 0 : ClosureExprInnerTyped::as_string () const
1602 : {
1603 0 : std::string str = ClosureExpr::as_string ();
1604 :
1605 0 : str += "\n Return type: " + return_type->as_string ();
1606 :
1607 0 : str += "\n Body: " + expr->as_string ();
1608 :
1609 0 : return str;
1610 : }
1611 :
1612 : std::string
1613 0 : QualifiedPathType::as_string () const
1614 : {
1615 0 : std::string str ("<");
1616 0 : str += type_to_invoke_on->as_string ();
1617 :
1618 0 : if (has_as_clause ())
1619 0 : str += " as " + trait_path.as_string ();
1620 :
1621 0 : return str + ">";
1622 0 : }
1623 :
1624 : std::string
1625 0 : BorrowExpr::as_string () const
1626 : {
1627 : /* TODO: find way to incorporate outer attrs - may have to represent in
1628 : * different style (i.e. something more like BorrowExpr: \n outer attrs) */
1629 :
1630 0 : std::string str ("&");
1631 :
1632 0 : if (raw_borrow)
1633 : {
1634 0 : str += "raw ";
1635 0 : str += get_is_mut () ? "const " : "mut ";
1636 : }
1637 : else
1638 : {
1639 0 : if (double_borrow)
1640 0 : str += "&";
1641 :
1642 0 : if (get_is_mut ())
1643 0 : str += "mut ";
1644 : }
1645 0 : str += main_or_left_expr->as_string ();
1646 :
1647 0 : return str;
1648 : }
1649 :
1650 : std::string
1651 0 : BoxExpr::as_string () const
1652 : {
1653 0 : return "box " + expr->as_string ();
1654 : }
1655 :
1656 : void
1657 20 : BoxExpr::accept_vis (ASTVisitor &vis)
1658 : {
1659 20 : vis.visit (*this);
1660 20 : }
1661 :
1662 : std::string
1663 0 : ReturnExpr::as_string () const
1664 : {
1665 : /* TODO: find way to incorporate outer attrs - may have to represent in
1666 : * different style (i.e. something more like BorrowExpr: \n outer attrs) */
1667 :
1668 0 : std::string str ("return ");
1669 :
1670 0 : if (has_returned_expr ())
1671 0 : str += get_returned_expr ().as_string ();
1672 :
1673 0 : return str;
1674 : }
1675 :
1676 : std::string
1677 0 : TryExpr::as_string () const
1678 : {
1679 : /* TODO: find way to incorporate outer attrs - may have to represent in
1680 : * different style (i.e. something more like BorrowExpr: \n outer attrs) */
1681 :
1682 0 : std::string str ("try ");
1683 :
1684 0 : str += block_expr->as_string ();
1685 :
1686 0 : return str;
1687 : }
1688 :
1689 : std::string
1690 0 : RangeToExpr::as_string () const
1691 : {
1692 0 : return ".." + to->as_string ();
1693 : }
1694 :
1695 : std::string
1696 0 : ContinueExpr::as_string () const
1697 : {
1698 : // TODO: rewrite format to allow outer attributes
1699 0 : std::string str ("continue ");
1700 :
1701 0 : if (has_label ())
1702 0 : str += get_label_unchecked ().as_string ();
1703 :
1704 0 : return str;
1705 : }
1706 :
1707 : std::string
1708 0 : NegationExpr::as_string () const
1709 : {
1710 : // TODO: rewrite formula to allow outer attributes
1711 0 : std::string str;
1712 :
1713 0 : switch (expr_type)
1714 : {
1715 0 : case NegationOperator::NEGATE:
1716 0 : str = "-";
1717 0 : break;
1718 0 : case NegationOperator::NOT:
1719 0 : str = "!";
1720 0 : break;
1721 0 : default:
1722 0 : return "ERROR_MARK_STRING - negation expr";
1723 : }
1724 :
1725 0 : str += main_or_left_expr->as_string ();
1726 :
1727 0 : return str;
1728 0 : }
1729 :
1730 : std::string
1731 0 : RangeFromExpr::as_string () const
1732 : {
1733 0 : return from->as_string () + "..";
1734 : }
1735 :
1736 : std::string
1737 0 : RangeFullExpr::as_string () const
1738 : {
1739 0 : return "..";
1740 : }
1741 :
1742 : std::string
1743 0 : ArrayIndexExpr::as_string () const
1744 : {
1745 : // TODO: rewrite formula to allow outer attributes
1746 0 : return array_expr->as_string () + "[" + index_expr->as_string () + "]";
1747 : }
1748 :
1749 : std::string
1750 0 : AssignmentExpr::as_string () const
1751 : {
1752 0 : std::string str ("AssignmentExpr: ");
1753 :
1754 0 : if (main_or_left_expr == nullptr || right_expr == nullptr)
1755 : {
1756 0 : str += "error (either or both expressions are null)";
1757 : }
1758 : else
1759 : {
1760 : // left expr
1761 0 : str += "\n left: " + main_or_left_expr->as_string ();
1762 :
1763 : // right expr
1764 0 : str += "\n right: " + right_expr->as_string ();
1765 : }
1766 :
1767 0 : return str;
1768 : }
1769 :
1770 : std::string
1771 0 : AsyncBlockExpr::as_string () const
1772 : {
1773 0 : std::string str = "AsyncBlockExpr: ";
1774 :
1775 : // get outer attributes
1776 : // str += "\n " + Expr::as_string ();
1777 0 : str += append_attributes (outer_attrs, OUTER);
1778 :
1779 0 : str += "\n Has move: ";
1780 0 : str += has_move ? "true" : "false";
1781 :
1782 0 : return str + "\n" + block_expr->as_string ();
1783 0 : }
1784 :
1785 : std::string
1786 0 : ComparisonExpr::as_string () const
1787 : {
1788 : // TODO: rewrite to better reflect non-literal expressions
1789 0 : std::string str (main_or_left_expr->as_string ());
1790 :
1791 0 : switch (expr_type)
1792 : {
1793 0 : case ComparisonOperator::EQUAL:
1794 0 : str += " == ";
1795 0 : break;
1796 0 : case ComparisonOperator::NOT_EQUAL:
1797 0 : str += " != ";
1798 0 : break;
1799 0 : case ComparisonOperator::GREATER_THAN:
1800 0 : str += " > ";
1801 0 : break;
1802 0 : case ComparisonOperator::LESS_THAN:
1803 0 : str += " < ";
1804 0 : break;
1805 0 : case ComparisonOperator::GREATER_OR_EQUAL:
1806 0 : str += " >= ";
1807 0 : break;
1808 0 : case ComparisonOperator::LESS_OR_EQUAL:
1809 0 : str += " <= ";
1810 0 : break;
1811 0 : default:
1812 0 : return "ERROR_MARK_STRING - comparison expr";
1813 : }
1814 :
1815 0 : str += right_expr->as_string ();
1816 :
1817 0 : return str;
1818 0 : }
1819 :
1820 : std::string
1821 0 : MethodCallExpr::as_string () const
1822 : {
1823 0 : std::string str = "MethodCallExpr: ";
1824 :
1825 0 : str += append_attributes (outer_attrs, OUTER);
1826 :
1827 0 : str += "\n Object (receiver) expr: \n";
1828 0 : str += receiver->as_string ();
1829 :
1830 0 : str += "\n Method path segment: \n";
1831 0 : str += method_name.as_string ();
1832 :
1833 0 : str += "\n Call params:";
1834 0 : if (params.empty ())
1835 : {
1836 0 : str += "none";
1837 : }
1838 : else
1839 : {
1840 0 : for (const auto ¶m : params)
1841 : {
1842 0 : if (param == nullptr)
1843 0 : return "ERROR_MARK_STRING - method call expr param is null";
1844 :
1845 0 : str += "\n " + param->as_string ();
1846 : }
1847 : }
1848 :
1849 0 : return str;
1850 0 : }
1851 :
1852 : std::string
1853 0 : TupleIndexExpr::as_string () const
1854 : {
1855 : // TODO: rewrite dump to better reflect non-literal exprs
1856 0 : return tuple_expr->as_string () + "." + std::to_string (tuple_index);
1857 : }
1858 :
1859 : std::string
1860 0 : DereferenceExpr::as_string () const
1861 : {
1862 : // TODO: rewrite dump to better reflect non-literal exprs
1863 0 : return "*" + main_or_left_expr->as_string ();
1864 : }
1865 :
1866 : std::string
1867 0 : FieldAccessExpr::as_string () const
1868 : {
1869 : // TODO: rewrite dump to better reflect non-literal exprs
1870 0 : return receiver->as_string () + "." + field.as_string ();
1871 : }
1872 :
1873 : std::string
1874 0 : LazyBooleanExpr::as_string () const
1875 : {
1876 : // TODO: rewrite dump to better reflect non-literal exprs
1877 0 : std::string str (main_or_left_expr->as_string ());
1878 :
1879 0 : switch (expr_type)
1880 : {
1881 0 : case LazyBooleanOperator::LOGICAL_OR:
1882 0 : str += " || ";
1883 0 : break;
1884 0 : case LazyBooleanOperator::LOGICAL_AND:
1885 0 : str += " && ";
1886 0 : break;
1887 0 : default:
1888 0 : return "ERROR_MARK_STRING - lazy boolean expr out of bounds";
1889 : }
1890 :
1891 0 : str += right_expr->as_string ();
1892 :
1893 0 : return str;
1894 0 : }
1895 :
1896 : std::string
1897 0 : RangeFromToExpr::as_string () const
1898 : {
1899 : // TODO: rewrite dump to better reflect non-literal exprs
1900 0 : return from->as_string () + ".." + to->as_string ();
1901 : }
1902 :
1903 : std::string
1904 0 : RangeToInclExpr::as_string () const
1905 : {
1906 : // TODO: rewrite dump to better reflect non-literal exprs
1907 0 : return "..=" + to->as_string ();
1908 : }
1909 :
1910 : std::string
1911 0 : UnsafeBlockExpr::as_string () const
1912 : {
1913 0 : std::string str = "UnsafeBlockExpr:" + indent_spaces (enter);
1914 :
1915 : // get outer attributes
1916 0 : str += append_attributes (outer_attrs, OUTER);
1917 :
1918 0 : str += indent_spaces (stay) + expr->as_string () + "\n" + indent_spaces (out);
1919 :
1920 0 : return str;
1921 : }
1922 :
1923 : std::string
1924 0 : ClosureExprInner::as_string () const
1925 : {
1926 0 : std::string str = ClosureExpr::as_string ();
1927 :
1928 0 : str += "\n Expression: " + closure_inner->as_string ();
1929 :
1930 0 : return str;
1931 : }
1932 :
1933 : std::string
1934 0 : IfExpr::as_string () const
1935 : {
1936 0 : std::string str = "IfExpr: ";
1937 :
1938 0 : str += append_attributes (outer_attrs, OUTER);
1939 :
1940 0 : str += "\n Condition expr: " + condition->as_string ();
1941 :
1942 0 : str += "\n If block expr: " + if_block->as_string ();
1943 :
1944 0 : return str;
1945 : }
1946 :
1947 : std::string
1948 0 : IfExprConseqElse::as_string () const
1949 : {
1950 0 : std::string str = IfExpr::as_string ();
1951 :
1952 0 : str += "\n Else expr: " + else_block->as_string ();
1953 :
1954 0 : return str;
1955 : }
1956 :
1957 : std::string
1958 0 : IfLetExpr::as_string () const
1959 : {
1960 0 : std::string str = "IfLetExpr: ";
1961 :
1962 0 : str += append_attributes (outer_attrs, OUTER);
1963 :
1964 0 : str += "\n Condition match arm patterns: ";
1965 0 : if (match_arm_pattern == nullptr)
1966 : {
1967 0 : str += "none";
1968 : }
1969 : else
1970 : {
1971 0 : str += "\n " + match_arm_pattern->as_string ();
1972 : }
1973 :
1974 0 : str += "\n Scrutinee expr: " + value->as_string ();
1975 :
1976 0 : str += "\n If let block expr: " + if_block->as_string ();
1977 :
1978 0 : return str;
1979 : }
1980 :
1981 : std::string
1982 0 : IfLetExprConseqElse::as_string () const
1983 : {
1984 0 : std::string str = IfLetExpr::as_string ();
1985 :
1986 0 : str += "\n Else expr: " + else_block->as_string ();
1987 :
1988 0 : return str;
1989 : }
1990 :
1991 : std::string
1992 0 : RangeFromToInclExpr::as_string () const
1993 : {
1994 : // TODO: rewrite to allow dumps with non-literal exprs
1995 0 : return from->as_string () + "..=" + to->as_string ();
1996 : }
1997 :
1998 : std::string
1999 0 : ErrorPropagationExpr::as_string () const
2000 : {
2001 : // TODO: rewrite to allow dumps with non-literal exprs
2002 0 : return main_or_left_expr->as_string () + "?";
2003 : }
2004 :
2005 : std::string
2006 0 : CompoundAssignmentExpr::as_string () const
2007 : {
2008 0 : std::string operator_str;
2009 0 : operator_str.reserve (1);
2010 :
2011 : // get operator string
2012 0 : switch (expr_type)
2013 : {
2014 0 : case CompoundAssignmentOperator::ADD:
2015 0 : operator_str = "+";
2016 0 : break;
2017 0 : case CompoundAssignmentOperator::SUBTRACT:
2018 0 : operator_str = "-";
2019 0 : break;
2020 0 : case CompoundAssignmentOperator::MULTIPLY:
2021 0 : operator_str = "*";
2022 0 : break;
2023 0 : case CompoundAssignmentOperator::DIVIDE:
2024 0 : operator_str = "/";
2025 0 : break;
2026 0 : case CompoundAssignmentOperator::MODULUS:
2027 0 : operator_str = "%";
2028 0 : break;
2029 0 : case CompoundAssignmentOperator::BITWISE_AND:
2030 0 : operator_str = "&";
2031 0 : break;
2032 0 : case CompoundAssignmentOperator::BITWISE_OR:
2033 0 : operator_str = "|";
2034 0 : break;
2035 0 : case CompoundAssignmentOperator::BITWISE_XOR:
2036 0 : operator_str = "^";
2037 0 : break;
2038 0 : case CompoundAssignmentOperator::LEFT_SHIFT:
2039 0 : operator_str = "<<";
2040 0 : break;
2041 0 : case CompoundAssignmentOperator::RIGHT_SHIFT:
2042 0 : operator_str = ">>";
2043 0 : break;
2044 0 : default:
2045 0 : operator_str = "invalid operator. wtf";
2046 0 : break;
2047 : }
2048 :
2049 0 : operator_str += "=";
2050 :
2051 0 : std::string str ("CompoundAssignmentExpr: ");
2052 0 : if (main_or_left_expr == nullptr || right_expr == nullptr)
2053 : {
2054 0 : str += "error. this is probably a parsing failure.";
2055 : }
2056 : else
2057 : {
2058 0 : str += "\n left: " + main_or_left_expr->as_string ();
2059 0 : str += "\n right: " + right_expr->as_string ();
2060 0 : str += "\n operator: " + operator_str;
2061 : }
2062 :
2063 0 : return str;
2064 0 : }
2065 :
2066 : std::string
2067 0 : ArithmeticOrLogicalExpr::as_string () const
2068 : {
2069 0 : std::string operator_str;
2070 0 : operator_str.reserve (1);
2071 :
2072 : // get operator string
2073 0 : switch (expr_type)
2074 : {
2075 0 : case ArithmeticOrLogicalOperator::ADD:
2076 0 : operator_str = "+";
2077 0 : break;
2078 0 : case ArithmeticOrLogicalOperator::SUBTRACT:
2079 0 : operator_str = "-";
2080 0 : break;
2081 0 : case ArithmeticOrLogicalOperator::MULTIPLY:
2082 0 : operator_str = "*";
2083 0 : break;
2084 0 : case ArithmeticOrLogicalOperator::DIVIDE:
2085 0 : operator_str = "/";
2086 0 : break;
2087 0 : case ArithmeticOrLogicalOperator::MODULUS:
2088 0 : operator_str = "%";
2089 0 : break;
2090 0 : case ArithmeticOrLogicalOperator::BITWISE_AND:
2091 0 : operator_str = "&";
2092 0 : break;
2093 0 : case ArithmeticOrLogicalOperator::BITWISE_OR:
2094 0 : operator_str = "|";
2095 0 : break;
2096 0 : case ArithmeticOrLogicalOperator::BITWISE_XOR:
2097 0 : operator_str = "^";
2098 0 : break;
2099 0 : case ArithmeticOrLogicalOperator::LEFT_SHIFT:
2100 0 : operator_str = "<<";
2101 0 : break;
2102 0 : case ArithmeticOrLogicalOperator::RIGHT_SHIFT:
2103 0 : operator_str = ">>";
2104 0 : break;
2105 0 : default:
2106 0 : operator_str = "invalid operator. wtf";
2107 0 : break;
2108 : }
2109 :
2110 0 : std::string str ("ArithmeticOrLogicalExpr: ");
2111 0 : if (main_or_left_expr == nullptr || right_expr == nullptr)
2112 : {
2113 0 : str += "error. this is probably a parsing failure.";
2114 : }
2115 : else
2116 : {
2117 0 : str += main_or_left_expr->as_string () + " ";
2118 0 : str += operator_str + " ";
2119 0 : str += right_expr->as_string ();
2120 : }
2121 :
2122 0 : return str;
2123 0 : }
2124 :
2125 : std::string
2126 0 : CallExpr::as_string () const
2127 : {
2128 0 : std::string str = "CallExpr: ";
2129 :
2130 0 : str += append_attributes (outer_attrs, OUTER);
2131 :
2132 0 : str += "\n Function expr: ";
2133 0 : str += function->as_string ();
2134 :
2135 0 : str += "\n Call params:";
2136 0 : if (!has_params ())
2137 : {
2138 0 : str += "none";
2139 : }
2140 : else
2141 : {
2142 0 : for (const auto ¶m : params)
2143 : {
2144 0 : if (param == nullptr)
2145 0 : return "ERROR_MARK_STRING - call expr param is null";
2146 :
2147 0 : str += "\n " + param->as_string ();
2148 : }
2149 : }
2150 :
2151 0 : return str;
2152 0 : }
2153 :
2154 : std::string
2155 0 : WhileLoopExpr::as_string () const
2156 : {
2157 0 : std::string str = "WhileLoopExpr: ";
2158 :
2159 0 : str += append_attributes (outer_attrs, OUTER);
2160 :
2161 0 : str += "\n Label: ";
2162 0 : if (!has_loop_label ())
2163 0 : str += "none";
2164 : else
2165 0 : str += get_loop_label ().as_string ();
2166 :
2167 0 : str += "\n Conditional expr: " + condition->as_string ();
2168 :
2169 0 : str += "\n Loop block: " + loop_block->as_string ();
2170 :
2171 0 : return str;
2172 : }
2173 :
2174 : std::string
2175 0 : WhileLetLoopExpr::as_string () const
2176 : {
2177 0 : std::string str = "WhileLetLoopExpr: ";
2178 :
2179 0 : str += append_attributes (outer_attrs, OUTER);
2180 :
2181 0 : str += "\n Label: ";
2182 0 : if (!has_loop_label ())
2183 0 : str += "none";
2184 : else
2185 0 : str += get_loop_label ().as_string ();
2186 :
2187 0 : str += "\n Match arm patterns: ";
2188 0 : if (match_arm_pattern == nullptr)
2189 : {
2190 0 : str += "none";
2191 : }
2192 : else
2193 : {
2194 0 : str += "\n " + match_arm_pattern->as_string ();
2195 : }
2196 :
2197 0 : str += "\n Scrutinee expr: " + scrutinee->as_string ();
2198 :
2199 0 : str += "\n Loop block: " + loop_block->as_string ();
2200 :
2201 0 : return str;
2202 : }
2203 :
2204 : std::string
2205 0 : LoopExpr::as_string () const
2206 : {
2207 0 : std::string str = "LoopExpr: (infinite loop)";
2208 :
2209 0 : str += append_attributes (outer_attrs, OUTER);
2210 :
2211 0 : str += "\n Label: ";
2212 0 : if (!has_loop_label ())
2213 0 : str += "none";
2214 : else
2215 0 : str += get_loop_label ().as_string ();
2216 :
2217 0 : str += "\n Loop block: " + loop_block->as_string ();
2218 :
2219 0 : return str;
2220 : }
2221 :
2222 : std::string
2223 0 : ArrayExpr::as_string () const
2224 : {
2225 0 : std::string str = "ArrayExpr:";
2226 :
2227 0 : str += append_attributes (outer_attrs, OUTER);
2228 :
2229 : // inner attributes
2230 0 : str += append_attributes (inner_attrs, INNER);
2231 :
2232 0 : str += "\n Array elems: ";
2233 0 : str += internal_elements->as_string ();
2234 :
2235 0 : return str;
2236 : }
2237 :
2238 : std::string
2239 0 : AwaitExpr::as_string () const
2240 : {
2241 : // TODO: rewrite dump to allow non-literal exprs
2242 0 : return awaited_expr->as_string () + ".await";
2243 : }
2244 :
2245 : std::string
2246 0 : BreakExpr::as_string () const
2247 : {
2248 : // TODO: rewrite dump to allow outer attrs, non-literal exprs
2249 0 : std::string str ("break ");
2250 :
2251 0 : if (has_label ())
2252 0 : str += get_label_unchecked ().as_string () + " ";
2253 :
2254 0 : if (has_break_expr ())
2255 0 : str += get_break_expr_unchecked ().as_string ();
2256 :
2257 0 : return str;
2258 : }
2259 :
2260 : std::string
2261 0 : LoopLabel::as_string () const
2262 : {
2263 0 : return label.as_string () + ": (label) ";
2264 : }
2265 :
2266 : std::string
2267 0 : MatchArm::as_string () const
2268 : {
2269 : // outer attributes
2270 0 : std::string str = append_attributes (outer_attrs, OUTER);
2271 :
2272 0 : str += "\nPatterns: ";
2273 0 : if (match_arm_pattern == nullptr)
2274 : {
2275 0 : str += "none";
2276 : }
2277 : else
2278 : {
2279 0 : str += "\n " + match_arm_pattern->as_string ();
2280 : }
2281 :
2282 0 : str += "\nGuard expr: ";
2283 0 : if (!has_match_arm_guard ())
2284 0 : str += "none";
2285 : else
2286 0 : str += guard_expr->as_string ();
2287 :
2288 0 : return str;
2289 : }
2290 :
2291 : std::string
2292 0 : MatchCase::as_string () const
2293 : {
2294 0 : std::string str ("MatchCase: (match arm) ");
2295 :
2296 0 : str += "\n Match arm matcher: \n" + arm.as_string ();
2297 0 : str += "\n Expr: " + expr->as_string ();
2298 :
2299 0 : return str;
2300 : }
2301 :
2302 : std::string
2303 0 : MatchExpr::as_string () const
2304 : {
2305 0 : std::string str ("MatchExpr:");
2306 :
2307 0 : str += append_attributes (outer_attrs, OUTER);
2308 :
2309 0 : str += "\n Scrutinee expr: " + branch_value->as_string ();
2310 :
2311 : // inner attributes
2312 0 : str += append_attributes (inner_attrs, INNER);
2313 :
2314 : // match arms
2315 0 : str += "\n Match arms: ";
2316 0 : if (match_arms.empty ())
2317 : {
2318 0 : str += "none";
2319 : }
2320 : else
2321 : {
2322 0 : for (const auto &arm : match_arms)
2323 0 : str += "\n " + arm.as_string ();
2324 : }
2325 :
2326 0 : return str;
2327 : }
2328 :
2329 : std::string
2330 0 : TupleExpr::as_string () const
2331 : {
2332 0 : std::string str ("TupleExpr:");
2333 :
2334 0 : str += append_attributes (outer_attrs, OUTER);
2335 :
2336 : // inner attributes
2337 0 : str += append_attributes (inner_attrs, INNER);
2338 :
2339 0 : str += "\n Tuple elements: ";
2340 0 : if (tuple_elems.empty ())
2341 : {
2342 0 : str += "none";
2343 : }
2344 : else
2345 : {
2346 0 : for (const auto &elem : tuple_elems)
2347 0 : str += "\n " + elem->as_string ();
2348 : }
2349 :
2350 0 : return str;
2351 : }
2352 :
2353 : std::string
2354 0 : FunctionParam::as_string () const
2355 : {
2356 : // TODO: rewrite dump to allow non-literal types
2357 0 : return param_name->as_string () + " : " + type->as_string ();
2358 : }
2359 :
2360 : void
2361 239158 : FunctionParam::accept_vis (ASTVisitor &vis)
2362 : {
2363 239158 : vis.visit (*this);
2364 239158 : }
2365 :
2366 : void
2367 181243 : SelfParam::accept_vis (ASTVisitor &vis)
2368 : {
2369 181243 : vis.visit (*this);
2370 181243 : }
2371 :
2372 : void
2373 15469 : VariadicParam::accept_vis (ASTVisitor &vis)
2374 : {
2375 15469 : vis.visit (*this);
2376 15469 : }
2377 :
2378 : std::string
2379 0 : VariadicParam::as_string () const
2380 : {
2381 0 : if (has_pattern ())
2382 0 : return get_pattern ().as_string () + " : ...";
2383 : else
2384 0 : return "...";
2385 : }
2386 :
2387 : std::string
2388 0 : FunctionQualifiers::as_string () const
2389 : {
2390 0 : std::string str;
2391 :
2392 0 : if (is_async ())
2393 0 : str += "async ";
2394 0 : if (is_const ())
2395 0 : str += "const ";
2396 0 : if (is_unsafe ())
2397 0 : str += "unsafe ";
2398 :
2399 0 : if (has_extern)
2400 : {
2401 0 : str += "extern";
2402 0 : if (extern_abi != "")
2403 0 : str += " \"" + extern_abi + "\"";
2404 : }
2405 :
2406 0 : return str;
2407 : }
2408 :
2409 : std::string
2410 0 : TraitBound::as_string () const
2411 : {
2412 0 : std::string str ("TraitBound:");
2413 :
2414 0 : str += "\n Has opening question mark: ";
2415 0 : if (opening_question_mark)
2416 0 : str += "true";
2417 : else
2418 0 : str += "false";
2419 :
2420 0 : str += "\n For lifetimes: ";
2421 0 : if (!has_for_lifetimes ())
2422 : {
2423 0 : str += "none";
2424 : }
2425 : else
2426 : {
2427 0 : for (const auto &lifetime : for_lifetimes)
2428 0 : str += "\n " + lifetime.as_string ();
2429 : }
2430 :
2431 0 : str += "\n Type path: " + type_path.as_string ();
2432 :
2433 0 : return str;
2434 : }
2435 :
2436 : std::string
2437 0 : MacroMatcher::as_string () const
2438 : {
2439 0 : std::string str ("Macro matcher: ");
2440 :
2441 0 : str += "\n Delim type: ";
2442 :
2443 0 : switch (delim_type)
2444 : {
2445 0 : case PARENS:
2446 0 : str += "parentheses";
2447 0 : break;
2448 0 : case SQUARE:
2449 0 : str += "square";
2450 0 : break;
2451 0 : case CURLY:
2452 0 : str += "curly";
2453 0 : break;
2454 0 : default:
2455 0 : return "ERROR_MARK_STRING - macro matcher delim";
2456 : }
2457 :
2458 0 : str += "\n Matches: ";
2459 :
2460 0 : if (matches.empty ())
2461 : {
2462 0 : str += "none";
2463 : }
2464 : else
2465 : {
2466 0 : for (const auto &match : matches)
2467 0 : str += "\n " + match->as_string ();
2468 : }
2469 :
2470 0 : return str;
2471 0 : }
2472 :
2473 : std::string
2474 0 : LifetimeParam::as_string () const
2475 : {
2476 0 : std::string str ("LifetimeParam: ");
2477 :
2478 0 : str += "\n Outer attribute:";
2479 0 : if (!has_outer_attribute ())
2480 0 : str += "none";
2481 0 : for (auto &attr : outer_attrs)
2482 0 : str += " " + attr.as_string ();
2483 :
2484 0 : str += "\n Lifetime: " + lifetime.as_string ();
2485 :
2486 0 : str += "\n Lifetime bounds: ";
2487 0 : if (!has_lifetime_bounds ())
2488 : {
2489 0 : str += "none";
2490 : }
2491 : else
2492 : {
2493 0 : for (const auto &bound : lifetime_bounds)
2494 0 : str += "\n " + bound.as_string ();
2495 : }
2496 :
2497 0 : return str;
2498 : }
2499 :
2500 : std::string
2501 0 : MacroMatchFragment::as_string () const
2502 : {
2503 0 : return "$" + ident.as_string () + ": " + frag_spec.as_string ();
2504 : }
2505 :
2506 : std::string
2507 0 : MacroMatchRepetition::as_string () const
2508 : {
2509 0 : std::string str ("Macro match repetition: ");
2510 :
2511 0 : str += "\n Matches: ";
2512 0 : if (matches.empty ())
2513 : {
2514 0 : str += "none";
2515 : }
2516 : else
2517 : {
2518 0 : for (const auto &match : matches)
2519 0 : str += "\n " + match->as_string ();
2520 : }
2521 :
2522 0 : str += "\n Sep: ";
2523 0 : if (!has_sep ())
2524 0 : str += "none";
2525 : else
2526 0 : str += sep->as_string ();
2527 :
2528 0 : str += "\n Op: ";
2529 0 : switch (op)
2530 : {
2531 0 : case ANY:
2532 0 : str += "*";
2533 0 : break;
2534 0 : case ONE_OR_MORE:
2535 0 : str += "+";
2536 0 : break;
2537 0 : case ZERO_OR_ONE:
2538 0 : str += "?";
2539 0 : break;
2540 0 : case NONE:
2541 0 : str += "no op? shouldn't be allowed";
2542 0 : break;
2543 0 : default:
2544 0 : return "ERROR_MARK_STRING - unknown op in macro match repetition";
2545 : }
2546 :
2547 0 : return str;
2548 0 : }
2549 :
2550 : std::string
2551 94 : Lifetime::as_string () const
2552 : {
2553 94 : switch (lifetime_type)
2554 : {
2555 94 : case NAMED:
2556 94 : return "'" + lifetime_name;
2557 0 : case STATIC:
2558 0 : return "'static";
2559 0 : case WILDCARD:
2560 0 : return "'_";
2561 0 : default:
2562 0 : return "ERROR-MARK-STRING: lifetime type failure";
2563 : }
2564 : }
2565 :
2566 : std::string
2567 0 : TypeParam::as_string () const
2568 : {
2569 0 : std::string str ("TypeParam: ");
2570 :
2571 0 : str += "\n Outer attribute:";
2572 0 : if (!has_outer_attribute ())
2573 0 : str += "none";
2574 0 : for (auto &attr : outer_attrs)
2575 0 : str += " " + attr.as_string ();
2576 :
2577 0 : str += "\n Identifier: " + type_representation.as_string ();
2578 :
2579 0 : str += "\n Type param bounds: ";
2580 0 : if (!has_type_param_bounds ())
2581 : {
2582 0 : str += "none";
2583 : }
2584 : else
2585 : {
2586 0 : for (const auto &bound : type_param_bounds)
2587 0 : str += "\n " + bound->as_string ();
2588 : }
2589 :
2590 0 : str += "\n Type: ";
2591 0 : if (!has_type ())
2592 0 : str += "none";
2593 : else
2594 0 : str += type->as_string ();
2595 :
2596 0 : return str;
2597 : }
2598 :
2599 : std::string
2600 0 : ForLoopExpr::as_string () const
2601 : {
2602 0 : std::string str = "ForLoopExpr: ";
2603 :
2604 0 : str += append_attributes (outer_attrs, OUTER);
2605 :
2606 0 : str += "\n Label: ";
2607 0 : if (!has_loop_label ())
2608 0 : str += "none";
2609 : else
2610 0 : str += get_loop_label ().as_string ();
2611 :
2612 0 : str += "\n Pattern: " + pattern->as_string ();
2613 :
2614 0 : str += "\n Iterator expr: " + iterator_expr->as_string ();
2615 :
2616 0 : str += "\n Loop block: " + loop_block->as_string ();
2617 :
2618 0 : return str;
2619 : }
2620 :
2621 : std::string
2622 0 : LetStmt::as_string () const
2623 : {
2624 : // TODO: rewrite to work with non-linearisable types and exprs
2625 0 : std::string str = append_attributes (outer_attrs, OUTER);
2626 :
2627 0 : str += "\n" + indent_spaces (stay) + "let " + variables_pattern->as_string ();
2628 :
2629 0 : if (has_type ())
2630 0 : str += " : " + type->as_string ();
2631 :
2632 0 : if (has_init_expr ())
2633 0 : str += " = " + init_expr->as_string ();
2634 :
2635 0 : return str;
2636 : }
2637 :
2638 : std::string
2639 0 : InferredType::as_string () const
2640 : {
2641 0 : return "_ (inferred)";
2642 : }
2643 :
2644 : std::string
2645 0 : TypeCastExpr::as_string () const
2646 : {
2647 : // TODO: rewrite to work with non-linearisable exprs and types
2648 0 : return main_or_left_expr->as_string () + " as "
2649 0 : + type_to_convert_to->as_string ();
2650 : }
2651 :
2652 : std::string
2653 0 : ImplTraitType::as_string () const
2654 : {
2655 0 : std::string str ("ImplTraitType: \n TypeParamBounds: ");
2656 :
2657 0 : if (type_param_bounds.empty ())
2658 : {
2659 0 : str += "none";
2660 : }
2661 : else
2662 : {
2663 0 : for (const auto &bound : type_param_bounds)
2664 0 : str += "\n " + bound->as_string ();
2665 : }
2666 :
2667 0 : return str;
2668 : }
2669 :
2670 : std::string
2671 0 : ReferenceType::as_string () const
2672 : {
2673 : // TODO: rewrite to work with non-linearisable types
2674 0 : std::string str ("&");
2675 :
2676 0 : if (has_lifetime ())
2677 0 : str += get_lifetime ().as_string () + " ";
2678 :
2679 0 : if (has_mut)
2680 0 : str += "mut ";
2681 :
2682 0 : str += type->as_string ();
2683 :
2684 0 : return str;
2685 : }
2686 :
2687 : std::string
2688 0 : RawPointerType::as_string () const
2689 : {
2690 : // TODO: rewrite to work with non-linearisable types
2691 0 : std::string str ("*");
2692 :
2693 0 : switch (pointer_type)
2694 : {
2695 0 : case MUT:
2696 0 : str += "mut ";
2697 0 : break;
2698 0 : case CONST:
2699 0 : str += "const ";
2700 0 : break;
2701 0 : default:
2702 0 : return "ERROR_MARK_STRING - unknown pointer type in raw pointer type";
2703 : }
2704 :
2705 0 : str += type->as_string ();
2706 :
2707 0 : return str;
2708 0 : }
2709 :
2710 : std::string
2711 0 : TraitObjectType::as_string () const
2712 : {
2713 0 : std::string str ("TraitObjectType: \n Has dyn dispatch: ");
2714 :
2715 0 : if (has_dyn)
2716 0 : str += "true";
2717 : else
2718 0 : str += "false";
2719 :
2720 0 : str += "\n TypeParamBounds: ";
2721 0 : if (type_param_bounds.empty ())
2722 : {
2723 0 : str += "none";
2724 : }
2725 : else
2726 : {
2727 0 : for (const auto &bound : type_param_bounds)
2728 0 : str += "\n " + bound->as_string ();
2729 : }
2730 :
2731 0 : return str;
2732 : }
2733 :
2734 : std::string
2735 0 : BareFunctionType::as_string () const
2736 : {
2737 0 : std::string str ("BareFunctionType: \n For lifetimes: ");
2738 :
2739 0 : if (!has_for_lifetimes ())
2740 : {
2741 0 : str += "none";
2742 : }
2743 : else
2744 : {
2745 0 : for (const auto &for_lifetime : for_lifetimes)
2746 0 : str += "\n " + for_lifetime.as_string ();
2747 : }
2748 :
2749 0 : str += "\n Qualifiers: " + function_qualifiers.as_string ();
2750 :
2751 0 : str += "\n Params: ";
2752 0 : if (params.empty ())
2753 : {
2754 0 : str += "none";
2755 : }
2756 : else
2757 : {
2758 0 : for (const auto ¶m : params)
2759 0 : str += "\n " + param.as_string ();
2760 : }
2761 :
2762 0 : str += "\n Is variadic: ";
2763 0 : if (_is_variadic)
2764 0 : str += "true";
2765 : else
2766 0 : str += "false";
2767 :
2768 0 : str += "\n Return type: ";
2769 0 : if (!has_return_type ())
2770 0 : str += "none (void)";
2771 : else
2772 0 : str += return_type->as_string ();
2773 :
2774 0 : return str;
2775 : }
2776 :
2777 : std::string
2778 0 : ImplTraitTypeOneBound::as_string () const
2779 : {
2780 0 : std::string str ("ImplTraitTypeOneBound: \n TraitBound: ");
2781 :
2782 0 : return str + trait_bound->as_string ();
2783 0 : }
2784 :
2785 : std::string
2786 0 : TraitObjectTypeOneBound::as_string () const
2787 : {
2788 0 : std::string str ("TraitObjectTypeOneBound: \n Has dyn dispatch: ");
2789 :
2790 0 : if (has_dyn)
2791 0 : str += "true";
2792 : else
2793 0 : str += "false";
2794 :
2795 0 : str += "\n TraitBound: " + trait_bound.as_string ();
2796 :
2797 0 : return str;
2798 : }
2799 :
2800 : std::string
2801 0 : ArrayType::as_string () const
2802 : {
2803 : // TODO: rewrite to work with non-linearisable types and exprs
2804 0 : return "[" + elem_type->as_string () + "; " + size.as_string () + "]";
2805 : }
2806 :
2807 : std::string
2808 0 : SliceType::as_string () const
2809 : {
2810 : // TODO: rewrite to work with non-linearisable types
2811 0 : return "[" + elem_type->as_string () + "]";
2812 : }
2813 :
2814 : std::string
2815 0 : TupleType::as_string () const
2816 : {
2817 : // TODO: rewrite to work with non-linearisable types
2818 0 : std::string str ("(");
2819 :
2820 0 : if (!is_unit_type ())
2821 : {
2822 : auto i = elems.begin ();
2823 : auto e = elems.end ();
2824 :
2825 0 : for (; i != e; i++)
2826 : {
2827 0 : str += (*i)->as_string ();
2828 0 : if (e != i + 1)
2829 0 : str += ", ";
2830 : }
2831 : }
2832 :
2833 0 : str += ")";
2834 :
2835 0 : return str;
2836 : }
2837 :
2838 : std::string
2839 0 : StructExpr::as_string () const
2840 : {
2841 0 : std::string str = append_attributes (outer_attrs, OUTER);
2842 0 : indent_spaces (enter);
2843 0 : str += "\n" + indent_spaces (stay) + "StructExpr:";
2844 0 : indent_spaces (enter);
2845 0 : str += "\n" + indent_spaces (stay) + "PathInExpr:\n";
2846 0 : str += indent_spaces (stay) + struct_name.as_string ();
2847 0 : indent_spaces (out);
2848 0 : indent_spaces (out);
2849 0 : return str;
2850 : }
2851 :
2852 : std::string
2853 0 : StructExprStruct::as_string () const
2854 : {
2855 : // TODO: doesn't this require data from StructExpr?
2856 0 : std::string str ("StructExprStruct (or subclass): ");
2857 :
2858 0 : str += "\n Path: " + get_struct_name ().as_string ();
2859 :
2860 : // inner attributes
2861 0 : str += append_attributes (inner_attrs, INNER);
2862 :
2863 0 : return str;
2864 : }
2865 :
2866 : std::string
2867 0 : StructBase::as_string () const
2868 : {
2869 0 : if (base_struct != nullptr)
2870 0 : return base_struct->as_string ();
2871 : else
2872 0 : return "ERROR_MARK_STRING - invalid struct base had as string applied";
2873 : }
2874 :
2875 : std::string
2876 0 : StructExprFieldWithVal::as_string () const
2877 : {
2878 : // used to get value string
2879 0 : return value->as_string ();
2880 : }
2881 :
2882 : std::string
2883 0 : StructExprFieldIdentifierValue::as_string () const
2884 : {
2885 : // TODO: rewrite to work with non-linearisable exprs
2886 0 : return field_name.as_string () + " : " + StructExprFieldWithVal::as_string ();
2887 : }
2888 :
2889 : std::string
2890 0 : StructExprFieldIndexValue::as_string () const
2891 : {
2892 : // TODO: rewrite to work with non-linearisable exprs
2893 0 : return std::to_string (index) + " : " + StructExprFieldWithVal::as_string ();
2894 : }
2895 :
2896 : std::string
2897 0 : StructExprStructFields::as_string () const
2898 : {
2899 0 : std::string str = StructExprStruct::as_string ();
2900 :
2901 0 : str += "\n Fields: ";
2902 0 : if (fields.empty ())
2903 : {
2904 0 : str += "none";
2905 : }
2906 : else
2907 : {
2908 0 : for (const auto &field : fields)
2909 0 : str += "\n " + field->as_string ();
2910 : }
2911 :
2912 0 : str += "\n Struct base: ";
2913 0 : if (!has_struct_base ())
2914 0 : str += "none";
2915 : else
2916 0 : str += struct_base.as_string ();
2917 :
2918 0 : return str;
2919 : }
2920 :
2921 : std::string
2922 0 : EnumItem::as_string () const
2923 : {
2924 0 : std::string str = VisItem::as_string ();
2925 0 : str += variant_name.as_string ();
2926 :
2927 0 : return str;
2928 : }
2929 :
2930 : std::string
2931 0 : EnumItemTuple::as_string () const
2932 : {
2933 0 : std::string str = EnumItem::as_string ();
2934 :
2935 : // add tuple opening parens
2936 0 : str += "(";
2937 :
2938 : // tuple fields
2939 0 : if (has_tuple_fields ())
2940 : {
2941 : auto i = tuple_fields.begin ();
2942 : auto e = tuple_fields.end ();
2943 :
2944 0 : for (; i != e; i++)
2945 : {
2946 0 : str += (*i).as_string ();
2947 0 : if (e != i + 1)
2948 0 : str += ", ";
2949 : }
2950 : }
2951 :
2952 : // add tuple closing parens
2953 0 : str += ")";
2954 :
2955 0 : return str;
2956 : }
2957 :
2958 : std::string
2959 0 : TupleField::as_string () const
2960 : {
2961 : // TODO: rewrite to work with non-linearisable exprs
2962 :
2963 : // outer attributes
2964 0 : std::string str = append_attributes (outer_attrs, OUTER);
2965 :
2966 0 : if (has_visibility ())
2967 0 : str += "\n" + visibility.as_string ();
2968 :
2969 0 : str += " " + field_type->as_string ();
2970 :
2971 0 : return str;
2972 : }
2973 :
2974 : std::string
2975 0 : EnumItemStruct::as_string () const
2976 : {
2977 0 : std::string str = EnumItem::as_string ();
2978 :
2979 : // add struct opening parens
2980 0 : str += "{";
2981 :
2982 : // tuple fields
2983 0 : if (has_struct_fields ())
2984 : {
2985 : auto i = struct_fields.begin ();
2986 : auto e = struct_fields.end ();
2987 :
2988 0 : for (; i != e; i++)
2989 : {
2990 0 : str += (*i).as_string ();
2991 0 : if (e != i + 1)
2992 0 : str += ", ";
2993 : }
2994 : }
2995 :
2996 : // add struct closing parens
2997 0 : str += "}";
2998 :
2999 0 : return str;
3000 : }
3001 :
3002 : std::string
3003 0 : StructField::as_string () const
3004 : {
3005 : // TODO: rewrite to work with non-linearisable exprs
3006 : // outer attributes
3007 0 : std::string str = append_attributes (outer_attrs, OUTER);
3008 :
3009 0 : if (has_visibility ())
3010 0 : str += "\n" + visibility.as_string ();
3011 :
3012 0 : str += " " + field_name.as_string () + " : " + field_type->as_string ();
3013 :
3014 0 : return str;
3015 : }
3016 :
3017 : std::string
3018 0 : EnumItemDiscriminant::as_string () const
3019 : {
3020 : // TODO: rewrite to work with non-linearisable exprs
3021 0 : std::string str = EnumItem::as_string ();
3022 :
3023 : // add equal and expression
3024 0 : str += " = " + expression->as_string ();
3025 :
3026 0 : return str;
3027 : }
3028 :
3029 : std::string
3030 0 : ExternalTypeItem::as_string () const
3031 : {
3032 0 : auto str = append_attributes (outer_attrs, OUTER);
3033 :
3034 0 : str += "type " + item_name.as_string () + ";";
3035 :
3036 0 : return str;
3037 : }
3038 :
3039 : std::string
3040 0 : ExternalStaticItem::as_string () const
3041 : {
3042 : // outer attributes
3043 0 : std::string str = append_attributes (outer_attrs, OUTER);
3044 :
3045 : // start visibility on new line and with a space
3046 0 : str += "\n" + visibility.as_string () + " ";
3047 :
3048 0 : str += "static ";
3049 :
3050 0 : if (has_mut)
3051 0 : str += "mut ";
3052 :
3053 : // add name
3054 0 : str += item_name.as_string ();
3055 :
3056 : // add type on new line
3057 0 : str += "\n Type: " + item_type->as_string ();
3058 :
3059 0 : return str;
3060 : }
3061 :
3062 : std::string
3063 0 : TraitItemType::as_string () const
3064 : {
3065 0 : std::string str = append_attributes (outer_attrs, OUTER);
3066 :
3067 0 : str += "\ntype " + name.as_string ();
3068 :
3069 0 : if (has_generics ())
3070 : {
3071 0 : str += "<";
3072 0 : for (size_t i = 0; i < generic_params.size (); i++)
3073 : {
3074 0 : if (i > 0)
3075 0 : str += ", ";
3076 0 : str += generic_params[i]->as_string ();
3077 : }
3078 0 : str += ">";
3079 : }
3080 :
3081 0 : str += "\n Type param bounds: ";
3082 0 : if (!has_type_param_bounds ())
3083 : {
3084 0 : str += "none";
3085 : }
3086 : else
3087 : {
3088 0 : for (const auto &bound : type_param_bounds)
3089 : {
3090 : // DEBUG: null pointer check
3091 0 : if (bound == nullptr)
3092 : {
3093 0 : rust_debug (
3094 : "something really terrible has gone wrong - null pointer "
3095 : "type param bound in trait item type.");
3096 0 : return "NULL_POINTER_MARK";
3097 : }
3098 :
3099 0 : str += "\n " + bound->as_string ();
3100 : }
3101 : }
3102 :
3103 0 : return str;
3104 0 : }
3105 :
3106 : std::string
3107 0 : SelfParam::as_string () const
3108 : {
3109 : // TODO: rewrite to allow non-linearisable types
3110 0 : if (is_error ())
3111 : {
3112 0 : return "error";
3113 : }
3114 : else
3115 : {
3116 0 : if (has_type ())
3117 : {
3118 : // type (i.e. not ref, no lifetime)
3119 0 : std::string str;
3120 :
3121 0 : if (is_mut)
3122 0 : str += "mut ";
3123 :
3124 0 : str += "self : ";
3125 :
3126 0 : str += type->as_string ();
3127 :
3128 0 : return str;
3129 0 : }
3130 0 : else if (has_lifetime ())
3131 : {
3132 : // ref and lifetime
3133 0 : std::string str = "&" + get_lifetime ().as_string () + " ";
3134 :
3135 0 : if (is_mut)
3136 0 : str += "mut ";
3137 :
3138 0 : str += "self";
3139 :
3140 0 : return str;
3141 0 : }
3142 0 : else if (has_ref)
3143 : {
3144 : // ref with no lifetime
3145 0 : std::string str = "&";
3146 :
3147 0 : if (is_mut)
3148 0 : str += " mut ";
3149 :
3150 0 : str += "self";
3151 :
3152 0 : return str;
3153 0 : }
3154 : else
3155 : {
3156 : // no ref, no type
3157 0 : std::string str;
3158 :
3159 0 : if (is_mut)
3160 0 : str += "mut ";
3161 :
3162 0 : str += "self";
3163 :
3164 0 : return str;
3165 0 : }
3166 : }
3167 : }
3168 :
3169 : std::string
3170 0 : ArrayElemsCopied::as_string () const
3171 : {
3172 : // TODO: rewrite to allow non-linearisable exprs
3173 0 : return elem_to_copy->as_string () + "; " + num_copies->as_string ();
3174 : }
3175 :
3176 : std::string
3177 0 : LifetimeWhereClauseItem::as_string () const
3178 : {
3179 0 : std::string str ("Lifetime: ");
3180 :
3181 0 : str += lifetime.as_string ();
3182 :
3183 0 : str += "\nLifetime bounds: ";
3184 :
3185 0 : for (const auto &bound : lifetime_bounds)
3186 0 : str += "\n " + bound.as_string ();
3187 :
3188 0 : return str;
3189 : }
3190 :
3191 : std::string
3192 0 : TypeBoundWhereClauseItem::as_string () const
3193 : {
3194 0 : std::string str ("For lifetimes: ");
3195 :
3196 0 : if (!has_for_lifetimes ())
3197 : {
3198 0 : str += "none";
3199 : }
3200 : else
3201 : {
3202 0 : for (const auto &for_lifetime : for_lifetimes)
3203 0 : str += "\n " + for_lifetime.as_string ();
3204 : }
3205 :
3206 0 : str += "\nType: " + bound_type->as_string ();
3207 :
3208 0 : str += "\nType param bounds bounds: ";
3209 :
3210 0 : for (const auto &bound : type_param_bounds)
3211 : {
3212 : // debug null pointer check
3213 0 : if (bound == nullptr)
3214 0 : return "NULL_POINTER_MARK - type param bounds";
3215 :
3216 0 : str += "\n " + bound->as_string ();
3217 : }
3218 :
3219 0 : return str;
3220 0 : }
3221 :
3222 : std::string
3223 0 : ArrayElemsValues::as_string () const
3224 : {
3225 0 : std::string str;
3226 :
3227 0 : for (const auto &expr : values)
3228 : {
3229 : // DEBUG: null pointer check
3230 0 : if (expr == nullptr)
3231 : {
3232 0 : rust_debug ("something really terrible has gone wrong - null pointer "
3233 : "expr in array elems values.");
3234 0 : return "NULL_POINTER_MARK";
3235 : }
3236 :
3237 0 : str += "\n " + expr->as_string ();
3238 : }
3239 :
3240 0 : return str;
3241 0 : }
3242 :
3243 : std::string
3244 0 : MaybeNamedParam::as_string () const
3245 : {
3246 : // TODO: rewrite to allow using non-linearisable types in dump
3247 0 : std::string str;
3248 :
3249 0 : switch (param_kind)
3250 : {
3251 : case UNNAMED:
3252 : break;
3253 0 : case IDENTIFIER:
3254 0 : str = name.as_string () + " : ";
3255 0 : break;
3256 0 : case WILDCARD:
3257 0 : str = "_ : ";
3258 0 : break;
3259 0 : default:
3260 0 : return "ERROR_MARK_STRING - maybe named param unrecognised param kind";
3261 : }
3262 :
3263 0 : str += param_type->as_string ();
3264 :
3265 0 : return str;
3266 0 : }
3267 :
3268 12788 : MetaItemInner::~MetaItemInner () = default;
3269 :
3270 : std::unique_ptr<MetaNameValueStr>
3271 0 : MetaItemInner::to_meta_name_value_str () const
3272 : {
3273 0 : if (is_key_value_pair ())
3274 : {
3275 0 : auto converted_item = static_cast<const MetaNameValueStr *> (this);
3276 0 : return converted_item->to_meta_name_value_str ();
3277 : }
3278 : // TODO actually parse foo = bar
3279 0 : return nullptr;
3280 : }
3281 :
3282 : std::string
3283 126 : MetaItemSeq::as_string () const
3284 : {
3285 126 : std::string path_str = path.as_string () + "(";
3286 :
3287 126 : auto i = seq.begin ();
3288 126 : auto e = seq.end ();
3289 :
3290 282 : for (; i != e; i++)
3291 : {
3292 312 : path_str += (*i)->as_string ();
3293 156 : if (e != i + 1)
3294 30 : path_str += ", ";
3295 : }
3296 :
3297 126 : return path_str + ")";
3298 126 : }
3299 :
3300 : std::string
3301 0 : MetaListPaths::as_string () const
3302 : {
3303 0 : std::string str = ident.as_string () + "(";
3304 :
3305 0 : auto i = paths.begin ();
3306 0 : auto e = paths.end ();
3307 :
3308 0 : for (; i != e; i++)
3309 : {
3310 0 : str += (*i).as_string ();
3311 0 : if (e != i + 1)
3312 0 : str += ", ";
3313 : }
3314 :
3315 0 : return str + ")";
3316 0 : }
3317 :
3318 : std::string
3319 0 : MetaListNameValueStr::as_string () const
3320 : {
3321 0 : std::string str = ident.as_string () + "(";
3322 :
3323 0 : auto i = strs.begin ();
3324 0 : auto e = strs.end ();
3325 :
3326 0 : for (; i != e; i++)
3327 : {
3328 0 : str += (*i).as_string ();
3329 0 : if (e != i + 1)
3330 0 : str += ", ";
3331 : }
3332 :
3333 0 : return str + ")";
3334 0 : }
3335 :
3336 : std::string
3337 2115 : AttrInputMetaItemContainer::as_string () const
3338 : {
3339 2115 : std::string str = "(";
3340 :
3341 2115 : auto i = items.begin ();
3342 2115 : auto e = items.end ();
3343 :
3344 4230 : for (; i != e; i++)
3345 : {
3346 4230 : str += (*i)->as_string ();
3347 2115 : if (e != i + 1)
3348 1 : str += ", ";
3349 : }
3350 :
3351 2115 : return str + ")";
3352 2115 : }
3353 :
3354 19 : AttrInputExpr::AttrInputExpr (const AttrInputExpr &oth)
3355 19 : : expr (oth.expr->clone_expr ())
3356 19 : {}
3357 :
3358 : AttrInputExpr &
3359 0 : AttrInputExpr::operator= (const AttrInputExpr &oth)
3360 : {
3361 0 : expr = oth.expr->clone_expr ();
3362 0 : return *this;
3363 : }
3364 :
3365 : std::string
3366 0 : AttrInputExpr::as_string () const
3367 : {
3368 0 : return expr->as_string ();
3369 : }
3370 :
3371 : void
3372 56 : AttrInputExpr::accept_vis (ASTVisitor &vis)
3373 : {
3374 56 : vis.visit (*this);
3375 56 : }
3376 :
3377 : /* Override that calls the function recursively on all items contained within
3378 : * the module. */
3379 : void
3380 0 : Module::add_crate_name (std::vector<std::string> &names) const
3381 : {
3382 : /* TODO: test whether module has been 'cfg'-ed out to determine whether to
3383 : * exclude it from search */
3384 :
3385 0 : for (const auto &item : items)
3386 0 : item->add_crate_name (names);
3387 0 : }
3388 :
3389 : static bool
3390 121 : file_exists (const std::string path)
3391 : {
3392 : // Simply check if the file exists
3393 : // FIXME: This does not work on Windows
3394 0 : return access (path.c_str (), F_OK) != -1;
3395 : }
3396 :
3397 : static std::string
3398 79 : filename_from_path_attribute (std::vector<Attribute> &outer_attrs)
3399 : {
3400 : // An out-of-line module cannot have inner attributes. Additionally, the
3401 : // default name is specified as `""` so that the caller can detect the case
3402 : // of "no path given" and use the default path logic (`name.rs` or
3403 : // `name/mod.rs`).
3404 79 : return extract_module_path ({}, outer_attrs, "");
3405 : }
3406 :
3407 : void
3408 82 : Module::process_file_path ()
3409 : {
3410 82 : rust_assert (kind == Module::ModuleKind::UNLOADED);
3411 :
3412 82 : if (!module_file.empty ())
3413 : {
3414 3 : rust_error_at (locus, "error handling module file for %qs",
3415 3 : module_name.as_string ().c_str ());
3416 67 : return;
3417 : }
3418 :
3419 : // This corresponds to the path of the file 'including' the module. So the
3420 : // file that contains the 'mod <file>;' directive
3421 79 : std::string including_fpath (outer_filename);
3422 :
3423 79 : std::string expected_file_path = module_name.as_string () + ".rs";
3424 79 : std::string expected_dir_path = "mod.rs";
3425 :
3426 79 : auto dir_slash_pos = including_fpath.rfind (file_separator);
3427 79 : std::string current_directory_name;
3428 79 : std::string including_fname;
3429 :
3430 : // If we haven't found a file_separator, then we may have to look for files in
3431 : // the current directory ('.')
3432 79 : if (dir_slash_pos == std::string::npos)
3433 : {
3434 1 : including_fname = std::move (including_fpath);
3435 2 : including_fpath = std::string (".") + file_separator + including_fname;
3436 1 : dir_slash_pos = 1;
3437 : }
3438 : else
3439 : {
3440 78 : including_fname = including_fpath.substr (dir_slash_pos + 1);
3441 : }
3442 :
3443 79 : current_directory_name
3444 158 : = including_fpath.substr (0, dir_slash_pos) + file_separator;
3445 :
3446 79 : auto path_string = filename_from_path_attribute (get_outer_attrs ());
3447 :
3448 79 : std::string including_subdir;
3449 79 : bool subdir_was_added = false;
3450 79 : if (path_string.empty () && module_scope.empty ()
3451 117 : && get_file_subdir (including_fname, including_subdir))
3452 : {
3453 76 : current_directory_name += including_subdir + file_separator;
3454 38 : subdir_was_added = true;
3455 : }
3456 :
3457 : // Handle inline module declarations adding path components.
3458 84 : for (auto const &name : module_scope)
3459 : {
3460 5 : current_directory_name.append (name);
3461 5 : current_directory_name.append (file_separator);
3462 : }
3463 :
3464 79 : if (!path_string.empty ())
3465 : {
3466 40 : module_file = current_directory_name + path_string;
3467 40 : return;
3468 : }
3469 :
3470 : // FIXME: We also have to search for
3471 : // <directory>/<including_fname>/<module_name>.rs In rustc, this is done via
3472 : // the concept of `DirOwnernship`, which is based on whether or not the
3473 : // current file is titled `mod.rs`.
3474 :
3475 : // First, we search for <directory>/<module_name>.rs
3476 39 : std::string file_mod_path = current_directory_name + expected_file_path;
3477 78 : bool file_mod_found = file_exists (file_mod_path);
3478 :
3479 : // Then, search for <directory>/<module_name>/mod.rs
3480 39 : std::string dir_mod_path = current_directory_name + module_name.as_string ()
3481 39 : + file_separator + expected_dir_path;
3482 78 : bool dir_mod_found = file_exists (dir_mod_path);
3483 :
3484 39 : if (!file_mod_found && !dir_mod_found && subdir_was_added)
3485 : {
3486 22 : size_t suffix_len
3487 22 : = including_subdir.length () + std::string (file_separator).length ();
3488 22 : std::string fallback_dir
3489 22 : = current_directory_name.substr (0, current_directory_name.length ()
3490 22 : - suffix_len);
3491 22 : std::string fallback_file = fallback_dir + expected_file_path;
3492 22 : std::string fallback_dir_mod = fallback_dir + module_name.as_string ()
3493 22 : + file_separator + expected_dir_path;
3494 44 : if (file_exists (fallback_file))
3495 : {
3496 1 : file_mod_found = true;
3497 1 : file_mod_path = fallback_file;
3498 : }
3499 42 : else if (file_exists (fallback_dir_mod))
3500 : {
3501 0 : dir_mod_found = true;
3502 0 : dir_mod_path = fallback_dir_mod;
3503 : }
3504 22 : }
3505 :
3506 39 : bool multiple_candidates_found = file_mod_found && dir_mod_found;
3507 39 : bool no_candidates_found = !file_mod_found && !dir_mod_found;
3508 :
3509 39 : if (multiple_candidates_found)
3510 0 : rust_error_at (locus,
3511 : "two candidates found for module %s: %s.rs and %s%smod.rs",
3512 0 : module_name.as_string ().c_str (),
3513 0 : module_name.as_string ().c_str (),
3514 0 : module_name.as_string ().c_str (), file_separator);
3515 :
3516 39 : if (no_candidates_found)
3517 21 : rust_error_at (locus, "no candidate found for module %s",
3518 21 : module_name.as_string ().c_str ());
3519 :
3520 39 : if (no_candidates_found || multiple_candidates_found)
3521 21 : return;
3522 :
3523 33 : module_file = std::move (file_mod_found ? file_mod_path : dir_mod_path);
3524 100 : }
3525 :
3526 : void
3527 82 : Module::load_items ()
3528 : {
3529 82 : process_file_path ();
3530 :
3531 : // We will already have errored out appropriately in the process_file_path ()
3532 : // method
3533 82 : if (module_file.empty ())
3534 32 : return;
3535 :
3536 61 : RAIIFile file_wrap (module_file.c_str ());
3537 61 : Linemap *linemap = Session::get_instance ().linemap;
3538 61 : if (!file_wrap.ok ())
3539 : {
3540 11 : rust_error_at (get_locus (), "cannot open module file %s: %m",
3541 : module_file.c_str ());
3542 11 : return;
3543 : }
3544 :
3545 50 : rust_debug ("Attempting to parse file %s", module_file.c_str ());
3546 :
3547 50 : Lexer lex (module_file.c_str (), std::move (file_wrap), linemap);
3548 50 : Parser<Lexer> parser (lex);
3549 :
3550 : // we need to parse any possible inner attributes for this module
3551 50 : inner_attrs = parser.parse_inner_attributes ();
3552 50 : auto parsed_items = parser.parse_items ().value_or (
3553 50 : std::vector<std::unique_ptr<AST::Item>>{});
3554 :
3555 50 : for (const auto &error : parser.get_errors ())
3556 0 : error.emit ();
3557 :
3558 50 : items = std::move (parsed_items);
3559 50 : kind = ModuleKind::LOADED;
3560 61 : }
3561 :
3562 : void
3563 1002 : Attribute::parse_attr_to_meta_item ()
3564 : {
3565 : // only parse if has attribute input and not already parsed
3566 1002 : if (!has_attr_input () || is_parsed_to_meta_item ())
3567 338 : return;
3568 :
3569 664 : auto res = attr_input->parse_to_meta_item ();
3570 664 : std::unique_ptr<AttrInput> converted_input (res);
3571 :
3572 664 : if (converted_input != nullptr)
3573 664 : attr_input = std::move (converted_input);
3574 664 : }
3575 :
3576 : AttrInputMetaItemContainer *
3577 10266 : DelimTokenTree::parse_to_meta_item () const
3578 : {
3579 : // must have token trees
3580 10266 : if (token_trees.empty ())
3581 : return nullptr;
3582 :
3583 : /* assume top-level delim token tree in attribute - convert all nested ones
3584 : * to token stream */
3585 10266 : std::vector<std::unique_ptr<Token>> token_stream_wrapped = to_token_stream ();
3586 :
3587 10266 : std::vector<const_TokenPtr> token_stream;
3588 10266 : token_stream.reserve (token_stream_wrapped.size ());
3589 51172 : for (auto &tk : token_stream_wrapped)
3590 81812 : token_stream.push_back (tk->get_tok_ptr ());
3591 :
3592 10266 : AttributeParser parser (std::move (token_stream));
3593 10266 : std::vector<std::unique_ptr<MetaItemInner>> meta_items (
3594 10266 : parser.parse_meta_item_seq ());
3595 :
3596 10266 : return new AttrInputMetaItemContainer (std::move (meta_items));
3597 10266 : }
3598 :
3599 10266 : AttributeParser::AttributeParser (std::vector<const_TokenPtr> token_stream,
3600 10266 : int stream_start_pos)
3601 10266 : : lexer (new MacroInvocLexer (std::move (token_stream))),
3602 10266 : parser (new Parser<MacroInvocLexer> (*lexer))
3603 : {
3604 10266 : if (stream_start_pos)
3605 0 : lexer->skip_token (stream_start_pos - 1);
3606 10266 : }
3607 :
3608 10266 : AttributeParser::~AttributeParser () {}
3609 :
3610 : std::unique_ptr<MetaItemInner>
3611 11655 : AttributeParser::parse_meta_item_inner ()
3612 : {
3613 : // if first tok not identifier, not a "special" case one
3614 23310 : if (lexer->peek_token ()->get_id () != IDENTIFIER)
3615 : {
3616 56 : switch (lexer->peek_token ()->get_id ())
3617 : {
3618 28 : case CHAR_LITERAL:
3619 28 : case STRING_LITERAL:
3620 28 : case BYTE_CHAR_LITERAL:
3621 28 : case BYTE_STRING_LITERAL:
3622 28 : case RAW_STRING_LITERAL:
3623 28 : case INT_LITERAL:
3624 28 : case FLOAT_LITERAL:
3625 28 : case TRUE_LITERAL:
3626 28 : case FALSE_LITERAL:
3627 28 : return parse_meta_item_lit ();
3628 :
3629 0 : case SUPER:
3630 0 : case SELF:
3631 0 : case CRATE:
3632 0 : case DOLLAR_SIGN:
3633 0 : case SCOPE_RESOLUTION:
3634 0 : return parse_path_meta_item ();
3635 :
3636 0 : default:
3637 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3638 : "unrecognised token '%s' in meta item",
3639 : get_token_description (
3640 0 : lexer->peek_token ()->get_id ()));
3641 0 : return nullptr;
3642 : }
3643 : }
3644 :
3645 : // else, check for path
3646 23254 : if (lexer->peek_token (1)->get_id () == SCOPE_RESOLUTION)
3647 : {
3648 : // path
3649 0 : return parse_path_meta_item ();
3650 : }
3651 :
3652 23254 : auto ident = lexer->peek_token ()->get_str ();
3653 11627 : auto ident_locus = lexer->peek_token ()->get_locus ();
3654 :
3655 23254 : if (is_end_meta_item_tok (lexer->peek_token (1)->get_id ()))
3656 : {
3657 : // meta word syntax
3658 7913 : lexer->skip_token ();
3659 23739 : return std::unique_ptr<MetaWord> (new MetaWord (ident, ident_locus));
3660 : }
3661 :
3662 7428 : if (lexer->peek_token (1)->get_id () == EQUAL)
3663 : {
3664 : // maybe meta name value str syntax - check next 2 tokens
3665 7202 : if (lexer->peek_token (2)->get_id () == STRING_LITERAL
3666 7200 : && is_end_meta_item_tok (lexer->peek_token (3)->get_id ()))
3667 : {
3668 : // meta name value str syntax
3669 3599 : const_TokenPtr value_tok = lexer->peek_token (2);
3670 3599 : auto value = value_tok->get_str ();
3671 3599 : auto locus = value_tok->get_locus ();
3672 :
3673 3599 : lexer->skip_token (2);
3674 :
3675 3599 : return std::unique_ptr<MetaNameValueStr> (
3676 7198 : new MetaNameValueStr (ident, ident_locus, std::move (value),
3677 10797 : locus));
3678 7198 : }
3679 : else
3680 : {
3681 : // just interpret as path-based meta item
3682 2 : return parse_path_meta_item ();
3683 : }
3684 : }
3685 :
3686 226 : if (lexer->peek_token (1)->get_id () != LEFT_PAREN)
3687 : {
3688 0 : rust_error_at (lexer->peek_token (1)->get_locus (),
3689 : "unexpected token '%s' after identifier in attribute",
3690 0 : get_token_description (lexer->peek_token (1)->get_id ()));
3691 0 : return nullptr;
3692 : }
3693 :
3694 : // is it one of those special cases like not?
3695 226 : if (lexer->peek_token ()->get_id () == IDENTIFIER)
3696 : {
3697 113 : return parse_path_meta_item ();
3698 : }
3699 :
3700 0 : auto meta_items = parse_meta_item_seq ();
3701 :
3702 : // pass for meta name value str
3703 0 : std::vector<MetaNameValueStr> meta_name_value_str_items;
3704 0 : for (const auto &item : meta_items)
3705 : {
3706 0 : std::unique_ptr<MetaNameValueStr> converted_item
3707 0 : = item->to_meta_name_value_str ();
3708 0 : if (converted_item == nullptr)
3709 : {
3710 0 : meta_name_value_str_items.clear ();
3711 0 : break;
3712 : }
3713 0 : meta_name_value_str_items.push_back (std::move (*converted_item));
3714 0 : }
3715 : // if valid, return this
3716 0 : if (!meta_name_value_str_items.empty ())
3717 : {
3718 0 : return std::unique_ptr<MetaListNameValueStr> (
3719 0 : new MetaListNameValueStr (ident, ident_locus,
3720 0 : std::move (meta_name_value_str_items)));
3721 : }
3722 :
3723 : // // pass for meta list idents
3724 : // std::vector<Identifier> ident_items;
3725 : // for (const auto &item : meta_items)
3726 : // {
3727 : // std::unique_ptr<Identifier> converted_ident (item->to_ident_item ());
3728 : // if (converted_ident == nullptr)
3729 : // {
3730 : // ident_items.clear ();
3731 : // break;
3732 : // }
3733 : // ident_items.push_back (std::move (*converted_ident));
3734 : // }
3735 : // // if valid return this
3736 : // if (!ident_items.empty ())
3737 : // {
3738 : // return std::unique_ptr<MetaListIdents> (
3739 : // new MetaListIdents (std::move (ident), std::move (ident_items)));
3740 : // }
3741 : // // as currently no meta list ident, currently no path. may change in future
3742 :
3743 : // pass for meta list paths
3744 0 : std::vector<SimplePath> path_items;
3745 0 : for (const auto &item : meta_items)
3746 : {
3747 0 : SimplePath converted_path (item->to_path_item ());
3748 0 : if (converted_path.is_empty ())
3749 : {
3750 0 : path_items.clear ();
3751 0 : break;
3752 : }
3753 0 : path_items.push_back (std::move (converted_path));
3754 0 : }
3755 0 : if (!path_items.empty ())
3756 : {
3757 0 : return std::unique_ptr<MetaListPaths> (
3758 0 : new MetaListPaths (ident, ident_locus, std::move (path_items)));
3759 : }
3760 :
3761 0 : rust_error_at (UNKNOWN_LOCATION, "failed to parse any meta item inner");
3762 0 : return nullptr;
3763 11627 : }
3764 :
3765 : bool
3766 15226 : AttributeParser::is_end_meta_item_tok (TokenId id) const
3767 : {
3768 15226 : return id == COMMA || id == RIGHT_PAREN;
3769 : }
3770 :
3771 : std::unique_ptr<MetaItem>
3772 115 : AttributeParser::parse_path_meta_item ()
3773 : {
3774 115 : auto path = parser->parse_simple_path ();
3775 115 : if (!path)
3776 : {
3777 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3778 : "failed to parse simple path in attribute");
3779 0 : return nullptr;
3780 : }
3781 :
3782 230 : switch (lexer->peek_token ()->get_id ())
3783 : {
3784 113 : case LEFT_PAREN:
3785 113 : {
3786 113 : std::vector<std::unique_ptr<MetaItemInner>> meta_items
3787 113 : = parse_meta_item_seq ();
3788 :
3789 113 : return std::unique_ptr<MetaItemSeq> (
3790 226 : new MetaItemSeq (std::move (path.value ()), std::move (meta_items)));
3791 113 : }
3792 2 : case EQUAL:
3793 2 : {
3794 2 : lexer->skip_token ();
3795 :
3796 2 : auto expr = parser->parse_expr ();
3797 :
3798 : // handle error
3799 : // parse_expr should already emit an error and return nullptr
3800 2 : if (!expr)
3801 0 : return nullptr;
3802 :
3803 2 : return std::unique_ptr<MetaItemPathExpr> (
3804 2 : new MetaItemPathExpr (std::move (path.value ()),
3805 4 : std::move (expr.value ())));
3806 2 : }
3807 0 : case COMMA:
3808 : // just simple path
3809 0 : return std::unique_ptr<MetaItemPath> (
3810 0 : new MetaItemPath (std::move (path.value ())));
3811 0 : default:
3812 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3813 : "unrecognised token '%s' in meta item",
3814 0 : get_token_description (lexer->peek_token ()->get_id ()));
3815 0 : return nullptr;
3816 : }
3817 115 : }
3818 :
3819 : /* Parses a parenthesised sequence of meta item inners. Parentheses are
3820 : * required here. */
3821 : std::vector<std::unique_ptr<MetaItemInner>>
3822 10379 : AttributeParser::parse_meta_item_seq ()
3823 : {
3824 10379 : std::vector<std::unique_ptr<MetaItemInner>> meta_items;
3825 :
3826 20758 : if (lexer->peek_token ()->get_id () != LEFT_PAREN)
3827 : {
3828 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3829 : "missing left paren in delim token tree");
3830 0 : return {};
3831 : }
3832 10379 : lexer->skip_token ();
3833 :
3834 10379 : while (lexer->peek_token ()->get_id () != END_OF_FILE
3835 34986 : && lexer->peek_token ()->get_id () != RIGHT_PAREN)
3836 : {
3837 11655 : std::unique_ptr<MetaItemInner> inner = parse_meta_item_inner ();
3838 11655 : if (inner == nullptr)
3839 : {
3840 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3841 : "failed to parse inner meta item in attribute");
3842 0 : return {};
3843 : }
3844 11655 : meta_items.push_back (std::move (inner));
3845 :
3846 23310 : if (lexer->peek_token ()->get_id () != COMMA)
3847 : break;
3848 :
3849 1283 : lexer->skip_token ();
3850 11655 : }
3851 :
3852 20758 : if (lexer->peek_token ()->get_id () != RIGHT_PAREN)
3853 : {
3854 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3855 : "missing right paren in delim token tree");
3856 0 : return {};
3857 : }
3858 10379 : lexer->skip_token ();
3859 :
3860 10379 : return meta_items;
3861 10379 : }
3862 :
3863 : /* Collects any nested token trees into a flat token stream, suitable for
3864 : * parsing. */
3865 : std::vector<std::unique_ptr<Token>>
3866 27666 : DelimTokenTree::to_token_stream () const
3867 : {
3868 27666 : std::vector<std::unique_ptr<Token>> tokens;
3869 190571 : for (const auto &tree : token_trees)
3870 : {
3871 162905 : std::vector<std::unique_ptr<Token>> stream = tree->to_token_stream ();
3872 :
3873 162905 : tokens.insert (tokens.end (), std::make_move_iterator (stream.begin ()),
3874 : std::make_move_iterator (stream.end ()));
3875 162905 : }
3876 :
3877 27666 : tokens.shrink_to_fit ();
3878 27666 : return tokens;
3879 : }
3880 :
3881 : std::unique_ptr<MetaItemLitExpr>
3882 28 : AttributeParser::parse_meta_item_lit ()
3883 : {
3884 28 : auto lit_expr = parser->parse_literal_expr ({});
3885 :
3886 : // TODO: return nullptr instead?
3887 28 : if (!lit_expr)
3888 0 : lit_expr = std::unique_ptr<LiteralExpr> (
3889 0 : new LiteralExpr (Literal::create_error (), {},
3890 0 : lexer->peek_token ()->get_locus ()));
3891 :
3892 28 : return std::unique_ptr<MetaItemLitExpr> (
3893 28 : new MetaItemLitExpr (std::move (*lit_expr.value ())));
3894 28 : }
3895 :
3896 : bool
3897 0 : AttrInputMetaItemContainer::check_cfg_predicate (const Session &session) const
3898 : {
3899 0 : if (items.empty ())
3900 : return false;
3901 :
3902 0 : for (const auto &inner_item : items)
3903 : {
3904 0 : if (!inner_item->check_cfg_predicate (session))
3905 0 : return false;
3906 : }
3907 :
3908 : return true;
3909 : }
3910 :
3911 : bool
3912 1 : MetaItemLitExpr::check_cfg_predicate (const Session &) const
3913 : {
3914 : /* as far as I can tell, a literal expr can never be a valid cfg body, so
3915 : * false */
3916 1 : rust_error_at (this->get_locus (), "'%s' predicate key cannot be a literal",
3917 1 : this->as_string ().c_str ());
3918 :
3919 1 : return false;
3920 : }
3921 :
3922 : bool
3923 0 : MetaListNameValueStr::check_cfg_predicate (const Session &session) const
3924 : {
3925 0 : if (ident.as_string () == "all")
3926 : {
3927 0 : for (const auto &str : strs)
3928 : {
3929 0 : if (!str.check_cfg_predicate (session))
3930 0 : return false;
3931 : }
3932 : return true;
3933 : }
3934 0 : else if (ident.as_string () == "any")
3935 : {
3936 0 : for (const auto &str : strs)
3937 : {
3938 0 : if (str.check_cfg_predicate (session))
3939 0 : return true;
3940 : }
3941 : return false;
3942 : }
3943 0 : else if (ident.as_string () == "not")
3944 : {
3945 0 : if (strs.size () != 1)
3946 : {
3947 : /* HACK: convert vector platform-dependent size_type to string to
3948 : * use in printf */
3949 0 : rust_error_at (UNKNOWN_LOCATION,
3950 : "cfg predicate could not be checked for "
3951 : "MetaListNameValueStr with ident of "
3952 : "'not' because there are '%s' elements, not '1'",
3953 0 : std::to_string (strs.size ()).c_str ());
3954 0 : return false;
3955 : }
3956 :
3957 0 : return !strs[0].check_cfg_predicate (session);
3958 : }
3959 : else
3960 : {
3961 0 : rust_error_at (UNKNOWN_LOCATION,
3962 : "cfg predicate could not be checked for "
3963 : "MetaListNameValueStr with ident of "
3964 : "'%s' - ident must be 'all' or 'any'",
3965 0 : ident.as_string ().c_str ());
3966 0 : return false;
3967 : }
3968 : }
3969 :
3970 : bool
3971 0 : MetaListPaths::check_cfg_predicate (const Session &session) const
3972 : {
3973 0 : if (ident.as_string () == "all")
3974 : {
3975 0 : for (const auto &path : paths)
3976 : {
3977 0 : if (!check_path_exists_in_cfg (session, path))
3978 0 : return false;
3979 : }
3980 : return true;
3981 : }
3982 0 : else if (ident.as_string () == "any")
3983 : {
3984 0 : for (const auto &path : paths)
3985 : {
3986 0 : if (check_path_exists_in_cfg (session, path))
3987 0 : return true;
3988 : }
3989 : return false;
3990 : }
3991 0 : else if (ident.as_string () == "not")
3992 : {
3993 0 : if (paths.size () != 1)
3994 : {
3995 : // HACK: convert vector platform-dependent size_type to string to
3996 : // use in printf
3997 0 : rust_error_at (UNKNOWN_LOCATION,
3998 : "cfg predicate could not be checked for MetaListPaths "
3999 : "with ident of 'not' "
4000 : "because there are '%s' elements, not '1'",
4001 0 : std::to_string (paths.size ()).c_str ());
4002 0 : return false;
4003 : }
4004 :
4005 0 : return !check_path_exists_in_cfg (session, paths[0]);
4006 : }
4007 : else
4008 : {
4009 0 : rust_error_at (UNKNOWN_LOCATION,
4010 : "cfg predicate could not be checked for "
4011 : "MetaListNameValueStr with ident of "
4012 : "'%s' - ident must be 'all' or 'any'",
4013 0 : ident.as_string ().c_str ());
4014 0 : return false;
4015 : }
4016 : }
4017 :
4018 : bool
4019 0 : MetaListPaths::check_path_exists_in_cfg (const Session &session,
4020 : const SimplePath &path) const
4021 : {
4022 0 : return session.options.target_data.has_key (path.as_string ());
4023 : }
4024 :
4025 : bool
4026 119 : MetaItemSeq::check_cfg_predicate (const Session &session) const
4027 : {
4028 119 : if (path.as_string () == "all")
4029 : {
4030 19 : for (const auto &item : seq)
4031 : {
4032 15 : if (!item->check_cfg_predicate (session))
4033 13 : return false;
4034 : }
4035 : return true;
4036 : }
4037 108 : else if (path.as_string () == "any")
4038 : {
4039 32 : for (const auto &item : seq)
4040 : {
4041 26 : if (item->check_cfg_predicate (session))
4042 9 : return true;
4043 : }
4044 : return false;
4045 : }
4046 97 : else if (path.as_string () == "not")
4047 : {
4048 97 : if (seq.size () != 1)
4049 : {
4050 : /* HACK: convert vector platform-dependent size_type to string to
4051 : * use in printf */
4052 0 : rust_error_at (UNKNOWN_LOCATION,
4053 : "cfg predicate could not be checked for MetaItemSeq "
4054 : "with ident of 'not' "
4055 : "because there are '%s' elements, not '1'",
4056 0 : std::to_string (seq.size ()).c_str ());
4057 0 : return false;
4058 : }
4059 :
4060 97 : return !seq[0]->check_cfg_predicate (session);
4061 : }
4062 : else
4063 : {
4064 0 : rust_error_at (
4065 : UNKNOWN_LOCATION,
4066 : "cfg predicate could not be checked for MetaItemSeq with path of "
4067 : "'%s' - path must be 'all' or 'any'",
4068 0 : path.as_string ().c_str ());
4069 0 : return false;
4070 : }
4071 : }
4072 :
4073 : bool
4074 323 : MetaWord::check_cfg_predicate (const Session &session) const
4075 : {
4076 646 : return session.options.target_data.has_key (ident.as_string ());
4077 : }
4078 :
4079 : bool
4080 0 : MetaItemPath::check_cfg_predicate (const Session &session) const
4081 : {
4082 : /* Strictly speaking, this should always be false, but maybe do check
4083 : * relating to SimplePath being identifier. Currently, it would return true
4084 : * if path as identifier existed, and if the path in string form existed
4085 : * (though this shouldn't occur). */
4086 0 : return session.options.target_data.has_key (path.as_string ());
4087 : }
4088 :
4089 : bool
4090 1884 : MetaNameValueStr::check_cfg_predicate (const Session &session) const
4091 : {
4092 : // DEBUG
4093 5684 : rust_debug (
4094 : "checked key-value pair for cfg: '%s', '%s' - is%s in target data",
4095 : ident.as_string ().c_str (), str.c_str (),
4096 : session.options.target_data.has_key_value_pair (ident.as_string (), str)
4097 : ? ""
4098 : : " not");
4099 :
4100 3768 : return session.options.target_data.has_key_value_pair (ident.as_string (),
4101 1884 : str);
4102 : }
4103 :
4104 : bool
4105 0 : MetaItemPathExpr::check_cfg_predicate (const Session &session) const
4106 : {
4107 : // FIXME: Accept path expressions
4108 0 : rust_assert (expr->is_literal ());
4109 0 : return session.options.target_data.has_key_value_pair (path.as_string (),
4110 0 : expr->as_string ());
4111 : }
4112 :
4113 : std::vector<std::unique_ptr<Token>>
4114 154738 : Token::to_token_stream () const
4115 : {
4116 : /* initialisation list doesn't work as it needs copy constructor, so have to
4117 : * do this */
4118 154738 : std::vector<std::unique_ptr<Token>> dummy_vector;
4119 154738 : dummy_vector.reserve (1);
4120 154738 : dummy_vector.push_back (std::unique_ptr<Token> (clone_token_impl ()));
4121 154738 : return dummy_vector;
4122 : }
4123 :
4124 : Attribute
4125 0 : MetaNameValueStr::to_attribute () const
4126 : {
4127 0 : LiteralExpr lit_expr (str, Literal::LitType::STRING,
4128 0 : PrimitiveCoreType::CORETYPE_UNKNOWN, {}, str_locus);
4129 : // FIXME: What location do we put here? Is the literal above supposed to have
4130 : // an empty location as well?
4131 : // Should MetaNameValueStr keep a location?
4132 0 : return Attribute (SimplePath::from_str (ident.as_string (), ident_locus),
4133 0 : std::unique_ptr<AttrInputLiteral> (
4134 0 : new AttrInputLiteral (std::move (lit_expr))));
4135 0 : }
4136 :
4137 : Attribute
4138 0 : MetaItemPath::to_attribute () const
4139 : {
4140 0 : return Attribute (path, nullptr);
4141 : }
4142 :
4143 : Attribute
4144 8 : MetaItemSeq::to_attribute () const
4145 : {
4146 8 : std::vector<std::unique_ptr<MetaItemInner>> new_seq;
4147 8 : new_seq.reserve (seq.size ());
4148 16 : for (const auto &e : seq)
4149 8 : new_seq.push_back (e->clone_meta_item_inner ());
4150 :
4151 8 : std::unique_ptr<AttrInputMetaItemContainer> new_seq_container (
4152 8 : new AttrInputMetaItemContainer (std::move (new_seq)));
4153 8 : return Attribute (path, std::move (new_seq_container));
4154 8 : }
4155 :
4156 : Attribute
4157 0 : MetaWord::to_attribute () const
4158 : {
4159 0 : return Attribute (SimplePath::from_str (ident.as_string (), ident_locus),
4160 0 : nullptr);
4161 : }
4162 :
4163 : Attribute
4164 0 : MetaListPaths::to_attribute () const
4165 : {
4166 : /* probably one of the most annoying conversions - have to lose specificity by
4167 : * turning it into just AttrInputMetaItemContainer (i.e. paths-only nature is
4168 : * no longer known). If conversions back are required, might have to do a
4169 : * "check all are paths" pass or something. */
4170 :
4171 0 : std::vector<std::unique_ptr<MetaItemInner>> new_seq;
4172 0 : new_seq.reserve (paths.size ());
4173 0 : for (const auto &e : paths)
4174 0 : new_seq.push_back (std::unique_ptr<MetaItemPath> (new MetaItemPath (e)));
4175 :
4176 0 : std::unique_ptr<AttrInputMetaItemContainer> new_seq_container (
4177 0 : new AttrInputMetaItemContainer (std::move (new_seq)));
4178 0 : return Attribute (SimplePath::from_str (ident.as_string (), ident_locus),
4179 0 : std::move (new_seq_container));
4180 0 : }
4181 :
4182 : Attribute
4183 0 : MetaListNameValueStr::to_attribute () const
4184 : {
4185 0 : std::vector<std::unique_ptr<MetaItemInner>> new_seq;
4186 0 : new_seq.reserve (strs.size ());
4187 0 : for (const auto &e : strs)
4188 0 : new_seq.push_back (
4189 0 : std::unique_ptr<MetaNameValueStr> (new MetaNameValueStr (e)));
4190 :
4191 0 : std::unique_ptr<AttrInputMetaItemContainer> new_seq_container (
4192 0 : new AttrInputMetaItemContainer (std::move (new_seq)));
4193 0 : return Attribute (SimplePath::from_str (ident.as_string (), ident_locus),
4194 0 : std::move (new_seq_container));
4195 0 : }
4196 :
4197 : Attribute
4198 1 : MetaItemPathExpr::to_attribute () const
4199 : {
4200 1 : auto input = std::make_unique<AttrInputExpr> (expr->clone_expr ());
4201 1 : return Attribute (path, std::move (input));
4202 1 : }
4203 :
4204 : std::vector<Attribute>
4205 9 : AttrInputMetaItemContainer::separate_cfg_attrs () const
4206 : {
4207 9 : rust_assert (!items.empty ());
4208 :
4209 9 : if (items.size () == 1)
4210 0 : return {};
4211 :
4212 9 : std::vector<Attribute> attrs;
4213 9 : attrs.reserve (items.size () - 1);
4214 :
4215 18 : for (auto it = items.begin () + 1; it != items.end (); ++it)
4216 : {
4217 9 : auto &item = **it;
4218 :
4219 9 : Attribute attr = item.to_attribute ();
4220 9 : if (attr.is_empty ())
4221 : {
4222 : /* TODO should this be an error that causes us to chuck out
4223 : * everything? */
4224 0 : continue;
4225 : }
4226 9 : attrs.push_back (std::move (attr));
4227 9 : }
4228 :
4229 9 : attrs.shrink_to_fit ();
4230 9 : return attrs;
4231 9 : }
4232 :
4233 : bool
4234 2147 : Attribute::check_cfg_predicate (const Session &session) const
4235 : {
4236 2147 : auto string_path = path.as_string ();
4237 : /* assume that cfg predicate actually can exist, i.e. attribute has cfg or
4238 : * cfg_attr path */
4239 2147 : if (!has_attr_input ())
4240 : {
4241 1 : rust_error_at (path.get_locus (), "%qs is not followed by parentheses",
4242 : string_path.c_str ());
4243 1 : return false;
4244 : }
4245 :
4246 : // assume that it has already been parsed
4247 2146 : if (!is_parsed_to_meta_item ())
4248 : return false;
4249 :
4250 2146 : auto &meta_item = static_cast<AttrInputMetaItemContainer &> (*attr_input);
4251 2146 : if (meta_item.get_items ().empty ())
4252 : {
4253 3 : rust_error_at (path.get_locus (), "malformed %<%s%> attribute input",
4254 : string_path.c_str ());
4255 3 : return false;
4256 : }
4257 :
4258 2143 : if (string_path == Values::Attributes::CFG
4259 2143 : && meta_item.get_items ().size () != 1)
4260 : {
4261 1 : rust_error_at (path.get_locus (), "multiple %qs predicates are specified",
4262 1 : path.as_string ().c_str ());
4263 1 : return false;
4264 : }
4265 2142 : return meta_item.get_items ().front ()->check_cfg_predicate (session);
4266 2147 : }
4267 :
4268 : std::vector<Attribute>
4269 9 : Attribute::separate_cfg_attrs () const
4270 : {
4271 18 : if (!has_attr_input () || path.as_string () != Values::Attributes::CFG_ATTR)
4272 0 : return {};
4273 :
4274 : // assume that it has already been parsed
4275 9 : if (!is_parsed_to_meta_item ())
4276 0 : return {};
4277 :
4278 9 : return attr_input->separate_cfg_attrs ();
4279 : }
4280 :
4281 : bool
4282 7419 : Attribute::is_parsed_to_meta_item () const
4283 : {
4284 7419 : return has_attr_input () && attr_input->is_meta_item ();
4285 : }
4286 :
4287 : void
4288 37511 : BlockExpr::normalize_tail_expr ()
4289 : {
4290 37511 : if (!expr)
4291 : {
4292 : // HACK: try to turn the last statement into a tail expression
4293 21323 : if (!statements.empty () && statements.back ()->is_expr ())
4294 : {
4295 : // Watch out: This reference become invalid when the vector is
4296 : // modified.
4297 14316 : auto &stmt = static_cast<ExprStmt &> (*statements.back ());
4298 :
4299 14316 : if (!stmt.is_semicolon_followed ())
4300 : {
4301 59 : expr = stmt.take_expr ();
4302 59 : statements.pop_back ();
4303 : }
4304 : }
4305 : }
4306 37511 : }
4307 :
4308 : /* Visitor implementations - these are short but inlining can't happen anyway
4309 : * due to virtual functions and I didn't want to make the ast header includes
4310 : * any longer than they already are. */
4311 :
4312 : void
4313 1452647 : Token::accept_vis (ASTVisitor &vis)
4314 : {
4315 1452647 : vis.visit (*this);
4316 1452647 : }
4317 :
4318 : void
4319 279103 : DelimTokenTree::accept_vis (ASTVisitor &vis)
4320 : {
4321 279103 : vis.visit (*this);
4322 279103 : }
4323 :
4324 : void
4325 640446 : IdentifierExpr::accept_vis (ASTVisitor &vis)
4326 : {
4327 640446 : vis.visit (*this);
4328 640445 : }
4329 :
4330 : void
4331 240 : Lifetime::accept_vis (ASTVisitor &vis)
4332 : {
4333 240 : vis.visit (*this);
4334 240 : }
4335 :
4336 : void
4337 4923 : LifetimeParam::accept_vis (ASTVisitor &vis)
4338 : {
4339 4923 : vis.visit (*this);
4340 4923 : }
4341 :
4342 : void
4343 3103821 : LiteralExpr::accept_vis (ASTVisitor &vis)
4344 : {
4345 3103821 : vis.visit (*this);
4346 3103821 : }
4347 :
4348 : void
4349 254799 : AttrInputLiteral::accept_vis (ASTVisitor &vis)
4350 : {
4351 254799 : vis.visit (*this);
4352 254799 : }
4353 :
4354 : void
4355 0 : MetaItemLitExpr::accept_vis (ASTVisitor &vis)
4356 : {
4357 0 : vis.visit (*this);
4358 0 : }
4359 :
4360 : void
4361 2 : MetaItemPathExpr::accept_vis (ASTVisitor &vis)
4362 : {
4363 2 : vis.visit (*this);
4364 2 : }
4365 :
4366 : void
4367 52668 : BorrowExpr::accept_vis (ASTVisitor &vis)
4368 : {
4369 52668 : vis.visit (*this);
4370 52668 : }
4371 :
4372 : void
4373 95781 : DereferenceExpr::accept_vis (ASTVisitor &vis)
4374 : {
4375 95781 : vis.visit (*this);
4376 95781 : }
4377 :
4378 : void
4379 13 : ErrorPropagationExpr::accept_vis (ASTVisitor &vis)
4380 : {
4381 13 : vis.visit (*this);
4382 13 : }
4383 :
4384 : void
4385 16438 : NegationExpr::accept_vis (ASTVisitor &vis)
4386 : {
4387 16438 : vis.visit (*this);
4388 16438 : }
4389 :
4390 : void
4391 2703191 : ArithmeticOrLogicalExpr::accept_vis (ASTVisitor &vis)
4392 : {
4393 2703191 : vis.visit (*this);
4394 2703191 : }
4395 :
4396 : void
4397 82139 : ComparisonExpr::accept_vis (ASTVisitor &vis)
4398 : {
4399 82139 : vis.visit (*this);
4400 82139 : }
4401 :
4402 : void
4403 8217 : LazyBooleanExpr::accept_vis (ASTVisitor &vis)
4404 : {
4405 8217 : vis.visit (*this);
4406 8217 : }
4407 :
4408 : void
4409 144999 : TypeCastExpr::accept_vis (ASTVisitor &vis)
4410 : {
4411 144999 : vis.visit (*this);
4412 144999 : }
4413 :
4414 : void
4415 56195 : AssignmentExpr::accept_vis (ASTVisitor &vis)
4416 : {
4417 56195 : vis.visit (*this);
4418 56195 : }
4419 :
4420 : void
4421 17280 : CompoundAssignmentExpr::accept_vis (ASTVisitor &vis)
4422 : {
4423 17280 : vis.visit (*this);
4424 17280 : }
4425 :
4426 : void
4427 6304 : ArrayElemsValues::accept_vis (ASTVisitor &vis)
4428 : {
4429 6304 : vis.visit (*this);
4430 6304 : }
4431 :
4432 : void
4433 2552 : ArrayElemsCopied::accept_vis (ASTVisitor &vis)
4434 : {
4435 2552 : vis.visit (*this);
4436 2552 : }
4437 :
4438 : void
4439 8871 : ArrayExpr::accept_vis (ASTVisitor &vis)
4440 : {
4441 8871 : vis.visit (*this);
4442 8871 : }
4443 :
4444 : void
4445 6482 : ArrayIndexExpr::accept_vis (ASTVisitor &vis)
4446 : {
4447 6482 : vis.visit (*this);
4448 6482 : }
4449 :
4450 : void
4451 12658 : TupleExpr::accept_vis (ASTVisitor &vis)
4452 : {
4453 12658 : vis.visit (*this);
4454 12658 : }
4455 :
4456 : void
4457 21387 : TupleIndexExpr::accept_vis (ASTVisitor &vis)
4458 : {
4459 21387 : vis.visit (*this);
4460 21387 : }
4461 :
4462 : void
4463 1725 : StructExprStruct::accept_vis (ASTVisitor &vis)
4464 : {
4465 1725 : vis.visit (*this);
4466 1725 : }
4467 :
4468 : void
4469 4338 : StructExprFieldIdentifier::accept_vis (ASTVisitor &vis)
4470 : {
4471 4338 : vis.visit (*this);
4472 4338 : }
4473 :
4474 : void
4475 45987 : StructExprFieldIdentifierValue::accept_vis (ASTVisitor &vis)
4476 : {
4477 45987 : vis.visit (*this);
4478 45987 : }
4479 :
4480 : void
4481 924 : StructExprFieldIndexValue::accept_vis (ASTVisitor &vis)
4482 : {
4483 924 : vis.visit (*this);
4484 924 : }
4485 :
4486 : void
4487 29610 : StructExprStructFields::accept_vis (ASTVisitor &vis)
4488 : {
4489 29610 : vis.visit (*this);
4490 29610 : }
4491 :
4492 : void
4493 0 : StructExprStructBase::accept_vis (ASTVisitor &vis)
4494 : {
4495 0 : vis.visit (*this);
4496 0 : }
4497 :
4498 : void
4499 307529 : CallExpr::accept_vis (ASTVisitor &vis)
4500 : {
4501 307529 : vis.visit (*this);
4502 307529 : }
4503 :
4504 : void
4505 71164 : MethodCallExpr::accept_vis (ASTVisitor &vis)
4506 : {
4507 71164 : vis.visit (*this);
4508 71164 : }
4509 :
4510 : void
4511 115865 : FieldAccessExpr::accept_vis (ASTVisitor &vis)
4512 : {
4513 115865 : vis.visit (*this);
4514 115865 : }
4515 :
4516 : void
4517 788 : ClosureExprInner::accept_vis (ASTVisitor &vis)
4518 : {
4519 788 : vis.visit (*this);
4520 788 : }
4521 :
4522 : void
4523 416237 : BlockExpr::accept_vis (ASTVisitor &vis)
4524 : {
4525 416237 : vis.visit (*this);
4526 416236 : }
4527 :
4528 : void
4529 685 : AnonConst::accept_vis (ASTVisitor &vis)
4530 : {
4531 685 : vis.visit (*this);
4532 685 : }
4533 :
4534 : void
4535 272 : ConstBlock::accept_vis (ASTVisitor &vis)
4536 : {
4537 272 : vis.visit (*this);
4538 272 : }
4539 :
4540 : void
4541 631 : ClosureExprInnerTyped::accept_vis (ASTVisitor &vis)
4542 : {
4543 631 : vis.visit (*this);
4544 631 : }
4545 :
4546 : void
4547 444 : ContinueExpr::accept_vis (ASTVisitor &vis)
4548 : {
4549 444 : vis.visit (*this);
4550 444 : }
4551 :
4552 : void
4553 2163 : BreakExpr::accept_vis (ASTVisitor &vis)
4554 : {
4555 2163 : vis.visit (*this);
4556 2162 : }
4557 :
4558 : void
4559 1659 : RangeFromToExpr::accept_vis (ASTVisitor &vis)
4560 : {
4561 1659 : vis.visit (*this);
4562 1659 : }
4563 :
4564 : void
4565 147 : RangeFromExpr::accept_vis (ASTVisitor &vis)
4566 : {
4567 147 : vis.visit (*this);
4568 147 : }
4569 :
4570 : void
4571 147 : RangeToExpr::accept_vis (ASTVisitor &vis)
4572 : {
4573 147 : vis.visit (*this);
4574 147 : }
4575 :
4576 : void
4577 0 : RangeFullExpr::accept_vis (ASTVisitor &vis)
4578 : {
4579 0 : vis.visit (*this);
4580 0 : }
4581 :
4582 : void
4583 147 : RangeFromToInclExpr::accept_vis (ASTVisitor &vis)
4584 : {
4585 147 : vis.visit (*this);
4586 147 : }
4587 :
4588 : void
4589 0 : RangeToInclExpr::accept_vis (ASTVisitor &vis)
4590 : {
4591 0 : vis.visit (*this);
4592 0 : }
4593 :
4594 : void
4595 12388 : ReturnExpr::accept_vis (ASTVisitor &vis)
4596 : {
4597 12388 : vis.visit (*this);
4598 12388 : }
4599 :
4600 : void
4601 13 : TryExpr::accept_vis (ASTVisitor &vis)
4602 : {
4603 13 : vis.visit (*this);
4604 13 : }
4605 :
4606 : void
4607 82556 : UnsafeBlockExpr::accept_vis (ASTVisitor &vis)
4608 : {
4609 82556 : vis.visit (*this);
4610 82556 : }
4611 :
4612 : void
4613 2659 : LoopExpr::accept_vis (ASTVisitor &vis)
4614 : {
4615 2659 : vis.visit (*this);
4616 2659 : }
4617 :
4618 : void
4619 2153 : WhileLoopExpr::accept_vis (ASTVisitor &vis)
4620 : {
4621 2153 : vis.visit (*this);
4622 2153 : }
4623 :
4624 : void
4625 24 : WhileLetLoopExpr::accept_vis (ASTVisitor &vis)
4626 : {
4627 24 : vis.visit (*this);
4628 24 : }
4629 :
4630 : void
4631 393 : ForLoopExpr::accept_vis (ASTVisitor &vis)
4632 : {
4633 393 : vis.visit (*this);
4634 393 : }
4635 :
4636 : void
4637 28910 : IfExpr::accept_vis (ASTVisitor &vis)
4638 : {
4639 28910 : vis.visit (*this);
4640 28910 : }
4641 :
4642 : void
4643 31073 : IfExprConseqElse::accept_vis (ASTVisitor &vis)
4644 : {
4645 31073 : vis.visit (*this);
4646 31073 : }
4647 :
4648 : void
4649 395 : IfLetExpr::accept_vis (ASTVisitor &vis)
4650 : {
4651 395 : vis.visit (*this);
4652 395 : }
4653 :
4654 : void
4655 257 : IfLetExprConseqElse::accept_vis (ASTVisitor &vis)
4656 : {
4657 257 : vis.visit (*this);
4658 257 : }
4659 :
4660 : void
4661 25404 : MatchExpr::accept_vis (ASTVisitor &vis)
4662 : {
4663 25404 : vis.visit (*this);
4664 25404 : }
4665 :
4666 : void
4667 0 : AwaitExpr::accept_vis (ASTVisitor &vis)
4668 : {
4669 0 : vis.visit (*this);
4670 0 : }
4671 :
4672 : void
4673 0 : AsyncBlockExpr::accept_vis (ASTVisitor &vis)
4674 : {
4675 0 : vis.visit (*this);
4676 0 : }
4677 :
4678 : void
4679 426 : InlineAsm::accept_vis (ASTVisitor &vis)
4680 : {
4681 426 : vis.visit (*this);
4682 426 : }
4683 :
4684 : void
4685 34 : LlvmInlineAsm::accept_vis (ASTVisitor &vis)
4686 : {
4687 34 : vis.visit (*this);
4688 34 : }
4689 :
4690 : void
4691 105642 : TypeParam::accept_vis (ASTVisitor &vis)
4692 : {
4693 105642 : vis.visit (*this);
4694 105642 : }
4695 :
4696 : void
4697 38 : LifetimeWhereClauseItem::accept_vis (ASTVisitor &vis)
4698 : {
4699 38 : vis.visit (*this);
4700 38 : }
4701 :
4702 : void
4703 7234 : TypeBoundWhereClauseItem::accept_vis (ASTVisitor &vis)
4704 : {
4705 7234 : vis.visit (*this);
4706 7234 : }
4707 :
4708 : void
4709 30259 : Module::accept_vis (ASTVisitor &vis)
4710 : {
4711 30259 : vis.visit (*this);
4712 30259 : }
4713 :
4714 : void
4715 537 : ExternCrate::accept_vis (ASTVisitor &vis)
4716 : {
4717 537 : vis.visit (*this);
4718 537 : }
4719 :
4720 : void
4721 147 : UseTreeGlob::accept_vis (ASTVisitor &vis)
4722 : {
4723 147 : vis.visit (*this);
4724 147 : }
4725 :
4726 : void
4727 2146 : UseTreeList::accept_vis (ASTVisitor &vis)
4728 : {
4729 2146 : vis.visit (*this);
4730 2146 : }
4731 :
4732 : void
4733 6810 : UseTreeRebind::accept_vis (ASTVisitor &vis)
4734 : {
4735 6810 : vis.visit (*this);
4736 6810 : }
4737 :
4738 : void
4739 16649 : UseDeclaration::accept_vis (ASTVisitor &vis)
4740 : {
4741 16649 : vis.visit (*this);
4742 16649 : }
4743 :
4744 : void
4745 445335 : Function::accept_vis (ASTVisitor &vis)
4746 : {
4747 445335 : vis.visit (*this);
4748 445334 : }
4749 :
4750 : void
4751 31966 : TypeAlias::accept_vis (ASTVisitor &vis)
4752 : {
4753 31966 : vis.visit (*this);
4754 31966 : }
4755 :
4756 : void
4757 35726 : StructStruct::accept_vis (ASTVisitor &vis)
4758 : {
4759 35726 : vis.visit (*this);
4760 35726 : }
4761 :
4762 : void
4763 21536 : TupleStruct::accept_vis (ASTVisitor &vis)
4764 : {
4765 21536 : vis.visit (*this);
4766 21536 : }
4767 :
4768 : void
4769 10913 : EnumItem::accept_vis (ASTVisitor &vis)
4770 : {
4771 10913 : vis.visit (*this);
4772 10913 : }
4773 :
4774 : void
4775 11108 : EnumItemTuple::accept_vis (ASTVisitor &vis)
4776 : {
4777 11108 : vis.visit (*this);
4778 11108 : }
4779 :
4780 : void
4781 2215 : EnumItemStruct::accept_vis (ASTVisitor &vis)
4782 : {
4783 2215 : vis.visit (*this);
4784 2215 : }
4785 :
4786 : void
4787 6972 : EnumItemDiscriminant::accept_vis (ASTVisitor &vis)
4788 : {
4789 6972 : vis.visit (*this);
4790 6972 : }
4791 :
4792 : void
4793 12733 : Enum::accept_vis (ASTVisitor &vis)
4794 : {
4795 12733 : vis.visit (*this);
4796 12733 : }
4797 :
4798 : void
4799 2348 : Union::accept_vis (ASTVisitor &vis)
4800 : {
4801 2348 : vis.visit (*this);
4802 2348 : }
4803 :
4804 : void
4805 12591 : ConstantItem::accept_vis (ASTVisitor &vis)
4806 : {
4807 12591 : vis.visit (*this);
4808 12591 : }
4809 :
4810 : void
4811 1299 : StaticItem::accept_vis (ASTVisitor &vis)
4812 : {
4813 1299 : vis.visit (*this);
4814 1299 : }
4815 :
4816 : void
4817 19625 : TraitItemType::accept_vis (ASTVisitor &vis)
4818 : {
4819 19625 : vis.visit (*this);
4820 19625 : }
4821 :
4822 : void
4823 89847 : Trait::accept_vis (ASTVisitor &vis)
4824 : {
4825 89847 : vis.visit (*this);
4826 89847 : }
4827 :
4828 : void
4829 21206 : InherentImpl::accept_vis (ASTVisitor &vis)
4830 : {
4831 21206 : vis.visit (*this);
4832 21206 : }
4833 :
4834 : void
4835 102737 : TraitImpl::accept_vis (ASTVisitor &vis)
4836 : {
4837 102737 : vis.visit (*this);
4838 102737 : }
4839 :
4840 : void
4841 19 : ExternalTypeItem::accept_vis (ASTVisitor &vis)
4842 : {
4843 19 : vis.visit (*this);
4844 19 : }
4845 :
4846 : void
4847 20 : ExternalStaticItem::accept_vis (ASTVisitor &vis)
4848 : {
4849 20 : vis.visit (*this);
4850 20 : }
4851 :
4852 : void
4853 36400 : ExternBlock::accept_vis (ASTVisitor &vis)
4854 : {
4855 36400 : vis.visit (*this);
4856 36400 : }
4857 :
4858 : void
4859 19359 : MacroMatchFragment::accept_vis (ASTVisitor &vis)
4860 : {
4861 19359 : vis.visit (*this);
4862 19359 : }
4863 :
4864 : void
4865 9057 : MacroMatchRepetition::accept_vis (ASTVisitor &vis)
4866 : {
4867 9057 : vis.visit (*this);
4868 9057 : }
4869 :
4870 : void
4871 849 : MacroMatcher::accept_vis (ASTVisitor &vis)
4872 : {
4873 849 : vis.visit (*this);
4874 849 : }
4875 :
4876 : void
4877 29528 : MacroRulesDefinition::accept_vis (ASTVisitor &vis)
4878 : {
4879 29528 : vis.visit (*this);
4880 29528 : }
4881 :
4882 : void
4883 18039 : MacroInvocation::accept_vis (ASTVisitor &vis)
4884 : {
4885 18039 : vis.visit (*this);
4886 18039 : }
4887 :
4888 : void
4889 1384 : EmptyStmt::accept_vis (ASTVisitor &vis)
4890 : {
4891 1384 : vis.visit (*this);
4892 1384 : }
4893 :
4894 : void
4895 308794 : LetStmt::accept_vis (ASTVisitor &vis)
4896 : {
4897 308794 : vis.visit (*this);
4898 308794 : }
4899 :
4900 : void
4901 265665 : ExprStmt::accept_vis (ASTVisitor &vis)
4902 : {
4903 265665 : vis.visit (*this);
4904 265664 : }
4905 :
4906 : void
4907 44070 : TraitBound::accept_vis (ASTVisitor &vis)
4908 : {
4909 44070 : vis.visit (*this);
4910 44070 : }
4911 :
4912 : void
4913 0 : ImplTraitType::accept_vis (ASTVisitor &vis)
4914 : {
4915 0 : vis.visit (*this);
4916 0 : }
4917 :
4918 : void
4919 266 : TraitObjectType::accept_vis (ASTVisitor &vis)
4920 : {
4921 266 : vis.visit (*this);
4922 266 : }
4923 :
4924 : void
4925 161 : ParenthesisedType::accept_vis (ASTVisitor &vis)
4926 : {
4927 161 : vis.visit (*this);
4928 161 : }
4929 :
4930 : void
4931 2144 : ImplTraitTypeOneBound::accept_vis (ASTVisitor &vis)
4932 : {
4933 2144 : vis.visit (*this);
4934 2144 : }
4935 :
4936 : void
4937 3425 : TraitObjectTypeOneBound::accept_vis (ASTVisitor &vis)
4938 : {
4939 3425 : vis.visit (*this);
4940 3425 : }
4941 :
4942 : void
4943 9603 : TupleType::accept_vis (ASTVisitor &vis)
4944 : {
4945 9603 : vis.visit (*this);
4946 9603 : }
4947 :
4948 : void
4949 3947 : NeverType::accept_vis (ASTVisitor &vis)
4950 : {
4951 3947 : vis.visit (*this);
4952 3947 : }
4953 :
4954 : void
4955 168736 : RawPointerType::accept_vis (ASTVisitor &vis)
4956 : {
4957 168736 : vis.visit (*this);
4958 168736 : }
4959 :
4960 : void
4961 119367 : ReferenceType::accept_vis (ASTVisitor &vis)
4962 : {
4963 119367 : vis.visit (*this);
4964 119367 : }
4965 :
4966 : void
4967 17515 : ArrayType::accept_vis (ASTVisitor &vis)
4968 : {
4969 17515 : vis.visit (*this);
4970 17515 : }
4971 :
4972 : void
4973 19317 : SliceType::accept_vis (ASTVisitor &vis)
4974 : {
4975 19317 : vis.visit (*this);
4976 19317 : }
4977 :
4978 : void
4979 6095 : InferredType::accept_vis (ASTVisitor &vis)
4980 : {
4981 6095 : vis.visit (*this);
4982 6095 : }
4983 :
4984 : void
4985 1376 : BareFunctionType::accept_vis (ASTVisitor &vis)
4986 : {
4987 1376 : vis.visit (*this);
4988 1376 : }
4989 :
4990 : void
4991 255 : MetaItemSeq::accept_vis (ASTVisitor &vis)
4992 : {
4993 255 : vis.visit (*this);
4994 255 : }
4995 :
4996 : void
4997 626 : MetaItemPath::accept_vis (ASTVisitor &vis)
4998 : {
4999 626 : vis.visit (*this);
5000 626 : }
5001 :
5002 : void
5003 0 : MetaListPaths::accept_vis (ASTVisitor &vis)
5004 : {
5005 0 : vis.visit (*this);
5006 0 : }
5007 :
5008 : void
5009 6686 : MetaNameValueStr::accept_vis (ASTVisitor &vis)
5010 : {
5011 6686 : vis.visit (*this);
5012 6686 : }
5013 :
5014 : void
5015 0 : MetaListNameValueStr::accept_vis (ASTVisitor &vis)
5016 : {
5017 0 : vis.visit (*this);
5018 0 : }
5019 :
5020 : void
5021 8068 : AttrInputMetaItemContainer::accept_vis (ASTVisitor &vis)
5022 : {
5023 8068 : vis.visit (*this);
5024 8068 : }
5025 :
5026 : void
5027 1084 : MetaWord::accept_vis (ASTVisitor &vis)
5028 : {
5029 1084 : vis.visit (*this);
5030 1084 : }
5031 :
5032 : void
5033 0 : FormatArgs::accept_vis (ASTVisitor &vis)
5034 : {
5035 0 : vis.visit (*this);
5036 0 : }
5037 :
5038 : void
5039 215 : OffsetOf::accept_vis (ASTVisitor &vis)
5040 : {
5041 215 : vis.visit (*this);
5042 215 : }
5043 :
5044 : std::string
5045 0 : FormatArgs::as_string () const
5046 : {
5047 : // FIXME(Arthur): Improve
5048 0 : return "FormatArgs";
5049 : }
5050 :
5051 : std::string
5052 0 : OffsetOf::as_string () const
5053 : {
5054 0 : return "OffsetOf(" + type->as_string () + ", " + field.as_string () + ")";
5055 : }
5056 :
5057 : location_t
5058 3 : FormatArgs::get_locus () const
5059 : {
5060 3 : return loc;
5061 : }
5062 :
5063 : bool
5064 0 : FormatArgs::is_expr_without_block () const
5065 : {
5066 0 : return false;
5067 : }
5068 :
5069 : void
5070 0 : FormatArgs::mark_for_strip ()
5071 : {
5072 0 : marked_for_strip = true;
5073 0 : }
5074 :
5075 : bool
5076 0 : FormatArgs::is_marked_for_strip () const
5077 : {
5078 0 : return marked_for_strip;
5079 : }
5080 :
5081 : std::vector<Attribute> &
5082 0 : FormatArgs::get_outer_attrs ()
5083 : {
5084 0 : rust_unreachable ();
5085 : }
5086 :
5087 : void
5088 0 : FormatArgs::set_outer_attrs (std::vector<Attribute>)
5089 : {
5090 0 : rust_unreachable ();
5091 : }
5092 :
5093 : Expr *
5094 0 : FormatArgs::clone_expr_impl () const
5095 : {
5096 0 : std::cerr << "[ARTHUR] cloning FormatArgs! " << std::endl;
5097 :
5098 0 : return new FormatArgs (*this);
5099 : }
5100 :
5101 : std::vector<Attribute> &
5102 0 : OffsetOf::get_outer_attrs ()
5103 : {
5104 0 : rust_unreachable ();
5105 : }
5106 :
5107 : void
5108 0 : OffsetOf::set_outer_attrs (std::vector<Attribute>)
5109 : {
5110 0 : rust_unreachable ();
5111 : }
5112 :
5113 : Expr *
5114 96 : OffsetOf::clone_expr_impl () const
5115 : {
5116 96 : return new OffsetOf (*this);
5117 : }
5118 :
5119 : } // namespace AST
5120 :
5121 : std::ostream &
5122 0 : operator<< (std::ostream &os, Identifier const &i)
5123 : {
5124 0 : return os << i.as_string ();
5125 : }
5126 :
5127 : } // namespace Rust
|