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 23283 : SingleASTNode::SingleASTNode (SingleASTNode const &other)
47 : {
48 23283 : kind = other.kind;
49 23283 : switch (kind)
50 : {
51 10394 : case Kind::Expr:
52 10394 : expr = other.expr->clone_expr ();
53 10394 : break;
54 :
55 10376 : case Kind::Item:
56 10376 : item = other.item->clone_item ();
57 10376 : break;
58 :
59 1922 : case Kind::Stmt:
60 1922 : stmt = other.stmt->clone_stmt ();
61 1922 : 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 6 : case Kind::Pattern:
76 6 : pattern = other.pattern->clone_pattern ();
77 6 : break;
78 : }
79 23283 : }
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 2 : SingleASTNode::accept_vis (ASTVisitor &vis)
120 : {
121 2 : switch (kind)
122 : {
123 2 : case Kind::Expr:
124 2 : expr->accept_vis (vis);
125 2 : 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 2 : }
152 :
153 : bool
154 8259 : SingleASTNode::is_error ()
155 : {
156 8259 : switch (kind)
157 : {
158 1920 : case Kind::Expr:
159 1920 : return expr == nullptr;
160 5182 : case Kind::Item:
161 5182 : return item == nullptr;
162 907 : case Kind::Stmt:
163 907 : 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 11669 : Attribute::as_string () const
254 : {
255 11669 : std::string path_str = path.as_string ();
256 11669 : if (attr_input == nullptr)
257 4757 : return path_str;
258 : else
259 6912 : return path_str + attr_input->as_string ();
260 11669 : }
261 :
262 : void
263 0 : Attribute::accept_vis (ASTVisitor &vis)
264 : {
265 0 : vis.visit (*this);
266 0 : }
267 :
268 : bool
269 84675 : Attribute::is_derive () const
270 : {
271 153722 : 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 129898 : Attribute::Attribute (Attribute const &other)
356 129898 : : path (other.path), locus (other.locus),
357 129898 : inner_attribute (other.inner_attribute)
358 : {
359 : // guard to protect from null pointer dereference
360 129898 : if (other.attr_input != nullptr)
361 109915 : attr_input = other.attr_input->clone_attr_input ();
362 129898 : }
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 4795 : DelimTokenTree::as_string () const
382 : {
383 4795 : std::string start_delim;
384 4795 : std::string end_delim;
385 4795 : switch (delim_type)
386 : {
387 4795 : case PARENS:
388 4795 : start_delim = "(";
389 4795 : end_delim = ")";
390 4795 : 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 9590 : std::string str = start_delim;
405 4795 : if (!token_trees.empty ())
406 : {
407 19372 : for (const auto &tree : token_trees)
408 : {
409 : // DEBUG: null pointer check
410 14577 : 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 29154 : str += tree->as_string ();
419 : }
420 : }
421 4795 : str += end_delim;
422 :
423 4795 : return str;
424 4795 : }
425 :
426 : std::string
427 148068 : Token::as_string () const
428 : {
429 148068 : if (tok_ref->should_have_str ())
430 : {
431 42799 : std::string str = tok_ref->get_str ();
432 :
433 84782 : std::string quote = is_string_lit () ? "\"" : "";
434 42799 : return quote + str + quote;
435 42799 : }
436 : else
437 : {
438 105269 : return tok_ref->get_token_description ();
439 : }
440 : }
441 :
442 : std::string
443 690896 : SimplePathSegment::as_string () const
444 : {
445 690896 : return segment_name;
446 : }
447 :
448 : const std::string
449 205567 : SimplePath::as_string () const
450 : {
451 205567 : std::string path;
452 205567 : if (opening_scope_resolution)
453 0 : path = "::";
454 :
455 : // crappy hack because doing proper for loop would be more code
456 205567 : bool first_time = true;
457 411185 : for (const auto &segment : segments)
458 : {
459 205618 : if (first_time)
460 : {
461 411134 : path += segment.as_string ();
462 205567 : first_time = false;
463 : }
464 : else
465 : {
466 102 : path += "::" + segment.as_string ();
467 : }
468 :
469 : // DEBUG: remove later. Checks for path error.
470 205618 : 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 205567 : 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 44818 : Function::Function (Function const &other)
1106 44818 : : VisItem (other), ExternalItem (other.get_node_id ()),
1107 44818 : qualifiers (other.qualifiers), function_name (other.function_name),
1108 44818 : where_clause (other.where_clause), locus (other.locus),
1109 89636 : is_external_function (other.is_external_function)
1110 : {
1111 : // guard to prevent null dereference (always required)
1112 44818 : if (other.return_type != nullptr)
1113 36578 : return_type = other.return_type->clone_type ();
1114 :
1115 : // guard to prevent null dereference (only required if error state)
1116 44818 : if (other.has_body ())
1117 34931 : function_body = other.function_body.value ()->clone_block_expr ();
1118 : else
1119 9887 : function_body = tl::nullopt;
1120 :
1121 44818 : generic_params.reserve (other.generic_params.size ());
1122 48742 : for (const auto &e : other.generic_params)
1123 3924 : generic_params.push_back (e->clone_generic_param ());
1124 :
1125 44818 : function_params.reserve (other.function_params.size ());
1126 103250 : for (const auto &e : other.function_params)
1127 58432 : function_params.push_back (e->clone_param ());
1128 44818 : }
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 84 : BoxExpr::accept_vis (ASTVisitor &vis)
1658 : {
1659 84 : vis.visit (*this);
1660 84 : }
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 241011 : FunctionParam::accept_vis (ASTVisitor &vis)
2362 : {
2363 241011 : vis.visit (*this);
2364 241011 : }
2365 :
2366 : void
2367 183829 : SelfParam::accept_vis (ASTVisitor &vis)
2368 : {
2369 183829 : vis.visit (*this);
2370 183829 : }
2371 :
2372 : void
2373 15865 : VariadicParam::accept_vis (ASTVisitor &vis)
2374 : {
2375 15865 : vis.visit (*this);
2376 15865 : }
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 83 : Lifetime::as_string () const
2552 : {
2553 83 : switch (lifetime_type)
2554 : {
2555 83 : case NAMED:
2556 83 : 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 13091 : 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 2116 : AttrInputMetaItemContainer::as_string () const
3338 : {
3339 2116 : std::string str = "(";
3340 :
3341 2116 : auto i = items.begin ();
3342 2116 : auto e = items.end ();
3343 :
3344 4232 : for (; i != e; i++)
3345 : {
3346 4232 : str += (*i)->as_string ();
3347 2116 : if (e != i + 1)
3348 1 : str += ", ";
3349 : }
3350 :
3351 2116 : return str + ")";
3352 2116 : }
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 1003 : Attribute::parse_attr_to_meta_item ()
3564 : {
3565 : // only parse if has attribute input and not already parsed
3566 1003 : if (!has_attr_input () || is_parsed_to_meta_item ())
3567 338 : return;
3568 :
3569 665 : auto res = attr_input->parse_to_meta_item ();
3570 665 : std::unique_ptr<AttrInput> converted_input (res);
3571 :
3572 665 : if (converted_input != nullptr)
3573 665 : attr_input = std::move (converted_input);
3574 665 : }
3575 :
3576 : AttrInputMetaItemContainer *
3577 10393 : DelimTokenTree::parse_to_meta_item () const
3578 : {
3579 : // must have token trees
3580 10393 : 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 10393 : std::vector<std::unique_ptr<Token>> token_stream_wrapped = to_token_stream ();
3586 :
3587 10393 : std::vector<const_TokenPtr> token_stream;
3588 10393 : token_stream.reserve (token_stream_wrapped.size ());
3589 52069 : for (auto &tk : token_stream_wrapped)
3590 83352 : token_stream.push_back (tk->get_tok_ptr ());
3591 :
3592 10393 : AttributeParser parser (std::move (token_stream));
3593 10393 : std::vector<std::unique_ptr<MetaItemInner>> meta_items (
3594 10393 : parser.parse_meta_item_seq ());
3595 :
3596 10393 : return new AttrInputMetaItemContainer (std::move (meta_items));
3597 10393 : }
3598 :
3599 10393 : AttributeParser::AttributeParser (std::vector<const_TokenPtr> token_stream,
3600 10393 : int stream_start_pos)
3601 10393 : : lexer (new MacroInvocLexer (std::move (token_stream))),
3602 10393 : parser (new Parser<MacroInvocLexer> (*lexer))
3603 : {
3604 10393 : if (stream_start_pos)
3605 0 : lexer->skip_token (stream_start_pos - 1);
3606 10393 : }
3607 :
3608 10393 : AttributeParser::~AttributeParser () {}
3609 :
3610 : std::unique_ptr<MetaItemInner>
3611 11958 : AttributeParser::parse_meta_item_inner ()
3612 : {
3613 : // if first tok not identifier, not a "special" case one
3614 23916 : 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 C_STRING_LITERAL:
3624 28 : case INT_LITERAL:
3625 28 : case FLOAT_LITERAL:
3626 28 : case TRUE_LITERAL:
3627 28 : case FALSE_LITERAL:
3628 28 : return parse_meta_item_lit ();
3629 :
3630 0 : case SUPER:
3631 0 : case SELF:
3632 0 : case CRATE:
3633 0 : case DOLLAR_SIGN:
3634 0 : case SCOPE_RESOLUTION:
3635 0 : return parse_path_meta_item ();
3636 :
3637 0 : default:
3638 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3639 : "unrecognised token '%s' in meta item",
3640 : get_token_description (
3641 0 : lexer->peek_token ()->get_id ()));
3642 0 : return nullptr;
3643 : }
3644 : }
3645 :
3646 : // else, check for path
3647 23860 : if (lexer->peek_token (1)->get_id () == SCOPE_RESOLUTION)
3648 : {
3649 : // path
3650 0 : return parse_path_meta_item ();
3651 : }
3652 :
3653 23860 : auto ident = lexer->peek_token ()->get_str ();
3654 11930 : auto ident_locus = lexer->peek_token ()->get_locus ();
3655 :
3656 23860 : if (is_end_meta_item_tok (lexer->peek_token (1)->get_id ()))
3657 : {
3658 : // meta word syntax
3659 8198 : lexer->skip_token ();
3660 24594 : return std::unique_ptr<MetaWord> (new MetaWord (ident, ident_locus));
3661 : }
3662 :
3663 7464 : if (lexer->peek_token (1)->get_id () == EQUAL)
3664 : {
3665 : // maybe meta name value str syntax - check next 2 tokens
3666 7238 : if (lexer->peek_token (2)->get_id () == STRING_LITERAL
3667 7236 : && is_end_meta_item_tok (lexer->peek_token (3)->get_id ()))
3668 : {
3669 : // meta name value str syntax
3670 3617 : const_TokenPtr value_tok = lexer->peek_token (2);
3671 3617 : auto value = value_tok->get_str ();
3672 3617 : auto locus = value_tok->get_locus ();
3673 :
3674 3617 : lexer->skip_token (2);
3675 :
3676 3617 : return std::unique_ptr<MetaNameValueStr> (
3677 7234 : new MetaNameValueStr (ident, ident_locus, std::move (value),
3678 10851 : locus));
3679 7234 : }
3680 : else
3681 : {
3682 : // just interpret as path-based meta item
3683 2 : return parse_path_meta_item ();
3684 : }
3685 : }
3686 :
3687 226 : if (lexer->peek_token (1)->get_id () != LEFT_PAREN)
3688 : {
3689 0 : rust_error_at (lexer->peek_token (1)->get_locus (),
3690 : "unexpected token '%s' after identifier in attribute",
3691 0 : get_token_description (lexer->peek_token (1)->get_id ()));
3692 0 : return nullptr;
3693 : }
3694 :
3695 : // is it one of those special cases like not?
3696 226 : if (lexer->peek_token ()->get_id () == IDENTIFIER)
3697 : {
3698 113 : return parse_path_meta_item ();
3699 : }
3700 :
3701 0 : auto meta_items = parse_meta_item_seq ();
3702 :
3703 : // pass for meta name value str
3704 0 : std::vector<MetaNameValueStr> meta_name_value_str_items;
3705 0 : for (const auto &item : meta_items)
3706 : {
3707 0 : std::unique_ptr<MetaNameValueStr> converted_item
3708 0 : = item->to_meta_name_value_str ();
3709 0 : if (converted_item == nullptr)
3710 : {
3711 0 : meta_name_value_str_items.clear ();
3712 0 : break;
3713 : }
3714 0 : meta_name_value_str_items.push_back (std::move (*converted_item));
3715 0 : }
3716 : // if valid, return this
3717 0 : if (!meta_name_value_str_items.empty ())
3718 : {
3719 0 : return std::unique_ptr<MetaListNameValueStr> (
3720 0 : new MetaListNameValueStr (ident, ident_locus,
3721 0 : std::move (meta_name_value_str_items)));
3722 : }
3723 :
3724 : // // pass for meta list idents
3725 : // std::vector<Identifier> ident_items;
3726 : // for (const auto &item : meta_items)
3727 : // {
3728 : // std::unique_ptr<Identifier> converted_ident (item->to_ident_item ());
3729 : // if (converted_ident == nullptr)
3730 : // {
3731 : // ident_items.clear ();
3732 : // break;
3733 : // }
3734 : // ident_items.push_back (std::move (*converted_ident));
3735 : // }
3736 : // // if valid return this
3737 : // if (!ident_items.empty ())
3738 : // {
3739 : // return std::unique_ptr<MetaListIdents> (
3740 : // new MetaListIdents (std::move (ident), std::move (ident_items)));
3741 : // }
3742 : // // as currently no meta list ident, currently no path. may change in future
3743 :
3744 : // pass for meta list paths
3745 0 : std::vector<SimplePath> path_items;
3746 0 : for (const auto &item : meta_items)
3747 : {
3748 0 : SimplePath converted_path (item->to_path_item ());
3749 0 : if (converted_path.is_empty ())
3750 : {
3751 0 : path_items.clear ();
3752 0 : break;
3753 : }
3754 0 : path_items.push_back (std::move (converted_path));
3755 0 : }
3756 0 : if (!path_items.empty ())
3757 : {
3758 0 : return std::unique_ptr<MetaListPaths> (
3759 0 : new MetaListPaths (ident, ident_locus, std::move (path_items)));
3760 : }
3761 :
3762 0 : rust_error_at (UNKNOWN_LOCATION, "failed to parse any meta item inner");
3763 0 : return nullptr;
3764 11930 : }
3765 :
3766 : bool
3767 15547 : AttributeParser::is_end_meta_item_tok (TokenId id) const
3768 : {
3769 15547 : return id == COMMA || id == RIGHT_PAREN;
3770 : }
3771 :
3772 : std::unique_ptr<MetaItem>
3773 115 : AttributeParser::parse_path_meta_item ()
3774 : {
3775 115 : auto path = parser->parse_simple_path ();
3776 115 : if (!path)
3777 : {
3778 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3779 : "failed to parse simple path in attribute");
3780 0 : return nullptr;
3781 : }
3782 :
3783 230 : switch (lexer->peek_token ()->get_id ())
3784 : {
3785 113 : case LEFT_PAREN:
3786 113 : {
3787 113 : std::vector<std::unique_ptr<MetaItemInner>> meta_items
3788 113 : = parse_meta_item_seq ();
3789 :
3790 113 : return std::unique_ptr<MetaItemSeq> (
3791 226 : new MetaItemSeq (std::move (path.value ()), std::move (meta_items)));
3792 113 : }
3793 2 : case EQUAL:
3794 2 : {
3795 2 : lexer->skip_token ();
3796 :
3797 2 : auto expr = parser->parse_expr ();
3798 :
3799 : // handle error
3800 : // parse_expr should already emit an error and return nullptr
3801 2 : if (!expr)
3802 0 : return nullptr;
3803 :
3804 2 : return std::unique_ptr<MetaItemPathExpr> (
3805 2 : new MetaItemPathExpr (std::move (path.value ()),
3806 4 : std::move (expr.value ())));
3807 2 : }
3808 0 : case COMMA:
3809 : // just simple path
3810 0 : return std::unique_ptr<MetaItemPath> (
3811 0 : new MetaItemPath (std::move (path.value ())));
3812 0 : default:
3813 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3814 : "unrecognised token '%s' in meta item",
3815 0 : get_token_description (lexer->peek_token ()->get_id ()));
3816 0 : return nullptr;
3817 : }
3818 115 : }
3819 :
3820 : /* Parses a parenthesised sequence of meta item inners. Parentheses are
3821 : * required here. */
3822 : std::vector<std::unique_ptr<MetaItemInner>>
3823 10506 : AttributeParser::parse_meta_item_seq ()
3824 : {
3825 10506 : std::vector<std::unique_ptr<MetaItemInner>> meta_items;
3826 :
3827 21012 : if (lexer->peek_token ()->get_id () != LEFT_PAREN)
3828 : {
3829 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3830 : "missing left paren in delim token tree");
3831 0 : return {};
3832 : }
3833 10506 : lexer->skip_token ();
3834 :
3835 10506 : while (lexer->peek_token ()->get_id () != END_OF_FILE
3836 35898 : && lexer->peek_token ()->get_id () != RIGHT_PAREN)
3837 : {
3838 11958 : std::unique_ptr<MetaItemInner> inner = parse_meta_item_inner ();
3839 11958 : if (inner == nullptr)
3840 : {
3841 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3842 : "failed to parse inner meta item in attribute");
3843 0 : return {};
3844 : }
3845 11958 : meta_items.push_back (std::move (inner));
3846 :
3847 23916 : if (lexer->peek_token ()->get_id () != COMMA)
3848 : break;
3849 :
3850 1460 : lexer->skip_token ();
3851 11958 : }
3852 :
3853 21012 : if (lexer->peek_token ()->get_id () != RIGHT_PAREN)
3854 : {
3855 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3856 : "missing right paren in delim token tree");
3857 0 : return {};
3858 : }
3859 10506 : lexer->skip_token ();
3860 :
3861 10506 : return meta_items;
3862 10506 : }
3863 :
3864 : /* Collects any nested token trees into a flat token stream, suitable for
3865 : * parsing. */
3866 : std::vector<std::unique_ptr<Token>>
3867 27816 : DelimTokenTree::to_token_stream () const
3868 : {
3869 27816 : std::vector<std::unique_ptr<Token>> tokens;
3870 191620 : for (const auto &tree : token_trees)
3871 : {
3872 163804 : std::vector<std::unique_ptr<Token>> stream = tree->to_token_stream ();
3873 :
3874 163804 : tokens.insert (tokens.end (), std::make_move_iterator (stream.begin ()),
3875 : std::make_move_iterator (stream.end ()));
3876 163804 : }
3877 :
3878 27816 : tokens.shrink_to_fit ();
3879 27816 : return tokens;
3880 : }
3881 :
3882 : std::unique_ptr<MetaItemLitExpr>
3883 28 : AttributeParser::parse_meta_item_lit ()
3884 : {
3885 28 : auto lit_expr = parser->parse_literal_expr ({});
3886 :
3887 : // TODO: return nullptr instead?
3888 28 : if (!lit_expr)
3889 0 : lit_expr = std::unique_ptr<LiteralExpr> (
3890 0 : new LiteralExpr (Literal::create_error (), {},
3891 0 : lexer->peek_token ()->get_locus ()));
3892 :
3893 28 : return std::unique_ptr<MetaItemLitExpr> (
3894 28 : new MetaItemLitExpr (std::move (*lit_expr.value ())));
3895 28 : }
3896 :
3897 : bool
3898 0 : AttrInputMetaItemContainer::check_cfg_predicate (const Session &session) const
3899 : {
3900 0 : if (items.empty ())
3901 : return false;
3902 :
3903 0 : for (const auto &inner_item : items)
3904 : {
3905 0 : if (!inner_item->check_cfg_predicate (session))
3906 0 : return false;
3907 : }
3908 :
3909 : return true;
3910 : }
3911 :
3912 : bool
3913 1 : MetaItemLitExpr::check_cfg_predicate (const Session &) const
3914 : {
3915 : /* as far as I can tell, a literal expr can never be a valid cfg body, so
3916 : * false */
3917 1 : rust_error_at (this->get_locus (), "'%s' predicate key cannot be a literal",
3918 1 : this->as_string ().c_str ());
3919 :
3920 1 : return false;
3921 : }
3922 :
3923 : bool
3924 0 : MetaListNameValueStr::check_cfg_predicate (const Session &session) const
3925 : {
3926 0 : if (ident.as_string () == "all")
3927 : {
3928 0 : for (const auto &str : strs)
3929 : {
3930 0 : if (!str.check_cfg_predicate (session))
3931 0 : return false;
3932 : }
3933 : return true;
3934 : }
3935 0 : else if (ident.as_string () == "any")
3936 : {
3937 0 : for (const auto &str : strs)
3938 : {
3939 0 : if (str.check_cfg_predicate (session))
3940 0 : return true;
3941 : }
3942 : return false;
3943 : }
3944 0 : else if (ident.as_string () == "not")
3945 : {
3946 0 : if (strs.size () != 1)
3947 : {
3948 : /* HACK: convert vector platform-dependent size_type to string to
3949 : * use in printf */
3950 0 : rust_error_at (UNKNOWN_LOCATION,
3951 : "cfg predicate could not be checked for "
3952 : "MetaListNameValueStr with ident of "
3953 : "'not' because there are '%s' elements, not '1'",
3954 0 : std::to_string (strs.size ()).c_str ());
3955 0 : return false;
3956 : }
3957 :
3958 0 : return !strs[0].check_cfg_predicate (session);
3959 : }
3960 : else
3961 : {
3962 0 : rust_error_at (UNKNOWN_LOCATION,
3963 : "cfg predicate could not be checked for "
3964 : "MetaListNameValueStr with ident of "
3965 : "'%s' - ident must be 'all' or 'any'",
3966 0 : ident.as_string ().c_str ());
3967 0 : return false;
3968 : }
3969 : }
3970 :
3971 : bool
3972 0 : MetaListPaths::check_cfg_predicate (const Session &session) const
3973 : {
3974 0 : if (ident.as_string () == "all")
3975 : {
3976 0 : for (const auto &path : paths)
3977 : {
3978 0 : if (!check_path_exists_in_cfg (session, path))
3979 0 : return false;
3980 : }
3981 : return true;
3982 : }
3983 0 : else if (ident.as_string () == "any")
3984 : {
3985 0 : for (const auto &path : paths)
3986 : {
3987 0 : if (check_path_exists_in_cfg (session, path))
3988 0 : return true;
3989 : }
3990 : return false;
3991 : }
3992 0 : else if (ident.as_string () == "not")
3993 : {
3994 0 : if (paths.size () != 1)
3995 : {
3996 : // HACK: convert vector platform-dependent size_type to string to
3997 : // use in printf
3998 0 : rust_error_at (UNKNOWN_LOCATION,
3999 : "cfg predicate could not be checked for MetaListPaths "
4000 : "with ident of 'not' "
4001 : "because there are '%s' elements, not '1'",
4002 0 : std::to_string (paths.size ()).c_str ());
4003 0 : return false;
4004 : }
4005 :
4006 0 : return !check_path_exists_in_cfg (session, paths[0]);
4007 : }
4008 : else
4009 : {
4010 0 : rust_error_at (UNKNOWN_LOCATION,
4011 : "cfg predicate could not be checked for "
4012 : "MetaListNameValueStr with ident of "
4013 : "'%s' - ident must be 'all' or 'any'",
4014 0 : ident.as_string ().c_str ());
4015 0 : return false;
4016 : }
4017 : }
4018 :
4019 : bool
4020 0 : MetaListPaths::check_path_exists_in_cfg (const Session &session,
4021 : const SimplePath &path) const
4022 : {
4023 0 : return session.options.target_data.has_key (path.as_string ());
4024 : }
4025 :
4026 : bool
4027 119 : MetaItemSeq::check_cfg_predicate (const Session &session) const
4028 : {
4029 119 : if (path.as_string () == "all")
4030 : {
4031 19 : for (const auto &item : seq)
4032 : {
4033 15 : if (!item->check_cfg_predicate (session))
4034 13 : return false;
4035 : }
4036 : return true;
4037 : }
4038 108 : else if (path.as_string () == "any")
4039 : {
4040 32 : for (const auto &item : seq)
4041 : {
4042 26 : if (item->check_cfg_predicate (session))
4043 9 : return true;
4044 : }
4045 : return false;
4046 : }
4047 97 : else if (path.as_string () == "not")
4048 : {
4049 97 : if (seq.size () != 1)
4050 : {
4051 : /* HACK: convert vector platform-dependent size_type to string to
4052 : * use in printf */
4053 0 : rust_error_at (UNKNOWN_LOCATION,
4054 : "cfg predicate could not be checked for MetaItemSeq "
4055 : "with ident of 'not' "
4056 : "because there are '%s' elements, not '1'",
4057 0 : std::to_string (seq.size ()).c_str ());
4058 0 : return false;
4059 : }
4060 :
4061 97 : return !seq[0]->check_cfg_predicate (session);
4062 : }
4063 : else
4064 : {
4065 0 : rust_error_at (
4066 : UNKNOWN_LOCATION,
4067 : "cfg predicate could not be checked for MetaItemSeq with path of "
4068 : "'%s' - path must be 'all' or 'any'",
4069 0 : path.as_string ().c_str ());
4070 0 : return false;
4071 : }
4072 : }
4073 :
4074 : bool
4075 324 : MetaWord::check_cfg_predicate (const Session &session) const
4076 : {
4077 648 : return session.options.target_data.has_key (ident.as_string ());
4078 : }
4079 :
4080 : bool
4081 0 : MetaItemPath::check_cfg_predicate (const Session &session) const
4082 : {
4083 : /* Strictly speaking, this should always be false, but maybe do check
4084 : * relating to SimplePath being identifier. Currently, it would return true
4085 : * if path as identifier existed, and if the path in string form existed
4086 : * (though this shouldn't occur). */
4087 0 : return session.options.target_data.has_key (path.as_string ());
4088 : }
4089 :
4090 : bool
4091 1884 : MetaNameValueStr::check_cfg_predicate (const Session &session) const
4092 : {
4093 : // DEBUG
4094 5684 : rust_debug (
4095 : "checked key-value pair for cfg: '%s', '%s' - is%s in target data",
4096 : ident.as_string ().c_str (), str.c_str (),
4097 : session.options.target_data.has_key_value_pair (ident.as_string (), str)
4098 : ? ""
4099 : : " not");
4100 :
4101 3768 : return session.options.target_data.has_key_value_pair (ident.as_string (),
4102 1884 : str);
4103 : }
4104 :
4105 : bool
4106 0 : MetaItemPathExpr::check_cfg_predicate (const Session &session) const
4107 : {
4108 : // FIXME: Accept path expressions
4109 0 : rust_assert (expr->is_literal ());
4110 0 : return session.options.target_data.has_key_value_pair (path.as_string (),
4111 0 : expr->as_string ());
4112 : }
4113 :
4114 : std::vector<std::unique_ptr<Token>>
4115 155627 : Token::to_token_stream () const
4116 : {
4117 : /* initialisation list doesn't work as it needs copy constructor, so have to
4118 : * do this */
4119 155627 : std::vector<std::unique_ptr<Token>> dummy_vector;
4120 155627 : dummy_vector.reserve (1);
4121 155627 : dummy_vector.push_back (std::unique_ptr<Token> (clone_token_impl ()));
4122 155627 : return dummy_vector;
4123 : }
4124 :
4125 : Attribute
4126 0 : MetaNameValueStr::to_attribute () const
4127 : {
4128 0 : LiteralExpr lit_expr (str, Literal::LitType::STRING,
4129 0 : PrimitiveCoreType::CORETYPE_UNKNOWN, {}, str_locus);
4130 : // FIXME: What location do we put here? Is the literal above supposed to have
4131 : // an empty location as well?
4132 : // Should MetaNameValueStr keep a location?
4133 0 : return Attribute (SimplePath::from_str (ident.as_string (), ident_locus),
4134 0 : std::unique_ptr<AttrInputLiteral> (
4135 0 : new AttrInputLiteral (std::move (lit_expr))));
4136 0 : }
4137 :
4138 : Attribute
4139 0 : MetaItemPath::to_attribute () const
4140 : {
4141 0 : return Attribute (path, nullptr);
4142 : }
4143 :
4144 : Attribute
4145 8 : MetaItemSeq::to_attribute () const
4146 : {
4147 8 : std::vector<std::unique_ptr<MetaItemInner>> new_seq;
4148 8 : new_seq.reserve (seq.size ());
4149 16 : for (const auto &e : seq)
4150 8 : new_seq.push_back (e->clone_meta_item_inner ());
4151 :
4152 8 : std::unique_ptr<AttrInputMetaItemContainer> new_seq_container (
4153 8 : new AttrInputMetaItemContainer (std::move (new_seq)));
4154 8 : return Attribute (path, std::move (new_seq_container));
4155 8 : }
4156 :
4157 : Attribute
4158 0 : MetaWord::to_attribute () const
4159 : {
4160 0 : return Attribute (SimplePath::from_str (ident.as_string (), ident_locus),
4161 0 : nullptr);
4162 : }
4163 :
4164 : Attribute
4165 0 : MetaListPaths::to_attribute () const
4166 : {
4167 : /* probably one of the most annoying conversions - have to lose specificity by
4168 : * turning it into just AttrInputMetaItemContainer (i.e. paths-only nature is
4169 : * no longer known). If conversions back are required, might have to do a
4170 : * "check all are paths" pass or something. */
4171 :
4172 0 : std::vector<std::unique_ptr<MetaItemInner>> new_seq;
4173 0 : new_seq.reserve (paths.size ());
4174 0 : for (const auto &e : paths)
4175 0 : new_seq.push_back (std::unique_ptr<MetaItemPath> (new MetaItemPath (e)));
4176 :
4177 0 : std::unique_ptr<AttrInputMetaItemContainer> new_seq_container (
4178 0 : new AttrInputMetaItemContainer (std::move (new_seq)));
4179 0 : return Attribute (SimplePath::from_str (ident.as_string (), ident_locus),
4180 0 : std::move (new_seq_container));
4181 0 : }
4182 :
4183 : Attribute
4184 0 : MetaListNameValueStr::to_attribute () const
4185 : {
4186 0 : std::vector<std::unique_ptr<MetaItemInner>> new_seq;
4187 0 : new_seq.reserve (strs.size ());
4188 0 : for (const auto &e : strs)
4189 0 : new_seq.push_back (
4190 0 : std::unique_ptr<MetaNameValueStr> (new MetaNameValueStr (e)));
4191 :
4192 0 : std::unique_ptr<AttrInputMetaItemContainer> new_seq_container (
4193 0 : new AttrInputMetaItemContainer (std::move (new_seq)));
4194 0 : return Attribute (SimplePath::from_str (ident.as_string (), ident_locus),
4195 0 : std::move (new_seq_container));
4196 0 : }
4197 :
4198 : Attribute
4199 1 : MetaItemPathExpr::to_attribute () const
4200 : {
4201 1 : auto input = std::make_unique<AttrInputExpr> (expr->clone_expr ());
4202 1 : return Attribute (path, std::move (input));
4203 1 : }
4204 :
4205 : std::vector<Attribute>
4206 9 : AttrInputMetaItemContainer::separate_cfg_attrs () const
4207 : {
4208 9 : rust_assert (!items.empty ());
4209 :
4210 9 : if (items.size () == 1)
4211 0 : return {};
4212 :
4213 9 : std::vector<Attribute> attrs;
4214 9 : attrs.reserve (items.size () - 1);
4215 :
4216 18 : for (auto it = items.begin () + 1; it != items.end (); ++it)
4217 : {
4218 9 : auto &item = **it;
4219 :
4220 9 : Attribute attr = item.to_attribute ();
4221 9 : if (attr.is_empty ())
4222 : {
4223 : /* TODO should this be an error that causes us to chuck out
4224 : * everything? */
4225 0 : continue;
4226 : }
4227 9 : attrs.push_back (std::move (attr));
4228 9 : }
4229 :
4230 9 : attrs.shrink_to_fit ();
4231 9 : return attrs;
4232 9 : }
4233 :
4234 : bool
4235 2148 : Attribute::check_cfg_predicate (const Session &session) const
4236 : {
4237 2148 : auto string_path = path.as_string ();
4238 : /* assume that cfg predicate actually can exist, i.e. attribute has cfg or
4239 : * cfg_attr path */
4240 2148 : if (!has_attr_input ())
4241 : {
4242 1 : rust_error_at (path.get_locus (), "%qs is not followed by parentheses",
4243 : string_path.c_str ());
4244 1 : return false;
4245 : }
4246 :
4247 : // assume that it has already been parsed
4248 2147 : if (!is_parsed_to_meta_item ())
4249 : return false;
4250 :
4251 2147 : auto &meta_item = static_cast<AttrInputMetaItemContainer &> (*attr_input);
4252 2147 : if (meta_item.get_items ().empty ())
4253 : {
4254 3 : rust_error_at (path.get_locus (), "malformed %<%s%> attribute input",
4255 : string_path.c_str ());
4256 3 : return false;
4257 : }
4258 :
4259 2144 : if (string_path == Values::Attributes::CFG
4260 2144 : && meta_item.get_items ().size () != 1)
4261 : {
4262 1 : rust_error_at (path.get_locus (), "multiple %qs predicates are specified",
4263 1 : path.as_string ().c_str ());
4264 1 : return false;
4265 : }
4266 2143 : return meta_item.get_items ().front ()->check_cfg_predicate (session);
4267 2148 : }
4268 :
4269 : std::vector<Attribute>
4270 9 : Attribute::separate_cfg_attrs () const
4271 : {
4272 18 : if (!has_attr_input () || path.as_string () != Values::Attributes::CFG_ATTR)
4273 0 : return {};
4274 :
4275 : // assume that it has already been parsed
4276 9 : if (!is_parsed_to_meta_item ())
4277 0 : return {};
4278 :
4279 9 : return attr_input->separate_cfg_attrs ();
4280 : }
4281 :
4282 : bool
4283 7423 : Attribute::is_parsed_to_meta_item () const
4284 : {
4285 7423 : return has_attr_input () && attr_input->is_meta_item ();
4286 : }
4287 :
4288 : void
4289 38009 : BlockExpr::normalize_tail_expr ()
4290 : {
4291 38009 : if (!expr)
4292 : {
4293 : // HACK: try to turn the last statement into a tail expression
4294 21548 : if (!statements.empty () && statements.back ()->is_expr ())
4295 : {
4296 : // Watch out: This reference become invalid when the vector is
4297 : // modified.
4298 14408 : auto &stmt = static_cast<ExprStmt &> (*statements.back ());
4299 :
4300 14408 : if (!stmt.is_semicolon_followed ())
4301 : {
4302 59 : expr = stmt.take_expr ();
4303 59 : statements.pop_back ();
4304 : }
4305 : }
4306 : }
4307 38009 : }
4308 :
4309 : /* Visitor implementations - these are short but inlining can't happen anyway
4310 : * due to virtual functions and I didn't want to make the ast header includes
4311 : * any longer than they already are. */
4312 :
4313 : void
4314 1467674 : Token::accept_vis (ASTVisitor &vis)
4315 : {
4316 1467674 : vis.visit (*this);
4317 1467674 : }
4318 :
4319 : void
4320 281501 : DelimTokenTree::accept_vis (ASTVisitor &vis)
4321 : {
4322 281501 : vis.visit (*this);
4323 281501 : }
4324 :
4325 : void
4326 646035 : IdentifierExpr::accept_vis (ASTVisitor &vis)
4327 : {
4328 646035 : vis.visit (*this);
4329 646034 : }
4330 :
4331 : void
4332 240 : Lifetime::accept_vis (ASTVisitor &vis)
4333 : {
4334 240 : vis.visit (*this);
4335 240 : }
4336 :
4337 : void
4338 4835 : LifetimeParam::accept_vis (ASTVisitor &vis)
4339 : {
4340 4835 : vis.visit (*this);
4341 4835 : }
4342 :
4343 : void
4344 3111332 : LiteralExpr::accept_vis (ASTVisitor &vis)
4345 : {
4346 3111332 : vis.visit (*this);
4347 3111332 : }
4348 :
4349 : void
4350 256391 : AttrInputLiteral::accept_vis (ASTVisitor &vis)
4351 : {
4352 256391 : vis.visit (*this);
4353 256391 : }
4354 :
4355 : void
4356 0 : MetaItemLitExpr::accept_vis (ASTVisitor &vis)
4357 : {
4358 0 : vis.visit (*this);
4359 0 : }
4360 :
4361 : void
4362 2 : MetaItemPathExpr::accept_vis (ASTVisitor &vis)
4363 : {
4364 2 : vis.visit (*this);
4365 2 : }
4366 :
4367 : void
4368 54252 : BorrowExpr::accept_vis (ASTVisitor &vis)
4369 : {
4370 54252 : vis.visit (*this);
4371 54252 : }
4372 :
4373 : void
4374 96055 : DereferenceExpr::accept_vis (ASTVisitor &vis)
4375 : {
4376 96055 : vis.visit (*this);
4377 96055 : }
4378 :
4379 : void
4380 13 : ErrorPropagationExpr::accept_vis (ASTVisitor &vis)
4381 : {
4382 13 : vis.visit (*this);
4383 13 : }
4384 :
4385 : void
4386 16504 : NegationExpr::accept_vis (ASTVisitor &vis)
4387 : {
4388 16504 : vis.visit (*this);
4389 16504 : }
4390 :
4391 : void
4392 2703738 : ArithmeticOrLogicalExpr::accept_vis (ASTVisitor &vis)
4393 : {
4394 2703738 : vis.visit (*this);
4395 2703738 : }
4396 :
4397 : void
4398 83566 : ComparisonExpr::accept_vis (ASTVisitor &vis)
4399 : {
4400 83566 : vis.visit (*this);
4401 83566 : }
4402 :
4403 : void
4404 8559 : LazyBooleanExpr::accept_vis (ASTVisitor &vis)
4405 : {
4406 8559 : vis.visit (*this);
4407 8559 : }
4408 :
4409 : void
4410 147466 : TypeCastExpr::accept_vis (ASTVisitor &vis)
4411 : {
4412 147466 : vis.visit (*this);
4413 147466 : }
4414 :
4415 : void
4416 56243 : AssignmentExpr::accept_vis (ASTVisitor &vis)
4417 : {
4418 56243 : vis.visit (*this);
4419 56243 : }
4420 :
4421 : void
4422 17351 : CompoundAssignmentExpr::accept_vis (ASTVisitor &vis)
4423 : {
4424 17351 : vis.visit (*this);
4425 17351 : }
4426 :
4427 : void
4428 6377 : ArrayElemsValues::accept_vis (ASTVisitor &vis)
4429 : {
4430 6377 : vis.visit (*this);
4431 6377 : }
4432 :
4433 : void
4434 2552 : ArrayElemsCopied::accept_vis (ASTVisitor &vis)
4435 : {
4436 2552 : vis.visit (*this);
4437 2552 : }
4438 :
4439 : void
4440 8944 : ArrayExpr::accept_vis (ASTVisitor &vis)
4441 : {
4442 8944 : vis.visit (*this);
4443 8944 : }
4444 :
4445 : void
4446 6483 : ArrayIndexExpr::accept_vis (ASTVisitor &vis)
4447 : {
4448 6483 : vis.visit (*this);
4449 6483 : }
4450 :
4451 : void
4452 12724 : TupleExpr::accept_vis (ASTVisitor &vis)
4453 : {
4454 12724 : vis.visit (*this);
4455 12724 : }
4456 :
4457 : void
4458 21450 : TupleIndexExpr::accept_vis (ASTVisitor &vis)
4459 : {
4460 21450 : vis.visit (*this);
4461 21450 : }
4462 :
4463 : void
4464 1725 : StructExprStruct::accept_vis (ASTVisitor &vis)
4465 : {
4466 1725 : vis.visit (*this);
4467 1725 : }
4468 :
4469 : void
4470 4338 : StructExprFieldIdentifier::accept_vis (ASTVisitor &vis)
4471 : {
4472 4338 : vis.visit (*this);
4473 4338 : }
4474 :
4475 : void
4476 46919 : StructExprFieldIdentifierValue::accept_vis (ASTVisitor &vis)
4477 : {
4478 46919 : vis.visit (*this);
4479 46919 : }
4480 :
4481 : void
4482 924 : StructExprFieldIndexValue::accept_vis (ASTVisitor &vis)
4483 : {
4484 924 : vis.visit (*this);
4485 924 : }
4486 :
4487 : void
4488 30416 : StructExprStructFields::accept_vis (ASTVisitor &vis)
4489 : {
4490 30416 : vis.visit (*this);
4491 30416 : }
4492 :
4493 : void
4494 0 : StructExprStructBase::accept_vis (ASTVisitor &vis)
4495 : {
4496 0 : vis.visit (*this);
4497 0 : }
4498 :
4499 : void
4500 309134 : CallExpr::accept_vis (ASTVisitor &vis)
4501 : {
4502 309134 : vis.visit (*this);
4503 309133 : }
4504 :
4505 : void
4506 72799 : MethodCallExpr::accept_vis (ASTVisitor &vis)
4507 : {
4508 72799 : vis.visit (*this);
4509 72799 : }
4510 :
4511 : void
4512 117223 : FieldAccessExpr::accept_vis (ASTVisitor &vis)
4513 : {
4514 117223 : vis.visit (*this);
4515 117223 : }
4516 :
4517 : void
4518 788 : ClosureExprInner::accept_vis (ASTVisitor &vis)
4519 : {
4520 788 : vis.visit (*this);
4521 788 : }
4522 :
4523 : void
4524 421447 : BlockExpr::accept_vis (ASTVisitor &vis)
4525 : {
4526 421447 : vis.visit (*this);
4527 421443 : }
4528 :
4529 : void
4530 689 : AnonConst::accept_vis (ASTVisitor &vis)
4531 : {
4532 689 : vis.visit (*this);
4533 689 : }
4534 :
4535 : void
4536 272 : ConstBlock::accept_vis (ASTVisitor &vis)
4537 : {
4538 272 : vis.visit (*this);
4539 272 : }
4540 :
4541 : void
4542 631 : ClosureExprInnerTyped::accept_vis (ASTVisitor &vis)
4543 : {
4544 631 : vis.visit (*this);
4545 631 : }
4546 :
4547 : void
4548 444 : ContinueExpr::accept_vis (ASTVisitor &vis)
4549 : {
4550 444 : vis.visit (*this);
4551 444 : }
4552 :
4553 : void
4554 2288 : BreakExpr::accept_vis (ASTVisitor &vis)
4555 : {
4556 2288 : vis.visit (*this);
4557 2287 : }
4558 :
4559 : void
4560 1659 : RangeFromToExpr::accept_vis (ASTVisitor &vis)
4561 : {
4562 1659 : vis.visit (*this);
4563 1659 : }
4564 :
4565 : void
4566 147 : RangeFromExpr::accept_vis (ASTVisitor &vis)
4567 : {
4568 147 : vis.visit (*this);
4569 147 : }
4570 :
4571 : void
4572 147 : RangeToExpr::accept_vis (ASTVisitor &vis)
4573 : {
4574 147 : vis.visit (*this);
4575 147 : }
4576 :
4577 : void
4578 0 : RangeFullExpr::accept_vis (ASTVisitor &vis)
4579 : {
4580 0 : vis.visit (*this);
4581 0 : }
4582 :
4583 : void
4584 147 : RangeFromToInclExpr::accept_vis (ASTVisitor &vis)
4585 : {
4586 147 : vis.visit (*this);
4587 147 : }
4588 :
4589 : void
4590 0 : RangeToInclExpr::accept_vis (ASTVisitor &vis)
4591 : {
4592 0 : vis.visit (*this);
4593 0 : }
4594 :
4595 : void
4596 12388 : ReturnExpr::accept_vis (ASTVisitor &vis)
4597 : {
4598 12388 : vis.visit (*this);
4599 12388 : }
4600 :
4601 : void
4602 13 : TryExpr::accept_vis (ASTVisitor &vis)
4603 : {
4604 13 : vis.visit (*this);
4605 13 : }
4606 :
4607 : void
4608 84053 : UnsafeBlockExpr::accept_vis (ASTVisitor &vis)
4609 : {
4610 84053 : vis.visit (*this);
4611 84053 : }
4612 :
4613 : void
4614 2740 : LoopExpr::accept_vis (ASTVisitor &vis)
4615 : {
4616 2740 : vis.visit (*this);
4617 2739 : }
4618 :
4619 : void
4620 2175 : WhileLoopExpr::accept_vis (ASTVisitor &vis)
4621 : {
4622 2175 : vis.visit (*this);
4623 2175 : }
4624 :
4625 : void
4626 36 : WhileLetLoopExpr::accept_vis (ASTVisitor &vis)
4627 : {
4628 36 : vis.visit (*this);
4629 36 : }
4630 :
4631 : void
4632 404 : ForLoopExpr::accept_vis (ASTVisitor &vis)
4633 : {
4634 404 : vis.visit (*this);
4635 404 : }
4636 :
4637 : void
4638 28984 : IfExpr::accept_vis (ASTVisitor &vis)
4639 : {
4640 28984 : vis.visit (*this);
4641 28984 : }
4642 :
4643 : void
4644 32209 : IfExprConseqElse::accept_vis (ASTVisitor &vis)
4645 : {
4646 32209 : vis.visit (*this);
4647 32209 : }
4648 :
4649 : void
4650 395 : IfLetExpr::accept_vis (ASTVisitor &vis)
4651 : {
4652 395 : vis.visit (*this);
4653 395 : }
4654 :
4655 : void
4656 257 : IfLetExprConseqElse::accept_vis (ASTVisitor &vis)
4657 : {
4658 257 : vis.visit (*this);
4659 257 : }
4660 :
4661 : void
4662 25524 : MatchExpr::accept_vis (ASTVisitor &vis)
4663 : {
4664 25524 : vis.visit (*this);
4665 25522 : }
4666 :
4667 : void
4668 0 : AwaitExpr::accept_vis (ASTVisitor &vis)
4669 : {
4670 0 : vis.visit (*this);
4671 0 : }
4672 :
4673 : void
4674 0 : AsyncBlockExpr::accept_vis (ASTVisitor &vis)
4675 : {
4676 0 : vis.visit (*this);
4677 0 : }
4678 :
4679 : void
4680 426 : InlineAsm::accept_vis (ASTVisitor &vis)
4681 : {
4682 426 : vis.visit (*this);
4683 426 : }
4684 :
4685 : void
4686 34 : LlvmInlineAsm::accept_vis (ASTVisitor &vis)
4687 : {
4688 34 : vis.visit (*this);
4689 34 : }
4690 :
4691 : void
4692 107515 : TypeParam::accept_vis (ASTVisitor &vis)
4693 : {
4694 107515 : vis.visit (*this);
4695 107515 : }
4696 :
4697 : void
4698 38 : LifetimeWhereClauseItem::accept_vis (ASTVisitor &vis)
4699 : {
4700 38 : vis.visit (*this);
4701 38 : }
4702 :
4703 : void
4704 7274 : TypeBoundWhereClauseItem::accept_vis (ASTVisitor &vis)
4705 : {
4706 7274 : vis.visit (*this);
4707 7274 : }
4708 :
4709 : void
4710 30643 : Module::accept_vis (ASTVisitor &vis)
4711 : {
4712 30643 : vis.visit (*this);
4713 30643 : }
4714 :
4715 : void
4716 559 : ExternCrate::accept_vis (ASTVisitor &vis)
4717 : {
4718 559 : vis.visit (*this);
4719 559 : }
4720 :
4721 : void
4722 178 : UseTreeGlob::accept_vis (ASTVisitor &vis)
4723 : {
4724 178 : vis.visit (*this);
4725 178 : }
4726 :
4727 : void
4728 2173 : UseTreeList::accept_vis (ASTVisitor &vis)
4729 : {
4730 2173 : vis.visit (*this);
4731 2173 : }
4732 :
4733 : void
4734 6886 : UseTreeRebind::accept_vis (ASTVisitor &vis)
4735 : {
4736 6886 : vis.visit (*this);
4737 6886 : }
4738 :
4739 : void
4740 16900 : UseDeclaration::accept_vis (ASTVisitor &vis)
4741 : {
4742 16900 : vis.visit (*this);
4743 16900 : }
4744 :
4745 : void
4746 451487 : Function::accept_vis (ASTVisitor &vis)
4747 : {
4748 451487 : vis.visit (*this);
4749 451485 : }
4750 :
4751 : void
4752 32509 : TypeAlias::accept_vis (ASTVisitor &vis)
4753 : {
4754 32509 : vis.visit (*this);
4755 32509 : }
4756 :
4757 : void
4758 37123 : StructStruct::accept_vis (ASTVisitor &vis)
4759 : {
4760 37123 : vis.visit (*this);
4761 37123 : }
4762 :
4763 : void
4764 21601 : TupleStruct::accept_vis (ASTVisitor &vis)
4765 : {
4766 21601 : vis.visit (*this);
4767 21601 : }
4768 :
4769 : void
4770 11023 : EnumItem::accept_vis (ASTVisitor &vis)
4771 : {
4772 11023 : vis.visit (*this);
4773 11023 : }
4774 :
4775 : void
4776 11152 : EnumItemTuple::accept_vis (ASTVisitor &vis)
4777 : {
4778 11152 : vis.visit (*this);
4779 11152 : }
4780 :
4781 : void
4782 2215 : EnumItemStruct::accept_vis (ASTVisitor &vis)
4783 : {
4784 2215 : vis.visit (*this);
4785 2215 : }
4786 :
4787 : void
4788 6994 : EnumItemDiscriminant::accept_vis (ASTVisitor &vis)
4789 : {
4790 6994 : vis.visit (*this);
4791 6994 : }
4792 :
4793 : void
4794 12817 : Enum::accept_vis (ASTVisitor &vis)
4795 : {
4796 12817 : vis.visit (*this);
4797 12817 : }
4798 :
4799 : void
4800 2348 : Union::accept_vis (ASTVisitor &vis)
4801 : {
4802 2348 : vis.visit (*this);
4803 2348 : }
4804 :
4805 : void
4806 12769 : ConstantItem::accept_vis (ASTVisitor &vis)
4807 : {
4808 12769 : vis.visit (*this);
4809 12769 : }
4810 :
4811 : void
4812 1298 : StaticItem::accept_vis (ASTVisitor &vis)
4813 : {
4814 1298 : vis.visit (*this);
4815 1298 : }
4816 :
4817 : void
4818 19694 : TraitItemType::accept_vis (ASTVisitor &vis)
4819 : {
4820 19694 : vis.visit (*this);
4821 19694 : }
4822 :
4823 : void
4824 91676 : Trait::accept_vis (ASTVisitor &vis)
4825 : {
4826 91676 : vis.visit (*this);
4827 91676 : }
4828 :
4829 : void
4830 21752 : InherentImpl::accept_vis (ASTVisitor &vis)
4831 : {
4832 21752 : vis.visit (*this);
4833 21752 : }
4834 :
4835 : void
4836 104208 : TraitImpl::accept_vis (ASTVisitor &vis)
4837 : {
4838 104208 : vis.visit (*this);
4839 104208 : }
4840 :
4841 : void
4842 19 : ExternalTypeItem::accept_vis (ASTVisitor &vis)
4843 : {
4844 19 : vis.visit (*this);
4845 19 : }
4846 :
4847 : void
4848 20 : ExternalStaticItem::accept_vis (ASTVisitor &vis)
4849 : {
4850 20 : vis.visit (*this);
4851 20 : }
4852 :
4853 : void
4854 37254 : ExternBlock::accept_vis (ASTVisitor &vis)
4855 : {
4856 37254 : vis.visit (*this);
4857 37254 : }
4858 :
4859 : void
4860 19395 : MacroMatchFragment::accept_vis (ASTVisitor &vis)
4861 : {
4862 19395 : vis.visit (*this);
4863 19395 : }
4864 :
4865 : void
4866 9084 : MacroMatchRepetition::accept_vis (ASTVisitor &vis)
4867 : {
4868 9084 : vis.visit (*this);
4869 9084 : }
4870 :
4871 : void
4872 849 : MacroMatcher::accept_vis (ASTVisitor &vis)
4873 : {
4874 849 : vis.visit (*this);
4875 849 : }
4876 :
4877 : void
4878 29595 : MacroRulesDefinition::accept_vis (ASTVisitor &vis)
4879 : {
4880 29595 : vis.visit (*this);
4881 29595 : }
4882 :
4883 : void
4884 18326 : MacroInvocation::accept_vis (ASTVisitor &vis)
4885 : {
4886 18326 : vis.visit (*this);
4887 18326 : }
4888 :
4889 : void
4890 1384 : EmptyStmt::accept_vis (ASTVisitor &vis)
4891 : {
4892 1384 : vis.visit (*this);
4893 1384 : }
4894 :
4895 : void
4896 313807 : LetStmt::accept_vis (ASTVisitor &vis)
4897 : {
4898 313807 : vis.visit (*this);
4899 313806 : }
4900 :
4901 : void
4902 267049 : ExprStmt::accept_vis (ASTVisitor &vis)
4903 : {
4904 267049 : vis.visit (*this);
4905 267047 : }
4906 :
4907 : void
4908 44310 : TraitBound::accept_vis (ASTVisitor &vis)
4909 : {
4910 44310 : vis.visit (*this);
4911 44310 : }
4912 :
4913 : void
4914 0 : ImplTraitType::accept_vis (ASTVisitor &vis)
4915 : {
4916 0 : vis.visit (*this);
4917 0 : }
4918 :
4919 : void
4920 266 : TraitObjectType::accept_vis (ASTVisitor &vis)
4921 : {
4922 266 : vis.visit (*this);
4923 266 : }
4924 :
4925 : void
4926 161 : ParenthesisedType::accept_vis (ASTVisitor &vis)
4927 : {
4928 161 : vis.visit (*this);
4929 161 : }
4930 :
4931 : void
4932 2144 : ImplTraitTypeOneBound::accept_vis (ASTVisitor &vis)
4933 : {
4934 2144 : vis.visit (*this);
4935 2144 : }
4936 :
4937 : void
4938 4470 : TraitObjectTypeOneBound::accept_vis (ASTVisitor &vis)
4939 : {
4940 4470 : vis.visit (*this);
4941 4470 : }
4942 :
4943 : void
4944 9718 : TupleType::accept_vis (ASTVisitor &vis)
4945 : {
4946 9718 : vis.visit (*this);
4947 9718 : }
4948 :
4949 : void
4950 3966 : NeverType::accept_vis (ASTVisitor &vis)
4951 : {
4952 3966 : vis.visit (*this);
4953 3966 : }
4954 :
4955 : void
4956 172694 : RawPointerType::accept_vis (ASTVisitor &vis)
4957 : {
4958 172694 : vis.visit (*this);
4959 172694 : }
4960 :
4961 : void
4962 120495 : ReferenceType::accept_vis (ASTVisitor &vis)
4963 : {
4964 120495 : vis.visit (*this);
4965 120495 : }
4966 :
4967 : void
4968 17603 : ArrayType::accept_vis (ASTVisitor &vis)
4969 : {
4970 17603 : vis.visit (*this);
4971 17603 : }
4972 :
4973 : void
4974 20111 : SliceType::accept_vis (ASTVisitor &vis)
4975 : {
4976 20111 : vis.visit (*this);
4977 20111 : }
4978 :
4979 : void
4980 6207 : InferredType::accept_vis (ASTVisitor &vis)
4981 : {
4982 6207 : vis.visit (*this);
4983 6207 : }
4984 :
4985 : void
4986 1439 : BareFunctionType::accept_vis (ASTVisitor &vis)
4987 : {
4988 1439 : vis.visit (*this);
4989 1439 : }
4990 :
4991 : void
4992 255 : MetaItemSeq::accept_vis (ASTVisitor &vis)
4993 : {
4994 255 : vis.visit (*this);
4995 255 : }
4996 :
4997 : void
4998 626 : MetaItemPath::accept_vis (ASTVisitor &vis)
4999 : {
5000 626 : vis.visit (*this);
5001 626 : }
5002 :
5003 : void
5004 0 : MetaListPaths::accept_vis (ASTVisitor &vis)
5005 : {
5006 0 : vis.visit (*this);
5007 0 : }
5008 :
5009 : void
5010 6686 : MetaNameValueStr::accept_vis (ASTVisitor &vis)
5011 : {
5012 6686 : vis.visit (*this);
5013 6686 : }
5014 :
5015 : void
5016 0 : MetaListNameValueStr::accept_vis (ASTVisitor &vis)
5017 : {
5018 0 : vis.visit (*this);
5019 0 : }
5020 :
5021 : void
5022 8068 : AttrInputMetaItemContainer::accept_vis (ASTVisitor &vis)
5023 : {
5024 8068 : vis.visit (*this);
5025 8068 : }
5026 :
5027 : void
5028 1084 : MetaWord::accept_vis (ASTVisitor &vis)
5029 : {
5030 1084 : vis.visit (*this);
5031 1084 : }
5032 :
5033 : void
5034 0 : FormatArgs::accept_vis (ASTVisitor &vis)
5035 : {
5036 0 : vis.visit (*this);
5037 0 : }
5038 :
5039 : void
5040 215 : OffsetOf::accept_vis (ASTVisitor &vis)
5041 : {
5042 215 : vis.visit (*this);
5043 215 : }
5044 :
5045 : std::string
5046 0 : FormatArgs::as_string () const
5047 : {
5048 : // FIXME(Arthur): Improve
5049 0 : return "FormatArgs";
5050 : }
5051 :
5052 : std::string
5053 0 : OffsetOf::as_string () const
5054 : {
5055 0 : return "OffsetOf(" + type->as_string () + ", " + field.as_string () + ")";
5056 : }
5057 :
5058 : location_t
5059 3 : FormatArgs::get_locus () const
5060 : {
5061 3 : return loc;
5062 : }
5063 :
5064 : bool
5065 0 : FormatArgs::is_expr_without_block () const
5066 : {
5067 0 : return false;
5068 : }
5069 :
5070 : void
5071 0 : FormatArgs::mark_for_strip ()
5072 : {
5073 0 : marked_for_strip = true;
5074 0 : }
5075 :
5076 : bool
5077 0 : FormatArgs::is_marked_for_strip () const
5078 : {
5079 0 : return marked_for_strip;
5080 : }
5081 :
5082 : std::vector<Attribute> &
5083 0 : FormatArgs::get_outer_attrs ()
5084 : {
5085 0 : rust_unreachable ();
5086 : }
5087 :
5088 : void
5089 0 : FormatArgs::set_outer_attrs (std::vector<Attribute>)
5090 : {
5091 0 : rust_unreachable ();
5092 : }
5093 :
5094 : Expr *
5095 0 : FormatArgs::clone_expr_impl () const
5096 : {
5097 0 : std::cerr << "[ARTHUR] cloning FormatArgs! " << std::endl;
5098 :
5099 0 : return new FormatArgs (*this);
5100 : }
5101 :
5102 : std::vector<Attribute> &
5103 0 : OffsetOf::get_outer_attrs ()
5104 : {
5105 0 : rust_unreachable ();
5106 : }
5107 :
5108 : void
5109 0 : OffsetOf::set_outer_attrs (std::vector<Attribute>)
5110 : {
5111 0 : rust_unreachable ();
5112 : }
5113 :
5114 : Expr *
5115 96 : OffsetOf::clone_expr_impl () const
5116 : {
5117 96 : return new OffsetOf (*this);
5118 : }
5119 :
5120 : } // namespace AST
5121 :
5122 : std::ostream &
5123 0 : operator<< (std::ostream &os, Identifier const &i)
5124 : {
5125 0 : return os << i.as_string ();
5126 : }
5127 :
5128 : } // namespace Rust
|