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