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