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