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 348367 : SingleASTNode::SingleASTNode (SingleASTNode const &other)
47 : {
48 348367 : kind = other.kind;
49 348367 : switch (kind)
50 : {
51 287873 : case Kind::Expr:
52 287873 : expr = other.expr->clone_expr ();
53 287873 : break;
54 :
55 45511 : case Kind::Item:
56 45511 : item = other.item->clone_item ();
57 45511 : break;
58 :
59 3436 : case Kind::Stmt:
60 3436 : stmt = other.stmt->clone_stmt ();
61 3436 : break;
62 :
63 12 : case Kind::Extern:
64 12 : external_item = other.external_item->clone_external_item ();
65 12 : break;
66 :
67 9044 : case Kind::Assoc:
68 9044 : assoc_item = other.assoc_item->clone_associated_item ();
69 9044 : break;
70 :
71 2485 : case Kind::Type:
72 2485 : type = other.type->clone_type ();
73 2485 : break;
74 :
75 6 : case Kind::Pattern:
76 6 : pattern = other.pattern->clone_pattern ();
77 6 : break;
78 : }
79 348367 : }
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 174 : SingleASTNode::accept_vis (ASTVisitor &vis)
120 : {
121 174 : switch (kind)
122 : {
123 174 : case Kind::Expr:
124 174 : expr->accept_vis (vis);
125 174 : 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 174 : }
152 :
153 : bool
154 81908 : SingleASTNode::is_error ()
155 : {
156 81908 : switch (kind)
157 : {
158 52536 : case Kind::Expr:
159 52536 : return expr == nullptr;
160 22727 : case Kind::Item:
161 22727 : return item == nullptr;
162 1619 : case Kind::Stmt:
163 1619 : return stmt == nullptr;
164 6 : case Kind::Extern:
165 6 : return external_item == nullptr;
166 4522 : case Kind::Assoc:
167 4522 : return assoc_item == nullptr;
168 497 : case Kind::Type:
169 497 : 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 24628787 : Attribute::as_string () const
254 : {
255 24628787 : std::string path_str = path.as_string ();
256 24628787 : if (attr_input == nullptr)
257 710766 : return path_str;
258 : else
259 23918021 : return path_str + attr_input->as_string ();
260 24628787 : }
261 :
262 : void
263 0 : Attribute::accept_vis (ASTVisitor &vis)
264 : {
265 0 : vis.visit (*this);
266 0 : }
267 :
268 : bool
269 3810589 : Attribute::is_derive () const
270 : {
271 7201990 : 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 998 : Attribute::get_traits_to_derive ()
281 : {
282 998 : rust_assert (this->is_derive ());
283 :
284 998 : this->parse_attr_to_meta_item ();
285 998 : std::vector<std::reference_wrapper<AST::SimplePath>> result;
286 998 : auto &input = get_attr_input ();
287 998 : switch (input.get_attr_input_type ())
288 : {
289 998 : case AST::AttrInput::META_ITEM:
290 998 : {
291 998 : auto &meta = static_cast<AST::AttrInputMetaItemContainer &> (input);
292 3648 : for (auto ¤t : meta.get_items ())
293 : {
294 : // HACK: Find a better way to achieve the downcast.
295 2650 : switch (current->get_kind ())
296 : {
297 2650 : case AST::MetaItemInner::Kind::MetaItem:
298 2650 : {
299 : // Let raw pointer go out of scope without freeing, it doesn't
300 : // own the data anyway
301 2650 : auto meta_item
302 2650 : = static_cast<AST::MetaItem *> (current.get ());
303 2650 : switch (meta_item->get_item_kind ())
304 : {
305 1325 : case AST::MetaItem::ItemKind::Path:
306 1325 : {
307 1325 : auto path
308 : = static_cast<AST::MetaItemPath *> (meta_item);
309 1325 : result.push_back (path->get_path ());
310 : }
311 1325 : break;
312 1325 : case AST::MetaItem::ItemKind::Word:
313 1325 : {
314 1325 : auto word = static_cast<AST::MetaWord *> (meta_item);
315 : // Convert current word to path
316 1325 : current = std::make_unique<AST::MetaItemPath> (
317 2650 : AST::MetaItemPath (AST::SimplePath::from_str (
318 1325 : word->get_ident ().as_string (),
319 2650 : word->get_locus ())));
320 1325 : auto path
321 1325 : = static_cast<AST::MetaItemPath *> (current.get ());
322 :
323 1325 : result.push_back (path->get_path ());
324 : }
325 1325 : 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 2650 : break;
334 : }
335 : }
336 2650 : break;
337 0 : case AST::MetaItemInner::Kind::LitExpr:
338 0 : default:
339 0 : gcc_unreachable ();
340 2650 : 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 998 : break;
350 : }
351 998 : return result;
352 : }
353 :
354 : // Copy constructor must deep copy attr_input as unique pointer
355 1715388 : Attribute::Attribute (Attribute const &other)
356 1715388 : : path (other.path), locus (other.locus),
357 1715388 : inner_attribute (other.inner_attribute)
358 : {
359 : // guard to protect from null pointer dereference
360 1715388 : if (other.attr_input != nullptr)
361 1557477 : attr_input = other.attr_input->clone_attr_input ();
362 1715388 : }
363 :
364 : // overload assignment operator to use custom clone method
365 : Attribute &
366 83 : Attribute::operator= (Attribute const &other)
367 : {
368 83 : path = other.path;
369 83 : locus = other.locus;
370 83 : inner_attribute = other.inner_attribute;
371 : // guard to protect from null pointer dereference
372 83 : if (other.attr_input != nullptr)
373 76 : attr_input = other.attr_input->clone_attr_input ();
374 : else
375 7 : attr_input = nullptr;
376 :
377 83 : return *this;
378 : }
379 :
380 : std::string
381 4538750 : DelimTokenTree::as_string () const
382 : {
383 4538750 : std::string start_delim;
384 4538750 : std::string end_delim;
385 4538750 : switch (delim_type)
386 : {
387 4538750 : case PARENS:
388 4538750 : start_delim = "(";
389 4538750 : end_delim = ")";
390 4538750 : 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 9077500 : std::string str = start_delim;
405 4538750 : if (!token_trees.empty ())
406 : {
407 36800647 : for (const auto &tree : token_trees)
408 : {
409 : // DEBUG: null pointer check
410 32261897 : 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 64523794 : str += tree->as_string ();
419 : }
420 : }
421 4538750 : str += end_delim;
422 :
423 4538750 : return str;
424 4538750 : }
425 :
426 : std::string
427 28984512 : Token::as_string () const
428 : {
429 28984512 : if (tok_ref->should_have_str ())
430 : {
431 12224281 : std::string str = tok_ref->get_str ();
432 :
433 21715021 : std::string quote = is_string_lit () ? "\"" : "";
434 12224281 : return quote + str + quote;
435 12224281 : }
436 : else
437 : {
438 16760231 : return tok_ref->get_token_description ();
439 : }
440 : }
441 :
442 : std::string
443 41961646 : SimplePathSegment::as_string () const
444 : {
445 41961646 : return segment_name;
446 : }
447 :
448 : const std::string
449 26060032 : SimplePath::as_string () const
450 : {
451 26060032 : std::string path;
452 26060032 : if (opening_scope_resolution)
453 0 : path = "::";
454 :
455 : // crappy hack because doing proper for loop would be more code
456 26060032 : bool first_time = true;
457 52121063 : for (const auto &segment : segments)
458 : {
459 26061031 : if (first_time)
460 : {
461 52120064 : path += segment.as_string ();
462 26060032 : first_time = false;
463 : }
464 : else
465 : {
466 1998 : path += "::" + segment.as_string ();
467 : }
468 :
469 : // DEBUG: remove later. Checks for path error.
470 26061031 : 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 26060032 : 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 116646 : Function::Function (Function const &other)
1106 116646 : : VisItem (other), ExternalItem (other.get_node_id ()),
1107 116646 : qualifiers (other.qualifiers), function_name (other.function_name),
1108 116646 : where_clause (other.where_clause), locus (other.locus),
1109 233292 : is_external_function (other.is_external_function)
1110 : {
1111 : // guard to prevent null dereference (always required)
1112 116646 : if (other.return_type != nullptr)
1113 97476 : return_type = other.return_type->clone_type ();
1114 :
1115 : // guard to prevent null dereference (only required if error state)
1116 116646 : if (other.has_body ())
1117 102461 : function_body = other.function_body.value ()->clone_block_expr ();
1118 : else
1119 14185 : function_body = tl::nullopt;
1120 :
1121 116646 : generic_params.reserve (other.generic_params.size ());
1122 127144 : for (const auto &e : other.generic_params)
1123 10498 : generic_params.push_back (e->clone_generic_param ());
1124 :
1125 116646 : function_params.reserve (other.function_params.size ());
1126 303768 : for (const auto &e : other.function_params)
1127 187122 : function_params.push_back (e->clone_param ());
1128 116646 : }
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 0 : auto i = generic_params.begin ();
1400 0 : 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 : TraitAlias::as_string () const
1423 : {
1424 0 : std::string str = VisItem::as_string ();
1425 :
1426 0 : str += " " + alias_name.as_string ();
1427 :
1428 : // generic params
1429 0 : str += "\n Generic params: ";
1430 0 : if (!has_generics ())
1431 : {
1432 0 : str += "none";
1433 : }
1434 : else
1435 : {
1436 0 : auto i = generic_params.begin ();
1437 0 : auto e = generic_params.end ();
1438 :
1439 0 : for (; i != e; i++)
1440 : {
1441 0 : str += (*i)->as_string ();
1442 0 : if (e != i + 1)
1443 0 : str += ", ";
1444 : }
1445 : }
1446 :
1447 0 : str += "\n Bounds: ";
1448 0 : if (alias_bounds.empty ())
1449 : {
1450 0 : str += "none";
1451 : }
1452 : else
1453 : {
1454 0 : bool needs_plus = false;
1455 :
1456 0 : for (auto &bound : alias_bounds)
1457 : {
1458 0 : if (needs_plus)
1459 0 : str += " + ";
1460 0 : needs_plus = true;
1461 0 : str += bound->as_string ();
1462 : }
1463 : }
1464 :
1465 0 : str += "\n Where clause: ";
1466 0 : if (!has_where_clause ())
1467 0 : str += "none";
1468 : else
1469 0 : str += where_clause.as_string ();
1470 :
1471 0 : return str;
1472 : }
1473 :
1474 : std::string
1475 0 : ExternBlock::as_string () const
1476 : {
1477 0 : std::string str = VisItem::as_string ();
1478 :
1479 0 : str += "extern ";
1480 0 : if (has_abi ())
1481 0 : str += "\"" + abi + "\" ";
1482 :
1483 0 : str += append_attributes (inner_attrs, INNER);
1484 :
1485 0 : str += "\n external items: ";
1486 0 : if (!has_extern_items ())
1487 : {
1488 0 : str += "none";
1489 : }
1490 : else
1491 : {
1492 0 : for (const auto &item : extern_items)
1493 0 : str += "\n " + item->as_string ();
1494 : }
1495 :
1496 0 : return str;
1497 : }
1498 :
1499 : std::string
1500 0 : MacroRule::as_string () const
1501 : {
1502 0 : std::string str ("Macro rule: ");
1503 :
1504 0 : str += "\n Matcher: \n ";
1505 0 : str += matcher.as_string ();
1506 :
1507 0 : str += "\n Transcriber: \n ";
1508 0 : str += transcriber.as_string ();
1509 :
1510 0 : return str;
1511 : }
1512 :
1513 : std::string
1514 0 : MacroRulesDefinition::as_string () const
1515 : {
1516 0 : std::string str;
1517 :
1518 : // get outer attrs
1519 0 : str += append_attributes (outer_attrs, OUTER);
1520 :
1521 : // TODO: deal with macro_2_0
1522 0 : str += "macro_rules!";
1523 :
1524 0 : str += rule_name.as_string ();
1525 :
1526 0 : str += "\n Macro rules: ";
1527 0 : if (rules.empty ())
1528 : {
1529 0 : str += "none";
1530 : }
1531 : else
1532 : {
1533 0 : for (const auto &rule : rules)
1534 0 : str += "\n " + rule.as_string ();
1535 : }
1536 :
1537 0 : str += "\n Delim type: ";
1538 0 : switch (delim_type)
1539 : {
1540 0 : case PARENS:
1541 0 : str += "parentheses";
1542 0 : break;
1543 0 : case SQUARE:
1544 0 : str += "square";
1545 0 : break;
1546 0 : case CURLY:
1547 0 : str += "curly";
1548 0 : break;
1549 0 : default:
1550 0 : return "ERROR_MARK_STRING - delim type in macro invocation";
1551 : }
1552 :
1553 0 : return str;
1554 0 : }
1555 :
1556 : std::string
1557 0 : MacroInvocation::as_string () const
1558 : {
1559 0 : std::string str = "MacroInvocation: ";
1560 0 : auto is_builtin = kind == InvocKind::Builtin;
1561 :
1562 0 : if (is_builtin)
1563 0 : str += "[builtin] ";
1564 : else
1565 0 : str += "[regular] ";
1566 :
1567 0 : str += append_attributes (outer_attrs, OUTER);
1568 :
1569 0 : str += "\n " + invoc_data.as_string ();
1570 :
1571 0 : str += "\n has semicolon: ";
1572 0 : str += has_semicolon () ? "true" : "false";
1573 :
1574 0 : if (is_builtin)
1575 : {
1576 0 : str += "[PENDING EAGER INVOCATIONS]: ";
1577 0 : for (auto &pending : pending_eager_invocs)
1578 : {
1579 0 : str += pending->as_string ();
1580 0 : str += "\n";
1581 : }
1582 : }
1583 :
1584 0 : return str;
1585 : }
1586 :
1587 : std::string
1588 0 : MacroInvocData::as_string () const
1589 : {
1590 0 : return path.as_string () + "!" + token_tree.as_string ();
1591 : }
1592 :
1593 : std::string
1594 0 : ExprStmt::as_string () const
1595 : {
1596 0 : std::string str = indent_spaces (enter) + "ExprStmt: \n";
1597 :
1598 0 : if (expr == nullptr)
1599 : {
1600 0 : str += "none (this should not happen and is an error)";
1601 : }
1602 : else
1603 : {
1604 0 : indent_spaces (enter);
1605 0 : str += expr->as_string ();
1606 0 : if (semicolon_followed)
1607 0 : str += ";";
1608 0 : indent_spaces (out);
1609 : }
1610 :
1611 0 : indent_spaces (out);
1612 0 : return str;
1613 : }
1614 :
1615 : std::string
1616 0 : ClosureParam::as_string () const
1617 : {
1618 0 : std::string str (pattern->as_string ());
1619 :
1620 0 : if (has_type_given ())
1621 0 : str += " : " + type->as_string ();
1622 :
1623 0 : return str;
1624 : }
1625 :
1626 : std::string
1627 0 : ClosureExpr::as_string () const
1628 : {
1629 0 : std::string str = "ClosureExpr:";
1630 :
1631 0 : str += append_attributes (outer_attrs, OUTER);
1632 :
1633 0 : str += "\n Has move: ";
1634 0 : if (has_move)
1635 0 : str += "true";
1636 : else
1637 0 : str += "false";
1638 :
1639 0 : str += "\n Params: ";
1640 0 : if (params.empty ())
1641 : {
1642 0 : str += "none";
1643 : }
1644 : else
1645 : {
1646 0 : for (const auto ¶m : params)
1647 0 : str += "\n " + param.as_string ();
1648 : }
1649 :
1650 0 : return str;
1651 : }
1652 :
1653 : std::string
1654 0 : ClosureExprInnerTyped::as_string () const
1655 : {
1656 0 : std::string str = ClosureExpr::as_string ();
1657 :
1658 0 : str += "\n Return type: " + return_type->as_string ();
1659 :
1660 0 : str += "\n Body: " + expr->as_string ();
1661 :
1662 0 : return str;
1663 : }
1664 :
1665 : std::string
1666 0 : QualifiedPathType::as_string () const
1667 : {
1668 0 : std::string str ("<");
1669 0 : str += type_to_invoke_on->as_string ();
1670 :
1671 0 : if (has_as_clause ())
1672 0 : str += " as " + trait_path.as_string ();
1673 :
1674 0 : return str + ">";
1675 0 : }
1676 :
1677 : std::string
1678 0 : BorrowExpr::as_string () const
1679 : {
1680 : /* TODO: find way to incorporate outer attrs - may have to represent in
1681 : * different style (i.e. something more like BorrowExpr: \n outer attrs) */
1682 :
1683 0 : std::string str ("&");
1684 :
1685 0 : if (raw_borrow)
1686 : {
1687 0 : str += "raw ";
1688 0 : str += get_is_mut () ? "const " : "mut ";
1689 : }
1690 : else
1691 : {
1692 0 : if (double_borrow)
1693 0 : str += "&";
1694 :
1695 0 : if (get_is_mut ())
1696 0 : str += "mut ";
1697 : }
1698 0 : str += main_or_left_expr->as_string ();
1699 :
1700 0 : return str;
1701 : }
1702 :
1703 : std::string
1704 0 : BoxExpr::as_string () const
1705 : {
1706 0 : return "box " + expr->as_string ();
1707 : }
1708 :
1709 : void
1710 807 : BoxExpr::accept_vis (ASTVisitor &vis)
1711 : {
1712 807 : vis.visit (*this);
1713 807 : }
1714 :
1715 : std::string
1716 0 : ReturnExpr::as_string () const
1717 : {
1718 : /* TODO: find way to incorporate outer attrs - may have to represent in
1719 : * different style (i.e. something more like BorrowExpr: \n outer attrs) */
1720 :
1721 0 : std::string str ("return ");
1722 :
1723 0 : if (has_returned_expr ())
1724 0 : str += get_returned_expr ().as_string ();
1725 :
1726 0 : return str;
1727 : }
1728 :
1729 : std::string
1730 0 : TryExpr::as_string () const
1731 : {
1732 : /* TODO: find way to incorporate outer attrs - may have to represent in
1733 : * different style (i.e. something more like BorrowExpr: \n outer attrs) */
1734 :
1735 0 : std::string str ("try ");
1736 :
1737 0 : str += block_expr->as_string ();
1738 :
1739 0 : return str;
1740 : }
1741 :
1742 : std::string
1743 0 : RangeToExpr::as_string () const
1744 : {
1745 0 : return ".." + to->as_string ();
1746 : }
1747 :
1748 : std::string
1749 0 : ContinueExpr::as_string () const
1750 : {
1751 : // TODO: rewrite format to allow outer attributes
1752 0 : std::string str ("continue ");
1753 :
1754 0 : if (has_label ())
1755 0 : str += get_label_unchecked ().as_string ();
1756 :
1757 0 : return str;
1758 : }
1759 :
1760 : std::string
1761 0 : NegationExpr::as_string () const
1762 : {
1763 : // TODO: rewrite formula to allow outer attributes
1764 0 : std::string str;
1765 :
1766 0 : switch (expr_type)
1767 : {
1768 0 : case NegationOperator::NEGATE:
1769 0 : str = "-";
1770 0 : break;
1771 0 : case NegationOperator::NOT:
1772 0 : str = "!";
1773 0 : break;
1774 0 : default:
1775 0 : return "ERROR_MARK_STRING - negation expr";
1776 : }
1777 :
1778 0 : str += main_or_left_expr->as_string ();
1779 :
1780 0 : return str;
1781 0 : }
1782 :
1783 : std::string
1784 0 : RangeFromExpr::as_string () const
1785 : {
1786 0 : return from->as_string () + "..";
1787 : }
1788 :
1789 : std::string
1790 0 : RangeFullExpr::as_string () const
1791 : {
1792 0 : return "..";
1793 : }
1794 :
1795 : std::string
1796 0 : ArrayIndexExpr::as_string () const
1797 : {
1798 : // TODO: rewrite formula to allow outer attributes
1799 0 : return array_expr->as_string () + "[" + index_expr->as_string () + "]";
1800 : }
1801 :
1802 : std::string
1803 0 : AssignmentExpr::as_string () const
1804 : {
1805 0 : std::string str ("AssignmentExpr: ");
1806 :
1807 0 : if (main_or_left_expr == nullptr || right_expr == nullptr)
1808 : {
1809 0 : str += "error (either or both expressions are null)";
1810 : }
1811 : else
1812 : {
1813 : // left expr
1814 0 : str += "\n left: " + main_or_left_expr->as_string ();
1815 :
1816 : // right expr
1817 0 : str += "\n right: " + right_expr->as_string ();
1818 : }
1819 :
1820 0 : return str;
1821 : }
1822 :
1823 : std::string
1824 0 : AsyncBlockExpr::as_string () const
1825 : {
1826 0 : std::string str = "AsyncBlockExpr: ";
1827 :
1828 : // get outer attributes
1829 : // str += "\n " + Expr::as_string ();
1830 0 : str += append_attributes (outer_attrs, OUTER);
1831 :
1832 0 : str += "\n Has move: ";
1833 0 : str += has_move ? "true" : "false";
1834 :
1835 0 : return str + "\n" + block_expr->as_string ();
1836 0 : }
1837 :
1838 : std::string
1839 0 : ComparisonExpr::as_string () const
1840 : {
1841 : // TODO: rewrite to better reflect non-literal expressions
1842 0 : std::string str (main_or_left_expr->as_string ());
1843 :
1844 0 : switch (expr_type)
1845 : {
1846 0 : case ComparisonOperator::EQUAL:
1847 0 : str += " == ";
1848 0 : break;
1849 0 : case ComparisonOperator::NOT_EQUAL:
1850 0 : str += " != ";
1851 0 : break;
1852 0 : case ComparisonOperator::GREATER_THAN:
1853 0 : str += " > ";
1854 0 : break;
1855 0 : case ComparisonOperator::LESS_THAN:
1856 0 : str += " < ";
1857 0 : break;
1858 0 : case ComparisonOperator::GREATER_OR_EQUAL:
1859 0 : str += " >= ";
1860 0 : break;
1861 0 : case ComparisonOperator::LESS_OR_EQUAL:
1862 0 : str += " <= ";
1863 0 : break;
1864 0 : default:
1865 0 : return "ERROR_MARK_STRING - comparison expr";
1866 : }
1867 :
1868 0 : str += right_expr->as_string ();
1869 :
1870 0 : return str;
1871 0 : }
1872 :
1873 : std::string
1874 0 : MethodCallExpr::as_string () const
1875 : {
1876 0 : std::string str = "MethodCallExpr: ";
1877 :
1878 0 : str += append_attributes (outer_attrs, OUTER);
1879 :
1880 0 : str += "\n Object (receiver) expr: \n";
1881 0 : str += receiver->as_string ();
1882 :
1883 0 : str += "\n Method path segment: \n";
1884 0 : str += method_name.as_string ();
1885 :
1886 0 : str += "\n Call params:";
1887 0 : if (params.empty ())
1888 : {
1889 0 : str += "none";
1890 : }
1891 : else
1892 : {
1893 0 : for (const auto ¶m : params)
1894 : {
1895 0 : if (param == nullptr)
1896 0 : return "ERROR_MARK_STRING - method call expr param is null";
1897 :
1898 0 : str += "\n " + param->as_string ();
1899 : }
1900 : }
1901 :
1902 0 : return str;
1903 0 : }
1904 :
1905 : std::string
1906 0 : TupleIndexExpr::as_string () const
1907 : {
1908 : // TODO: rewrite dump to better reflect non-literal exprs
1909 0 : return tuple_expr->as_string () + "." + std::to_string (tuple_index);
1910 : }
1911 :
1912 : std::string
1913 0 : DereferenceExpr::as_string () const
1914 : {
1915 : // TODO: rewrite dump to better reflect non-literal exprs
1916 0 : return "*" + main_or_left_expr->as_string ();
1917 : }
1918 :
1919 : std::string
1920 0 : FieldAccessExpr::as_string () const
1921 : {
1922 : // TODO: rewrite dump to better reflect non-literal exprs
1923 0 : return receiver->as_string () + "." + field.as_string ();
1924 : }
1925 :
1926 : std::string
1927 0 : LazyBooleanExpr::as_string () const
1928 : {
1929 : // TODO: rewrite dump to better reflect non-literal exprs
1930 0 : std::string str (main_or_left_expr->as_string ());
1931 :
1932 0 : switch (expr_type)
1933 : {
1934 0 : case LazyBooleanOperator::LOGICAL_OR:
1935 0 : str += " || ";
1936 0 : break;
1937 0 : case LazyBooleanOperator::LOGICAL_AND:
1938 0 : str += " && ";
1939 0 : break;
1940 0 : default:
1941 0 : return "ERROR_MARK_STRING - lazy boolean expr out of bounds";
1942 : }
1943 :
1944 0 : str += right_expr->as_string ();
1945 :
1946 0 : return str;
1947 0 : }
1948 :
1949 : std::string
1950 0 : RangeFromToExpr::as_string () const
1951 : {
1952 : // TODO: rewrite dump to better reflect non-literal exprs
1953 0 : return from->as_string () + ".." + to->as_string ();
1954 : }
1955 :
1956 : std::string
1957 0 : RangeToInclExpr::as_string () const
1958 : {
1959 : // TODO: rewrite dump to better reflect non-literal exprs
1960 0 : return "..=" + to->as_string ();
1961 : }
1962 :
1963 : std::string
1964 0 : UnsafeBlockExpr::as_string () const
1965 : {
1966 0 : std::string str = "UnsafeBlockExpr:" + indent_spaces (enter);
1967 :
1968 : // get outer attributes
1969 0 : str += append_attributes (outer_attrs, OUTER);
1970 :
1971 0 : str += indent_spaces (stay) + expr->as_string () + "\n" + indent_spaces (out);
1972 :
1973 0 : return str;
1974 : }
1975 :
1976 : std::string
1977 0 : ClosureExprInner::as_string () const
1978 : {
1979 0 : std::string str = ClosureExpr::as_string ();
1980 :
1981 0 : str += "\n Expression: " + closure_inner->as_string ();
1982 :
1983 0 : return str;
1984 : }
1985 :
1986 : std::string
1987 0 : IfExpr::as_string () const
1988 : {
1989 0 : std::string str = "IfExpr: ";
1990 :
1991 0 : str += append_attributes (outer_attrs, OUTER);
1992 :
1993 0 : str += "\n Condition expr: " + condition->as_string ();
1994 :
1995 0 : str += "\n If block expr: " + if_block->as_string ();
1996 :
1997 0 : return str;
1998 : }
1999 :
2000 : std::string
2001 0 : IfExprConseqElse::as_string () const
2002 : {
2003 0 : std::string str = IfExpr::as_string ();
2004 :
2005 0 : str += "\n Else expr: " + else_block->as_string ();
2006 :
2007 0 : return str;
2008 : }
2009 :
2010 : std::string
2011 0 : IfLetExpr::as_string () const
2012 : {
2013 0 : std::string str = "IfLetExpr: ";
2014 :
2015 0 : str += append_attributes (outer_attrs, OUTER);
2016 :
2017 0 : str += "\n Condition match arm patterns: ";
2018 0 : if (match_arm_pattern == nullptr)
2019 : {
2020 0 : str += "none";
2021 : }
2022 : else
2023 : {
2024 0 : str += "\n " + match_arm_pattern->as_string ();
2025 : }
2026 :
2027 0 : str += "\n Scrutinee expr: " + value->as_string ();
2028 :
2029 0 : str += "\n If let block expr: " + if_block->as_string ();
2030 :
2031 0 : return str;
2032 : }
2033 :
2034 : std::string
2035 0 : IfLetExprConseqElse::as_string () const
2036 : {
2037 0 : std::string str = IfLetExpr::as_string ();
2038 :
2039 0 : str += "\n Else expr: " + else_block->as_string ();
2040 :
2041 0 : return str;
2042 : }
2043 :
2044 : std::string
2045 0 : RangeFromToInclExpr::as_string () const
2046 : {
2047 : // TODO: rewrite to allow dumps with non-literal exprs
2048 0 : return from->as_string () + "..=" + to->as_string ();
2049 : }
2050 :
2051 : std::string
2052 0 : ErrorPropagationExpr::as_string () const
2053 : {
2054 : // TODO: rewrite to allow dumps with non-literal exprs
2055 0 : return main_or_left_expr->as_string () + "?";
2056 : }
2057 :
2058 : std::string
2059 0 : CompoundAssignmentExpr::as_string () const
2060 : {
2061 0 : std::string operator_str;
2062 0 : operator_str.reserve (1);
2063 :
2064 : // get operator string
2065 0 : switch (expr_type)
2066 : {
2067 0 : case CompoundAssignmentOperator::ADD:
2068 0 : operator_str = "+";
2069 0 : break;
2070 0 : case CompoundAssignmentOperator::SUBTRACT:
2071 0 : operator_str = "-";
2072 0 : break;
2073 0 : case CompoundAssignmentOperator::MULTIPLY:
2074 0 : operator_str = "*";
2075 0 : break;
2076 0 : case CompoundAssignmentOperator::DIVIDE:
2077 0 : operator_str = "/";
2078 0 : break;
2079 0 : case CompoundAssignmentOperator::MODULUS:
2080 0 : operator_str = "%";
2081 0 : break;
2082 0 : case CompoundAssignmentOperator::BITWISE_AND:
2083 0 : operator_str = "&";
2084 0 : break;
2085 0 : case CompoundAssignmentOperator::BITWISE_OR:
2086 0 : operator_str = "|";
2087 0 : break;
2088 0 : case CompoundAssignmentOperator::BITWISE_XOR:
2089 0 : operator_str = "^";
2090 0 : break;
2091 0 : case CompoundAssignmentOperator::LEFT_SHIFT:
2092 0 : operator_str = "<<";
2093 0 : break;
2094 0 : case CompoundAssignmentOperator::RIGHT_SHIFT:
2095 0 : operator_str = ">>";
2096 0 : break;
2097 0 : default:
2098 0 : operator_str = "invalid operator. wtf";
2099 0 : break;
2100 : }
2101 :
2102 0 : operator_str += "=";
2103 :
2104 0 : std::string str ("CompoundAssignmentExpr: ");
2105 0 : if (main_or_left_expr == nullptr || right_expr == nullptr)
2106 : {
2107 0 : str += "error. this is probably a parsing failure.";
2108 : }
2109 : else
2110 : {
2111 0 : str += "\n left: " + main_or_left_expr->as_string ();
2112 0 : str += "\n right: " + right_expr->as_string ();
2113 0 : str += "\n operator: " + operator_str;
2114 : }
2115 :
2116 0 : return str;
2117 0 : }
2118 :
2119 : std::string
2120 0 : ArithmeticOrLogicalExpr::as_string () const
2121 : {
2122 0 : std::string operator_str;
2123 0 : operator_str.reserve (1);
2124 :
2125 : // get operator string
2126 0 : switch (expr_type)
2127 : {
2128 0 : case ArithmeticOrLogicalOperator::ADD:
2129 0 : operator_str = "+";
2130 0 : break;
2131 0 : case ArithmeticOrLogicalOperator::SUBTRACT:
2132 0 : operator_str = "-";
2133 0 : break;
2134 0 : case ArithmeticOrLogicalOperator::MULTIPLY:
2135 0 : operator_str = "*";
2136 0 : break;
2137 0 : case ArithmeticOrLogicalOperator::DIVIDE:
2138 0 : operator_str = "/";
2139 0 : break;
2140 0 : case ArithmeticOrLogicalOperator::MODULUS:
2141 0 : operator_str = "%";
2142 0 : break;
2143 0 : case ArithmeticOrLogicalOperator::BITWISE_AND:
2144 0 : operator_str = "&";
2145 0 : break;
2146 0 : case ArithmeticOrLogicalOperator::BITWISE_OR:
2147 0 : operator_str = "|";
2148 0 : break;
2149 0 : case ArithmeticOrLogicalOperator::BITWISE_XOR:
2150 0 : operator_str = "^";
2151 0 : break;
2152 0 : case ArithmeticOrLogicalOperator::LEFT_SHIFT:
2153 0 : operator_str = "<<";
2154 0 : break;
2155 0 : case ArithmeticOrLogicalOperator::RIGHT_SHIFT:
2156 0 : operator_str = ">>";
2157 0 : break;
2158 0 : default:
2159 0 : operator_str = "invalid operator. wtf";
2160 0 : break;
2161 : }
2162 :
2163 0 : std::string str ("ArithmeticOrLogicalExpr: ");
2164 0 : if (main_or_left_expr == nullptr || right_expr == nullptr)
2165 : {
2166 0 : str += "error. this is probably a parsing failure.";
2167 : }
2168 : else
2169 : {
2170 0 : str += main_or_left_expr->as_string () + " ";
2171 0 : str += operator_str + " ";
2172 0 : str += right_expr->as_string ();
2173 : }
2174 :
2175 0 : return str;
2176 0 : }
2177 :
2178 : std::string
2179 0 : CallExpr::as_string () const
2180 : {
2181 0 : std::string str = "CallExpr: ";
2182 :
2183 0 : str += append_attributes (outer_attrs, OUTER);
2184 :
2185 0 : str += "\n Function expr: ";
2186 0 : str += function->as_string ();
2187 :
2188 0 : str += "\n Call params:";
2189 0 : if (!has_params ())
2190 : {
2191 0 : str += "none";
2192 : }
2193 : else
2194 : {
2195 0 : for (const auto ¶m : params)
2196 : {
2197 0 : if (param == nullptr)
2198 0 : return "ERROR_MARK_STRING - call expr param is null";
2199 :
2200 0 : str += "\n " + param->as_string ();
2201 : }
2202 : }
2203 :
2204 0 : return str;
2205 0 : }
2206 :
2207 : std::string
2208 0 : WhileLoopExpr::as_string () const
2209 : {
2210 0 : std::string str = "WhileLoopExpr: ";
2211 :
2212 0 : str += append_attributes (outer_attrs, OUTER);
2213 :
2214 0 : str += "\n Label: ";
2215 0 : if (!has_loop_label ())
2216 0 : str += "none";
2217 : else
2218 0 : str += get_loop_label ().as_string ();
2219 :
2220 0 : str += "\n Conditional expr: " + condition->as_string ();
2221 :
2222 0 : str += "\n Loop block: " + loop_block->as_string ();
2223 :
2224 0 : return str;
2225 : }
2226 :
2227 : std::string
2228 0 : WhileLetLoopExpr::as_string () const
2229 : {
2230 0 : std::string str = "WhileLetLoopExpr: ";
2231 :
2232 0 : str += append_attributes (outer_attrs, OUTER);
2233 :
2234 0 : str += "\n Label: ";
2235 0 : if (!has_loop_label ())
2236 0 : str += "none";
2237 : else
2238 0 : str += get_loop_label ().as_string ();
2239 :
2240 0 : str += "\n Match arm patterns: ";
2241 0 : if (match_arm_pattern == nullptr)
2242 : {
2243 0 : str += "none";
2244 : }
2245 : else
2246 : {
2247 0 : str += "\n " + match_arm_pattern->as_string ();
2248 : }
2249 :
2250 0 : str += "\n Scrutinee expr: " + scrutinee->as_string ();
2251 :
2252 0 : str += "\n Loop block: " + loop_block->as_string ();
2253 :
2254 0 : return str;
2255 : }
2256 :
2257 : std::string
2258 0 : LoopExpr::as_string () const
2259 : {
2260 0 : std::string str = "LoopExpr: (infinite loop)";
2261 :
2262 0 : str += append_attributes (outer_attrs, OUTER);
2263 :
2264 0 : str += "\n Label: ";
2265 0 : if (!has_loop_label ())
2266 0 : str += "none";
2267 : else
2268 0 : str += get_loop_label ().as_string ();
2269 :
2270 0 : str += "\n Loop block: " + loop_block->as_string ();
2271 :
2272 0 : return str;
2273 : }
2274 :
2275 : std::string
2276 0 : ArrayExpr::as_string () const
2277 : {
2278 0 : std::string str = "ArrayExpr:";
2279 :
2280 0 : str += append_attributes (outer_attrs, OUTER);
2281 :
2282 : // inner attributes
2283 0 : str += append_attributes (inner_attrs, INNER);
2284 :
2285 0 : str += "\n Array elems: ";
2286 0 : str += internal_elements->as_string ();
2287 :
2288 0 : return str;
2289 : }
2290 :
2291 : std::string
2292 0 : AwaitExpr::as_string () const
2293 : {
2294 : // TODO: rewrite dump to allow non-literal exprs
2295 0 : return awaited_expr->as_string () + ".await";
2296 : }
2297 :
2298 : std::string
2299 0 : BreakExpr::as_string () const
2300 : {
2301 : // TODO: rewrite dump to allow outer attrs, non-literal exprs
2302 0 : std::string str ("break ");
2303 :
2304 0 : if (has_label ())
2305 0 : str += get_label_unchecked ().as_string () + " ";
2306 :
2307 0 : if (has_break_expr ())
2308 0 : str += get_break_expr_unchecked ().as_string ();
2309 :
2310 0 : return str;
2311 : }
2312 :
2313 : std::string
2314 0 : LoopLabel::as_string () const
2315 : {
2316 0 : return label.as_string () + ": (label) ";
2317 : }
2318 :
2319 : std::string
2320 0 : MatchArm::as_string () const
2321 : {
2322 : // outer attributes
2323 0 : std::string str = append_attributes (outer_attrs, OUTER);
2324 :
2325 0 : str += "\nPatterns: ";
2326 0 : if (match_arm_pattern == nullptr)
2327 : {
2328 0 : str += "none";
2329 : }
2330 : else
2331 : {
2332 0 : str += "\n " + match_arm_pattern->as_string ();
2333 : }
2334 :
2335 0 : str += "\nGuard expr: ";
2336 0 : if (!has_match_arm_guard ())
2337 0 : str += "none";
2338 : else
2339 0 : str += guard_expr->as_string ();
2340 :
2341 0 : return str;
2342 : }
2343 :
2344 : std::string
2345 0 : MatchCase::as_string () const
2346 : {
2347 0 : std::string str ("MatchCase: (match arm) ");
2348 :
2349 0 : str += "\n Match arm matcher: \n" + arm.as_string ();
2350 0 : str += "\n Expr: " + expr->as_string ();
2351 :
2352 0 : return str;
2353 : }
2354 :
2355 : std::string
2356 0 : MatchExpr::as_string () const
2357 : {
2358 0 : std::string str ("MatchExpr:");
2359 :
2360 0 : str += append_attributes (outer_attrs, OUTER);
2361 :
2362 0 : str += "\n Scrutinee expr: " + branch_value->as_string ();
2363 :
2364 : // inner attributes
2365 0 : str += append_attributes (inner_attrs, INNER);
2366 :
2367 : // match arms
2368 0 : str += "\n Match arms: ";
2369 0 : if (match_arms.empty ())
2370 : {
2371 0 : str += "none";
2372 : }
2373 : else
2374 : {
2375 0 : for (const auto &arm : match_arms)
2376 0 : str += "\n " + arm.as_string ();
2377 : }
2378 :
2379 0 : return str;
2380 : }
2381 :
2382 : std::string
2383 0 : TupleExpr::as_string () const
2384 : {
2385 0 : std::string str ("TupleExpr:");
2386 :
2387 0 : str += append_attributes (outer_attrs, OUTER);
2388 :
2389 : // inner attributes
2390 0 : str += append_attributes (inner_attrs, INNER);
2391 :
2392 0 : str += "\n Tuple elements: ";
2393 0 : if (tuple_elems.empty ())
2394 : {
2395 0 : str += "none";
2396 : }
2397 : else
2398 : {
2399 0 : for (const auto &elem : tuple_elems)
2400 0 : str += "\n " + elem->as_string ();
2401 : }
2402 :
2403 0 : return str;
2404 : }
2405 :
2406 : std::string
2407 0 : FunctionParam::as_string () const
2408 : {
2409 : // TODO: rewrite dump to allow non-literal types
2410 0 : return param_name->as_string () + " : " + type->as_string ();
2411 : }
2412 :
2413 : void
2414 3763685 : FunctionParam::accept_vis (ASTVisitor &vis)
2415 : {
2416 3763685 : vis.visit (*this);
2417 3763685 : }
2418 :
2419 : void
2420 2275223 : SelfParam::accept_vis (ASTVisitor &vis)
2421 : {
2422 2275223 : vis.visit (*this);
2423 2275223 : }
2424 :
2425 : void
2426 20379 : VariadicParam::accept_vis (ASTVisitor &vis)
2427 : {
2428 20379 : vis.visit (*this);
2429 20379 : }
2430 :
2431 : std::string
2432 0 : VariadicParam::as_string () const
2433 : {
2434 0 : if (has_pattern ())
2435 0 : return get_pattern ().as_string () + " : ...";
2436 : else
2437 0 : return "...";
2438 : }
2439 :
2440 : std::string
2441 0 : FunctionQualifiers::as_string () const
2442 : {
2443 0 : std::string str;
2444 :
2445 0 : if (is_async ())
2446 0 : str += "async ";
2447 0 : if (is_const ())
2448 0 : str += "const ";
2449 0 : if (is_unsafe ())
2450 0 : str += "unsafe ";
2451 :
2452 0 : if (has_extern)
2453 : {
2454 0 : str += "extern";
2455 0 : if (extern_abi != "")
2456 0 : str += " \"" + extern_abi + "\"";
2457 : }
2458 :
2459 0 : return str;
2460 : }
2461 :
2462 : std::string
2463 0 : TraitBound::as_string () const
2464 : {
2465 0 : std::string str ("TraitBound:");
2466 :
2467 0 : str += "\n Has opening question mark: ";
2468 0 : if (opening_question_mark)
2469 0 : str += "true";
2470 : else
2471 0 : str += "false";
2472 :
2473 0 : str += "\n For lifetimes: ";
2474 0 : if (!has_for_lifetimes ())
2475 : {
2476 0 : str += "none";
2477 : }
2478 : else
2479 : {
2480 0 : for (const auto &lifetime : for_lifetimes)
2481 0 : str += "\n " + lifetime.as_string ();
2482 : }
2483 :
2484 0 : str += "\n Type path: " + type_path.as_string ();
2485 :
2486 0 : return str;
2487 : }
2488 :
2489 : std::string
2490 0 : MacroMatcher::as_string () const
2491 : {
2492 0 : std::string str ("Macro matcher: ");
2493 :
2494 0 : str += "\n Delim type: ";
2495 :
2496 0 : switch (delim_type)
2497 : {
2498 0 : case PARENS:
2499 0 : str += "parentheses";
2500 0 : break;
2501 0 : case SQUARE:
2502 0 : str += "square";
2503 0 : break;
2504 0 : case CURLY:
2505 0 : str += "curly";
2506 0 : break;
2507 0 : default:
2508 0 : return "ERROR_MARK_STRING - macro matcher delim";
2509 : }
2510 :
2511 0 : str += "\n Matches: ";
2512 :
2513 0 : if (matches.empty ())
2514 : {
2515 0 : str += "none";
2516 : }
2517 : else
2518 : {
2519 0 : for (const auto &match : matches)
2520 0 : str += "\n " + match->as_string ();
2521 : }
2522 :
2523 0 : return str;
2524 0 : }
2525 :
2526 : std::string
2527 0 : LifetimeParam::as_string () const
2528 : {
2529 0 : std::string str ("LifetimeParam: ");
2530 :
2531 0 : str += "\n Outer attribute:";
2532 0 : if (!has_outer_attribute ())
2533 0 : str += "none";
2534 0 : for (auto &attr : outer_attrs)
2535 0 : str += " " + attr.as_string ();
2536 :
2537 0 : str += "\n Lifetime: " + lifetime.as_string ();
2538 :
2539 0 : str += "\n Lifetime bounds: ";
2540 0 : if (!has_lifetime_bounds ())
2541 : {
2542 0 : str += "none";
2543 : }
2544 : else
2545 : {
2546 0 : for (const auto &bound : lifetime_bounds)
2547 0 : str += "\n " + bound.as_string ();
2548 : }
2549 :
2550 0 : return str;
2551 : }
2552 :
2553 : std::string
2554 0 : MacroMatchFragment::as_string () const
2555 : {
2556 0 : return "$" + ident.as_string () + ": " + frag_spec.as_string ();
2557 : }
2558 :
2559 : std::string
2560 0 : MacroMatchRepetition::as_string () const
2561 : {
2562 0 : std::string str ("Macro match repetition: ");
2563 :
2564 0 : str += "\n Matches: ";
2565 0 : if (matches.empty ())
2566 : {
2567 0 : str += "none";
2568 : }
2569 : else
2570 : {
2571 0 : for (const auto &match : matches)
2572 0 : str += "\n " + match->as_string ();
2573 : }
2574 :
2575 0 : str += "\n Sep: ";
2576 0 : if (!has_sep ())
2577 0 : str += "none";
2578 : else
2579 0 : str += sep->as_string ();
2580 :
2581 0 : str += "\n Op: ";
2582 0 : switch (op)
2583 : {
2584 0 : case ANY:
2585 0 : str += "*";
2586 0 : break;
2587 0 : case ONE_OR_MORE:
2588 0 : str += "+";
2589 0 : break;
2590 0 : case ZERO_OR_ONE:
2591 0 : str += "?";
2592 0 : break;
2593 0 : case NONE:
2594 0 : str += "no op? shouldn't be allowed";
2595 0 : break;
2596 0 : default:
2597 0 : return "ERROR_MARK_STRING - unknown op in macro match repetition";
2598 : }
2599 :
2600 0 : return str;
2601 0 : }
2602 :
2603 : std::string
2604 120 : Lifetime::as_string () const
2605 : {
2606 120 : switch (lifetime_type)
2607 : {
2608 120 : case NAMED:
2609 120 : return "'" + lifetime_name;
2610 0 : case STATIC:
2611 0 : return "'static";
2612 0 : case WILDCARD:
2613 0 : return "'_";
2614 0 : default:
2615 0 : return "ERROR-MARK-STRING: lifetime type failure";
2616 : }
2617 : }
2618 :
2619 : std::string
2620 0 : TypeParam::as_string () const
2621 : {
2622 0 : std::string str ("TypeParam: ");
2623 :
2624 0 : str += "\n Outer attribute:";
2625 0 : if (!has_outer_attribute ())
2626 0 : str += "none";
2627 0 : for (auto &attr : outer_attrs)
2628 0 : str += " " + attr.as_string ();
2629 :
2630 0 : str += "\n Identifier: " + type_representation.as_string ();
2631 :
2632 0 : str += "\n Type param bounds: ";
2633 0 : if (!has_type_param_bounds ())
2634 : {
2635 0 : str += "none";
2636 : }
2637 : else
2638 : {
2639 0 : for (const auto &bound : type_param_bounds)
2640 0 : str += "\n " + bound->as_string ();
2641 : }
2642 :
2643 0 : str += "\n Type: ";
2644 0 : if (!has_type ())
2645 0 : str += "none";
2646 : else
2647 0 : str += type->as_string ();
2648 :
2649 0 : return str;
2650 : }
2651 :
2652 : std::string
2653 0 : ForLoopExpr::as_string () const
2654 : {
2655 0 : std::string str = "ForLoopExpr: ";
2656 :
2657 0 : str += append_attributes (outer_attrs, OUTER);
2658 :
2659 0 : str += "\n Label: ";
2660 0 : if (!has_loop_label ())
2661 0 : str += "none";
2662 : else
2663 0 : str += get_loop_label ().as_string ();
2664 :
2665 0 : str += "\n Pattern: " + pattern->as_string ();
2666 :
2667 0 : str += "\n Iterator expr: " + iterator_expr->as_string ();
2668 :
2669 0 : str += "\n Loop block: " + loop_block->as_string ();
2670 :
2671 0 : return str;
2672 : }
2673 :
2674 : std::string
2675 0 : LetStmt::as_string () const
2676 : {
2677 : // TODO: rewrite to work with non-linearisable types and exprs
2678 0 : std::string str = append_attributes (outer_attrs, OUTER);
2679 :
2680 0 : str += "\n" + indent_spaces (stay) + "let " + variables_pattern->as_string ();
2681 :
2682 0 : if (has_type ())
2683 0 : str += " : " + type->as_string ();
2684 :
2685 0 : if (has_init_expr ())
2686 0 : str += " = " + init_expr->as_string ();
2687 :
2688 0 : return str;
2689 : }
2690 :
2691 : std::string
2692 0 : InferredType::as_string () const
2693 : {
2694 0 : return "_ (inferred)";
2695 : }
2696 :
2697 : std::string
2698 0 : TypeCastExpr::as_string () const
2699 : {
2700 : // TODO: rewrite to work with non-linearisable exprs and types
2701 0 : return main_or_left_expr->as_string () + " as "
2702 0 : + type_to_convert_to->as_string ();
2703 : }
2704 :
2705 : std::string
2706 0 : ImplTraitType::as_string () const
2707 : {
2708 0 : std::string str ("ImplTraitType: \n TypeParamBounds: ");
2709 :
2710 0 : if (type_param_bounds.empty ())
2711 : {
2712 0 : str += "none";
2713 : }
2714 : else
2715 : {
2716 0 : for (const auto &bound : type_param_bounds)
2717 0 : str += "\n " + bound->as_string ();
2718 : }
2719 :
2720 0 : return str;
2721 : }
2722 :
2723 : std::string
2724 0 : ReferenceType::as_string () const
2725 : {
2726 : // TODO: rewrite to work with non-linearisable types
2727 0 : std::string str ("&");
2728 :
2729 0 : if (has_lifetime ())
2730 0 : str += get_lifetime ().as_string () + " ";
2731 :
2732 0 : if (has_mut)
2733 0 : str += "mut ";
2734 :
2735 0 : str += type->as_string ();
2736 :
2737 0 : return str;
2738 : }
2739 :
2740 : std::string
2741 0 : RawPointerType::as_string () const
2742 : {
2743 : // TODO: rewrite to work with non-linearisable types
2744 0 : std::string str ("*");
2745 :
2746 0 : switch (pointer_type)
2747 : {
2748 0 : case MUT:
2749 0 : str += "mut ";
2750 0 : break;
2751 0 : case CONST:
2752 0 : str += "const ";
2753 0 : break;
2754 0 : default:
2755 0 : return "ERROR_MARK_STRING - unknown pointer type in raw pointer type";
2756 : }
2757 :
2758 0 : str += type->as_string ();
2759 :
2760 0 : return str;
2761 0 : }
2762 :
2763 : std::string
2764 0 : TraitObjectType::as_string () const
2765 : {
2766 0 : std::string str ("TraitObjectType: \n Has dyn dispatch: ");
2767 :
2768 0 : if (has_dyn)
2769 0 : str += "true";
2770 : else
2771 0 : str += "false";
2772 :
2773 0 : str += "\n TypeParamBounds: ";
2774 0 : if (type_param_bounds.empty ())
2775 : {
2776 0 : str += "none";
2777 : }
2778 : else
2779 : {
2780 0 : for (const auto &bound : type_param_bounds)
2781 0 : str += "\n " + bound->as_string ();
2782 : }
2783 :
2784 0 : return str;
2785 : }
2786 :
2787 : std::string
2788 0 : BareFunctionType::as_string () const
2789 : {
2790 0 : std::string str ("BareFunctionType: \n For lifetimes: ");
2791 :
2792 0 : if (!has_for_lifetimes ())
2793 : {
2794 0 : str += "none";
2795 : }
2796 : else
2797 : {
2798 0 : for (const auto &for_lifetime : for_lifetimes)
2799 0 : str += "\n " + for_lifetime.as_string ();
2800 : }
2801 :
2802 0 : str += "\n Qualifiers: " + function_qualifiers.as_string ();
2803 :
2804 0 : str += "\n Params: ";
2805 0 : if (params.empty ())
2806 : {
2807 0 : str += "none";
2808 : }
2809 : else
2810 : {
2811 0 : for (const auto ¶m : params)
2812 0 : str += "\n " + param.as_string ();
2813 : }
2814 :
2815 0 : str += "\n Is variadic: ";
2816 0 : if (_is_variadic)
2817 0 : str += "true";
2818 : else
2819 0 : str += "false";
2820 :
2821 0 : str += "\n Return type: ";
2822 0 : if (!has_return_type ())
2823 0 : str += "none (void)";
2824 : else
2825 0 : str += return_type->as_string ();
2826 :
2827 0 : return str;
2828 : }
2829 :
2830 : std::string
2831 0 : ImplTraitTypeOneBound::as_string () const
2832 : {
2833 0 : std::string str ("ImplTraitTypeOneBound: \n TraitBound: ");
2834 :
2835 0 : return str + trait_bound->as_string ();
2836 0 : }
2837 :
2838 : std::string
2839 0 : TraitObjectTypeOneBound::as_string () const
2840 : {
2841 0 : std::string str ("TraitObjectTypeOneBound: \n Has dyn dispatch: ");
2842 :
2843 0 : if (has_dyn)
2844 0 : str += "true";
2845 : else
2846 0 : str += "false";
2847 :
2848 0 : str += "\n TraitBound: " + trait_bound.as_string ();
2849 :
2850 0 : return str;
2851 : }
2852 :
2853 : std::string
2854 0 : ArrayType::as_string () const
2855 : {
2856 : // TODO: rewrite to work with non-linearisable types and exprs
2857 0 : return "[" + elem_type->as_string () + "; " + size.as_string () + "]";
2858 : }
2859 :
2860 : std::string
2861 0 : SliceType::as_string () const
2862 : {
2863 : // TODO: rewrite to work with non-linearisable types
2864 0 : return "[" + elem_type->as_string () + "]";
2865 : }
2866 :
2867 : std::string
2868 0 : TupleType::as_string () const
2869 : {
2870 : // TODO: rewrite to work with non-linearisable types
2871 0 : std::string str ("(");
2872 :
2873 0 : if (!is_unit_type ())
2874 : {
2875 0 : auto i = elems.begin ();
2876 0 : auto e = elems.end ();
2877 :
2878 0 : for (; i != e; i++)
2879 : {
2880 0 : str += (*i)->as_string ();
2881 0 : if (e != i + 1)
2882 0 : str += ", ";
2883 : }
2884 : }
2885 :
2886 0 : str += ")";
2887 :
2888 0 : return str;
2889 : }
2890 :
2891 : std::string
2892 0 : StructExpr::as_string () const
2893 : {
2894 0 : std::string str = append_attributes (outer_attrs, OUTER);
2895 0 : indent_spaces (enter);
2896 0 : str += "\n" + indent_spaces (stay) + "StructExpr:";
2897 0 : indent_spaces (enter);
2898 0 : str += "\n" + indent_spaces (stay) + "PathInExpr:\n";
2899 0 : str += indent_spaces (stay) + struct_name.as_string ();
2900 0 : indent_spaces (out);
2901 0 : indent_spaces (out);
2902 0 : return str;
2903 : }
2904 :
2905 : std::string
2906 0 : StructExprStruct::as_string () const
2907 : {
2908 : // TODO: doesn't this require data from StructExpr?
2909 0 : std::string str ("StructExprStruct (or subclass): ");
2910 :
2911 0 : str += "\n Path: " + get_struct_name ().as_string ();
2912 :
2913 : // inner attributes
2914 0 : str += append_attributes (inner_attrs, INNER);
2915 :
2916 0 : return str;
2917 : }
2918 :
2919 : std::string
2920 0 : StructBase::as_string () const
2921 : {
2922 0 : if (base_struct != nullptr)
2923 0 : return base_struct->as_string ();
2924 : else
2925 0 : return "ERROR_MARK_STRING - invalid struct base had as string applied";
2926 : }
2927 :
2928 : std::string
2929 0 : StructExprFieldWithVal::as_string () const
2930 : {
2931 : // used to get value string
2932 0 : return value->as_string ();
2933 : }
2934 :
2935 : std::string
2936 0 : StructExprFieldIdentifierValue::as_string () const
2937 : {
2938 : // TODO: rewrite to work with non-linearisable exprs
2939 0 : return field_name.as_string () + " : " + StructExprFieldWithVal::as_string ();
2940 : }
2941 :
2942 : std::string
2943 0 : StructExprFieldIndexValue::as_string () const
2944 : {
2945 : // TODO: rewrite to work with non-linearisable exprs
2946 0 : return std::to_string (index) + " : " + StructExprFieldWithVal::as_string ();
2947 : }
2948 :
2949 : std::string
2950 0 : StructExprStructFields::as_string () const
2951 : {
2952 0 : std::string str = StructExprStruct::as_string ();
2953 :
2954 0 : str += "\n Fields: ";
2955 0 : if (fields.empty ())
2956 : {
2957 0 : str += "none";
2958 : }
2959 : else
2960 : {
2961 0 : for (const auto &field : fields)
2962 0 : str += "\n " + field->as_string ();
2963 : }
2964 :
2965 0 : str += "\n Struct base: ";
2966 0 : if (!has_struct_base ())
2967 0 : str += "none";
2968 : else
2969 0 : str += struct_base.as_string ();
2970 :
2971 0 : return str;
2972 : }
2973 :
2974 : std::string
2975 0 : EnumItem::as_string () const
2976 : {
2977 0 : std::string str = VisItem::as_string ();
2978 0 : str += variant_name.as_string ();
2979 :
2980 0 : return str;
2981 : }
2982 :
2983 : std::string
2984 0 : EnumItemTuple::as_string () const
2985 : {
2986 0 : std::string str = EnumItem::as_string ();
2987 :
2988 : // add tuple opening parens
2989 0 : str += "(";
2990 :
2991 : // tuple fields
2992 0 : if (has_tuple_fields ())
2993 : {
2994 0 : auto i = tuple_fields.begin ();
2995 0 : auto e = tuple_fields.end ();
2996 :
2997 0 : for (; i != e; i++)
2998 : {
2999 0 : str += (*i).as_string ();
3000 0 : if (e != i + 1)
3001 0 : str += ", ";
3002 : }
3003 : }
3004 :
3005 : // add tuple closing parens
3006 0 : str += ")";
3007 :
3008 0 : return str;
3009 : }
3010 :
3011 : std::string
3012 0 : TupleField::as_string () const
3013 : {
3014 : // TODO: rewrite to work with non-linearisable exprs
3015 :
3016 : // outer attributes
3017 0 : std::string str = append_attributes (outer_attrs, OUTER);
3018 :
3019 0 : if (has_visibility ())
3020 0 : str += "\n" + visibility.as_string ();
3021 :
3022 0 : str += " " + field_type->as_string ();
3023 :
3024 0 : return str;
3025 : }
3026 :
3027 : std::string
3028 0 : EnumItemStruct::as_string () const
3029 : {
3030 0 : std::string str = EnumItem::as_string ();
3031 :
3032 : // add struct opening parens
3033 0 : str += "{";
3034 :
3035 : // tuple fields
3036 0 : if (has_struct_fields ())
3037 : {
3038 0 : auto i = struct_fields.begin ();
3039 0 : auto e = struct_fields.end ();
3040 :
3041 0 : for (; i != e; i++)
3042 : {
3043 0 : str += (*i).as_string ();
3044 0 : if (e != i + 1)
3045 0 : str += ", ";
3046 : }
3047 : }
3048 :
3049 : // add struct closing parens
3050 0 : str += "}";
3051 :
3052 0 : return str;
3053 : }
3054 :
3055 : std::string
3056 0 : StructField::as_string () const
3057 : {
3058 : // TODO: rewrite to work with non-linearisable exprs
3059 : // outer attributes
3060 0 : std::string str = append_attributes (outer_attrs, OUTER);
3061 :
3062 0 : if (has_visibility ())
3063 0 : str += "\n" + visibility.as_string ();
3064 :
3065 0 : str += " " + field_name.as_string () + " : " + field_type->as_string ();
3066 :
3067 0 : return str;
3068 : }
3069 :
3070 : std::string
3071 0 : EnumItemDiscriminant::as_string () const
3072 : {
3073 : // TODO: rewrite to work with non-linearisable exprs
3074 0 : std::string str = EnumItem::as_string ();
3075 :
3076 : // add equal and expression
3077 0 : str += " = " + expression->as_string ();
3078 :
3079 0 : return str;
3080 : }
3081 :
3082 : std::string
3083 0 : ExternalTypeItem::as_string () const
3084 : {
3085 0 : auto str = append_attributes (outer_attrs, OUTER);
3086 :
3087 0 : str += "type " + item_name.as_string () + ";";
3088 :
3089 0 : return str;
3090 : }
3091 :
3092 : std::string
3093 0 : ExternalStaticItem::as_string () const
3094 : {
3095 : // outer attributes
3096 0 : std::string str = append_attributes (outer_attrs, OUTER);
3097 :
3098 : // start visibility on new line and with a space
3099 0 : str += "\n" + visibility.as_string () + " ";
3100 :
3101 0 : str += "static ";
3102 :
3103 0 : if (has_mut)
3104 0 : str += "mut ";
3105 :
3106 : // add name
3107 0 : str += item_name.as_string ();
3108 :
3109 : // add type on new line
3110 0 : str += "\n Type: " + item_type->as_string ();
3111 :
3112 0 : return str;
3113 : }
3114 :
3115 : std::string
3116 0 : TraitItemType::as_string () const
3117 : {
3118 0 : std::string str = append_attributes (outer_attrs, OUTER);
3119 :
3120 0 : str += "\ntype " + name.as_string ();
3121 :
3122 0 : if (has_generics ())
3123 : {
3124 0 : str += "<";
3125 0 : for (size_t i = 0; i < generic_params.size (); i++)
3126 : {
3127 0 : if (i > 0)
3128 0 : str += ", ";
3129 0 : str += generic_params[i]->as_string ();
3130 : }
3131 0 : str += ">";
3132 : }
3133 :
3134 0 : str += "\n Type param bounds: ";
3135 0 : if (!has_type_param_bounds ())
3136 : {
3137 0 : str += "none";
3138 : }
3139 : else
3140 : {
3141 0 : for (const auto &bound : type_param_bounds)
3142 : {
3143 : // DEBUG: null pointer check
3144 0 : if (bound == nullptr)
3145 : {
3146 0 : rust_debug (
3147 : "something really terrible has gone wrong - null pointer "
3148 : "type param bound in trait item type.");
3149 0 : return "NULL_POINTER_MARK";
3150 : }
3151 :
3152 0 : str += "\n " + bound->as_string ();
3153 : }
3154 : }
3155 :
3156 0 : return str;
3157 0 : }
3158 :
3159 : std::string
3160 0 : SelfParam::as_string () const
3161 : {
3162 : // TODO: rewrite to allow non-linearisable types
3163 0 : if (is_error ())
3164 : {
3165 0 : return "error";
3166 : }
3167 : else
3168 : {
3169 0 : if (has_type ())
3170 : {
3171 : // type (i.e. not ref, no lifetime)
3172 0 : std::string str;
3173 :
3174 0 : if (is_mut)
3175 0 : str += "mut ";
3176 :
3177 0 : str += "self : ";
3178 :
3179 0 : str += type->as_string ();
3180 :
3181 0 : return str;
3182 0 : }
3183 0 : else if (has_lifetime ())
3184 : {
3185 : // ref and lifetime
3186 0 : std::string str = "&" + get_lifetime ().as_string () + " ";
3187 :
3188 0 : if (is_mut)
3189 0 : str += "mut ";
3190 :
3191 0 : str += "self";
3192 :
3193 0 : return str;
3194 0 : }
3195 0 : else if (has_ref)
3196 : {
3197 : // ref with no lifetime
3198 0 : std::string str = "&";
3199 :
3200 0 : if (is_mut)
3201 0 : str += " mut ";
3202 :
3203 0 : str += "self";
3204 :
3205 0 : return str;
3206 0 : }
3207 : else
3208 : {
3209 : // no ref, no type
3210 0 : std::string str;
3211 :
3212 0 : if (is_mut)
3213 0 : str += "mut ";
3214 :
3215 0 : str += "self";
3216 :
3217 0 : return str;
3218 0 : }
3219 : }
3220 : }
3221 :
3222 : std::string
3223 0 : ArrayElemsCopied::as_string () const
3224 : {
3225 : // TODO: rewrite to allow non-linearisable exprs
3226 0 : return elem_to_copy->as_string () + "; " + num_copies->as_string ();
3227 : }
3228 :
3229 : std::string
3230 0 : LifetimeWhereClauseItem::as_string () const
3231 : {
3232 0 : std::string str ("Lifetime: ");
3233 :
3234 0 : str += lifetime.as_string ();
3235 :
3236 0 : str += "\nLifetime bounds: ";
3237 :
3238 0 : for (const auto &bound : lifetime_bounds)
3239 0 : str += "\n " + bound.as_string ();
3240 :
3241 0 : return str;
3242 : }
3243 :
3244 : std::string
3245 0 : TypeBoundWhereClauseItem::as_string () const
3246 : {
3247 0 : std::string str ("For lifetimes: ");
3248 :
3249 0 : if (!has_for_lifetimes ())
3250 : {
3251 0 : str += "none";
3252 : }
3253 : else
3254 : {
3255 0 : for (const auto &for_lifetime : for_lifetimes)
3256 0 : str += "\n " + for_lifetime.as_string ();
3257 : }
3258 :
3259 0 : str += "\nType: " + bound_type->as_string ();
3260 :
3261 0 : str += "\nType param bounds bounds: ";
3262 :
3263 0 : for (const auto &bound : type_param_bounds)
3264 : {
3265 : // debug null pointer check
3266 0 : if (bound == nullptr)
3267 0 : return "NULL_POINTER_MARK - type param bounds";
3268 :
3269 0 : str += "\n " + bound->as_string ();
3270 : }
3271 :
3272 0 : return str;
3273 0 : }
3274 :
3275 : std::string
3276 0 : ArrayElemsValues::as_string () const
3277 : {
3278 0 : std::string str;
3279 :
3280 0 : for (const auto &expr : values)
3281 : {
3282 : // DEBUG: null pointer check
3283 0 : if (expr == nullptr)
3284 : {
3285 0 : rust_debug ("something really terrible has gone wrong - null pointer "
3286 : "expr in array elems values.");
3287 0 : return "NULL_POINTER_MARK";
3288 : }
3289 :
3290 0 : str += "\n " + expr->as_string ();
3291 : }
3292 :
3293 0 : return str;
3294 0 : }
3295 :
3296 : std::string
3297 0 : MaybeNamedParam::as_string () const
3298 : {
3299 : // TODO: rewrite to allow using non-linearisable types in dump
3300 0 : std::string str;
3301 :
3302 0 : switch (param_kind)
3303 : {
3304 : case UNNAMED:
3305 : break;
3306 0 : case IDENTIFIER:
3307 0 : str = name.as_string () + " : ";
3308 0 : break;
3309 0 : case WILDCARD:
3310 0 : str = "_ : ";
3311 0 : break;
3312 0 : default:
3313 0 : return "ERROR_MARK_STRING - maybe named param unrecognised param kind";
3314 : }
3315 :
3316 0 : str += param_type->as_string ();
3317 :
3318 0 : return str;
3319 0 : }
3320 :
3321 44562 : MetaItemInner::~MetaItemInner () = default;
3322 :
3323 : std::unique_ptr<MetaNameValueStr>
3324 0 : MetaItemInner::to_meta_name_value_str () const
3325 : {
3326 0 : if (is_key_value_pair ())
3327 : {
3328 0 : auto converted_item = static_cast<const MetaNameValueStr *> (this);
3329 0 : return converted_item->to_meta_name_value_str ();
3330 : }
3331 : // TODO actually parse foo = bar
3332 0 : return nullptr;
3333 : }
3334 :
3335 : std::string
3336 546714 : MetaItemSeq::as_string () const
3337 : {
3338 546714 : std::string path_str = path.as_string () + "(";
3339 :
3340 546714 : auto i = seq.begin ();
3341 546714 : auto e = seq.end ();
3342 :
3343 1093428 : for (; i != e; i++)
3344 : {
3345 1093428 : path_str += (*i)->as_string ();
3346 546714 : if (e != i + 1)
3347 0 : path_str += ", ";
3348 : }
3349 :
3350 546714 : return path_str + ")";
3351 546714 : }
3352 :
3353 : std::string
3354 0 : MetaListPaths::as_string () const
3355 : {
3356 0 : std::string str = ident.as_string () + "(";
3357 :
3358 0 : auto i = paths.begin ();
3359 0 : auto e = paths.end ();
3360 :
3361 0 : for (; i != e; i++)
3362 : {
3363 0 : str += (*i).as_string ();
3364 0 : if (e != i + 1)
3365 0 : str += ", ";
3366 : }
3367 :
3368 0 : return str + ")";
3369 0 : }
3370 :
3371 : std::string
3372 0 : MetaListNameValueStr::as_string () const
3373 : {
3374 0 : std::string str = ident.as_string () + "(";
3375 :
3376 0 : auto i = strs.begin ();
3377 0 : auto e = strs.end ();
3378 :
3379 0 : for (; i != e; i++)
3380 : {
3381 0 : str += (*i).as_string ();
3382 0 : if (e != i + 1)
3383 0 : str += ", ";
3384 : }
3385 :
3386 0 : return str + ")";
3387 0 : }
3388 :
3389 : std::string
3390 546707 : AttrInputMetaItemContainer::as_string () const
3391 : {
3392 546707 : std::string str = "(";
3393 :
3394 546707 : auto i = items.begin ();
3395 546707 : auto e = items.end ();
3396 :
3397 1093414 : for (; i != e; i++)
3398 : {
3399 1093414 : str += (*i)->as_string ();
3400 546707 : if (e != i + 1)
3401 0 : str += ", ";
3402 : }
3403 :
3404 546707 : return str + ")";
3405 546707 : }
3406 :
3407 5998 : AttrInputExpr::AttrInputExpr (const AttrInputExpr &oth)
3408 5998 : : expr (oth.expr->clone_expr ())
3409 5998 : {}
3410 :
3411 : AttrInputExpr &
3412 0 : AttrInputExpr::operator= (const AttrInputExpr &oth)
3413 : {
3414 0 : expr = oth.expr->clone_expr ();
3415 0 : return *this;
3416 : }
3417 :
3418 : std::string
3419 0 : AttrInputExpr::as_string () const
3420 : {
3421 0 : return expr->as_string ();
3422 : }
3423 :
3424 : void
3425 25677 : AttrInputExpr::accept_vis (ASTVisitor &vis)
3426 : {
3427 25677 : vis.visit (*this);
3428 25677 : }
3429 :
3430 : /* Override that calls the function recursively on all items contained within
3431 : * the module. */
3432 : void
3433 0 : Module::add_crate_name (std::vector<std::string> &names) const
3434 : {
3435 : /* TODO: test whether module has been 'cfg'-ed out to determine whether to
3436 : * exclude it from search */
3437 :
3438 0 : for (const auto &item : items)
3439 0 : item->add_crate_name (names);
3440 0 : }
3441 :
3442 : static bool
3443 557 : file_exists (const std::string path)
3444 : {
3445 : // Simply check if the file exists
3446 : // FIXME: This does not work on Windows
3447 0 : return access (path.c_str (), F_OK) != -1;
3448 : }
3449 :
3450 : static std::string
3451 315 : filename_from_path_attribute (std::vector<Attribute> &outer_attrs)
3452 : {
3453 : // An out-of-line module cannot have inner attributes. Additionally, the
3454 : // default name is specified as `""` so that the caller can detect the case
3455 : // of "no path given" and use the default path logic (`name.rs` or
3456 : // `name/mod.rs`).
3457 315 : return extract_module_path ({}, outer_attrs, "");
3458 : }
3459 :
3460 : void
3461 318 : Module::process_file_path ()
3462 : {
3463 318 : rust_assert (kind == Module::ModuleKind::UNLOADED);
3464 :
3465 318 : if (!module_file.empty ())
3466 : {
3467 3 : rust_error_at (locus, "error handling module file for %qs",
3468 3 : module_name.as_string ().c_str ());
3469 85 : return;
3470 : }
3471 :
3472 : // This corresponds to the path of the file 'including' the module. So the
3473 : // file that contains the 'mod <file>;' directive
3474 315 : std::string including_fpath (outer_filename);
3475 :
3476 315 : std::string expected_file_path = module_name.as_string () + ".rs";
3477 315 : std::string expected_dir_path = "mod.rs";
3478 :
3479 315 : auto dir_slash_pos = including_fpath.rfind (file_separator);
3480 315 : std::string current_directory_name;
3481 315 : std::string including_fname;
3482 :
3483 : // If we haven't found a file_separator, then we may have to look for files in
3484 : // the current directory ('.')
3485 315 : if (dir_slash_pos == std::string::npos)
3486 : {
3487 1 : including_fname = std::move (including_fpath);
3488 2 : including_fpath = std::string (".") + file_separator + including_fname;
3489 1 : dir_slash_pos = 1;
3490 : }
3491 : else
3492 : {
3493 314 : including_fname = including_fpath.substr (dir_slash_pos + 1);
3494 : }
3495 :
3496 315 : current_directory_name
3497 630 : = including_fpath.substr (0, dir_slash_pos) + file_separator;
3498 :
3499 315 : auto path_string = filename_from_path_attribute (get_outer_attrs ());
3500 :
3501 315 : std::string including_subdir;
3502 315 : bool subdir_was_added = false;
3503 315 : if (path_string.empty () && module_scope.empty ()
3504 568 : && get_file_subdir (including_fname, including_subdir))
3505 : {
3506 82 : current_directory_name += including_subdir + file_separator;
3507 41 : subdir_was_added = true;
3508 : }
3509 :
3510 : // Handle inline module declarations adding path components.
3511 323 : for (auto const &name : module_scope)
3512 : {
3513 8 : current_directory_name.append (name);
3514 8 : current_directory_name.append (file_separator);
3515 : }
3516 :
3517 315 : if (!path_string.empty ())
3518 : {
3519 58 : module_file = current_directory_name + path_string;
3520 58 : return;
3521 : }
3522 :
3523 : // FIXME: We also have to search for
3524 : // <directory>/<including_fname>/<module_name>.rs In rustc, this is done via
3525 : // the concept of `DirOwnernship`, which is based on whether or not the
3526 : // current file is titled `mod.rs`.
3527 :
3528 : // First, we search for <directory>/<module_name>.rs
3529 257 : std::string file_mod_path = current_directory_name + expected_file_path;
3530 514 : bool file_mod_found = file_exists (file_mod_path);
3531 :
3532 : // Then, search for <directory>/<module_name>/mod.rs
3533 257 : std::string dir_mod_path = current_directory_name + module_name.as_string ()
3534 257 : + file_separator + expected_dir_path;
3535 514 : bool dir_mod_found = file_exists (dir_mod_path);
3536 :
3537 257 : if (!file_mod_found && !dir_mod_found && subdir_was_added)
3538 : {
3539 22 : size_t suffix_len
3540 22 : = including_subdir.length () + std::string (file_separator).length ();
3541 22 : std::string fallback_dir
3542 22 : = current_directory_name.substr (0, current_directory_name.length ()
3543 22 : - suffix_len);
3544 22 : std::string fallback_file = fallback_dir + expected_file_path;
3545 22 : std::string fallback_dir_mod = fallback_dir + module_name.as_string ()
3546 22 : + file_separator + expected_dir_path;
3547 44 : if (file_exists (fallback_file))
3548 : {
3549 1 : file_mod_found = true;
3550 1 : file_mod_path = fallback_file;
3551 : }
3552 42 : else if (file_exists (fallback_dir_mod))
3553 : {
3554 0 : dir_mod_found = true;
3555 0 : dir_mod_path = fallback_dir_mod;
3556 : }
3557 22 : }
3558 :
3559 257 : bool multiple_candidates_found = file_mod_found && dir_mod_found;
3560 257 : bool no_candidates_found = !file_mod_found && !dir_mod_found;
3561 :
3562 257 : if (multiple_candidates_found)
3563 0 : rust_error_at (locus,
3564 : "two candidates found for module %s: %s.rs and %s%smod.rs",
3565 0 : module_name.as_string ().c_str (),
3566 0 : module_name.as_string ().c_str (),
3567 0 : module_name.as_string ().c_str (), file_separator);
3568 :
3569 257 : if (no_candidates_found)
3570 21 : rust_error_at (locus, "no candidate found for module %s",
3571 21 : module_name.as_string ().c_str ());
3572 :
3573 257 : if (no_candidates_found || multiple_candidates_found)
3574 21 : return;
3575 :
3576 279 : module_file = std::move (file_mod_found ? file_mod_path : dir_mod_path);
3577 336 : }
3578 :
3579 : void
3580 318 : Module::load_items ()
3581 : {
3582 318 : process_file_path ();
3583 :
3584 : // We will already have errored out appropriately in the process_file_path ()
3585 : // method
3586 318 : if (module_file.empty ())
3587 32 : return;
3588 :
3589 297 : RAIIFile file_wrap (module_file.c_str ());
3590 297 : Linemap *linemap = Session::get_instance ().linemap;
3591 297 : if (!file_wrap.ok ())
3592 : {
3593 11 : rust_error_at (get_locus (), "cannot open module file %s: %m",
3594 : module_file.c_str ());
3595 11 : return;
3596 : }
3597 :
3598 286 : rust_debug ("Attempting to parse file %s", module_file.c_str ());
3599 :
3600 286 : Lexer lex (module_file.c_str (), std::move (file_wrap), linemap);
3601 286 : Parser<Lexer> parser (lex);
3602 :
3603 : // we need to parse any possible inner attributes for this module
3604 286 : inner_attrs = parser.parse_inner_attributes ();
3605 286 : auto parsed_items = parser.parse_items ().value_or (
3606 286 : std::vector<std::unique_ptr<AST::Item>>{});
3607 :
3608 286 : for (const auto &error : parser.get_errors ())
3609 0 : error.emit ();
3610 :
3611 286 : items = std::move (parsed_items);
3612 286 : kind = ModuleKind::LOADED;
3613 583 : }
3614 :
3615 : void
3616 4149 : Attribute::parse_attr_to_meta_item ()
3617 : {
3618 : // only parse if has attribute input and not already parsed
3619 4149 : if (!has_attr_input () || is_parsed_to_meta_item ())
3620 997 : return;
3621 :
3622 3152 : auto res = attr_input->parse_to_meta_item ();
3623 3152 : std::unique_ptr<AttrInput> converted_input (res);
3624 :
3625 3152 : if (converted_input != nullptr)
3626 3152 : attr_input = std::move (converted_input);
3627 3152 : }
3628 :
3629 : AttrInputMetaItemContainer *
3630 18540 : DelimTokenTree::parse_to_meta_item () const
3631 : {
3632 : // must have token trees
3633 18540 : if (token_trees.empty ())
3634 : return nullptr;
3635 :
3636 : /* assume top-level delim token tree in attribute - convert all nested ones
3637 : * to token stream */
3638 18540 : std::vector<std::unique_ptr<Token>> token_stream_wrapped = to_token_stream ();
3639 :
3640 18540 : std::vector<const_TokenPtr> token_stream;
3641 18540 : token_stream.reserve (token_stream_wrapped.size ());
3642 127460 : for (auto &tk : token_stream_wrapped)
3643 217840 : token_stream.push_back (tk->get_tok_ptr ());
3644 :
3645 18540 : AttributeParser parser (std::move (token_stream));
3646 18540 : std::vector<std::unique_ptr<MetaItemInner>> meta_items (
3647 18540 : parser.parse_meta_item_seq ());
3648 :
3649 18540 : return new AttrInputMetaItemContainer (std::move (meta_items));
3650 18540 : }
3651 :
3652 18569 : AttributeParser::AttributeParser (std::vector<const_TokenPtr> token_stream,
3653 : int stream_start_pos)
3654 18569 : : lexer (new MacroInvocLexer (std::move (token_stream))),
3655 18569 : parser (new Parser<MacroInvocLexer> (*lexer))
3656 : {
3657 18569 : if (stream_start_pos)
3658 0 : lexer->skip_token (stream_start_pos - 1);
3659 18569 : }
3660 :
3661 18569 : AttributeParser::~AttributeParser () {}
3662 :
3663 : std::unique_ptr<MetaItemInner>
3664 30336 : AttributeParser::parse_meta_item_inner ()
3665 : {
3666 : // if first tok not identifier, not a "special" case one
3667 60672 : if (lexer->peek_token ()->get_id () != IDENTIFIER)
3668 : {
3669 74 : switch (lexer->peek_token ()->get_id ())
3670 : {
3671 37 : case CHAR_LITERAL:
3672 37 : case STRING_LITERAL:
3673 37 : case BYTE_CHAR_LITERAL:
3674 37 : case BYTE_STRING_LITERAL:
3675 37 : case RAW_STRING_LITERAL:
3676 37 : case C_STRING_LITERAL:
3677 37 : case INT_LITERAL:
3678 37 : case FLOAT_LITERAL:
3679 37 : case TRUE_LITERAL:
3680 37 : case FALSE_LITERAL:
3681 37 : return parse_meta_item_lit ();
3682 :
3683 0 : case SUPER:
3684 0 : case SELF:
3685 0 : case CRATE:
3686 0 : case DOLLAR_SIGN:
3687 0 : case SCOPE_RESOLUTION:
3688 0 : return parse_path_meta_item ();
3689 :
3690 0 : default:
3691 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3692 : "unrecognised token '%s' in meta item",
3693 : get_token_description (
3694 0 : lexer->peek_token ()->get_id ()));
3695 0 : return nullptr;
3696 : }
3697 : }
3698 :
3699 : // else, check for path
3700 60598 : if (lexer->peek_token (1)->get_id () == SCOPE_RESOLUTION)
3701 : {
3702 : // path
3703 0 : return parse_path_meta_item ();
3704 : }
3705 :
3706 60598 : auto ident = lexer->peek_token ()->get_str ();
3707 30299 : auto ident_locus = lexer->peek_token ()->get_locus ();
3708 :
3709 60598 : if (is_end_meta_item_tok (lexer->peek_token (1)->get_id ()))
3710 : {
3711 : // meta word syntax
3712 13812 : lexer->skip_token ();
3713 41436 : return std::unique_ptr<MetaWord> (new MetaWord (ident, ident_locus));
3714 : }
3715 :
3716 32974 : if (lexer->peek_token (1)->get_id () == EQUAL)
3717 : {
3718 : // maybe meta name value str syntax - check next 2 tokens
3719 28510 : if (lexer->peek_token (2)->get_id () == STRING_LITERAL
3720 28065 : && is_end_meta_item_tok (lexer->peek_token (3)->get_id ()))
3721 : {
3722 : // meta name value str syntax
3723 13810 : const_TokenPtr value_tok = lexer->peek_token (2);
3724 13810 : auto value = value_tok->get_str ();
3725 13810 : auto locus = value_tok->get_locus ();
3726 :
3727 13810 : lexer->skip_token (2);
3728 :
3729 13810 : return std::unique_ptr<MetaNameValueStr> (
3730 27620 : new MetaNameValueStr (ident, ident_locus, std::move (value),
3731 41430 : locus));
3732 27620 : }
3733 : else
3734 : {
3735 : // just interpret as path-based meta item
3736 445 : return parse_path_meta_item ();
3737 : }
3738 : }
3739 :
3740 4464 : if (lexer->peek_token (1)->get_id () != LEFT_PAREN)
3741 : {
3742 0 : rust_error_at (lexer->peek_token (1)->get_locus (),
3743 : "unexpected token '%s' after identifier in attribute",
3744 0 : get_token_description (lexer->peek_token (1)->get_id ()));
3745 0 : return nullptr;
3746 : }
3747 :
3748 : // is it one of those special cases like not?
3749 4464 : if (lexer->peek_token ()->get_id () == IDENTIFIER)
3750 : {
3751 2232 : return parse_path_meta_item ();
3752 : }
3753 :
3754 0 : auto meta_items = parse_meta_item_seq ();
3755 :
3756 : // pass for meta name value str
3757 0 : std::vector<MetaNameValueStr> meta_name_value_str_items;
3758 0 : for (const auto &item : meta_items)
3759 : {
3760 0 : std::unique_ptr<MetaNameValueStr> converted_item
3761 0 : = item->to_meta_name_value_str ();
3762 0 : if (converted_item == nullptr)
3763 : {
3764 0 : meta_name_value_str_items.clear ();
3765 0 : break;
3766 : }
3767 0 : meta_name_value_str_items.push_back (std::move (*converted_item));
3768 0 : }
3769 : // if valid, return this
3770 0 : if (!meta_name_value_str_items.empty ())
3771 : {
3772 0 : return std::unique_ptr<MetaListNameValueStr> (
3773 0 : new MetaListNameValueStr (ident, ident_locus,
3774 0 : std::move (meta_name_value_str_items)));
3775 : }
3776 :
3777 : // // pass for meta list idents
3778 : // std::vector<Identifier> ident_items;
3779 : // for (const auto &item : meta_items)
3780 : // {
3781 : // std::unique_ptr<Identifier> converted_ident (item->to_ident_item ());
3782 : // if (converted_ident == nullptr)
3783 : // {
3784 : // ident_items.clear ();
3785 : // break;
3786 : // }
3787 : // ident_items.push_back (std::move (*converted_ident));
3788 : // }
3789 : // // if valid return this
3790 : // if (!ident_items.empty ())
3791 : // {
3792 : // return std::unique_ptr<MetaListIdents> (
3793 : // new MetaListIdents (std::move (ident), std::move (ident_items)));
3794 : // }
3795 : // // as currently no meta list ident, currently no path. may change in future
3796 :
3797 : // pass for meta list paths
3798 0 : std::vector<SimplePath> path_items;
3799 0 : for (const auto &item : meta_items)
3800 : {
3801 0 : SimplePath converted_path (item->to_path_item ());
3802 0 : if (converted_path.is_empty ())
3803 : {
3804 0 : path_items.clear ();
3805 0 : break;
3806 : }
3807 0 : path_items.push_back (std::move (converted_path));
3808 0 : }
3809 0 : if (!path_items.empty ())
3810 : {
3811 0 : return std::unique_ptr<MetaListPaths> (
3812 0 : new MetaListPaths (ident, ident_locus, std::move (path_items)));
3813 : }
3814 :
3815 0 : rust_error_at (UNKNOWN_LOCATION, "failed to parse any meta item inner");
3816 0 : return nullptr;
3817 30299 : }
3818 :
3819 : bool
3820 44109 : AttributeParser::is_end_meta_item_tok (TokenId id) const
3821 : {
3822 44109 : return id == COMMA || id == RIGHT_PAREN;
3823 : }
3824 :
3825 : std::unique_ptr<MetaItem>
3826 2677 : AttributeParser::parse_path_meta_item ()
3827 : {
3828 2677 : auto path = parser->parse_simple_path ();
3829 2677 : if (!path)
3830 : {
3831 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3832 : "failed to parse simple path in attribute");
3833 0 : return nullptr;
3834 : }
3835 :
3836 5354 : switch (lexer->peek_token ()->get_id ())
3837 : {
3838 2232 : case LEFT_PAREN:
3839 2232 : {
3840 2232 : std::vector<std::unique_ptr<MetaItemInner>> meta_items
3841 2232 : = parse_meta_item_seq ();
3842 :
3843 2232 : return std::unique_ptr<MetaItemSeq> (
3844 4464 : new MetaItemSeq (std::move (path.value ()), std::move (meta_items)));
3845 2232 : }
3846 445 : case EQUAL:
3847 445 : {
3848 445 : lexer->skip_token ();
3849 :
3850 445 : auto expr = parser->parse_expr ();
3851 :
3852 : // handle error
3853 : // parse_expr should already emit an error and return nullptr
3854 445 : if (!expr)
3855 0 : return nullptr;
3856 :
3857 445 : return std::unique_ptr<MetaItemPathExpr> (
3858 445 : new MetaItemPathExpr (std::move (path.value ()),
3859 890 : std::move (expr.value ())));
3860 445 : }
3861 0 : case COMMA:
3862 : // just simple path
3863 0 : return std::unique_ptr<MetaItemPath> (
3864 0 : new MetaItemPath (std::move (path.value ())));
3865 0 : default:
3866 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3867 : "unrecognised token '%s' in meta item",
3868 0 : get_token_description (lexer->peek_token ()->get_id ()));
3869 0 : return nullptr;
3870 : }
3871 2677 : }
3872 :
3873 : /* Parses a parenthesised sequence of meta item inners. Parentheses are
3874 : * required here. */
3875 : std::vector<std::unique_ptr<MetaItemInner>>
3876 20801 : AttributeParser::parse_meta_item_seq ()
3877 : {
3878 20801 : std::vector<std::unique_ptr<MetaItemInner>> meta_items;
3879 :
3880 41602 : if (lexer->peek_token ()->get_id () != LEFT_PAREN)
3881 : {
3882 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3883 : "missing left paren in delim token tree");
3884 0 : return {};
3885 : }
3886 20801 : lexer->skip_token ();
3887 :
3888 20801 : while (lexer->peek_token ()->get_id () != END_OF_FILE
3889 91188 : && lexer->peek_token ()->get_id () != RIGHT_PAREN)
3890 : {
3891 30336 : std::unique_ptr<MetaItemInner> inner = parse_meta_item_inner ();
3892 30336 : if (inner == nullptr)
3893 : {
3894 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3895 : "failed to parse inner meta item in attribute");
3896 0 : return {};
3897 : }
3898 30336 : meta_items.push_back (std::move (inner));
3899 :
3900 60672 : if (lexer->peek_token ()->get_id () != COMMA)
3901 : break;
3902 :
3903 9595 : lexer->skip_token ();
3904 30336 : }
3905 :
3906 41602 : if (lexer->peek_token ()->get_id () != RIGHT_PAREN)
3907 : {
3908 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3909 : "missing right paren in delim token tree");
3910 0 : return {};
3911 : }
3912 20801 : lexer->skip_token ();
3913 :
3914 20801 : return meta_items;
3915 20801 : }
3916 :
3917 : /* Collects any nested token trees into a flat token stream, suitable for
3918 : * parsing. */
3919 : std::vector<std::unique_ptr<Token>>
3920 434266 : DelimTokenTree::to_token_stream () const
3921 : {
3922 434266 : std::vector<std::unique_ptr<Token>> tokens;
3923 4418459 : for (const auto &tree : token_trees)
3924 : {
3925 3984193 : std::vector<std::unique_ptr<Token>> stream = tree->to_token_stream ();
3926 :
3927 3984193 : tokens.insert (tokens.end (), std::make_move_iterator (stream.begin ()),
3928 : std::make_move_iterator (stream.end ()));
3929 3984193 : }
3930 :
3931 434266 : tokens.shrink_to_fit ();
3932 434266 : return tokens;
3933 : }
3934 :
3935 : std::unique_ptr<MetaItemLitExpr>
3936 37 : AttributeParser::parse_meta_item_lit ()
3937 : {
3938 37 : auto lit_expr = parser->parse_literal_expr ({});
3939 :
3940 : // TODO: return nullptr instead?
3941 37 : if (!lit_expr)
3942 0 : lit_expr = std::unique_ptr<LiteralExpr> (
3943 0 : new LiteralExpr (Literal::create_error (), {},
3944 0 : lexer->peek_token ()->get_locus ()));
3945 :
3946 37 : return std::unique_ptr<MetaItemLitExpr> (
3947 37 : new MetaItemLitExpr (std::move (*lit_expr.value ())));
3948 37 : }
3949 :
3950 : bool
3951 0 : AttrInputMetaItemContainer::check_cfg_predicate (const Session &session) const
3952 : {
3953 0 : if (items.empty ())
3954 : return false;
3955 :
3956 0 : for (const auto &inner_item : items)
3957 : {
3958 0 : if (!inner_item->check_cfg_predicate (session))
3959 0 : return false;
3960 : }
3961 :
3962 : return true;
3963 : }
3964 :
3965 : bool
3966 1 : MetaItemLitExpr::check_cfg_predicate (const Session &) const
3967 : {
3968 : /* as far as I can tell, a literal expr can never be a valid cfg body, so
3969 : * false */
3970 1 : rust_error_at (this->get_locus (), "'%s' predicate key cannot be a literal",
3971 1 : this->as_string ().c_str ());
3972 :
3973 1 : return false;
3974 : }
3975 :
3976 : bool
3977 0 : MetaListNameValueStr::check_cfg_predicate (const Session &session) const
3978 : {
3979 0 : if (ident.as_string () == "all")
3980 : {
3981 0 : for (const auto &str : strs)
3982 : {
3983 0 : if (!str.check_cfg_predicate (session))
3984 0 : return false;
3985 : }
3986 : return true;
3987 : }
3988 0 : else if (ident.as_string () == "any")
3989 : {
3990 0 : for (const auto &str : strs)
3991 : {
3992 0 : if (str.check_cfg_predicate (session))
3993 0 : return true;
3994 : }
3995 : return false;
3996 : }
3997 0 : else if (ident.as_string () == "not")
3998 : {
3999 0 : if (strs.size () != 1)
4000 : {
4001 : /* HACK: convert vector platform-dependent size_type to string to
4002 : * use in printf */
4003 0 : rust_error_at (UNKNOWN_LOCATION,
4004 : "cfg predicate could not be checked for "
4005 : "MetaListNameValueStr with ident of "
4006 : "'not' because there are '%s' elements, not '1'",
4007 0 : std::to_string (strs.size ()).c_str ());
4008 0 : return false;
4009 : }
4010 :
4011 0 : return !strs[0].check_cfg_predicate (session);
4012 : }
4013 : else
4014 : {
4015 0 : rust_error_at (UNKNOWN_LOCATION,
4016 : "cfg predicate could not be checked for "
4017 : "MetaListNameValueStr with ident of "
4018 : "'%s' - ident must be 'all' or 'any'",
4019 0 : ident.as_string ().c_str ());
4020 0 : return false;
4021 : }
4022 : }
4023 :
4024 : bool
4025 0 : MetaListPaths::check_cfg_predicate (const Session &session) const
4026 : {
4027 0 : if (ident.as_string () == "all")
4028 : {
4029 0 : for (const auto &path : paths)
4030 : {
4031 0 : if (!check_path_exists_in_cfg (session, path))
4032 0 : return false;
4033 : }
4034 : return true;
4035 : }
4036 0 : else if (ident.as_string () == "any")
4037 : {
4038 0 : for (const auto &path : paths)
4039 : {
4040 0 : if (check_path_exists_in_cfg (session, path))
4041 0 : return true;
4042 : }
4043 : return false;
4044 : }
4045 0 : else if (ident.as_string () == "not")
4046 : {
4047 0 : if (paths.size () != 1)
4048 : {
4049 : // HACK: convert vector platform-dependent size_type to string to
4050 : // use in printf
4051 0 : rust_error_at (UNKNOWN_LOCATION,
4052 : "cfg predicate could not be checked for MetaListPaths "
4053 : "with ident of 'not' "
4054 : "because there are '%s' elements, not '1'",
4055 0 : std::to_string (paths.size ()).c_str ());
4056 0 : return false;
4057 : }
4058 :
4059 0 : return !check_path_exists_in_cfg (session, paths[0]);
4060 : }
4061 : else
4062 : {
4063 0 : rust_error_at (UNKNOWN_LOCATION,
4064 : "cfg predicate could not be checked for "
4065 : "MetaListNameValueStr with ident of "
4066 : "'%s' - ident must be 'all' or 'any'",
4067 0 : ident.as_string ().c_str ());
4068 0 : return false;
4069 : }
4070 : }
4071 :
4072 : bool
4073 0 : MetaListPaths::check_path_exists_in_cfg (const Session &session,
4074 : const SimplePath &path) const
4075 : {
4076 0 : return session.options.target_data.has_key (path.as_string ());
4077 : }
4078 :
4079 : bool
4080 4192 : MetaItemSeq::check_cfg_predicate (const Session &session) const
4081 : {
4082 4192 : if (path.as_string () == "all")
4083 : {
4084 894 : for (const auto &item : seq)
4085 : {
4086 713 : if (!item->check_cfg_predicate (session))
4087 4192 : return false;
4088 : }
4089 : return true;
4090 : }
4091 3924 : else if (path.as_string () == "any")
4092 : {
4093 893 : for (const auto &item : seq)
4094 : {
4095 840 : if (item->check_cfg_predicate (session))
4096 4192 : return true;
4097 : }
4098 : return false;
4099 : }
4100 3513 : else if (path.as_string () == "not")
4101 : {
4102 3513 : if (seq.size () != 1)
4103 : {
4104 : /* HACK: convert vector platform-dependent size_type to string to
4105 : * use in printf */
4106 0 : rust_error_at (UNKNOWN_LOCATION,
4107 : "cfg predicate could not be checked for MetaItemSeq "
4108 : "with ident of 'not' "
4109 : "because there are '%s' elements, not '1'",
4110 0 : std::to_string (seq.size ()).c_str ());
4111 0 : return false;
4112 : }
4113 :
4114 3513 : return !seq[0]->check_cfg_predicate (session);
4115 : }
4116 : else
4117 : {
4118 0 : rust_error_at (
4119 : UNKNOWN_LOCATION,
4120 : "cfg predicate could not be checked for MetaItemSeq with path of "
4121 : "'%s' - path must be 'all' or 'any'",
4122 0 : path.as_string ().c_str ());
4123 0 : return false;
4124 : }
4125 : }
4126 :
4127 : bool
4128 3008 : MetaWord::check_cfg_predicate (const Session &session) const
4129 : {
4130 6016 : return session.options.target_data.has_key (ident.as_string ());
4131 : }
4132 :
4133 : bool
4134 0 : MetaItemPath::check_cfg_predicate (const Session &session) const
4135 : {
4136 : /* Strictly speaking, this should always be false, but maybe do check
4137 : * relating to SimplePath being identifier. Currently, it would return true
4138 : * if path as identifier existed, and if the path in string form existed
4139 : * (though this shouldn't occur). */
4140 0 : return session.options.target_data.has_key (path.as_string ());
4141 : }
4142 :
4143 : bool
4144 7815 : MetaNameValueStr::check_cfg_predicate (const Session &session) const
4145 : {
4146 : // DEBUG
4147 7815 : rust_debug (
4148 : "checked key-value pair for cfg: '%s', '%s' - is%s in target data",
4149 : ident.as_string ().c_str (), str.c_str (),
4150 : session.options.target_data.has_key_value_pair (ident.as_string (), str)
4151 : ? ""
4152 : : " not");
4153 :
4154 15630 : return session.options.target_data.has_key_value_pair (ident.as_string (),
4155 7815 : str);
4156 : }
4157 :
4158 : bool
4159 0 : MetaItemPathExpr::check_cfg_predicate (const Session &session) const
4160 : {
4161 : // FIXME: Accept path expressions
4162 0 : rust_assert (expr->is_literal ());
4163 0 : return session.options.target_data.has_key_value_pair (path.as_string (),
4164 0 : expr->as_string ());
4165 : }
4166 :
4167 : std::vector<std::unique_ptr<Token>>
4168 3767522 : Token::to_token_stream () const
4169 : {
4170 : /* initialisation list doesn't work as it needs copy constructor, so have to
4171 : * do this */
4172 3767522 : std::vector<std::unique_ptr<Token>> dummy_vector;
4173 3767522 : dummy_vector.reserve (1);
4174 3767522 : dummy_vector.push_back (std::unique_ptr<Token> (clone_token_impl ()));
4175 3767522 : return dummy_vector;
4176 : }
4177 :
4178 : Attribute
4179 9 : MetaNameValueStr::to_attribute () const
4180 : {
4181 9 : LiteralExpr lit_expr (str, Literal::LitType::STRING,
4182 18 : PrimitiveCoreType::CORETYPE_UNKNOWN, {}, str_locus);
4183 : // FIXME: What location do we put here? Is the literal above supposed to have
4184 : // an empty location as well?
4185 : // Should MetaNameValueStr keep a location?
4186 18 : return Attribute (SimplePath::from_str (ident.as_string (), ident_locus),
4187 18 : std::unique_ptr<AttrInputLiteral> (
4188 27 : new AttrInputLiteral (std::move (lit_expr))));
4189 9 : }
4190 :
4191 : Attribute
4192 0 : MetaItemPath::to_attribute () const
4193 : {
4194 0 : return Attribute (path, nullptr);
4195 : }
4196 :
4197 : Attribute
4198 50 : MetaItemSeq::to_attribute () const
4199 : {
4200 50 : std::vector<std::unique_ptr<MetaItemInner>> new_seq;
4201 50 : new_seq.reserve (seq.size ());
4202 101 : for (const auto &e : seq)
4203 51 : new_seq.push_back (e->clone_meta_item_inner ());
4204 :
4205 50 : std::unique_ptr<AttrInputMetaItemContainer> new_seq_container (
4206 50 : new AttrInputMetaItemContainer (std::move (new_seq)));
4207 50 : return Attribute (path, std::move (new_seq_container));
4208 50 : }
4209 :
4210 : Attribute
4211 1 : MetaWord::to_attribute () const
4212 : {
4213 2 : return Attribute (SimplePath::from_str (ident.as_string (), ident_locus),
4214 3 : nullptr);
4215 : }
4216 :
4217 : Attribute
4218 0 : MetaListPaths::to_attribute () const
4219 : {
4220 : /* probably one of the most annoying conversions - have to lose specificity by
4221 : * turning it into just AttrInputMetaItemContainer (i.e. paths-only nature is
4222 : * no longer known). If conversions back are required, might have to do a
4223 : * "check all are paths" pass or something. */
4224 :
4225 0 : std::vector<std::unique_ptr<MetaItemInner>> new_seq;
4226 0 : new_seq.reserve (paths.size ());
4227 0 : for (const auto &e : paths)
4228 0 : new_seq.push_back (std::unique_ptr<MetaItemPath> (new MetaItemPath (e)));
4229 :
4230 0 : std::unique_ptr<AttrInputMetaItemContainer> new_seq_container (
4231 0 : new AttrInputMetaItemContainer (std::move (new_seq)));
4232 0 : return Attribute (SimplePath::from_str (ident.as_string (), ident_locus),
4233 0 : std::move (new_seq_container));
4234 0 : }
4235 :
4236 : Attribute
4237 0 : MetaListNameValueStr::to_attribute () const
4238 : {
4239 0 : std::vector<std::unique_ptr<MetaItemInner>> new_seq;
4240 0 : new_seq.reserve (strs.size ());
4241 0 : for (const auto &e : strs)
4242 0 : new_seq.push_back (
4243 0 : std::unique_ptr<MetaNameValueStr> (new MetaNameValueStr (e)));
4244 :
4245 0 : std::unique_ptr<AttrInputMetaItemContainer> new_seq_container (
4246 0 : new AttrInputMetaItemContainer (std::move (new_seq)));
4247 0 : return Attribute (SimplePath::from_str (ident.as_string (), ident_locus),
4248 0 : std::move (new_seq_container));
4249 0 : }
4250 :
4251 : Attribute
4252 1 : MetaItemPathExpr::to_attribute () const
4253 : {
4254 1 : auto input = std::make_unique<AttrInputExpr> (expr->clone_expr ());
4255 1 : return Attribute (path, std::move (input));
4256 1 : }
4257 :
4258 : std::vector<Attribute>
4259 61 : AttrInputMetaItemContainer::separate_cfg_attrs () const
4260 : {
4261 61 : rust_assert (!items.empty ());
4262 :
4263 61 : if (items.size () == 1)
4264 0 : return {};
4265 :
4266 61 : std::vector<Attribute> attrs;
4267 61 : attrs.reserve (items.size () - 1);
4268 :
4269 122 : for (auto it = items.begin () + 1; it != items.end (); ++it)
4270 : {
4271 61 : auto &item = **it;
4272 :
4273 61 : Attribute attr = item.to_attribute ();
4274 61 : if (attr.is_empty ())
4275 : {
4276 : /* TODO should this be an error that causes us to chuck out
4277 : * everything? */
4278 0 : continue;
4279 : }
4280 61 : attrs.push_back (std::move (attr));
4281 61 : }
4282 :
4283 61 : attrs.shrink_to_fit ();
4284 61 : return attrs;
4285 61 : }
4286 :
4287 : bool
4288 9794 : Attribute::check_cfg_predicate (const Session &session) const
4289 : {
4290 9794 : auto string_path = path.as_string ();
4291 : /* assume that cfg predicate actually can exist, i.e. attribute has cfg or
4292 : * cfg_attr path */
4293 9794 : if (!has_attr_input ())
4294 : {
4295 1 : rust_error_at (path.get_locus (), "%qs is not followed by parentheses",
4296 : string_path.c_str ());
4297 1 : return false;
4298 : }
4299 :
4300 : // assume that it has already been parsed
4301 9793 : if (!is_parsed_to_meta_item ())
4302 : return false;
4303 :
4304 9793 : auto &meta_item = static_cast<AttrInputMetaItemContainer &> (*attr_input);
4305 9793 : if (meta_item.get_items ().empty ())
4306 : {
4307 3 : rust_error_at (path.get_locus (), "malformed %<%s%> attribute input",
4308 : string_path.c_str ());
4309 3 : return false;
4310 : }
4311 :
4312 9790 : if (string_path == Values::Attributes::CFG
4313 9790 : && meta_item.get_items ().size () != 1)
4314 : {
4315 1 : rust_error_at (path.get_locus (), "multiple %qs predicates are specified",
4316 1 : path.as_string ().c_str ());
4317 1 : return false;
4318 : }
4319 9789 : return meta_item.get_items ().front ()->check_cfg_predicate (session);
4320 9794 : }
4321 :
4322 : std::vector<Attribute>
4323 61 : Attribute::separate_cfg_attrs () const
4324 : {
4325 122 : if (!has_attr_input () || path.as_string () != Values::Attributes::CFG_ATTR)
4326 0 : return {};
4327 :
4328 : // assume that it has already been parsed
4329 61 : if (!is_parsed_to_meta_item ())
4330 0 : return {};
4331 :
4332 61 : return attr_input->separate_cfg_attrs ();
4333 : }
4334 :
4335 : bool
4336 31858 : Attribute::is_parsed_to_meta_item () const
4337 : {
4338 31858 : return has_attr_input () && attr_input->is_meta_item ();
4339 : }
4340 :
4341 : void
4342 128531 : BlockExpr::normalize_tail_expr ()
4343 : {
4344 128531 : if (!expr)
4345 : {
4346 : // HACK: try to turn the last statement into a tail expression
4347 93020 : if (!statements.empty () && statements.back ()->is_expr ())
4348 : {
4349 : // Watch out: This reference become invalid when the vector is
4350 : // modified.
4351 77941 : auto &stmt = static_cast<ExprStmt &> (*statements.back ());
4352 :
4353 77941 : if (!stmt.is_semicolon_followed ())
4354 : {
4355 85 : expr = stmt.take_expr ();
4356 85 : statements.pop_back ();
4357 : }
4358 : }
4359 : }
4360 128531 : }
4361 :
4362 : /* Visitor implementations - these are short but inlining can't happen anyway
4363 : * due to virtual functions and I didn't want to make the ast header includes
4364 : * any longer than they already are. */
4365 :
4366 : void
4367 33909823 : Token::accept_vis (ASTVisitor &vis)
4368 : {
4369 33909823 : vis.visit (*this);
4370 33909823 : }
4371 :
4372 : void
4373 4759448 : DelimTokenTree::accept_vis (ASTVisitor &vis)
4374 : {
4375 4759448 : vis.visit (*this);
4376 4759448 : }
4377 :
4378 : void
4379 36076766 : IdentifierExpr::accept_vis (ASTVisitor &vis)
4380 : {
4381 36076766 : vis.visit (*this);
4382 36076765 : }
4383 :
4384 : void
4385 36158 : Lifetime::accept_vis (ASTVisitor &vis)
4386 : {
4387 36158 : vis.visit (*this);
4388 36158 : }
4389 :
4390 : void
4391 270752 : LifetimeParam::accept_vis (ASTVisitor &vis)
4392 : {
4393 270752 : vis.visit (*this);
4394 270752 : }
4395 :
4396 : void
4397 52904382 : LiteralExpr::accept_vis (ASTVisitor &vis)
4398 : {
4399 52904382 : vis.visit (*this);
4400 52904382 : }
4401 :
4402 : void
4403 12124474 : AttrInputLiteral::accept_vis (ASTVisitor &vis)
4404 : {
4405 12124474 : vis.visit (*this);
4406 12124474 : }
4407 :
4408 : void
4409 0 : MetaItemLitExpr::accept_vis (ASTVisitor &vis)
4410 : {
4411 0 : vis.visit (*this);
4412 0 : }
4413 :
4414 : void
4415 2 : MetaItemPathExpr::accept_vis (ASTVisitor &vis)
4416 : {
4417 2 : vis.visit (*this);
4418 2 : }
4419 :
4420 : void
4421 1462906 : BorrowExpr::accept_vis (ASTVisitor &vis)
4422 : {
4423 1462906 : vis.visit (*this);
4424 1462906 : }
4425 :
4426 : void
4427 1842378 : DereferenceExpr::accept_vis (ASTVisitor &vis)
4428 : {
4429 1842378 : vis.visit (*this);
4430 1842378 : }
4431 :
4432 : void
4433 99040 : ErrorPropagationExpr::accept_vis (ASTVisitor &vis)
4434 : {
4435 99040 : vis.visit (*this);
4436 99040 : }
4437 :
4438 : void
4439 257039 : NegationExpr::accept_vis (ASTVisitor &vis)
4440 : {
4441 257039 : vis.visit (*this);
4442 257039 : }
4443 :
4444 : void
4445 8787229 : ArithmeticOrLogicalExpr::accept_vis (ASTVisitor &vis)
4446 : {
4447 8787229 : vis.visit (*this);
4448 8787229 : }
4449 :
4450 : void
4451 808502 : ComparisonExpr::accept_vis (ASTVisitor &vis)
4452 : {
4453 808502 : vis.visit (*this);
4454 808502 : }
4455 :
4456 : void
4457 201922 : LazyBooleanExpr::accept_vis (ASTVisitor &vis)
4458 : {
4459 201922 : vis.visit (*this);
4460 201922 : }
4461 :
4462 : void
4463 1271341 : TypeCastExpr::accept_vis (ASTVisitor &vis)
4464 : {
4465 1271341 : vis.visit (*this);
4466 1271341 : }
4467 :
4468 : void
4469 502821 : AssignmentExpr::accept_vis (ASTVisitor &vis)
4470 : {
4471 502821 : vis.visit (*this);
4472 502821 : }
4473 :
4474 : void
4475 306178 : CompoundAssignmentExpr::accept_vis (ASTVisitor &vis)
4476 : {
4477 306178 : vis.visit (*this);
4478 306178 : }
4479 :
4480 : void
4481 3346161 : ArrayElemsValues::accept_vis (ASTVisitor &vis)
4482 : {
4483 3346161 : vis.visit (*this);
4484 3346161 : }
4485 :
4486 : void
4487 15368 : ArrayElemsCopied::accept_vis (ASTVisitor &vis)
4488 : {
4489 15368 : vis.visit (*this);
4490 15368 : }
4491 :
4492 : void
4493 3361545 : ArrayExpr::accept_vis (ASTVisitor &vis)
4494 : {
4495 3361545 : vis.visit (*this);
4496 3361545 : }
4497 :
4498 : void
4499 207995 : ArrayIndexExpr::accept_vis (ASTVisitor &vis)
4500 : {
4501 207995 : vis.visit (*this);
4502 207995 : }
4503 :
4504 : void
4505 973334 : TupleExpr::accept_vis (ASTVisitor &vis)
4506 : {
4507 973334 : vis.visit (*this);
4508 973334 : }
4509 :
4510 : void
4511 1057337 : TupleIndexExpr::accept_vis (ASTVisitor &vis)
4512 : {
4513 1057337 : vis.visit (*this);
4514 1057337 : }
4515 :
4516 : void
4517 8402 : StructExprStruct::accept_vis (ASTVisitor &vis)
4518 : {
4519 8402 : vis.visit (*this);
4520 8402 : }
4521 :
4522 : void
4523 53455 : StructExprFieldIdentifier::accept_vis (ASTVisitor &vis)
4524 : {
4525 53455 : vis.visit (*this);
4526 53455 : }
4527 :
4528 : void
4529 260068 : StructExprFieldIdentifierValue::accept_vis (ASTVisitor &vis)
4530 : {
4531 260068 : vis.visit (*this);
4532 260068 : }
4533 :
4534 : void
4535 1054 : StructExprFieldIndexValue::accept_vis (ASTVisitor &vis)
4536 : {
4537 1054 : vis.visit (*this);
4538 1054 : }
4539 :
4540 : void
4541 165884 : StructExprStructFields::accept_vis (ASTVisitor &vis)
4542 : {
4543 165884 : vis.visit (*this);
4544 165884 : }
4545 :
4546 : void
4547 0 : StructExprStructBase::accept_vis (ASTVisitor &vis)
4548 : {
4549 0 : vis.visit (*this);
4550 0 : }
4551 :
4552 : void
4553 15051850 : CallExpr::accept_vis (ASTVisitor &vis)
4554 : {
4555 15051850 : vis.visit (*this);
4556 15051849 : }
4557 :
4558 : void
4559 8288558 : MethodCallExpr::accept_vis (ASTVisitor &vis)
4560 : {
4561 8288558 : vis.visit (*this);
4562 8288558 : }
4563 :
4564 : void
4565 1379599 : FieldAccessExpr::accept_vis (ASTVisitor &vis)
4566 : {
4567 1379599 : vis.visit (*this);
4568 1379599 : }
4569 :
4570 : void
4571 107822 : ClosureExprInner::accept_vis (ASTVisitor &vis)
4572 : {
4573 107822 : vis.visit (*this);
4574 107822 : }
4575 :
4576 : void
4577 3996144 : BlockExpr::accept_vis (ASTVisitor &vis)
4578 : {
4579 3996144 : vis.visit (*this);
4580 3996140 : }
4581 :
4582 : void
4583 1172 : AnonConst::accept_vis (ASTVisitor &vis)
4584 : {
4585 1172 : vis.visit (*this);
4586 1172 : }
4587 :
4588 : void
4589 309 : ConstBlock::accept_vis (ASTVisitor &vis)
4590 : {
4591 309 : vis.visit (*this);
4592 309 : }
4593 :
4594 : void
4595 973 : ClosureExprInnerTyped::accept_vis (ASTVisitor &vis)
4596 : {
4597 973 : vis.visit (*this);
4598 973 : }
4599 :
4600 : void
4601 7970 : ContinueExpr::accept_vis (ASTVisitor &vis)
4602 : {
4603 7970 : vis.visit (*this);
4604 7970 : }
4605 :
4606 : void
4607 19367 : BreakExpr::accept_vis (ASTVisitor &vis)
4608 : {
4609 19367 : vis.visit (*this);
4610 19366 : }
4611 :
4612 : void
4613 65559 : RangeFromToExpr::accept_vis (ASTVisitor &vis)
4614 : {
4615 65559 : vis.visit (*this);
4616 65559 : }
4617 :
4618 : void
4619 26429 : RangeFromExpr::accept_vis (ASTVisitor &vis)
4620 : {
4621 26429 : vis.visit (*this);
4622 26429 : }
4623 :
4624 : void
4625 42491 : RangeToExpr::accept_vis (ASTVisitor &vis)
4626 : {
4627 42491 : vis.visit (*this);
4628 42491 : }
4629 :
4630 : void
4631 18840 : RangeFullExpr::accept_vis (ASTVisitor &vis)
4632 : {
4633 18840 : vis.visit (*this);
4634 18840 : }
4635 :
4636 : void
4637 2029 : RangeFromToInclExpr::accept_vis (ASTVisitor &vis)
4638 : {
4639 2029 : vis.visit (*this);
4640 2029 : }
4641 :
4642 : void
4643 0 : RangeToInclExpr::accept_vis (ASTVisitor &vis)
4644 : {
4645 0 : vis.visit (*this);
4646 0 : }
4647 :
4648 : void
4649 178856 : ReturnExpr::accept_vis (ASTVisitor &vis)
4650 : {
4651 178856 : vis.visit (*this);
4652 178856 : }
4653 :
4654 : void
4655 9185 : TryExpr::accept_vis (ASTVisitor &vis)
4656 : {
4657 9185 : vis.visit (*this);
4658 9185 : }
4659 :
4660 : void
4661 423539 : UnsafeBlockExpr::accept_vis (ASTVisitor &vis)
4662 : {
4663 423539 : vis.visit (*this);
4664 423539 : }
4665 :
4666 : void
4667 21621 : LoopExpr::accept_vis (ASTVisitor &vis)
4668 : {
4669 21621 : vis.visit (*this);
4670 21620 : }
4671 :
4672 : void
4673 36273 : WhileLoopExpr::accept_vis (ASTVisitor &vis)
4674 : {
4675 36273 : vis.visit (*this);
4676 36273 : }
4677 :
4678 : void
4679 7743 : WhileLetLoopExpr::accept_vis (ASTVisitor &vis)
4680 : {
4681 7743 : vis.visit (*this);
4682 7743 : }
4683 :
4684 : void
4685 35610 : ForLoopExpr::accept_vis (ASTVisitor &vis)
4686 : {
4687 35610 : vis.visit (*this);
4688 35610 : }
4689 :
4690 : void
4691 260952 : IfExpr::accept_vis (ASTVisitor &vis)
4692 : {
4693 260952 : vis.visit (*this);
4694 260952 : }
4695 :
4696 : void
4697 327391 : IfExprConseqElse::accept_vis (ASTVisitor &vis)
4698 : {
4699 327391 : vis.visit (*this);
4700 327391 : }
4701 :
4702 : void
4703 20162 : IfLetExpr::accept_vis (ASTVisitor &vis)
4704 : {
4705 20162 : vis.visit (*this);
4706 20162 : }
4707 :
4708 : void
4709 9760 : IfLetExprConseqElse::accept_vis (ASTVisitor &vis)
4710 : {
4711 9760 : vis.visit (*this);
4712 9760 : }
4713 :
4714 : void
4715 1125104 : MatchExpr::accept_vis (ASTVisitor &vis)
4716 : {
4717 1125104 : vis.visit (*this);
4718 1125102 : }
4719 :
4720 : void
4721 0 : AwaitExpr::accept_vis (ASTVisitor &vis)
4722 : {
4723 0 : vis.visit (*this);
4724 0 : }
4725 :
4726 : void
4727 0 : AsyncBlockExpr::accept_vis (ASTVisitor &vis)
4728 : {
4729 0 : vis.visit (*this);
4730 0 : }
4731 :
4732 : void
4733 479 : InlineAsm::accept_vis (ASTVisitor &vis)
4734 : {
4735 479 : vis.visit (*this);
4736 479 : }
4737 :
4738 : void
4739 3069 : LlvmInlineAsm::accept_vis (ASTVisitor &vis)
4740 : {
4741 3069 : vis.visit (*this);
4742 3069 : }
4743 :
4744 : void
4745 1823815 : TypeParam::accept_vis (ASTVisitor &vis)
4746 : {
4747 1823815 : vis.visit (*this);
4748 1823815 : }
4749 :
4750 : void
4751 298 : LifetimeWhereClauseItem::accept_vis (ASTVisitor &vis)
4752 : {
4753 298 : vis.visit (*this);
4754 298 : }
4755 :
4756 : void
4757 272167 : TypeBoundWhereClauseItem::accept_vis (ASTVisitor &vis)
4758 : {
4759 272167 : vis.visit (*this);
4760 272167 : }
4761 :
4762 : void
4763 92560 : Module::accept_vis (ASTVisitor &vis)
4764 : {
4765 92560 : vis.visit (*this);
4766 92560 : }
4767 :
4768 : void
4769 1443 : ExternCrate::accept_vis (ASTVisitor &vis)
4770 : {
4771 1443 : vis.visit (*this);
4772 1435 : }
4773 :
4774 : void
4775 8374 : UseTreeGlob::accept_vis (ASTVisitor &vis)
4776 : {
4777 8374 : vis.visit (*this);
4778 8374 : }
4779 :
4780 : void
4781 28778 : UseTreeList::accept_vis (ASTVisitor &vis)
4782 : {
4783 28778 : vis.visit (*this);
4784 28778 : }
4785 :
4786 : void
4787 60725 : UseTreeRebind::accept_vis (ASTVisitor &vis)
4788 : {
4789 60725 : vis.visit (*this);
4790 60725 : }
4791 :
4792 : void
4793 188167 : UseDeclaration::accept_vis (ASTVisitor &vis)
4794 : {
4795 188167 : vis.visit (*this);
4796 188167 : }
4797 :
4798 : void
4799 3545366 : Function::accept_vis (ASTVisitor &vis)
4800 : {
4801 3545366 : vis.visit (*this);
4802 3545364 : }
4803 :
4804 : void
4805 676346 : TypeAlias::accept_vis (ASTVisitor &vis)
4806 : {
4807 676346 : vis.visit (*this);
4808 676346 : }
4809 :
4810 : void
4811 44 : TraitAlias::accept_vis (ASTVisitor &vis)
4812 : {
4813 44 : vis.visit (*this);
4814 44 : }
4815 :
4816 : void
4817 267903 : StructStruct::accept_vis (ASTVisitor &vis)
4818 : {
4819 267903 : vis.visit (*this);
4820 267903 : }
4821 :
4822 : void
4823 49853 : TupleStruct::accept_vis (ASTVisitor &vis)
4824 : {
4825 49853 : vis.visit (*this);
4826 49853 : }
4827 :
4828 : void
4829 29444 : EnumItem::accept_vis (ASTVisitor &vis)
4830 : {
4831 29444 : vis.visit (*this);
4832 29444 : }
4833 :
4834 : void
4835 22372 : EnumItemTuple::accept_vis (ASTVisitor &vis)
4836 : {
4837 22372 : vis.visit (*this);
4838 22372 : }
4839 :
4840 : void
4841 2691 : EnumItemStruct::accept_vis (ASTVisitor &vis)
4842 : {
4843 2691 : vis.visit (*this);
4844 2691 : }
4845 :
4846 : void
4847 9003 : EnumItemDiscriminant::accept_vis (ASTVisitor &vis)
4848 : {
4849 9003 : vis.visit (*this);
4850 9003 : }
4851 :
4852 : void
4853 23731 : Enum::accept_vis (ASTVisitor &vis)
4854 : {
4855 23731 : vis.visit (*this);
4856 23731 : }
4857 :
4858 : void
4859 3206 : Union::accept_vis (ASTVisitor &vis)
4860 : {
4861 3206 : vis.visit (*this);
4862 3206 : }
4863 :
4864 : void
4865 176635 : ConstantItem::accept_vis (ASTVisitor &vis)
4866 : {
4867 176635 : vis.visit (*this);
4868 176635 : }
4869 :
4870 : void
4871 9905 : StaticItem::accept_vis (ASTVisitor &vis)
4872 : {
4873 9905 : vis.visit (*this);
4874 9905 : }
4875 :
4876 : void
4877 35409 : TraitItemType::accept_vis (ASTVisitor &vis)
4878 : {
4879 35409 : vis.visit (*this);
4880 35409 : }
4881 :
4882 : void
4883 143769 : Trait::accept_vis (ASTVisitor &vis)
4884 : {
4885 143769 : vis.visit (*this);
4886 143769 : }
4887 :
4888 : void
4889 96057 : InherentImpl::accept_vis (ASTVisitor &vis)
4890 : {
4891 96057 : vis.visit (*this);
4892 96057 : }
4893 :
4894 : void
4895 1563338 : TraitImpl::accept_vis (ASTVisitor &vis)
4896 : {
4897 1563338 : vis.visit (*this);
4898 1563338 : }
4899 :
4900 : void
4901 308 : ExternalTypeItem::accept_vis (ASTVisitor &vis)
4902 : {
4903 308 : vis.visit (*this);
4904 308 : }
4905 :
4906 : void
4907 22 : ExternalStaticItem::accept_vis (ASTVisitor &vis)
4908 : {
4909 22 : vis.visit (*this);
4910 22 : }
4911 :
4912 : void
4913 53844 : ExternBlock::accept_vis (ASTVisitor &vis)
4914 : {
4915 53844 : vis.visit (*this);
4916 53844 : }
4917 :
4918 : void
4919 226215 : MacroMatchFragment::accept_vis (ASTVisitor &vis)
4920 : {
4921 226215 : vis.visit (*this);
4922 226215 : }
4923 :
4924 : void
4925 31576 : MacroMatchRepetition::accept_vis (ASTVisitor &vis)
4926 : {
4927 31576 : vis.visit (*this);
4928 31576 : }
4929 :
4930 : void
4931 5739 : MacroMatcher::accept_vis (ASTVisitor &vis)
4932 : {
4933 5739 : vis.visit (*this);
4934 5739 : }
4935 :
4936 : void
4937 213908 : MacroRulesDefinition::accept_vis (ASTVisitor &vis)
4938 : {
4939 213908 : vis.visit (*this);
4940 213908 : }
4941 :
4942 : void
4943 399700 : MacroInvocation::accept_vis (ASTVisitor &vis)
4944 : {
4945 399700 : vis.visit (*this);
4946 399700 : }
4947 :
4948 : void
4949 1583 : EmptyStmt::accept_vis (ASTVisitor &vis)
4950 : {
4951 1583 : vis.visit (*this);
4952 1583 : }
4953 :
4954 : void
4955 1516209 : LetStmt::accept_vis (ASTVisitor &vis)
4956 : {
4957 1516209 : vis.visit (*this);
4958 1516208 : }
4959 :
4960 : void
4961 1868933 : ExprStmt::accept_vis (ASTVisitor &vis)
4962 : {
4963 1868933 : vis.visit (*this);
4964 1868931 : }
4965 :
4966 : void
4967 935613 : TraitBound::accept_vis (ASTVisitor &vis)
4968 : {
4969 935613 : vis.visit (*this);
4970 935613 : }
4971 :
4972 : void
4973 18283 : ImplTraitType::accept_vis (ASTVisitor &vis)
4974 : {
4975 18283 : vis.visit (*this);
4976 18283 : }
4977 :
4978 : void
4979 13105 : TraitObjectType::accept_vis (ASTVisitor &vis)
4980 : {
4981 13105 : vis.visit (*this);
4982 13105 : }
4983 :
4984 : void
4985 2622 : ParenthesisedType::accept_vis (ASTVisitor &vis)
4986 : {
4987 2622 : vis.visit (*this);
4988 2622 : }
4989 :
4990 : void
4991 44837 : ImplTraitTypeOneBound::accept_vis (ASTVisitor &vis)
4992 : {
4993 44837 : vis.visit (*this);
4994 44837 : }
4995 :
4996 : void
4997 12403 : TraitObjectTypeOneBound::accept_vis (ASTVisitor &vis)
4998 : {
4999 12403 : vis.visit (*this);
5000 12403 : }
5001 :
5002 : void
5003 266711 : TupleType::accept_vis (ASTVisitor &vis)
5004 : {
5005 266711 : vis.visit (*this);
5006 266711 : }
5007 :
5008 : void
5009 17814 : NeverType::accept_vis (ASTVisitor &vis)
5010 : {
5011 17814 : vis.visit (*this);
5012 17814 : }
5013 :
5014 : void
5015 557276 : RawPointerType::accept_vis (ASTVisitor &vis)
5016 : {
5017 557276 : vis.visit (*this);
5018 557276 : }
5019 :
5020 : void
5021 2238964 : ReferenceType::accept_vis (ASTVisitor &vis)
5022 : {
5023 2238964 : vis.visit (*this);
5024 2238964 : }
5025 :
5026 : void
5027 100027 : ArrayType::accept_vis (ASTVisitor &vis)
5028 : {
5029 100027 : vis.visit (*this);
5030 100027 : }
5031 :
5032 : void
5033 191672 : SliceType::accept_vis (ASTVisitor &vis)
5034 : {
5035 191672 : vis.visit (*this);
5036 191672 : }
5037 :
5038 : void
5039 64126 : InferredType::accept_vis (ASTVisitor &vis)
5040 : {
5041 64126 : vis.visit (*this);
5042 64126 : }
5043 :
5044 : void
5045 116191 : BareFunctionType::accept_vis (ASTVisitor &vis)
5046 : {
5047 116191 : vis.visit (*this);
5048 116191 : }
5049 :
5050 : void
5051 16400 : MetaItemSeq::accept_vis (ASTVisitor &vis)
5052 : {
5053 16400 : vis.visit (*this);
5054 16400 : }
5055 :
5056 : void
5057 2670 : MetaItemPath::accept_vis (ASTVisitor &vis)
5058 : {
5059 2670 : vis.visit (*this);
5060 2670 : }
5061 :
5062 : void
5063 0 : MetaListPaths::accept_vis (ASTVisitor &vis)
5064 : {
5065 0 : vis.visit (*this);
5066 0 : }
5067 :
5068 : void
5069 30470 : MetaNameValueStr::accept_vis (ASTVisitor &vis)
5070 : {
5071 30470 : vis.visit (*this);
5072 30470 : }
5073 :
5074 : void
5075 0 : MetaListNameValueStr::accept_vis (ASTVisitor &vis)
5076 : {
5077 0 : vis.visit (*this);
5078 0 : }
5079 :
5080 : void
5081 42517 : AttrInputMetaItemContainer::accept_vis (ASTVisitor &vis)
5082 : {
5083 42517 : vis.visit (*this);
5084 42517 : }
5085 :
5086 : void
5087 12291 : MetaWord::accept_vis (ASTVisitor &vis)
5088 : {
5089 12291 : vis.visit (*this);
5090 12291 : }
5091 :
5092 : void
5093 0 : FormatArgs::accept_vis (ASTVisitor &vis)
5094 : {
5095 0 : vis.visit (*this);
5096 0 : }
5097 :
5098 : void
5099 244 : OffsetOf::accept_vis (ASTVisitor &vis)
5100 : {
5101 244 : vis.visit (*this);
5102 244 : }
5103 :
5104 : std::string
5105 0 : FormatArgs::as_string () const
5106 : {
5107 : // FIXME(Arthur): Improve
5108 0 : return "FormatArgs";
5109 : }
5110 :
5111 : std::string
5112 0 : OffsetOf::as_string () const
5113 : {
5114 0 : return "OffsetOf(" + type->as_string () + ", " + field.as_string () + ")";
5115 : }
5116 :
5117 : location_t
5118 76 : FormatArgs::get_locus () const
5119 : {
5120 76 : return loc;
5121 : }
5122 :
5123 : bool
5124 0 : FormatArgs::is_expr_without_block () const
5125 : {
5126 0 : return false;
5127 : }
5128 :
5129 : void
5130 0 : FormatArgs::mark_for_strip ()
5131 : {
5132 0 : marked_for_strip = true;
5133 0 : }
5134 :
5135 : bool
5136 0 : FormatArgs::is_marked_for_strip () const
5137 : {
5138 0 : return marked_for_strip;
5139 : }
5140 :
5141 : std::vector<Attribute> &
5142 0 : FormatArgs::get_outer_attrs ()
5143 : {
5144 0 : rust_unreachable ();
5145 : }
5146 :
5147 : void
5148 0 : FormatArgs::set_outer_attrs (std::vector<Attribute>)
5149 : {
5150 0 : rust_unreachable ();
5151 : }
5152 :
5153 : Expr *
5154 0 : FormatArgs::clone_expr_impl () const
5155 : {
5156 0 : std::cerr << "[ARTHUR] cloning FormatArgs! " << std::endl;
5157 :
5158 0 : return new FormatArgs (*this);
5159 : }
5160 :
5161 : std::vector<Attribute> &
5162 0 : OffsetOf::get_outer_attrs ()
5163 : {
5164 0 : rust_unreachable ();
5165 : }
5166 :
5167 : void
5168 0 : OffsetOf::set_outer_attrs (std::vector<Attribute>)
5169 : {
5170 0 : rust_unreachable ();
5171 : }
5172 :
5173 : Expr *
5174 96 : OffsetOf::clone_expr_impl () const
5175 : {
5176 96 : return new OffsetOf (*this);
5177 : }
5178 :
5179 : } // namespace AST
5180 :
5181 : std::ostream &
5182 0 : operator<< (std::ostream &os, Identifier const &i)
5183 : {
5184 0 : return os << i.as_string ();
5185 : }
5186 :
5187 : } // namespace Rust
|