1 /* General AST-related method implementations for Rust frontend.
2 Copyright (C) 2009-2023 Free Software Foundation, Inc.
4 This file is part of GCC.
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
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
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/>. */
20 #include "rust-system.h"
21 #include "rust-ast-full.h"
22 #include "rust-diagnostics.h"
23 #include "rust-ast-visitor.h"
24 #include "rust-macro.h"
25 #include "rust-session-manager.h"
27 #include "rust-parse.h"
30 /* Compilation unit used for various AST-related functions that would make
31 * the headers too long if they were defined inline and don't receive any
32 * benefits from being defined inline because they are virtual. Also used
33 * for various other stuff. */
46 indent_spaces (enum indent_mode mode
)
48 static int indent
= 0;
52 for (int i
= 0; i
< indent
; i
++)
60 // Gets a string in a certain delim type.
62 get_string_in_delims (std::string str_input
, DelimType delim_type
)
67 return "(" + str_input
+ ")";
69 return "[" + str_input
+ "]";
71 return "{" + str_input
+ "}";
73 return "ERROR-MARK-STRING (delims)";
85 get_mode_dump_desc (AttrMode mode
)
90 return "outer attributes";
92 return "inner attributes";
99 // Adds lines below adding attributes
101 append_attributes (std::vector
<Attribute
> attrs
, AttrMode mode
)
103 indent_spaces (enter
);
106 = "\n" + indent_spaces (stay
) + get_mode_dump_desc (mode
) + ": ";
107 // str += "\n" + indent_spaces (stay) + "inner attributes: ";
114 /* note that this does not print them with outer or "inner attribute"
115 * syntax - just prints the body */
116 for (const auto &attr
: attrs
)
117 str
+= "\n" + indent_spaces (stay
) + attr
.as_string ();
125 // Removes the beginning and end quotes of a quoted string.
127 unquote_string (std::string input
)
129 rust_assert (input
.front () == '"');
130 rust_assert (input
.back () == '"');
131 return input
.substr (1, input
.length () - 2);
135 Crate::as_string () const
137 rust_debug ("beginning crate recursive as-string");
139 std::string
str ("Crate: ");
142 str
+= append_attributes (inner_attrs
, INNER
);
152 for (const auto &item
: items
)
154 // DEBUG: null pointer check
157 rust_debug ("something really terrible has gone wrong - "
158 "null pointer item in crate.");
159 return "NULL_POINTER_MARK";
162 str
+= "\n " + item
->as_string ();
170 Attribute::as_string () const
172 std::string path_str
= path
.as_string ();
173 if (attr_input
== nullptr)
176 return path_str
+ attr_input
->as_string ();
179 // Copy constructor must deep copy attr_input as unique pointer
180 Attribute::Attribute (Attribute
const &other
)
181 : path (other
.path
), locus (other
.locus
)
183 // guard to protect from null pointer dereference
184 if (other
.attr_input
!= nullptr)
185 attr_input
= other
.attr_input
->clone_attr_input ();
188 // overload assignment operator to use custom clone method
190 Attribute::operator= (Attribute
const &other
)
194 // guard to protect from null pointer dereference
195 if (other
.attr_input
!= nullptr)
196 attr_input
= other
.attr_input
->clone_attr_input ();
198 attr_input
= nullptr;
204 DelimTokenTree::as_string () const
206 std::string start_delim
;
207 std::string end_delim
;
223 rust_debug ("Invalid delimiter type, "
224 "Should be PARENS, SQUARE, or CURLY.");
225 return "Invalid delimiter type";
227 std::string str
= start_delim
;
228 if (!token_trees
.empty ())
230 for (const auto &tree
: token_trees
)
232 // DEBUG: null pointer check
236 "something really terrible has gone wrong - null pointer "
237 "token tree in delim token tree.");
238 return "NULL_POINTER_MARK";
241 str
+= tree
->as_string ();
250 Token::as_string () const
252 if (tok_ref
->has_str ())
254 std::string str
= tok_ref
->get_str ();
256 std::string quote
= is_string_lit () ? "\"" : "";
257 return quote
+ str
+ quote
;
261 return tok_ref
->get_token_description ();
266 SimplePathSegment::as_string () const
272 SimplePath::as_string () const
275 if (has_opening_scope_resolution
)
278 // crappy hack because doing proper for loop would be more code
279 bool first_time
= true;
280 for (const auto &segment
: segments
)
284 path
+= segment
.as_string ();
289 path
+= "::" + segment
.as_string ();
292 // DEBUG: remove later. Checks for path error.
293 if (segment
.is_error ())
295 rust_debug ("segment in path is error - this should've been filtered "
296 "out. first segment "
298 segments
.at (0).as_string ().c_str ());
306 Visibility::as_string () const
311 return std::string ("");
313 return std::string ("pub");
315 return std::string ("pub(crate)");
317 return std::string ("pub(self)");
319 return std::string ("pub(super)");
321 return std::string ("pub(in ") + in_path
.as_string () + std::string (")");
327 // Creates a string that reflects the visibility stored.
329 VisItem::as_string () const
331 // FIXME: can't do formatting on string to make identation occur.
334 if (!outer_attrs
.empty ())
336 for (const auto &attr
: outer_attrs
)
337 str
+= attr
.as_string () + "\n";
340 if (has_visibility ())
341 str
+= visibility
.as_string () + " ";
347 Module::as_string () const
349 std::string str
= VisItem::as_string () + "mod " + module_name
;
351 // Return early if we're dealing with an unloaded module as their body resides
352 // in a different file
353 if (kind
== ModuleKind::UNLOADED
)
354 return str
+ "\n no body (reference to external file)\n";
357 str
+= append_attributes (inner_attrs
, INNER
);
362 // This can still happen if the module is loaded but empty, i.e. `mod foo {}`
369 for (const auto &item
: items
)
371 // DEBUG: null pointer check
374 rust_debug ("something really terrible has gone wrong - "
375 "null pointer item in crate.");
376 return "NULL_POINTER_MARK";
379 str
+= "\n " + item
->as_string ();
387 StaticItem::as_string () const
389 std::string str
= VisItem::as_string ();
391 str
+= indent_spaces (stay
) + "static";
398 // DEBUG: null pointer check
401 rust_debug ("something really terrible has gone wrong - null "
402 "pointer type in static item.");
403 return "NULL_POINTER_MARK";
405 str
+= "\n" + indent_spaces (stay
) + "Type: " + type
->as_string ();
407 // DEBUG: null pointer check
410 rust_debug ("something really terrible has gone wrong - null "
411 "pointer expr in static item.");
412 return "NULL_POINTER_MARK";
414 str
+= "\n" + indent_spaces (stay
) + "Expression: " + expr
->as_string ();
420 ExternCrate::as_string () const
422 std::string str
= VisItem::as_string ();
424 str
+= "extern crate " + referenced_crate
;
426 if (has_as_clause ())
427 str
+= " as " + as_clause_name
;
433 TupleStruct::as_string () const
435 std::string str
= VisItem::as_string ();
437 str
+= "struct " + struct_name
;
440 str
+= "\n Generic params: ";
441 if (generic_params
.empty ())
447 for (const auto ¶m
: generic_params
)
449 // DEBUG: null pointer check
450 if (param
== nullptr)
453 "something really terrible has gone wrong - null pointer "
454 "generic param in enum.");
455 return "NULL_POINTER_MARK";
458 str
+= "\n " + param
->as_string ();
463 str
+= "\n Tuple fields: ";
470 for (const auto &field
: fields
)
471 str
+= "\n " + field
.as_string ();
474 str
+= "\n Where clause: ";
475 if (has_where_clause ())
476 str
+= where_clause
.as_string ();
484 ConstantItem::as_string () const
486 std::string str
= VisItem::as_string ();
488 str
+= "const " + identifier
;
490 // DEBUG: null pointer check
493 rust_debug ("something really terrible has gone wrong - null "
494 "pointer type in const item.");
495 return "NULL_POINTER_MARK";
497 str
+= "\n Type: " + type
->as_string ();
499 // DEBUG: null pointer check
500 if (const_expr
== nullptr)
502 rust_debug ("something really terrible has gone wrong - null "
503 "pointer expr in const item.");
504 return "NULL_POINTER_MARK";
506 str
+= "\n Expression: " + const_expr
->as_string ();
512 InherentImpl::as_string () const
514 std::string str
= VisItem::as_string ();
519 str
+= "\n Generic params: ";
520 if (generic_params
.empty ())
526 for (const auto ¶m
: generic_params
)
528 // DEBUG: null pointer check
529 if (param
== nullptr)
532 "something really terrible has gone wrong - null pointer "
533 "generic param in inherent impl.");
534 return "NULL_POINTER_MARK";
537 str
+= "\n " + param
->as_string ();
541 str
+= "\n Type: " + trait_type
->as_string ();
543 str
+= "\n Where clause: ";
544 if (has_where_clause ())
545 str
+= where_clause
.as_string ();
550 str
+= append_attributes (inner_attrs
, INNER
);
552 // inherent impl items
553 str
+= "\n Inherent impl items: ";
554 if (!has_impl_items ())
560 for (const auto &item
: impl_items
)
561 str
+= "\n " + item
->as_string ();
568 Method::as_string () const
570 std::string
str ("Method: \n ");
572 str
+= vis
.as_string () + " " + qualifiers
.as_string ();
574 str
+= " fn " + method_name
;
577 str
+= "\n Generic params: ";
578 if (generic_params
.empty ())
584 for (const auto ¶m
: generic_params
)
586 // DEBUG: null pointer check
587 if (param
== nullptr)
590 "something really terrible has gone wrong - null pointer "
591 "generic param in method.");
592 return "NULL_POINTER_MARK";
595 str
+= "\n " + param
->as_string ();
599 str
+= "\n Self param: " + self_param
.as_string ();
601 str
+= "\n Function params: ";
602 if (function_params
.empty ())
608 for (const auto ¶m
: function_params
)
609 str
+= "\n " + param
.as_string ();
612 str
+= "\n Return type: ";
613 if (has_return_type ())
614 str
+= return_type
->as_string ();
616 str
+= "none (void)";
618 str
+= "\n Where clause: ";
619 if (has_where_clause ())
620 str
+= where_clause
.as_string ();
624 str
+= "\n Block expr (body): \n ";
625 str
+= function_body
->as_string ();
631 StructStruct::as_string () const
633 std::string str
= VisItem::as_string ();
635 str
+= "struct " + struct_name
;
638 str
+= "\n Generic params: ";
639 if (generic_params
.empty ())
645 for (const auto ¶m
: generic_params
)
647 // DEBUG: null pointer check
648 if (param
== nullptr)
651 "something really terrible has gone wrong - null pointer "
652 "generic param in enum.");
653 return "NULL_POINTER_MARK";
656 str
+= "\n " + param
->as_string ();
660 str
+= "\n Where clause: ";
661 if (has_where_clause ())
662 str
+= where_clause
.as_string ();
667 str
+= "\n Struct fields: ";
670 str
+= "none (unit)";
672 else if (fields
.empty ())
674 str
+= "none (non-unit)";
678 for (const auto &field
: fields
)
679 str
+= "\n " + field
.as_string ();
686 UseDeclaration::as_string () const
688 std::string str
= VisItem::as_string ();
690 // DEBUG: null pointer check
691 if (use_tree
== nullptr)
694 "something really terrible has gone wrong - null pointer use tree in "
696 return "NULL_POINTER_MARK";
699 str
+= "use " + use_tree
->as_string ();
705 UseTreeGlob::as_string () const
713 case PATH_PREFIXED
: {
714 std::string path_str
= path
.as_string ();
715 return path_str
+ "::*";
718 // some kind of error
725 UseTreeList::as_string () const
727 std::string path_str
;
736 case PATH_PREFIXED
: {
737 path_str
= path
.as_string () + "::{";
741 // some kind of error
742 return "ERROR-PATH-LIST";
747 auto i
= trees
.begin ();
748 auto e
= trees
.end ();
750 // DEBUG: null pointer check
753 rust_debug ("something really terrible has gone wrong - null pointer "
754 "tree in use tree list.");
755 return "NULL_POINTER_MARK";
760 path_str
+= (*i
)->as_string ();
770 return path_str
+ "}";
774 UseTreeRebind::as_string () const
776 std::string path_str
= path
.as_string ();
781 // nothing to add, just path
784 path_str
+= " as " + identifier
;
791 return "ERROR-PATH-REBIND";
798 Enum::as_string () const
800 std::string str
= VisItem::as_string ();
804 str
+= "\n Generic params: ";
805 if (generic_params
.empty ())
811 for (const auto ¶m
: generic_params
)
813 // DEBUG: null pointer check
814 if (param
== nullptr)
817 "something really terrible has gone wrong - null pointer "
818 "generic param in enum.");
819 return "NULL_POINTER_MARK";
822 str
+= "\n " + param
->as_string ();
826 str
+= "\n Where clause: ";
827 if (has_where_clause ())
828 str
+= where_clause
.as_string ();
840 for (const auto &item
: items
)
842 // DEBUG: null pointer check
846 "something really terrible has gone wrong - null pointer "
847 "enum item in enum.");
848 return "NULL_POINTER_MARK";
851 str
+= "\n " + item
->as_string ();
859 Trait::as_string () const
861 std::string str
= VisItem::as_string ();
866 str
+= "trait " + name
;
869 str
+= "\n Generic params: ";
870 if (generic_params
.empty ())
876 for (const auto ¶m
: generic_params
)
878 // DEBUG: null pointer check
879 if (param
== nullptr)
882 "something really terrible has gone wrong - null pointer "
883 "generic param in trait.");
884 return "NULL_POINTER_MARK";
887 str
+= "\n " + param
->as_string ();
891 str
+= "\n Type param bounds: ";
892 if (!has_type_param_bounds ())
898 for (const auto &bound
: type_param_bounds
)
900 // DEBUG: null pointer check
901 if (bound
== nullptr)
904 "something really terrible has gone wrong - null pointer "
905 "type param bound in trait.");
906 return "NULL_POINTER_MARK";
909 str
+= "\n " + bound
->as_string ();
913 str
+= "\n Where clause: ";
914 if (!has_where_clause ())
917 str
+= where_clause
.as_string ();
919 str
+= "\n Trait items: ";
920 if (!has_trait_items ())
926 for (const auto &item
: trait_items
)
928 // DEBUG: null pointer check
932 "something really terrible has gone wrong - null pointer "
933 "trait item in trait.");
934 return "NULL_POINTER_MARK";
937 str
+= "\n " + item
->as_string ();
945 Union::as_string () const
947 std::string str
= VisItem::as_string ();
949 str
+= "union " + union_name
;
952 str
+= "\n Generic params: ";
953 if (generic_params
.empty ())
959 for (const auto ¶m
: generic_params
)
961 // DEBUG: null pointer check
962 if (param
== nullptr)
965 "something really terrible has gone wrong - null pointer "
966 "generic param in union.");
967 return "NULL_POINTER_MARK";
970 str
+= "\n " + param
->as_string ();
974 str
+= "\n Where clause: ";
975 if (has_where_clause ())
976 str
+= where_clause
.as_string ();
981 str
+= "\n Struct fields (variants): ";
982 if (variants
.empty ())
988 for (const auto &field
: variants
)
989 str
+= "\n " + field
.as_string ();
996 Function::as_string () const
998 std::string str
= VisItem::as_string () + "\n";
999 std::string qstr
= qualifiers
.as_string ();
1003 if (has_return_type ())
1005 // DEBUG: null pointer check
1006 if (return_type
== nullptr)
1009 "something really terrible has gone wrong - null pointer return "
1010 "type in function.");
1011 return "NULL_POINTER_MARK";
1014 str
+= return_type
->as_string () + " ";
1021 str
+= function_name
;
1023 if (has_generics ())
1027 auto i
= generic_params
.begin ();
1028 auto e
= generic_params
.end ();
1030 // DEBUG: null pointer check
1033 rust_debug ("something really terrible has gone wrong - null pointer "
1034 "generic param in function item.");
1035 return "NULL_POINTER_MARK";
1040 str
+= (*i
)->as_string ();
1047 if (has_function_params ())
1049 auto i
= function_params
.begin ();
1050 auto e
= function_params
.end ();
1054 str
+= (*i
).as_string ();
1065 if (has_where_clause ())
1066 str
+= " where " + where_clause
.as_string ();
1070 // DEBUG: null pointer check
1071 if (function_body
== nullptr)
1074 "something really terrible has gone wrong - null pointer function "
1075 "body in function.");
1076 return "NULL_POINTER_MARK";
1078 str
+= function_body
->as_string () + "\n";
1084 WhereClause::as_string () const
1086 // just print where clause items, don't mention "where" or "where clause"
1089 if (where_clause_items
.empty ())
1095 for (const auto &item
: where_clause_items
)
1096 str
+= "\n " + item
->as_string ();
1103 BlockExpr::as_string () const
1105 std::string istr
= indent_spaces (enter
);
1106 std::string str
= istr
+ "BlockExpr:\n" + istr
;
1108 // get outer attributes
1109 str
+= append_attributes (outer_attrs
, OUTER
);
1112 str
+= append_attributes (inner_attrs
, INNER
);
1115 str
+= "\n" + indent_spaces (stay
) + "statements: ";
1116 if (statements
.empty ())
1122 for (const auto &stmt
: statements
)
1124 // DEBUG: null pointer check
1125 if (stmt
== nullptr)
1128 "something really terrible has gone wrong - null pointer "
1129 "stmt in block expr.");
1130 return "NULL_POINTER_MARK";
1133 str
+= "\n" + indent_spaces (stay
) + stmt
->as_string ();
1138 str
+= "\n" + indent_spaces (stay
) + "final expression: ";
1139 if (expr
== nullptr)
1142 str
+= "\n" + expr
->as_string ();
1144 str
+= "\n" + indent_spaces (out
);
1149 TraitImpl::as_string () const
1151 std::string str
= VisItem::as_string ();
1159 str
+= "\n Generic params: ";
1160 if (!has_generics ())
1166 for (const auto ¶m
: generic_params
)
1167 str
+= "\n " + param
->as_string ();
1170 str
+= "\n Has exclam: ";
1176 str
+= "\n TypePath (to trait): " + trait_path
.as_string ();
1178 str
+= "\n Type (struct to impl on): " + trait_type
->as_string ();
1180 str
+= "\n Where clause: ";
1181 if (!has_where_clause ())
1184 str
+= where_clause
.as_string ();
1187 str
+= append_attributes (inner_attrs
, INNER
);
1189 str
+= "\n trait impl items: ";
1190 if (!has_impl_items ())
1196 for (const auto &item
: impl_items
)
1197 str
+= "\n " + item
->as_string ();
1204 TypeAlias::as_string () const
1206 std::string str
= VisItem::as_string ();
1208 str
+= " " + new_type_name
;
1211 str
+= "\n Generic params: ";
1212 if (!has_generics ())
1218 auto i
= generic_params
.begin ();
1219 auto e
= generic_params
.end ();
1223 str
+= (*i
)->as_string ();
1229 str
+= "\n Where clause: ";
1230 if (!has_where_clause ())
1233 str
+= where_clause
.as_string ();
1235 str
+= "\n Type: " + existing_type
->as_string ();
1241 ExternBlock::as_string () const
1243 std::string str
= VisItem::as_string ();
1247 str
+= "\"" + abi
+ "\" ";
1249 str
+= append_attributes (inner_attrs
, INNER
);
1251 str
+= "\n external items: ";
1252 if (!has_extern_items ())
1258 for (const auto &item
: extern_items
)
1259 str
+= "\n " + item
->as_string ();
1266 MacroRule::as_string () const
1268 std::string
str ("Macro rule: ");
1270 str
+= "\n Matcher: \n ";
1271 str
+= matcher
.as_string ();
1273 str
+= "\n Transcriber: \n ";
1274 str
+= transcriber
.as_string ();
1280 MacroRulesDefinition::as_string () const
1285 str
+= append_attributes (outer_attrs
, OUTER
);
1287 str
+= "macro_rules!";
1291 str
+= "\n Macro rules: ";
1298 for (const auto &rule
: rules
)
1299 str
+= "\n " + rule
.as_string ();
1302 str
+= "\n Delim type: ";
1306 str
+= "parentheses";
1315 return "ERROR_MARK_STRING - delim type in macro invocation";
1322 MacroInvocation::as_string () const
1324 std::string str
= "MacroInvocation: ";
1326 str
+= append_attributes (outer_attrs
, OUTER
);
1328 str
+= "\n " + invoc_data
.as_string ();
1330 str
+= "\n has semicolon: ";
1331 str
+= has_semicolon () ? "true" : "false";
1337 MacroInvocData::as_string () const
1339 return path
.as_string () + "!" + token_tree
.as_string ();
1343 PathInExpression::as_string () const
1347 if (has_opening_scope_resolution
)
1350 return str
+ PathPattern::as_string ();
1354 ExprStmtWithBlock::as_string () const
1356 std::string str
= indent_spaces (enter
) + "ExprStmtWithBlock: \n";
1358 if (expr
== nullptr)
1360 str
+= "none (this should not happen and is an error)";
1364 indent_spaces (enter
);
1365 str
+= expr
->as_string ();
1366 indent_spaces (out
);
1369 indent_spaces (out
);
1374 ClosureParam::as_string () const
1376 std::string
str (pattern
->as_string ());
1378 if (has_type_given ())
1379 str
+= " : " + type
->as_string ();
1385 ClosureExpr::as_string () const
1387 std::string str
= "ClosureExpr:";
1389 str
+= append_attributes (outer_attrs
, OUTER
);
1391 str
+= "\n Has move: ";
1397 str
+= "\n Params: ";
1398 if (params
.empty ())
1404 for (const auto ¶m
: params
)
1405 str
+= "\n " + param
.as_string ();
1412 ClosureExprInnerTyped::as_string () const
1414 std::string str
= ClosureExpr::as_string ();
1416 str
+= "\n Return type: " + return_type
->as_string ();
1418 str
+= "\n Body: " + expr
->as_string ();
1424 PathPattern::as_string () const
1428 for (const auto &segment
: segments
)
1429 str
+= segment
.as_string () + "::";
1431 // basically a hack - remove last two characters of string (remove final ::)
1432 str
.erase (str
.length () - 2);
1438 QualifiedPathType::as_string () const
1440 std::string
str ("<");
1441 str
+= type_to_invoke_on
->as_string ();
1443 if (has_as_clause ())
1444 str
+= " as " + trait_path
.as_string ();
1450 QualifiedPathInExpression::as_string () const
1452 return path_type
.as_string () + "::" + PathPattern::as_string ();
1456 BorrowExpr::as_string () const
1458 /* TODO: find way to incorporate outer attrs - may have to represent in
1459 * different style (i.e. something more like BorrowExpr: \n outer attrs) */
1461 std::string
str ("&");
1469 str
+= main_or_left_expr
->as_string ();
1475 ReturnExpr::as_string () const
1477 /* TODO: find way to incorporate outer attrs - may have to represent in
1478 * different style (i.e. something more like BorrowExpr: \n outer attrs) */
1480 std::string
str ("return ");
1482 if (has_returned_expr ())
1483 str
+= return_expr
->as_string ();
1489 GroupedExpr::as_string () const
1491 std::string
str ("Grouped expr:");
1494 str
+= append_attributes (outer_attrs
, OUTER
);
1497 str
+= append_attributes (inner_attrs
, INNER
);
1499 str
+= "\n Expr in parens: " + expr_in_parens
->as_string ();
1505 RangeToExpr::as_string () const
1507 return ".." + to
->as_string ();
1511 ContinueExpr::as_string () const
1513 // TODO: rewrite format to allow outer attributes
1514 std::string
str ("continue ");
1517 str
+= label
.as_string ();
1523 NegationExpr::as_string () const
1525 // TODO: rewrite formula to allow outer attributes
1530 case NegationOperator::NEGATE
:
1533 case NegationOperator::NOT
:
1537 return "ERROR_MARK_STRING - negation expr";
1540 str
+= main_or_left_expr
->as_string ();
1546 RangeFromExpr::as_string () const
1548 return from
->as_string () + "..";
1552 RangeFullExpr::as_string () const
1558 ArrayIndexExpr::as_string () const
1560 // TODO: rewrite formula to allow outer attributes
1561 return array_expr
->as_string () + "[" + index_expr
->as_string () + "]";
1565 AssignmentExpr::as_string () const
1567 std::string
str ("AssignmentExpr: ");
1569 if (main_or_left_expr
== nullptr || right_expr
== nullptr)
1571 str
+= "error (either or both expressions are null)";
1576 str
+= "\n left: " + main_or_left_expr
->as_string ();
1579 str
+= "\n right: " + right_expr
->as_string ();
1586 AsyncBlockExpr::as_string () const
1588 std::string str
= "AsyncBlockExpr: ";
1590 // get outer attributes
1591 // str += "\n " + Expr::as_string ();
1592 str
+= append_attributes (outer_attrs
, OUTER
);
1594 str
+= "\n Has move: ";
1595 str
+= has_move
? "true" : "false";
1597 return str
+ "\n" + block_expr
->as_string ();
1601 ComparisonExpr::as_string () const
1603 // TODO: rewrite to better reflect non-literal expressions
1604 std::string
str (main_or_left_expr
->as_string ());
1608 case ComparisonOperator::EQUAL
:
1611 case ComparisonOperator::NOT_EQUAL
:
1614 case ComparisonOperator::GREATER_THAN
:
1617 case ComparisonOperator::LESS_THAN
:
1620 case ComparisonOperator::GREATER_OR_EQUAL
:
1623 case ComparisonOperator::LESS_OR_EQUAL
:
1627 return "ERROR_MARK_STRING - comparison expr";
1630 str
+= right_expr
->as_string ();
1636 MethodCallExpr::as_string () const
1638 std::string str
= "MethodCallExpr: ";
1640 str
+= append_attributes (outer_attrs
, OUTER
);
1642 str
+= "\n Object (receiver) expr: \n";
1643 str
+= receiver
->as_string ();
1645 str
+= "\n Method path segment: \n";
1646 str
+= method_name
.as_string ();
1648 str
+= "\n Call params:";
1649 if (params
.empty ())
1655 for (const auto ¶m
: params
)
1657 if (param
== nullptr)
1658 return "ERROR_MARK_STRING - method call expr param is null";
1660 str
+= "\n " + param
->as_string ();
1668 TupleIndexExpr::as_string () const
1670 // TODO: rewrite dump to better reflect non-literal exprs
1671 return tuple_expr
->as_string () + "." + std::to_string (tuple_index
);
1675 DereferenceExpr::as_string () const
1677 // TODO: rewrite dump to better reflect non-literal exprs
1678 return "*" + main_or_left_expr
->as_string ();
1682 FieldAccessExpr::as_string () const
1684 // TODO: rewrite dump to better reflect non-literal exprs
1685 return receiver
->as_string () + "." + field
;
1689 LazyBooleanExpr::as_string () const
1691 // TODO: rewrite dump to better reflect non-literal exprs
1692 std::string
str (main_or_left_expr
->as_string ());
1696 case LazyBooleanOperator::LOGICAL_OR
:
1699 case LazyBooleanOperator::LOGICAL_AND
:
1703 return "ERROR_MARK_STRING - lazy boolean expr out of bounds";
1706 str
+= right_expr
->as_string ();
1712 RangeFromToExpr::as_string () const
1714 // TODO: rewrite dump to better reflect non-literal exprs
1715 return from
->as_string () + ".." + to
->as_string ();
1719 RangeToInclExpr::as_string () const
1721 // TODO: rewrite dump to better reflect non-literal exprs
1722 return "..=" + to
->as_string ();
1726 UnsafeBlockExpr::as_string () const
1728 std::string str
= "UnsafeBlockExpr:" + indent_spaces (enter
);
1730 // get outer attributes
1731 str
+= append_attributes (outer_attrs
, OUTER
);
1733 str
+= indent_spaces (stay
) + expr
->as_string () + "\n" + indent_spaces (out
);
1739 ClosureExprInner::as_string () const
1741 std::string str
= ClosureExpr::as_string ();
1743 str
+= "\n Expression: " + closure_inner
->as_string ();
1749 IfExpr::as_string () const
1751 std::string str
= "IfExpr: ";
1753 str
+= append_attributes (outer_attrs
, OUTER
);
1755 str
+= "\n Condition expr: " + condition
->as_string ();
1757 str
+= "\n If block expr: " + if_block
->as_string ();
1763 IfExprConseqElse::as_string () const
1765 std::string str
= IfExpr::as_string ();
1767 str
+= "\n Else block expr: " + else_block
->as_string ();
1773 IfExprConseqIf::as_string () const
1775 std::string str
= IfExpr::as_string ();
1777 str
+= "\n Else if expr: \n " + conseq_if_expr
->as_string ();
1783 IfExprConseqIfLet::as_string () const
1785 std::string str
= IfExpr::as_string ();
1787 str
+= "\n Else if let expr: \n " + if_let_expr
->as_string ();
1793 IfLetExpr::as_string () const
1795 std::string str
= "IfLetExpr: ";
1797 str
+= append_attributes (outer_attrs
, OUTER
);
1799 str
+= "\n Condition match arm patterns: ";
1800 if (match_arm_patterns
.empty ())
1806 for (const auto &pattern
: match_arm_patterns
)
1807 str
+= "\n " + pattern
->as_string ();
1810 str
+= "\n Scrutinee expr: " + value
->as_string ();
1812 str
+= "\n If let block expr: " + if_block
->as_string ();
1818 IfLetExprConseqElse::as_string () const
1820 std::string str
= IfLetExpr::as_string ();
1822 str
+= "\n Else block expr: " + else_block
->as_string ();
1828 IfLetExprConseqIf::as_string () const
1830 std::string str
= IfLetExpr::as_string ();
1832 str
+= "\n Else if expr: \n " + if_expr
->as_string ();
1838 IfLetExprConseqIfLet::as_string () const
1840 std::string str
= IfLetExpr::as_string ();
1842 str
+= "\n Else if let expr: \n " + if_let_expr
->as_string ();
1848 RangeFromToInclExpr::as_string () const
1850 // TODO: rewrite to allow dumps with non-literal exprs
1851 return from
->as_string () + "..=" + to
->as_string ();
1855 ErrorPropagationExpr::as_string () const
1857 // TODO: rewrite to allow dumps with non-literal exprs
1858 return main_or_left_expr
->as_string () + "?";
1862 CompoundAssignmentExpr::as_string () const
1864 std::string operator_str
;
1865 operator_str
.reserve (1);
1867 // get operator string
1870 case CompoundAssignmentOperator::ADD
:
1873 case CompoundAssignmentOperator::SUBTRACT
:
1876 case CompoundAssignmentOperator::MULTIPLY
:
1879 case CompoundAssignmentOperator::DIVIDE
:
1882 case CompoundAssignmentOperator::MODULUS
:
1885 case CompoundAssignmentOperator::BITWISE_AND
:
1888 case CompoundAssignmentOperator::BITWISE_OR
:
1891 case CompoundAssignmentOperator::BITWISE_XOR
:
1894 case CompoundAssignmentOperator::LEFT_SHIFT
:
1895 operator_str
= "<<";
1897 case CompoundAssignmentOperator::RIGHT_SHIFT
:
1898 operator_str
= ">>";
1901 operator_str
= "invalid operator. wtf";
1905 operator_str
+= "=";
1907 std::string
str ("CompoundAssignmentExpr: ");
1908 if (main_or_left_expr
== nullptr || right_expr
== nullptr)
1910 str
+= "error. this is probably a parsing failure.";
1914 str
+= "\n left: " + main_or_left_expr
->as_string ();
1915 str
+= "\n right: " + right_expr
->as_string ();
1916 str
+= "\n operator: " + operator_str
;
1923 ArithmeticOrLogicalExpr::as_string () const
1925 std::string operator_str
;
1926 operator_str
.reserve (1);
1928 // get operator string
1931 case ArithmeticOrLogicalOperator::ADD
:
1934 case ArithmeticOrLogicalOperator::SUBTRACT
:
1937 case ArithmeticOrLogicalOperator::MULTIPLY
:
1940 case ArithmeticOrLogicalOperator::DIVIDE
:
1943 case ArithmeticOrLogicalOperator::MODULUS
:
1946 case ArithmeticOrLogicalOperator::BITWISE_AND
:
1949 case ArithmeticOrLogicalOperator::BITWISE_OR
:
1952 case ArithmeticOrLogicalOperator::BITWISE_XOR
:
1955 case ArithmeticOrLogicalOperator::LEFT_SHIFT
:
1956 operator_str
= "<<";
1958 case ArithmeticOrLogicalOperator::RIGHT_SHIFT
:
1959 operator_str
= ">>";
1962 operator_str
= "invalid operator. wtf";
1966 std::string
str ("ArithmeticOrLogicalExpr: ");
1967 if (main_or_left_expr
== nullptr || right_expr
== nullptr)
1969 str
+= "error. this is probably a parsing failure.";
1973 str
+= main_or_left_expr
->as_string () + " ";
1974 str
+= operator_str
+ " ";
1975 str
+= right_expr
->as_string ();
1982 CallExpr::as_string () const
1984 std::string str
= "CallExpr: ";
1986 str
+= append_attributes (outer_attrs
, OUTER
);
1988 str
+= "\n Function expr: ";
1989 str
+= function
->as_string ();
1991 str
+= "\n Call params:";
1998 for (const auto ¶m
: params
)
2000 if (param
== nullptr)
2001 return "ERROR_MARK_STRING - call expr param is null";
2003 str
+= "\n " + param
->as_string ();
2011 WhileLoopExpr::as_string () const
2013 std::string str
= "WhileLoopExpr: ";
2015 str
+= append_attributes (outer_attrs
, OUTER
);
2017 str
+= "\n Label: ";
2018 if (!has_loop_label ())
2021 str
+= loop_label
.as_string ();
2023 str
+= "\n Conditional expr: " + condition
->as_string ();
2025 str
+= "\n Loop block: " + loop_block
->as_string ();
2031 WhileLetLoopExpr::as_string () const
2033 std::string str
= "WhileLetLoopExpr: ";
2035 str
+= append_attributes (outer_attrs
, OUTER
);
2037 str
+= "\n Label: ";
2038 if (!has_loop_label ())
2041 str
+= loop_label
.as_string ();
2043 str
+= "\n Match arm patterns: ";
2044 if (match_arm_patterns
.empty ())
2050 for (const auto &pattern
: match_arm_patterns
)
2051 str
+= "\n " + pattern
->as_string ();
2054 str
+= "\n Scrutinee expr: " + scrutinee
->as_string ();
2056 str
+= "\n Loop block: " + loop_block
->as_string ();
2062 LoopExpr::as_string () const
2064 std::string str
= "LoopExpr: (infinite loop)";
2066 str
+= append_attributes (outer_attrs
, OUTER
);
2068 str
+= "\n Label: ";
2069 if (!has_loop_label ())
2072 str
+= loop_label
.as_string ();
2074 str
+= "\n Loop block: " + loop_block
->as_string ();
2080 ArrayExpr::as_string () const
2082 std::string str
= "ArrayExpr:";
2084 str
+= append_attributes (outer_attrs
, OUTER
);
2087 str
+= append_attributes (inner_attrs
, INNER
);
2089 str
+= "\n Array elems: ";
2090 str
+= internal_elements
->as_string ();
2096 AwaitExpr::as_string () const
2098 // TODO: rewrite dump to allow non-literal exprs
2099 return awaited_expr
->as_string () + ".await";
2103 BreakExpr::as_string () const
2105 // TODO: rewrite dump to allow outer attrs, non-literal exprs
2106 std::string
str ("break ");
2109 str
+= label
.as_string () + " ";
2111 if (has_break_expr ())
2112 str
+= break_expr
->as_string ();
2118 LoopLabel::as_string () const
2120 return label
.as_string () + ": (label) ";
2124 MatchArm::as_string () const
2127 std::string str
= append_attributes (outer_attrs
, OUTER
);
2129 str
+= "\nPatterns: ";
2130 if (match_arm_patterns
.empty ())
2136 for (const auto &pattern
: match_arm_patterns
)
2137 str
+= "\n " + pattern
->as_string ();
2140 str
+= "\nGuard expr: ";
2141 if (!has_match_arm_guard ())
2144 str
+= guard_expr
->as_string ();
2150 MatchCase::as_string () const
2152 std::string
str ("MatchCase: (match arm) ");
2154 str
+= "\n Match arm matcher: \n" + arm
.as_string ();
2155 str
+= "\n Expr: " + expr
->as_string ();
2161 MatchExpr::as_string () const
2163 std::string
str ("MatchExpr:");
2165 str
+= append_attributes (outer_attrs
, OUTER
);
2167 str
+= "\n Scrutinee expr: " + branch_value
->as_string ();
2170 str
+= append_attributes (inner_attrs
, INNER
);
2173 str
+= "\n Match arms: ";
2174 if (match_arms
.empty ())
2180 for (const auto &arm
: match_arms
)
2181 str
+= "\n " + arm
.as_string ();
2188 TupleExpr::as_string () const
2190 std::string
str ("TupleExpr:");
2192 str
+= append_attributes (outer_attrs
, OUTER
);
2195 str
+= append_attributes (inner_attrs
, INNER
);
2197 str
+= "\n Tuple elements: ";
2198 if (tuple_elems
.empty ())
2204 for (const auto &elem
: tuple_elems
)
2205 str
+= "\n " + elem
->as_string ();
2212 ExprStmtWithoutBlock::as_string () const
2214 std::string
str ("ExprStmtWithoutBlock:\n");
2215 indent_spaces (enter
);
2216 str
+= indent_spaces (stay
);
2218 if (expr
== nullptr)
2219 str
+= "none (this shouldn't happen and is probably an error)";
2221 str
+= expr
->as_string ();
2222 indent_spaces (out
);
2228 FunctionParam::as_string () const
2230 // TODO: rewrite dump to allow non-literal types
2231 return param_name
->as_string () + " : " + type
->as_string ();
2235 FunctionQualifiers::as_string () const
2239 switch (const_status
)
2251 return "ERROR_MARK_STRING: async-const status failure";
2260 if (extern_abi
!= "")
2261 str
+= " \"" + extern_abi
+ "\"";
2268 TraitBound::as_string () const
2270 std::string
str ("TraitBound:");
2272 str
+= "\n Has opening question mark: ";
2273 if (opening_question_mark
)
2278 str
+= "\n For lifetimes: ";
2279 if (!has_for_lifetimes ())
2285 for (const auto &lifetime
: for_lifetimes
)
2286 str
+= "\n " + lifetime
.as_string ();
2289 str
+= "\n Type path: " + type_path
.as_string ();
2295 MacroMatcher::as_string () const
2297 std::string
str ("Macro matcher: ");
2299 str
+= "\n Delim type: ";
2304 str
+= "parentheses";
2313 return "ERROR_MARK_STRING - macro matcher delim";
2316 str
+= "\n Matches: ";
2318 if (matches
.empty ())
2324 for (const auto &match
: matches
)
2325 str
+= "\n " + match
->as_string ();
2332 LifetimeParam::as_string () const
2334 std::string
str ("LifetimeParam: ");
2336 str
+= "\n Outer attribute: ";
2337 if (!has_outer_attribute ())
2340 str
+= outer_attr
.as_string ();
2342 str
+= "\n Lifetime: " + lifetime
.as_string ();
2344 str
+= "\n Lifetime bounds: ";
2345 if (!has_lifetime_bounds ())
2351 for (const auto &bound
: lifetime_bounds
)
2352 str
+= "\n " + bound
.as_string ();
2359 ConstGenericParam::as_string () const
2361 std::string
str ("ConstGenericParam: ");
2362 str
+= "const " + name
+ ": " + type
->as_string ();
2364 if (has_default_value ())
2365 str
+= " = " + get_default_value ().as_string ();
2371 MacroMatchFragment::as_string () const
2373 return "$" + ident
+ ": " + frag_spec
.as_string ();
2377 QualifiedPathInType::as_string () const
2379 /* TODO: this may need adjusting if segments (e.g. with functions) can't be
2381 std::string str
= path_type
.as_string ();
2383 for (const auto &segment
: segments
)
2384 str
+= "::" + segment
->as_string ();
2390 MacroMatchRepetition::as_string () const
2392 std::string
str ("Macro match repetition: ");
2394 str
+= "\n Matches: ";
2395 if (matches
.empty ())
2401 for (const auto &match
: matches
)
2402 str
+= "\n " + match
->as_string ();
2409 str
+= sep
->as_string ();
2424 str
+= "no op? shouldn't be allowed";
2427 return "ERROR_MARK_STRING - unknown op in macro match repetition";
2434 Lifetime::as_string () const
2437 return "error lifetime";
2439 switch (lifetime_type
)
2442 return "'" + lifetime_name
;
2448 return "ERROR-MARK-STRING: lifetime type failure";
2453 TypePath::as_string () const
2455 /* TODO: this may need to be rewritten if a segment (e.g. function) can't be
2459 if (has_opening_scope_resolution
)
2462 for (const auto &segment
: segments
)
2463 str
+= segment
->as_string () + "::";
2465 // kinda hack - remove last 2 '::' characters
2466 str
.erase (str
.length () - 2);
2472 TypeParam::as_string () const
2474 std::string
str ("TypeParam: ");
2476 str
+= "\n Outer attribute: ";
2477 if (!has_outer_attribute ())
2480 str
+= outer_attr
.as_string ();
2482 str
+= "\n Identifier: " + type_representation
;
2484 str
+= "\n Type param bounds: ";
2485 if (!has_type_param_bounds ())
2491 for (const auto &bound
: type_param_bounds
)
2492 str
+= "\n " + bound
->as_string ();
2499 str
+= type
->as_string ();
2505 PathPattern::convert_to_simple_path (bool with_opening_scope_resolution
) const
2507 if (!has_segments ())
2508 return SimplePath::create_empty ();
2510 // create vector of reserved size (to minimise reallocations)
2511 std::vector
<SimplePathSegment
> simple_segments
;
2512 simple_segments
.reserve (segments
.size ());
2514 for (const auto &segment
: segments
)
2516 // return empty path if doesn't meet simple path segment requirements
2517 if (segment
.is_error () || segment
.has_generic_args ()
2518 || segment
.as_string () == "Self")
2519 return SimplePath::create_empty ();
2521 // create segment and add to vector
2522 std::string segment_str
= segment
.as_string ();
2523 simple_segments
.push_back (
2524 SimplePathSegment (std::move (segment_str
), segment
.get_locus ()));
2527 // kind of a HACK to get locus depending on opening scope resolution
2528 Location locus
= Linemap::unknown_location ();
2529 if (with_opening_scope_resolution
)
2530 locus
= simple_segments
[0].get_locus () - 2; // minus 2 chars for ::
2532 locus
= simple_segments
[0].get_locus ();
2533 // FIXME: this hack probably doesn't actually work
2535 return SimplePath (std::move (simple_segments
), with_opening_scope_resolution
,
2540 TypePath::as_simple_path () const
2542 if (segments
.empty ())
2543 return SimplePath::create_empty ();
2545 // create vector of reserved size (to minimise reallocations)
2546 std::vector
<SimplePathSegment
> simple_segments
;
2547 simple_segments
.reserve (segments
.size ());
2549 for (const auto &segment
: segments
)
2551 // return empty path if doesn't meet simple path segment requirements
2552 if (segment
== nullptr || segment
->is_error ()
2553 || !segment
->is_ident_only () || segment
->as_string () == "Self")
2554 return SimplePath::create_empty ();
2556 // create segment and add to vector
2557 std::string segment_str
= segment
->as_string ();
2558 simple_segments
.push_back (
2559 SimplePathSegment (std::move (segment_str
), segment
->get_locus ()));
2562 return SimplePath (std::move (simple_segments
), has_opening_scope_resolution
,
2567 PathExprSegment::as_string () const
2569 // TODO: rewrite dump to work with non-literalisable types
2570 std::string ident_str
= segment_name
.as_string ();
2571 if (has_generic_args ())
2572 ident_str
+= "::<" + generic_args
.as_string () + ">";
2578 GenericArgs::as_string () const
2583 if (!lifetime_args
.empty ())
2585 auto i
= lifetime_args
.begin ();
2586 auto e
= lifetime_args
.end ();
2590 args
+= (*i
).as_string ();
2597 if (!generic_args
.empty ())
2599 auto i
= generic_args
.begin ();
2600 auto e
= generic_args
.end ();
2604 args
+= (*i
).as_string ();
2611 if (!binding_args
.empty ())
2613 auto i
= binding_args
.begin ();
2614 auto e
= binding_args
.end ();
2618 args
+= (*i
).as_string ();
2628 GenericArgsBinding::as_string () const
2630 // TODO: rewrite to work with non-literalisable types
2631 return identifier
+ " = " + type
->as_string ();
2635 ForLoopExpr::as_string () const
2637 std::string str
= "ForLoopExpr: ";
2639 str
+= append_attributes (outer_attrs
, OUTER
);
2641 str
+= "\n Label: ";
2642 if (!has_loop_label ())
2645 str
+= loop_label
.as_string ();
2647 str
+= "\n Pattern: " + pattern
->as_string ();
2649 str
+= "\n Iterator expr: " + iterator_expr
->as_string ();
2651 str
+= "\n Loop block: " + loop_block
->as_string ();
2657 RangePattern::as_string () const
2659 // TODO: maybe rewrite to work with non-linearisable bounds
2660 if (has_ellipsis_syntax
)
2661 return lower
->as_string () + "..." + upper
->as_string ();
2663 return lower
->as_string () + "..=" + upper
->as_string ();
2667 RangePatternBoundLiteral::as_string () const
2674 str
+= literal
.as_string ();
2680 SlicePattern::as_string () const
2682 std::string
str ("SlicePattern: ");
2684 for (const auto &pattern
: items
)
2685 str
+= "\n " + pattern
->as_string ();
2691 TuplePatternItemsMultiple::as_string () const
2695 for (const auto &pattern
: patterns
)
2696 str
+= "\n " + pattern
->as_string ();
2702 TuplePatternItemsRanged::as_string () const
2706 str
+= "\n Lower patterns: ";
2707 if (lower_patterns
.empty ())
2713 for (const auto &lower
: lower_patterns
)
2714 str
+= "\n " + lower
->as_string ();
2717 str
+= "\n Upper patterns: ";
2718 if (upper_patterns
.empty ())
2724 for (const auto &upper
: upper_patterns
)
2725 str
+= "\n " + upper
->as_string ();
2732 TuplePattern::as_string () const
2734 return "TuplePattern: " + items
->as_string ();
2738 StructPatternField::as_string () const
2741 std::string str
= append_attributes (outer_attrs
, OUTER
);
2747 StructPatternFieldIdent::as_string () const
2749 std::string str
= StructPatternField::as_string ();
2765 StructPatternFieldTuplePat::as_string () const
2767 // TODO: maybe rewrite to work with non-linearisable patterns
2768 std::string str
= StructPatternField::as_string ();
2772 str
+= std::to_string (index
) + " : " + tuple_pattern
->as_string ();
2778 StructPatternFieldIdentPat::as_string () const
2780 // TODO: maybe rewrite to work with non-linearisable patterns
2781 std::string str
= StructPatternField::as_string ();
2785 str
+= ident
+ " : " + ident_pattern
->as_string ();
2791 StructPatternElements::as_string () const
2793 std::string
str ("\n Fields: ");
2795 if (!has_struct_pattern_fields ())
2801 for (const auto &field
: fields
)
2802 str
+= "\n " + field
->as_string ();
2806 if (has_struct_pattern_etc
)
2815 StructPattern::as_string () const
2817 std::string
str ("StructPattern: \n Path: ");
2819 str
+= path
.as_string ();
2821 str
+= "\n Struct pattern elems: ";
2822 if (!has_struct_pattern_elems ())
2825 str
+= elems
.as_string ();
2831 LiteralPattern::as_string () const
2833 return lit
.as_string ();
2837 ReferencePattern::as_string () const
2839 // TODO: maybe rewrite to work with non-linearisable patterns
2840 std::string
str ("&");
2848 str
+= pattern
->as_string ();
2854 IdentifierPattern::as_string () const
2856 // TODO: maybe rewrite to work with non-linearisable patterns
2865 str
+= variable_ident
;
2867 if (has_pattern_to_bind ())
2868 str
+= " @ " + to_bind
->as_string ();
2874 TupleStructItemsNoRange::as_string () const
2878 for (const auto &pattern
: patterns
)
2879 str
+= "\n " + pattern
->as_string ();
2885 TupleStructItemsRange::as_string () const
2887 std::string
str ("\n Lower patterns: ");
2889 if (lower_patterns
.empty ())
2895 for (const auto &lower
: lower_patterns
)
2896 str
+= "\n " + lower
->as_string ();
2899 str
+= "\n Upper patterns: ";
2900 if (upper_patterns
.empty ())
2906 for (const auto &upper
: upper_patterns
)
2907 str
+= "\n " + upper
->as_string ();
2914 TupleStructPattern::as_string () const
2916 std::string
str ("TupleStructPattern: \n Path: ");
2918 str
+= path
.as_string ();
2920 str
+= "\n Tuple struct items: " + items
->as_string ();
2926 LetStmt::as_string () const
2928 // TODO: rewrite to work with non-linearisable types and exprs
2929 std::string str
= append_attributes (outer_attrs
, OUTER
);
2931 str
+= "\n" + indent_spaces (stay
) + "let " + variables_pattern
->as_string ();
2934 str
+= " : " + type
->as_string ();
2936 if (has_init_expr ())
2937 str
+= " = " + init_expr
->as_string ();
2942 // hopefully definition here will prevent circular dependency issue
2944 TypePath::to_trait_bound (bool in_parens
) const
2946 return new TraitBound (TypePath (*this), get_locus (), in_parens
);
2950 InferredType::as_string () const
2952 return "_ (inferred)";
2956 TypeCastExpr::as_string () const
2958 // TODO: rewrite to work with non-linearisable exprs and types
2959 return main_or_left_expr
->as_string () + " as "
2960 + type_to_convert_to
->as_string ();
2964 ImplTraitType::as_string () const
2966 std::string
str ("ImplTraitType: \n TypeParamBounds: ");
2968 if (type_param_bounds
.empty ())
2974 for (const auto &bound
: type_param_bounds
)
2975 str
+= "\n " + bound
->as_string ();
2982 ReferenceType::as_string () const
2984 // TODO: rewrite to work with non-linearisable types
2985 std::string
str ("&");
2987 if (has_lifetime ())
2988 str
+= lifetime
.as_string () + " ";
2993 str
+= type
->as_string ();
2999 RawPointerType::as_string () const
3001 // TODO: rewrite to work with non-linearisable types
3002 std::string
str ("*");
3004 switch (pointer_type
)
3013 return "ERROR_MARK_STRING - unknown pointer type in raw pointer type";
3016 str
+= type
->as_string ();
3022 TraitObjectType::as_string () const
3024 std::string
str ("TraitObjectType: \n Has dyn dispatch: ");
3031 str
+= "\n TypeParamBounds: ";
3032 if (type_param_bounds
.empty ())
3038 for (const auto &bound
: type_param_bounds
)
3039 str
+= "\n " + bound
->as_string ();
3046 BareFunctionType::as_string () const
3048 std::string
str ("BareFunctionType: \n For lifetimes: ");
3050 if (!has_for_lifetimes ())
3056 for (const auto &for_lifetime
: for_lifetimes
)
3057 str
+= "\n " + for_lifetime
.as_string ();
3060 str
+= "\n Qualifiers: " + function_qualifiers
.as_string ();
3062 str
+= "\n Params: ";
3063 if (params
.empty ())
3069 for (const auto ¶m
: params
)
3070 str
+= "\n " + param
.as_string ();
3073 str
+= "\n Is variadic: ";
3079 str
+= "\n Return type: ";
3080 if (!has_return_type ())
3081 str
+= "none (void)";
3083 str
+= return_type
->as_string ();
3089 ImplTraitTypeOneBound::as_string () const
3091 std::string
str ("ImplTraitTypeOneBound: \n TraitBound: ");
3093 return str
+ trait_bound
.as_string ();
3097 TypePathSegmentGeneric::as_string () const
3099 // TODO: rewrite to work with non-linearisable types
3100 return TypePathSegment::as_string () + "<" + generic_args
.as_string () + ">";
3104 TraitObjectTypeOneBound::as_string () const
3106 std::string
str ("TraitObjectTypeOneBound: \n Has dyn dispatch: ");
3113 str
+= "\n TraitBound: " + trait_bound
.as_string ();
3119 TypePathFunction::as_string () const
3121 // TODO: rewrite to work with non-linearisable types
3122 std::string
str ("(");
3126 auto i
= inputs
.begin ();
3127 auto e
= inputs
.end ();
3131 str
+= (*i
)->as_string ();
3139 if (has_return_type ())
3140 str
+= " -> " + return_type
->as_string ();
3146 TypePathSegmentFunction::as_string () const
3148 // TODO: rewrite to work with non-linearisable types
3149 return TypePathSegment::as_string () + function_path
.as_string ();
3153 ArrayType::as_string () const
3155 // TODO: rewrite to work with non-linearisable types and exprs
3156 return "[" + elem_type
->as_string () + "; " + size
->as_string () + "]";
3160 SliceType::as_string () const
3162 // TODO: rewrite to work with non-linearisable types
3163 return "[" + elem_type
->as_string () + "]";
3167 TupleType::as_string () const
3169 // TODO: rewrite to work with non-linearisable types
3170 std::string
str ("(");
3172 if (!is_unit_type ())
3174 auto i
= elems
.begin ();
3175 auto e
= elems
.end ();
3179 str
+= (*i
)->as_string ();
3191 StructExpr::as_string () const
3193 std::string str
= append_attributes (outer_attrs
, OUTER
);
3194 indent_spaces (enter
);
3195 str
+= "\n" + indent_spaces (stay
) + "StructExpr:";
3196 indent_spaces (enter
);
3197 str
+= "\n" + indent_spaces (stay
) + "PathInExpr:\n";
3198 str
+= indent_spaces (stay
) + struct_name
.as_string ();
3199 indent_spaces (out
);
3200 indent_spaces (out
);
3205 StructExprStruct::as_string () const
3207 // TODO: doesn't this require data from StructExpr?
3208 std::string
str ("StructExprStruct (or subclass): ");
3210 str
+= "\n Path: " + get_struct_name ().as_string ();
3213 str
+= append_attributes (inner_attrs
, INNER
);
3219 StructBase::as_string () const
3221 if (base_struct
!= nullptr)
3222 return base_struct
->as_string ();
3224 return "ERROR_MARK_STRING - invalid struct base had as string applied";
3228 StructExprFieldWithVal::as_string () const
3230 // used to get value string
3231 return value
->as_string ();
3235 StructExprFieldIdentifierValue::as_string () const
3237 // TODO: rewrite to work with non-linearisable exprs
3238 return field_name
+ " : " + StructExprFieldWithVal::as_string ();
3242 StructExprFieldIndexValue::as_string () const
3244 // TODO: rewrite to work with non-linearisable exprs
3245 return std::to_string (index
) + " : " + StructExprFieldWithVal::as_string ();
3249 StructExprStructFields::as_string () const
3251 std::string str
= StructExprStruct::as_string ();
3253 str
+= "\n Fields: ";
3254 if (fields
.empty ())
3260 for (const auto &field
: fields
)
3261 str
+= "\n " + field
->as_string ();
3264 str
+= "\n Struct base: ";
3265 if (!has_struct_base ())
3268 str
+= struct_base
.as_string ();
3274 EnumItem::as_string () const
3276 std::string str
= VisItem::as_string ();
3277 str
+= variant_name
;
3283 EnumItemTuple::as_string () const
3285 std::string str
= EnumItem::as_string ();
3287 // add tuple opening parens
3291 if (has_tuple_fields ())
3293 auto i
= tuple_fields
.begin ();
3294 auto e
= tuple_fields
.end ();
3298 str
+= (*i
).as_string ();
3304 // add tuple closing parens
3311 TupleField::as_string () const
3313 // TODO: rewrite to work with non-linearisable exprs
3316 std::string str
= append_attributes (outer_attrs
, OUTER
);
3318 if (has_visibility ())
3319 str
+= "\n" + visibility
.as_string ();
3321 str
+= " " + field_type
->as_string ();
3327 EnumItemStruct::as_string () const
3329 std::string str
= EnumItem::as_string ();
3331 // add struct opening parens
3335 if (has_struct_fields ())
3337 auto i
= struct_fields
.begin ();
3338 auto e
= struct_fields
.end ();
3342 str
+= (*i
).as_string ();
3348 // add struct closing parens
3355 StructField::as_string () const
3357 // TODO: rewrite to work with non-linearisable exprs
3359 std::string str
= append_attributes (outer_attrs
, OUTER
);
3361 if (has_visibility ())
3362 str
+= "\n" + visibility
.as_string ();
3364 str
+= " " + field_name
+ " : " + field_type
->as_string ();
3370 EnumItemDiscriminant::as_string () const
3372 // TODO: rewrite to work with non-linearisable exprs
3373 std::string str
= EnumItem::as_string ();
3375 // add equal and expression
3376 str
+= " = " + expression
->as_string ();
3382 ExternalStaticItem::as_string () const
3385 std::string str
= append_attributes (outer_attrs
, OUTER
);
3387 // start visibility on new line and with a space
3388 str
+= "\n" + visibility
.as_string () + " ";
3398 // add type on new line
3399 str
+= "\n Type: " + item_type
->as_string ();
3405 ExternalFunctionItem::as_string () const
3408 std::string str
= append_attributes (outer_attrs
, OUTER
);
3410 // start visibility on new line and with a space
3411 str
+= "\n" + visibility
.as_string () + " ";
3419 str
+= "\n Generic params: ";
3420 if (generic_params
.empty ())
3426 for (const auto ¶m
: generic_params
)
3428 // DEBUG: null pointer check
3429 if (param
== nullptr)
3432 "something really terrible has gone wrong - null pointer "
3433 "generic param in external function item.");
3434 return "NULL_POINTER_MARK";
3437 str
+= "\n " + param
->as_string ();
3442 str
+= "\n Function params: ";
3443 if (function_params
.empty () && !has_variadics
)
3449 for (const auto ¶m
: function_params
)
3450 str
+= "\n " + param
.as_string ();
3454 str
+= "\n variadic outer attrs: ";
3455 if (has_variadic_outer_attrs ())
3457 for (const auto &attr
: variadic_outer_attrs
)
3458 str
+= "\n " + attr
.as_string ();
3464 str
+= "\n ... (variadic)";
3468 // add type on new line
3469 str
+= "\n (return) Type: "
3470 + (has_return_type () ? return_type
->as_string () : "()");
3473 str
+= "\n Where clause: ";
3474 if (has_where_clause ())
3475 str
+= where_clause
.as_string ();
3483 NamedFunctionParam::as_string () const
3485 std::string str
= append_attributes (outer_attrs
, OUTER
);
3489 str
+= "\n Type: " + param_type
->as_string ();
3495 TraitItemFunc::as_string () const
3497 std::string str
= append_attributes (outer_attrs
, OUTER
);
3499 str
+= "\n" + decl
.as_string ();
3501 str
+= "\n Definition (block expr): ";
3502 if (has_definition ())
3503 str
+= block_expr
->as_string ();
3511 TraitFunctionDecl::as_string () const
3513 std::string str
= qualifiers
.as_string () + "fn " + function_name
;
3516 str
+= "\n Generic params: ";
3517 if (generic_params
.empty ())
3523 for (const auto ¶m
: generic_params
)
3525 // DEBUG: null pointer check
3526 if (param
== nullptr)
3529 "something really terrible has gone wrong - null pointer "
3530 "generic param in trait function decl.");
3531 return "NULL_POINTER_MARK";
3534 str
+= "\n " + param
->as_string ();
3538 str
+= "\n Function params: ";
3541 for (const auto ¶m
: function_params
)
3542 str
+= "\n " + param
.as_string ();
3549 str
+= "\n Return type: ";
3550 if (has_return_type ())
3551 str
+= return_type
->as_string ();
3553 str
+= "none (void)";
3555 str
+= "\n Where clause: ";
3556 if (has_where_clause ())
3557 str
+= where_clause
.as_string ();
3565 TraitItemMethod::as_string () const
3567 std::string str
= append_attributes (outer_attrs
, OUTER
);
3569 str
+= "\n" + decl
.as_string ();
3571 str
+= "\n Definition (block expr): ";
3572 if (has_definition ())
3573 str
+= block_expr
->as_string ();
3581 TraitMethodDecl::as_string () const
3583 std::string str
= qualifiers
.as_string () + "fn " + function_name
;
3586 str
+= "\n Generic params: ";
3587 if (generic_params
.empty ())
3593 for (const auto ¶m
: generic_params
)
3595 // DEBUG: null pointer check
3596 if (param
== nullptr)
3599 "something really terrible has gone wrong - null pointer "
3600 "generic param in trait function decl.");
3601 return "NULL_POINTER_MARK";
3604 str
+= "\n " + param
->as_string ();
3608 str
+= "\n Self param: " + self_param
.as_string ();
3610 str
+= "\n Function params: ";
3613 for (const auto ¶m
: function_params
)
3614 str
+= "\n " + param
.as_string ();
3621 str
+= "\n Return type: ";
3622 if (has_return_type ())
3623 str
+= return_type
->as_string ();
3625 str
+= "none (void)";
3627 str
+= "\n Where clause: ";
3628 if (has_where_clause ())
3629 str
+= where_clause
.as_string ();
3637 TraitItemConst::as_string () const
3639 // TODO: rewrite to work with non-linearisable exprs
3640 std::string str
= append_attributes (outer_attrs
, OUTER
);
3642 str
+= "\nconst " + name
+ " : " + type
->as_string ();
3644 if (has_expression ())
3645 str
+= " = " + expr
->as_string ();
3651 TraitItemType::as_string () const
3653 std::string str
= append_attributes (outer_attrs
, OUTER
);
3655 str
+= "\ntype " + name
;
3657 str
+= "\n Type param bounds: ";
3658 if (!has_type_param_bounds ())
3664 for (const auto &bound
: type_param_bounds
)
3666 // DEBUG: null pointer check
3667 if (bound
== nullptr)
3670 "something really terrible has gone wrong - null pointer "
3671 "type param bound in trait item type.");
3672 return "NULL_POINTER_MARK";
3675 str
+= "\n " + bound
->as_string ();
3683 SelfParam::as_string () const
3685 // TODO: rewrite to allow non-linearisable types
3694 // type (i.e. not ref, no lifetime)
3702 str
+= type
->as_string ();
3706 else if (has_lifetime ())
3709 std::string str
= "&" + lifetime
.as_string () + " ";
3720 // ref with no lifetime
3721 std::string str
= "&";
3746 ArrayElemsCopied::as_string () const
3748 // TODO: rewrite to allow non-linearisable exprs
3749 return elem_to_copy
->as_string () + "; " + num_copies
->as_string ();
3753 LifetimeWhereClauseItem::as_string () const
3755 std::string
str ("Lifetime: ");
3757 str
+= lifetime
.as_string ();
3759 str
+= "\nLifetime bounds: ";
3761 for (const auto &bound
: lifetime_bounds
)
3762 str
+= "\n " + bound
.as_string ();
3768 TypeBoundWhereClauseItem::as_string () const
3770 std::string
str ("For lifetimes: ");
3772 if (!has_for_lifetimes ())
3778 for (const auto &for_lifetime
: for_lifetimes
)
3779 str
+= "\n " + for_lifetime
.as_string ();
3782 str
+= "\nType: " + bound_type
->as_string ();
3784 str
+= "\nType param bounds bounds: ";
3786 for (const auto &bound
: type_param_bounds
)
3788 // debug null pointer check
3789 if (bound
== nullptr)
3790 return "NULL_POINTER_MARK - type param bounds";
3792 str
+= "\n " + bound
->as_string ();
3799 ArrayElemsValues::as_string () const
3803 for (const auto &expr
: values
)
3805 // DEBUG: null pointer check
3806 if (expr
== nullptr)
3808 rust_debug ("something really terrible has gone wrong - null pointer "
3809 "expr in array elems values.");
3810 return "NULL_POINTER_MARK";
3813 str
+= "\n " + expr
->as_string ();
3820 MaybeNamedParam::as_string () const
3822 // TODO: rewrite to allow using non-linearisable types in dump
3836 return "ERROR_MARK_STRING - maybe named param unrecognised param kind";
3839 str
+= param_type
->as_string ();
3844 MetaItemInner::~MetaItemInner () = default;
3846 std::unique_ptr
<MetaNameValueStr
>
3847 MetaItemInner::to_meta_name_value_str () const
3849 if (is_key_value_pair ())
3851 auto converted_item
= static_cast<const MetaNameValueStr
*> (this);
3852 return converted_item
->to_meta_name_value_str ();
3854 // TODO actually parse foo = bar
3859 MetaItemSeq::as_string () const
3861 std::string path_str
= path
.as_string () + "(";
3863 auto i
= seq
.begin ();
3864 auto e
= seq
.end ();
3868 path_str
+= (*i
)->as_string ();
3873 return path_str
+ ")";
3877 MetaListPaths::as_string () const
3879 std::string str
= ident
+ "(";
3881 auto i
= paths
.begin ();
3882 auto e
= paths
.end ();
3886 str
+= (*i
).as_string ();
3895 MetaListNameValueStr::as_string () const
3897 std::string str
= ident
+ "(";
3899 auto i
= strs
.begin ();
3900 auto e
= strs
.end ();
3904 str
+= (*i
).as_string ();
3913 AttrInputMetaItemContainer::as_string () const
3915 std::string str
= "(";
3917 auto i
= items
.begin ();
3918 auto e
= items
.end ();
3922 str
+= (*i
)->as_string ();
3930 /* Override that calls the function recursively on all items contained within
3933 Module::add_crate_name (std::vector
<std::string
> &names
) const
3935 /* TODO: test whether module has been 'cfg'-ed out to determine whether to
3936 * exclude it from search */
3938 for (const auto &item
: items
)
3939 item
->add_crate_name (names
);
3943 file_exists (const std::string path
)
3945 // Simply check if the file exists
3946 // FIXME: This does not work on Windows
3947 return access (path
.c_str (), F_OK
) != -1;
3951 filename_from_path_attribute (std::vector
<Attribute
> &outer_attrs
)
3953 // An out-of-line module cannot have inner attributes. Additionally, the
3954 // default name is specified as `""` so that the caller can detect the case
3955 // of "no path given" and use the default path logic (`name.rs` or
3957 return extract_module_path ({}, outer_attrs
, "");
3961 Module::process_file_path ()
3963 rust_assert (kind
== Module::ModuleKind::UNLOADED
);
3964 rust_assert (module_file
.empty ());
3966 // This corresponds to the path of the file 'including' the module. So the
3967 // file that contains the 'mod <file>;' directive
3968 std::string
including_fname (outer_filename
);
3970 std::string expected_file_path
= module_name
+ ".rs";
3971 std::string expected_dir_path
= "mod.rs";
3973 auto dir_slash_pos
= including_fname
.rfind (file_separator
);
3974 std::string current_directory_name
;
3976 // If we haven't found a file_separator, then we have to look for files in the
3977 // current directory ('.')
3978 if (dir_slash_pos
== std::string::npos
)
3979 current_directory_name
= std::string (".") + file_separator
;
3981 current_directory_name
3982 = including_fname
.substr (0, dir_slash_pos
) + file_separator
;
3984 // Handle inline module declarations adding path components.
3985 for (auto const &name
: module_scope
)
3987 current_directory_name
.append (name
);
3988 current_directory_name
.append (file_separator
);
3991 auto path_string
= filename_from_path_attribute (get_outer_attrs ());
3992 if (!path_string
.empty ())
3994 module_file
= current_directory_name
+ path_string
;
3998 // FIXME: We also have to search for
3999 // <directory>/<including_fname>/<module_name>.rs In rustc, this is done via
4000 // the concept of `DirOwnernship`, which is based on whether or not the
4001 // current file is titled `mod.rs`.
4003 // First, we search for <directory>/<module_name>.rs
4004 std::string file_mod_path
= current_directory_name
+ expected_file_path
;
4005 bool file_mod_found
= file_exists (file_mod_path
);
4007 // Then, search for <directory>/<module_name>/mod.rs
4008 std::string dir_mod_path
4009 = current_directory_name
+ module_name
+ file_separator
+ expected_dir_path
;
4010 bool dir_mod_found
= file_exists (dir_mod_path
);
4012 bool multiple_candidates_found
= file_mod_found
&& dir_mod_found
;
4013 bool no_candidates_found
= !file_mod_found
&& !dir_mod_found
;
4015 if (multiple_candidates_found
)
4016 rust_error_at (locus
,
4017 "two candidates found for module %s: %s.rs and %s%smod.rs",
4018 module_name
.c_str (), module_name
.c_str (),
4019 module_name
.c_str (), file_separator
);
4021 if (no_candidates_found
)
4022 rust_error_at (locus
, "no candidate found for module %s",
4023 module_name
.c_str ());
4025 if (no_candidates_found
|| multiple_candidates_found
)
4028 module_file
= std::move (file_mod_found
? file_mod_path
: dir_mod_path
);
4032 Module::load_items ()
4034 process_file_path ();
4036 // We will already have errored out appropriately in the process_file_path ()
4038 if (module_file
.empty ())
4041 RAIIFile
file_wrap (module_file
.c_str ());
4042 Linemap
*linemap
= Session::get_instance ().linemap
;
4043 if (!file_wrap
.ok ())
4045 rust_error_at (get_locus (), "cannot open module file %s: %m",
4046 module_file
.c_str ());
4050 rust_debug ("Attempting to parse file %s", module_file
.c_str ());
4052 Lexer
lex (module_file
.c_str (), std::move (file_wrap
), linemap
);
4053 Parser
<Lexer
> parser (lex
);
4055 // we need to parse any possible inner attributes for this module
4056 inner_attrs
= parser
.parse_inner_attributes ();
4057 auto parsed_items
= parser
.parse_items ();
4058 for (const auto &error
: parser
.get_errors ())
4059 error
.emit_error ();
4061 items
= std::move (parsed_items
);
4062 kind
= ModuleKind::LOADED
;
4066 Attribute::parse_attr_to_meta_item ()
4068 // only parse if has attribute input and not already parsed
4069 if (!has_attr_input () || is_parsed_to_meta_item ())
4072 auto res
= attr_input
->parse_to_meta_item ();
4073 std::unique_ptr
<AttrInput
> converted_input (res
);
4075 if (converted_input
!= nullptr)
4076 attr_input
= std::move (converted_input
);
4079 AttrInputMetaItemContainer
*
4080 DelimTokenTree::parse_to_meta_item () const
4082 // must have token trees
4083 if (token_trees
.empty ())
4086 /* assume top-level delim token tree in attribute - convert all nested ones
4087 * to token stream */
4088 std::vector
<std::unique_ptr
<Token
>> token_stream
= to_token_stream ();
4090 AttributeParser
parser (std::move (token_stream
));
4091 std::vector
<std::unique_ptr
<MetaItemInner
>> meta_items (
4092 parser
.parse_meta_item_seq ());
4094 return new AttrInputMetaItemContainer (std::move (meta_items
));
4097 std::unique_ptr
<MetaItemInner
>
4098 AttributeParser::parse_meta_item_inner ()
4100 // if first tok not identifier, not a "special" case one
4101 if (peek_token ()->get_id () != IDENTIFIER
)
4103 switch (peek_token ()->get_id ())
4106 case STRING_LITERAL
:
4107 case BYTE_CHAR_LITERAL
:
4108 case BYTE_STRING_LITERAL
:
4113 return parse_meta_item_lit ();
4119 case SCOPE_RESOLUTION
:
4120 return parse_path_meta_item ();
4123 rust_error_at (peek_token ()->get_locus (),
4124 "unrecognised token '%s' in meta item",
4125 get_token_description (peek_token ()->get_id ()));
4130 // else, check for path
4131 if (peek_token (1)->get_id () == SCOPE_RESOLUTION
)
4134 return parse_path_meta_item ();
4137 auto ident
= peek_token ()->as_string ();
4138 auto ident_locus
= peek_token ()->get_locus ();
4140 if (is_end_meta_item_tok (peek_token (1)->get_id ()))
4144 return std::unique_ptr
<MetaWord
> (new MetaWord (ident
, ident_locus
));
4147 if (peek_token (1)->get_id () == EQUAL
)
4149 // maybe meta name value str syntax - check next 2 tokens
4150 if (peek_token (2)->get_id () == STRING_LITERAL
4151 && is_end_meta_item_tok (peek_token (3)->get_id ()))
4153 // meta name value str syntax
4154 auto &value_tok
= peek_token (2);
4155 auto value
= value_tok
->as_string ();
4156 auto locus
= value_tok
->get_locus ();
4160 // remove the quotes from the string value
4161 std::string raw_value
= unquote_string (std::move (value
));
4163 return std::unique_ptr
<MetaNameValueStr
> (
4164 new MetaNameValueStr (ident
, ident_locus
, std::move (raw_value
),
4169 // just interpret as path-based meta item
4170 return parse_path_meta_item ();
4174 if (peek_token (1)->get_id () != LEFT_PAREN
)
4176 rust_error_at (peek_token (1)->get_locus (),
4177 "unexpected token '%s' after identifier in attribute",
4178 get_token_description (peek_token (1)->get_id ()));
4182 // is it one of those special cases like not?
4183 if (peek_token ()->get_id () == IDENTIFIER
)
4185 return parse_path_meta_item ();
4188 auto meta_items
= parse_meta_item_seq ();
4190 // pass for meta name value str
4191 std::vector
<MetaNameValueStr
> meta_name_value_str_items
;
4192 for (const auto &item
: meta_items
)
4194 std::unique_ptr
<MetaNameValueStr
> converted_item
4195 = item
->to_meta_name_value_str ();
4196 if (converted_item
== nullptr)
4198 meta_name_value_str_items
.clear ();
4201 meta_name_value_str_items
.push_back (std::move (*converted_item
));
4203 // if valid, return this
4204 if (!meta_name_value_str_items
.empty ())
4206 return std::unique_ptr
<MetaListNameValueStr
> (
4207 new MetaListNameValueStr (ident
, ident_locus
,
4208 std::move (meta_name_value_str_items
)));
4211 // // pass for meta list idents
4212 // std::vector<Identifier> ident_items;
4213 // for (const auto &item : meta_items)
4215 // std::unique_ptr<Identifier> converted_ident (item->to_ident_item ());
4216 // if (converted_ident == nullptr)
4218 // ident_items.clear ();
4221 // ident_items.push_back (std::move (*converted_ident));
4223 // // if valid return this
4224 // if (!ident_items.empty ())
4226 // return std::unique_ptr<MetaListIdents> (
4227 // new MetaListIdents (std::move (ident), std::move (ident_items)));
4229 // // as currently no meta list ident, currently no path. may change in future
4231 // pass for meta list paths
4232 std::vector
<SimplePath
> path_items
;
4233 for (const auto &item
: meta_items
)
4235 SimplePath
converted_path (item
->to_path_item ());
4236 if (converted_path
.is_empty ())
4238 path_items
.clear ();
4241 path_items
.push_back (std::move (converted_path
));
4243 if (!path_items
.empty ())
4245 return std::unique_ptr
<MetaListPaths
> (
4246 new MetaListPaths (ident
, ident_locus
, std::move (path_items
)));
4249 rust_error_at (Linemap::unknown_location (),
4250 "failed to parse any meta item inner");
4255 AttributeParser::is_end_meta_item_tok (TokenId id
) const
4257 return id
== COMMA
|| id
== RIGHT_PAREN
;
4260 std::unique_ptr
<MetaItem
>
4261 AttributeParser::parse_path_meta_item ()
4263 SimplePath path
= parse_simple_path ();
4264 if (path
.is_empty ())
4266 rust_error_at (peek_token ()->get_locus (),
4267 "failed to parse simple path in attribute");
4271 switch (peek_token ()->get_id ())
4274 std::vector
<std::unique_ptr
<MetaItemInner
>> meta_items
4275 = parse_meta_item_seq ();
4277 return std::unique_ptr
<MetaItemSeq
> (
4278 new MetaItemSeq (std::move (path
), std::move (meta_items
)));
4283 Location locus
= peek_token ()->get_locus ();
4284 Literal lit
= parse_literal ();
4285 if (lit
.is_error ())
4287 rust_error_at (peek_token ()->get_locus (),
4288 "failed to parse literal in attribute");
4291 LiteralExpr
expr (std::move (lit
), {}, locus
);
4293 /* shouldn't be required anymore due to parsing literal actually
4294 * skipping the token */
4295 return std::unique_ptr
<MetaItemPathLit
> (
4296 new MetaItemPathLit (std::move (path
), std::move (expr
)));
4300 return std::unique_ptr
<MetaItemPath
> (
4301 new MetaItemPath (std::move (path
)));
4303 rust_error_at (peek_token ()->get_locus (),
4304 "unrecognised token '%s' in meta item",
4305 get_token_description (peek_token ()->get_id ()));
4310 /* Parses a parenthesised sequence of meta item inners. Parentheses are
4312 std::vector
<std::unique_ptr
<MetaItemInner
>>
4313 AttributeParser::parse_meta_item_seq ()
4315 int vec_length
= token_stream
.size ();
4316 std::vector
<std::unique_ptr
<MetaItemInner
>> meta_items
;
4318 if (peek_token ()->get_id () != LEFT_PAREN
)
4320 rust_error_at (peek_token ()->get_locus (),
4321 "missing left paren in delim token tree");
4326 while (stream_pos
< vec_length
&& peek_token ()->get_id () != RIGHT_PAREN
)
4328 std::unique_ptr
<MetaItemInner
> inner
= parse_meta_item_inner ();
4329 if (inner
== nullptr)
4331 rust_error_at (peek_token ()->get_locus (),
4332 "failed to parse inner meta item in attribute");
4335 meta_items
.push_back (std::move (inner
));
4337 if (peek_token ()->get_id () != COMMA
)
4343 if (peek_token ()->get_id () != RIGHT_PAREN
)
4345 rust_error_at (peek_token ()->get_locus (),
4346 "missing right paren in delim token tree");
4354 /* Collects any nested token trees into a flat token stream, suitable for
4356 std::vector
<std::unique_ptr
<Token
>>
4357 DelimTokenTree::to_token_stream () const
4359 std::vector
<std::unique_ptr
<Token
>> tokens
;
4360 for (const auto &tree
: token_trees
)
4362 std::vector
<std::unique_ptr
<Token
>> stream
= tree
->to_token_stream ();
4364 tokens
.insert (tokens
.end (), std::make_move_iterator (stream
.begin ()),
4365 std::make_move_iterator (stream
.end ()));
4368 tokens
.shrink_to_fit ();
4373 AttributeParser::parse_literal ()
4375 const std::unique_ptr
<Token
> &tok
= peek_token ();
4376 switch (tok
->get_id ())
4380 return Literal (tok
->as_string (), Literal::CHAR
, tok
->get_type_hint ());
4381 case STRING_LITERAL
:
4383 return Literal (tok
->as_string (), Literal::STRING
,
4384 tok
->get_type_hint ());
4385 case BYTE_CHAR_LITERAL
:
4387 return Literal (tok
->as_string (), Literal::BYTE
, tok
->get_type_hint ());
4388 case BYTE_STRING_LITERAL
:
4390 return Literal (tok
->as_string (), Literal::BYTE_STRING
,
4391 tok
->get_type_hint ());
4394 return Literal (tok
->as_string (), Literal::INT
, tok
->get_type_hint ());
4397 return Literal (tok
->as_string (), Literal::FLOAT
, tok
->get_type_hint ());
4400 return Literal ("true", Literal::BOOL
, tok
->get_type_hint ());
4403 return Literal ("false", Literal::BOOL
, tok
->get_type_hint ());
4405 rust_error_at (tok
->get_locus (), "expected literal - found '%s'",
4406 get_token_description (tok
->get_id ()));
4407 return Literal::create_error ();
4412 AttributeParser::parse_simple_path ()
4414 bool has_opening_scope_res
= false;
4415 if (peek_token ()->get_id () == SCOPE_RESOLUTION
)
4417 has_opening_scope_res
= true;
4421 std::vector
<SimplePathSegment
> segments
;
4423 SimplePathSegment segment
= parse_simple_path_segment ();
4424 if (segment
.is_error ())
4427 peek_token ()->get_locus (),
4428 "failed to parse simple path segment in attribute simple path");
4429 return SimplePath::create_empty ();
4431 segments
.push_back (std::move (segment
));
4433 while (peek_token ()->get_id () == SCOPE_RESOLUTION
)
4437 SimplePathSegment segment
= parse_simple_path_segment ();
4438 if (segment
.is_error ())
4441 peek_token ()->get_locus (),
4442 "failed to parse simple path segment in attribute simple path");
4443 return SimplePath::create_empty ();
4445 segments
.push_back (std::move (segment
));
4447 segments
.shrink_to_fit ();
4449 return SimplePath (std::move (segments
), has_opening_scope_res
);
4453 AttributeParser::parse_simple_path_segment ()
4455 const std::unique_ptr
<Token
> &tok
= peek_token ();
4456 switch (tok
->get_id ())
4460 return SimplePathSegment (tok
->as_string (), tok
->get_locus ());
4463 return SimplePathSegment ("super", tok
->get_locus ());
4466 return SimplePathSegment ("self", tok
->get_locus ());
4469 return SimplePathSegment ("crate", tok
->get_locus ());
4471 if (peek_token (1)->get_id () == CRATE
)
4474 return SimplePathSegment ("$crate", tok
->get_locus ());
4478 rust_error_at (tok
->get_locus (),
4479 "unexpected token '%s' in simple path segment",
4480 get_token_description (tok
->get_id ()));
4481 return SimplePathSegment::create_error ();
4485 std::unique_ptr
<MetaItemLitExpr
>
4486 AttributeParser::parse_meta_item_lit ()
4488 Location locus
= peek_token ()->get_locus ();
4489 LiteralExpr
lit_expr (parse_literal (), {}, locus
);
4490 return std::unique_ptr
<MetaItemLitExpr
> (
4491 new MetaItemLitExpr (std::move (lit_expr
)));
4495 AttrInputMetaItemContainer::check_cfg_predicate (const Session
&session
) const
4500 for (const auto &inner_item
: items
)
4502 if (!inner_item
->check_cfg_predicate (session
))
4510 MetaItemLitExpr::check_cfg_predicate (const Session
&) const
4512 /* as far as I can tell, a literal expr can never be a valid cfg body, so
4518 MetaListNameValueStr::check_cfg_predicate (const Session
&session
) const
4522 for (const auto &str
: strs
)
4524 if (!str
.check_cfg_predicate (session
))
4529 else if (ident
== "any")
4531 for (const auto &str
: strs
)
4533 if (str
.check_cfg_predicate (session
))
4538 else if (ident
== "not")
4540 if (strs
.size () != 1)
4542 /* HACK: convert vector platform-dependent size_type to string to
4544 rust_error_at (Linemap::unknown_location (),
4545 "cfg predicate could not be checked for "
4546 "MetaListNameValueStr with ident of "
4547 "'not' because there are '%s' elements, not '1'",
4548 std::to_string (strs
.size ()).c_str ());
4552 return !strs
[0].check_cfg_predicate (session
);
4556 rust_error_at (Linemap::unknown_location (),
4557 "cfg predicate could not be checked for "
4558 "MetaListNameValueStr with ident of "
4559 "'%s' - ident must be 'all' or 'any'",
4566 MetaListPaths::check_cfg_predicate (const Session
&session
) const
4570 for (const auto &path
: paths
)
4572 if (!check_path_exists_in_cfg (session
, path
))
4577 else if (ident
== "any")
4579 for (const auto &path
: paths
)
4581 if (check_path_exists_in_cfg (session
, path
))
4586 else if (ident
== "not")
4588 if (paths
.size () != 1)
4590 // HACK: convert vector platform-dependent size_type to string to
4592 rust_error_at (Linemap::unknown_location (),
4593 "cfg predicate could not be checked for MetaListPaths "
4594 "with ident of 'not' "
4595 "because there are '%s' elements, not '1'",
4596 std::to_string (paths
.size ()).c_str ());
4600 return !check_path_exists_in_cfg (session
, paths
[0]);
4604 rust_error_at (Linemap::unknown_location (),
4605 "cfg predicate could not be checked for "
4606 "MetaListNameValueStr with ident of "
4607 "'%s' - ident must be 'all' or 'any'",
4614 MetaListPaths::check_path_exists_in_cfg (const Session
&session
,
4615 const SimplePath
&path
) const
4617 return session
.options
.target_data
.has_key (path
.as_string ());
4621 MetaItemSeq::check_cfg_predicate (const Session
&session
) const
4623 if (path
.as_string () == "all")
4625 for (const auto &item
: seq
)
4627 if (!item
->check_cfg_predicate (session
))
4632 else if (path
.as_string () == "any")
4634 for (const auto &item
: seq
)
4636 if (item
->check_cfg_predicate (session
))
4641 else if (path
.as_string () == "not")
4643 if (seq
.size () != 1)
4645 /* HACK: convert vector platform-dependent size_type to string to
4647 rust_error_at (Linemap::unknown_location (),
4648 "cfg predicate could not be checked for MetaItemSeq "
4649 "with ident of 'not' "
4650 "because there are '%s' elements, not '1'",
4651 std::to_string (seq
.size ()).c_str ());
4655 return !seq
[0]->check_cfg_predicate (session
);
4660 Linemap::unknown_location (),
4661 "cfg predicate could not be checked for MetaItemSeq with path of "
4662 "'%s' - path must be 'all' or 'any'",
4663 path
.as_string ().c_str ());
4669 MetaWord::check_cfg_predicate (const Session
&session
) const
4671 return session
.options
.target_data
.has_key (ident
);
4675 MetaItemPath::check_cfg_predicate (const Session
&session
) const
4677 /* Strictly speaking, this should always be false, but maybe do check
4678 * relating to SimplePath being identifier. Currently, it would return true
4679 * if path as identifier existed, and if the path in string form existed
4680 * (though this shouldn't occur). */
4681 return session
.options
.target_data
.has_key (path
.as_string ());
4685 MetaNameValueStr::check_cfg_predicate (const Session
&session
) const
4689 "checked key-value pair for cfg: '%s', '%s' - is%s in target data",
4690 ident
.c_str (), str
.c_str (),
4691 session
.options
.target_data
.has_key_value_pair (ident
, str
) ? "" : " not");
4693 return session
.options
.target_data
.has_key_value_pair (ident
, str
);
4697 MetaItemPathLit::check_cfg_predicate (const Session
&session
) const
4699 return session
.options
.target_data
.has_key_value_pair (path
.as_string (),
4703 std::vector
<std::unique_ptr
<Token
>>
4704 Token::to_token_stream () const
4706 /* initialisation list doesn't work as it needs copy constructor, so have to
4708 std::vector
<std::unique_ptr
<Token
>> dummy_vector
;
4709 dummy_vector
.reserve (1);
4710 dummy_vector
.push_back (std::unique_ptr
<Token
> (clone_token_impl ()));
4711 return dummy_vector
;
4715 MetaNameValueStr::to_attribute () const
4717 LiteralExpr
lit_expr (str
, Literal::LitType::STRING
,
4718 PrimitiveCoreType::CORETYPE_UNKNOWN
, {}, str_locus
);
4719 // FIXME: What location do we put here? Is the literal above supposed to have
4720 // an empty location as well?
4721 // Should MetaNameValueStr keep a location?
4722 return Attribute (SimplePath::from_str (ident
, ident_locus
),
4723 std::unique_ptr
<AttrInputLiteral
> (
4724 new AttrInputLiteral (std::move (lit_expr
))));
4728 MetaItemPath::to_attribute () const
4730 return Attribute (path
, nullptr);
4734 MetaItemSeq::to_attribute () const
4736 std::vector
<std::unique_ptr
<MetaItemInner
>> new_seq
;
4737 new_seq
.reserve (seq
.size ());
4738 for (const auto &e
: seq
)
4739 new_seq
.push_back (e
->clone_meta_item_inner ());
4741 std::unique_ptr
<AttrInputMetaItemContainer
> new_seq_container (
4742 new AttrInputMetaItemContainer (std::move (new_seq
)));
4743 return Attribute (path
, std::move (new_seq_container
));
4747 MetaWord::to_attribute () const
4749 return Attribute (SimplePath::from_str (ident
, ident_locus
), nullptr);
4753 MetaListPaths::to_attribute () const
4755 /* probably one of the most annoying conversions - have to lose specificity by
4756 * turning it into just AttrInputMetaItemContainer (i.e. paths-only nature is
4757 * no longer known). If conversions back are required, might have to do a
4758 * "check all are paths" pass or something. */
4760 std::vector
<std::unique_ptr
<MetaItemInner
>> new_seq
;
4761 new_seq
.reserve (paths
.size ());
4762 for (const auto &e
: paths
)
4763 new_seq
.push_back (std::unique_ptr
<MetaItemPath
> (new MetaItemPath (e
)));
4765 std::unique_ptr
<AttrInputMetaItemContainer
> new_seq_container (
4766 new AttrInputMetaItemContainer (std::move (new_seq
)));
4767 return Attribute (SimplePath::from_str (ident
, ident_locus
),
4768 std::move (new_seq_container
));
4772 MetaListNameValueStr::to_attribute () const
4774 std::vector
<std::unique_ptr
<MetaItemInner
>> new_seq
;
4775 new_seq
.reserve (strs
.size ());
4776 for (const auto &e
: strs
)
4778 std::unique_ptr
<MetaNameValueStr
> (new MetaNameValueStr (e
)));
4780 std::unique_ptr
<AttrInputMetaItemContainer
> new_seq_container (
4781 new AttrInputMetaItemContainer (std::move (new_seq
)));
4782 return Attribute (SimplePath::from_str (ident
, ident_locus
),
4783 std::move (new_seq_container
));
4787 MetaItemPathLit::to_attribute () const
4789 return Attribute (path
, std::unique_ptr
<AttrInputLiteral
> (
4790 new AttrInputLiteral (lit
)));
4793 std::vector
<Attribute
>
4794 AttrInputMetaItemContainer::separate_cfg_attrs () const
4796 rust_assert (!items
.empty ());
4798 if (items
.size () == 1)
4801 std::vector
<Attribute
> attrs
;
4802 attrs
.reserve (items
.size () - 1);
4804 for (auto it
= items
.begin () + 1; it
!= items
.end (); ++it
)
4806 Attribute attr
= (*it
)->to_attribute ();
4807 if (attr
.is_empty ())
4809 /* TODO should this be an error that causes us to chuck out
4813 attrs
.push_back (std::move (attr
));
4816 attrs
.shrink_to_fit ();
4821 Attribute::check_cfg_predicate (const Session
&session
) const
4823 /* assume that cfg predicate actually can exist, i.e. attribute has cfg or
4825 if (!has_attr_input ()
4826 || (path
.as_string () != "cfg" && path
.as_string () != "cfg_attr"))
4830 "tried to check cfg predicate on attr that either has no input "
4831 "or invalid path. attr: '%s'",
4832 as_string ().c_str ());
4837 // assume that it has already been parsed
4838 if (!is_parsed_to_meta_item ())
4841 return attr_input
->check_cfg_predicate (session
);
4844 std::vector
<Attribute
>
4845 Attribute::separate_cfg_attrs () const
4847 if (!has_attr_input () || path
.as_string () != "cfg_attr")
4850 // assume that it has already been parsed
4851 if (!is_parsed_to_meta_item ())
4854 return attr_input
->separate_cfg_attrs ();
4858 Attribute::is_parsed_to_meta_item () const
4860 return has_attr_input () && attr_input
->is_meta_item ();
4863 /* Visitor implementations - these are short but inlining can't happen anyway
4864 * due to virtual functions and I didn't want to make the ast header includes
4865 * any longer than they already are. */
4868 Token::accept_vis (ASTVisitor
&vis
)
4874 DelimTokenTree::accept_vis (ASTVisitor
&vis
)
4880 IdentifierExpr::accept_vis (ASTVisitor
&vis
)
4886 Lifetime::accept_vis (ASTVisitor
&vis
)
4892 LifetimeParam::accept_vis (ASTVisitor
&vis
)
4898 ConstGenericParam::accept_vis (ASTVisitor
&vis
)
4904 PathInExpression::accept_vis (ASTVisitor
&vis
)
4910 TypePathSegment::accept_vis (ASTVisitor
&vis
)
4916 TypePathSegmentGeneric::accept_vis (ASTVisitor
&vis
)
4922 TypePathSegmentFunction::accept_vis (ASTVisitor
&vis
)
4928 TypePath::accept_vis (ASTVisitor
&vis
)
4934 QualifiedPathInExpression::accept_vis (ASTVisitor
&vis
)
4940 QualifiedPathInType::accept_vis (ASTVisitor
&vis
)
4946 LiteralExpr::accept_vis (ASTVisitor
&vis
)
4952 AttrInputLiteral::accept_vis (ASTVisitor
&vis
)
4958 MetaItemLitExpr::accept_vis (ASTVisitor
&vis
)
4964 MetaItemPathLit::accept_vis (ASTVisitor
&vis
)
4970 BorrowExpr::accept_vis (ASTVisitor
&vis
)
4976 DereferenceExpr::accept_vis (ASTVisitor
&vis
)
4982 ErrorPropagationExpr::accept_vis (ASTVisitor
&vis
)
4988 NegationExpr::accept_vis (ASTVisitor
&vis
)
4994 ArithmeticOrLogicalExpr::accept_vis (ASTVisitor
&vis
)
5000 ComparisonExpr::accept_vis (ASTVisitor
&vis
)
5006 LazyBooleanExpr::accept_vis (ASTVisitor
&vis
)
5012 TypeCastExpr::accept_vis (ASTVisitor
&vis
)
5018 AssignmentExpr::accept_vis (ASTVisitor
&vis
)
5024 CompoundAssignmentExpr::accept_vis (ASTVisitor
&vis
)
5030 GroupedExpr::accept_vis (ASTVisitor
&vis
)
5036 ArrayElemsValues::accept_vis (ASTVisitor
&vis
)
5042 ArrayElemsCopied::accept_vis (ASTVisitor
&vis
)
5048 ArrayExpr::accept_vis (ASTVisitor
&vis
)
5054 ArrayIndexExpr::accept_vis (ASTVisitor
&vis
)
5060 TupleExpr::accept_vis (ASTVisitor
&vis
)
5066 TupleIndexExpr::accept_vis (ASTVisitor
&vis
)
5072 StructExprStruct::accept_vis (ASTVisitor
&vis
)
5078 StructExprFieldIdentifier::accept_vis (ASTVisitor
&vis
)
5084 StructExprFieldIdentifierValue::accept_vis (ASTVisitor
&vis
)
5090 StructExprFieldIndexValue::accept_vis (ASTVisitor
&vis
)
5096 StructExprStructFields::accept_vis (ASTVisitor
&vis
)
5102 StructExprStructBase::accept_vis (ASTVisitor
&vis
)
5108 CallExpr::accept_vis (ASTVisitor
&vis
)
5114 MethodCallExpr::accept_vis (ASTVisitor
&vis
)
5120 FieldAccessExpr::accept_vis (ASTVisitor
&vis
)
5126 ClosureExprInner::accept_vis (ASTVisitor
&vis
)
5132 BlockExpr::accept_vis (ASTVisitor
&vis
)
5138 ClosureExprInnerTyped::accept_vis (ASTVisitor
&vis
)
5144 ContinueExpr::accept_vis (ASTVisitor
&vis
)
5150 BreakExpr::accept_vis (ASTVisitor
&vis
)
5156 RangeFromToExpr::accept_vis (ASTVisitor
&vis
)
5162 RangeFromExpr::accept_vis (ASTVisitor
&vis
)
5168 RangeToExpr::accept_vis (ASTVisitor
&vis
)
5174 RangeFullExpr::accept_vis (ASTVisitor
&vis
)
5180 RangeFromToInclExpr::accept_vis (ASTVisitor
&vis
)
5186 RangeToInclExpr::accept_vis (ASTVisitor
&vis
)
5192 ReturnExpr::accept_vis (ASTVisitor
&vis
)
5198 UnsafeBlockExpr::accept_vis (ASTVisitor
&vis
)
5204 LoopExpr::accept_vis (ASTVisitor
&vis
)
5210 WhileLoopExpr::accept_vis (ASTVisitor
&vis
)
5216 WhileLetLoopExpr::accept_vis (ASTVisitor
&vis
)
5222 ForLoopExpr::accept_vis (ASTVisitor
&vis
)
5228 IfExpr::accept_vis (ASTVisitor
&vis
)
5234 IfExprConseqElse::accept_vis (ASTVisitor
&vis
)
5240 IfExprConseqIf::accept_vis (ASTVisitor
&vis
)
5246 IfExprConseqIfLet::accept_vis (ASTVisitor
&vis
)
5252 IfLetExpr::accept_vis (ASTVisitor
&vis
)
5258 IfLetExprConseqElse::accept_vis (ASTVisitor
&vis
)
5264 IfLetExprConseqIf::accept_vis (ASTVisitor
&vis
)
5270 IfLetExprConseqIfLet::accept_vis (ASTVisitor
&vis
)
5276 MatchExpr::accept_vis (ASTVisitor
&vis
)
5282 AwaitExpr::accept_vis (ASTVisitor
&vis
)
5288 AsyncBlockExpr::accept_vis (ASTVisitor
&vis
)
5294 TypeParam::accept_vis (ASTVisitor
&vis
)
5300 LifetimeWhereClauseItem::accept_vis (ASTVisitor
&vis
)
5306 TypeBoundWhereClauseItem::accept_vis (ASTVisitor
&vis
)
5312 Method::accept_vis (ASTVisitor
&vis
)
5318 Module::accept_vis (ASTVisitor
&vis
)
5324 ExternCrate::accept_vis (ASTVisitor
&vis
)
5330 UseTreeGlob::accept_vis (ASTVisitor
&vis
)
5336 UseTreeList::accept_vis (ASTVisitor
&vis
)
5342 UseTreeRebind::accept_vis (ASTVisitor
&vis
)
5348 UseDeclaration::accept_vis (ASTVisitor
&vis
)
5354 Function::accept_vis (ASTVisitor
&vis
)
5360 TypeAlias::accept_vis (ASTVisitor
&vis
)
5366 StructStruct::accept_vis (ASTVisitor
&vis
)
5372 TupleStruct::accept_vis (ASTVisitor
&vis
)
5378 EnumItem::accept_vis (ASTVisitor
&vis
)
5384 EnumItemTuple::accept_vis (ASTVisitor
&vis
)
5390 EnumItemStruct::accept_vis (ASTVisitor
&vis
)
5396 EnumItemDiscriminant::accept_vis (ASTVisitor
&vis
)
5402 Enum::accept_vis (ASTVisitor
&vis
)
5408 Union::accept_vis (ASTVisitor
&vis
)
5414 ConstantItem::accept_vis (ASTVisitor
&vis
)
5420 StaticItem::accept_vis (ASTVisitor
&vis
)
5426 TraitItemFunc::accept_vis (ASTVisitor
&vis
)
5432 TraitItemMethod::accept_vis (ASTVisitor
&vis
)
5438 TraitItemConst::accept_vis (ASTVisitor
&vis
)
5444 TraitItemType::accept_vis (ASTVisitor
&vis
)
5450 Trait::accept_vis (ASTVisitor
&vis
)
5456 InherentImpl::accept_vis (ASTVisitor
&vis
)
5462 TraitImpl::accept_vis (ASTVisitor
&vis
)
5468 ExternalStaticItem::accept_vis (ASTVisitor
&vis
)
5474 ExternalFunctionItem::accept_vis (ASTVisitor
&vis
)
5480 ExternBlock::accept_vis (ASTVisitor
&vis
)
5486 MacroMatchFragment::accept_vis (ASTVisitor
&vis
)
5492 MacroMatchRepetition::accept_vis (ASTVisitor
&vis
)
5498 MacroMatcher::accept_vis (ASTVisitor
&vis
)
5504 MacroRulesDefinition::accept_vis (ASTVisitor
&vis
)
5510 MacroInvocation::accept_vis (ASTVisitor
&vis
)
5516 LiteralPattern::accept_vis (ASTVisitor
&vis
)
5522 IdentifierPattern::accept_vis (ASTVisitor
&vis
)
5528 WildcardPattern::accept_vis (ASTVisitor
&vis
)
5534 RangePatternBoundLiteral::accept_vis (ASTVisitor
&vis
)
5540 RangePatternBoundPath::accept_vis (ASTVisitor
&vis
)
5546 RangePatternBoundQualPath::accept_vis (ASTVisitor
&vis
)
5552 RangePattern::accept_vis (ASTVisitor
&vis
)
5558 ReferencePattern::accept_vis (ASTVisitor
&vis
)
5564 StructPatternFieldTuplePat::accept_vis (ASTVisitor
&vis
)
5570 StructPatternFieldIdentPat::accept_vis (ASTVisitor
&vis
)
5576 StructPatternFieldIdent::accept_vis (ASTVisitor
&vis
)
5582 StructPattern::accept_vis (ASTVisitor
&vis
)
5588 TupleStructItemsNoRange::accept_vis (ASTVisitor
&vis
)
5594 TupleStructItemsRange::accept_vis (ASTVisitor
&vis
)
5600 TupleStructPattern::accept_vis (ASTVisitor
&vis
)
5606 TuplePatternItemsMultiple::accept_vis (ASTVisitor
&vis
)
5612 TuplePatternItemsRanged::accept_vis (ASTVisitor
&vis
)
5618 TuplePattern::accept_vis (ASTVisitor
&vis
)
5624 GroupedPattern::accept_vis (ASTVisitor
&vis
)
5630 SlicePattern::accept_vis (ASTVisitor
&vis
)
5636 EmptyStmt::accept_vis (ASTVisitor
&vis
)
5642 LetStmt::accept_vis (ASTVisitor
&vis
)
5648 ExprStmtWithoutBlock::accept_vis (ASTVisitor
&vis
)
5654 ExprStmtWithBlock::accept_vis (ASTVisitor
&vis
)
5660 TraitBound::accept_vis (ASTVisitor
&vis
)
5666 ImplTraitType::accept_vis (ASTVisitor
&vis
)
5672 TraitObjectType::accept_vis (ASTVisitor
&vis
)
5678 ParenthesisedType::accept_vis (ASTVisitor
&vis
)
5684 ImplTraitTypeOneBound::accept_vis (ASTVisitor
&vis
)
5690 TraitObjectTypeOneBound::accept_vis (ASTVisitor
&vis
)
5696 TupleType::accept_vis (ASTVisitor
&vis
)
5702 NeverType::accept_vis (ASTVisitor
&vis
)
5708 RawPointerType::accept_vis (ASTVisitor
&vis
)
5714 ReferenceType::accept_vis (ASTVisitor
&vis
)
5720 ArrayType::accept_vis (ASTVisitor
&vis
)
5726 SliceType::accept_vis (ASTVisitor
&vis
)
5732 InferredType::accept_vis (ASTVisitor
&vis
)
5738 BareFunctionType::accept_vis (ASTVisitor
&vis
)
5744 MetaItemSeq::accept_vis (ASTVisitor
&vis
)
5750 MetaItemPath::accept_vis (ASTVisitor
&vis
)
5756 MetaListPaths::accept_vis (ASTVisitor
&vis
)
5762 MetaNameValueStr::accept_vis (ASTVisitor
&vis
)
5768 MetaListNameValueStr::accept_vis (ASTVisitor
&vis
)
5774 AttrInputMetaItemContainer::accept_vis (ASTVisitor
&vis
)
5780 MetaWord::accept_vis (ASTVisitor
&vis
)
5786 GenericArg::disambiguate_to_const () const
5788 rust_assert (get_kind () == Kind::Either
);
5790 // FIXME: is it fine to have no outer attributes?
5791 return GenericArg::create_const (
5792 std::unique_ptr
<Expr
> (new IdentifierExpr (path
, {}, locus
)));
5796 GenericArg::disambiguate_to_type () const
5798 rust_assert (get_kind () == Kind::Either
);
5800 auto segment
= std::unique_ptr
<TypePathSegment
> (
5801 new TypePathSegment (path
, false, locus
));
5802 auto segments
= std::vector
<std::unique_ptr
<TypePathSegment
>> ();
5803 segments
.emplace_back (std::move (segment
));
5805 return GenericArg::create_type (
5806 std::unique_ptr
<Type
> (new TypePath (std::move (segments
), locus
)));