gccrs: Remove obsolete classes and functions.
[official-gcc.git] / gcc / rust / expand / rust-expand-visitor.cc
blobe42715b865f3df66967bff42f96ce7b1af49193f
1 // Copyright (C) 2020-2023 Free Software Foundation, Inc.
3 // This file is part of GCC.
5 // GCC is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation; either version 3, or (at your option) any later
8 // version.
10 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 // for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with GCC; see the file COPYING3. If not see
17 // <http://www.gnu.org/licenses/>.
19 #include "rust-expand-visitor.h"
20 #include "rust-proc-macro.h"
21 #include "rust-attributes.h"
22 #include "rust-ast.h"
23 #include "rust-type.h"
24 #include "rust-derive.h"
26 namespace Rust {
28 bool
29 is_builtin (AST::Attribute &attr)
31 auto &segments = attr.get_path ().get_segments ();
32 return !segments.empty ()
33 && !Analysis::BuiltinAttributeMappings::get ()
34 ->lookup_builtin (segments[0].get_segment_name ())
35 .is_error ();
38 /* Expand all of the macro invocations currently contained in a crate */
39 void
40 ExpandVisitor::go (AST::Crate &crate)
42 visit (crate);
45 static std::unique_ptr<AST::Item>
46 builtin_derive_item (AST::Item &item, const AST::Attribute &derive,
47 BuiltinMacro to_derive)
49 return AST::DeriveVisitor::derive (item, derive, to_derive);
52 static std::vector<std::unique_ptr<AST::Item>>
53 derive_item (AST::Item &item, AST::SimplePath &to_derive,
54 MacroExpander &expander)
56 std::vector<std::unique_ptr<AST::Item>> result;
57 auto frag = expander.expand_derive_proc_macro (item, to_derive);
58 if (!frag.is_error ())
60 for (auto &node : frag.get_nodes ())
62 switch (node.get_kind ())
64 case AST::SingleASTNode::ITEM:
65 result.push_back (node.take_item ());
66 break;
67 default:
68 rust_unreachable ();
72 return result;
75 static std::vector<std::unique_ptr<AST::Item>>
76 expand_item_attribute (AST::Item &item, AST::SimplePath &name,
77 MacroExpander &expander)
79 std::vector<std::unique_ptr<AST::Item>> result;
80 auto frag = expander.expand_attribute_proc_macro (item, name);
81 if (!frag.is_error ())
83 for (auto &node : frag.get_nodes ())
85 switch (node.get_kind ())
87 case AST::SingleASTNode::ITEM:
88 result.push_back (node.take_item ());
89 break;
90 default:
91 rust_unreachable ();
95 return result;
98 /* Helper function to expand a given attribute on a statement and collect back
99 * statements.
100 * T should be anything that can be used as a statement accepting outer
101 * attributes.
103 template <typename T>
104 static std::vector<std::unique_ptr<AST::Stmt>>
105 expand_stmt_attribute (T &statement, AST::SimplePath &attribute,
106 MacroExpander &expander)
108 std::vector<std::unique_ptr<AST::Stmt>> result;
109 auto frag = expander.expand_attribute_proc_macro (statement, attribute);
110 if (!frag.is_error ())
112 for (auto &node : frag.get_nodes ())
114 switch (node.get_kind ())
116 case AST::SingleASTNode::STMT:
117 result.push_back (node.take_stmt ());
118 break;
119 default:
120 rust_unreachable ();
124 return result;
127 void
128 expand_tail_expr (AST::BlockExpr &block_expr, MacroExpander &expander)
130 if (block_expr.has_tail_expr ())
132 auto tail = block_expr.take_tail_expr ();
133 auto attrs = tail->get_outer_attrs ();
134 bool changed = false;
135 for (auto it = attrs.begin (); it != attrs.end ();)
137 auto current = *it;
138 if (is_builtin (current))
140 it++;
142 else
144 it = attrs.erase (it);
145 changed = true;
146 auto new_stmts
147 = expand_stmt_attribute (block_expr, current.get_path (),
148 expander);
149 auto &stmts = block_expr.get_statements ();
150 std::move (new_stmts.begin (), new_stmts.end (),
151 std::inserter (stmts, stmts.end ()));
154 if (changed)
155 block_expr.normalize_tail_expr ();
156 else
157 block_expr.set_tail_expr (std::move (tail));
161 void
162 ExpandVisitor::expand_inner_items (
163 std::vector<std::unique_ptr<AST::Item>> &items)
165 expander.push_context (MacroExpander::ContextType::ITEM);
167 for (auto it = items.begin (); it != items.end (); it++)
169 auto &item = *it;
170 if (item->has_outer_attrs ())
172 auto &attrs = item->get_outer_attrs ();
174 for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
175 /* erase => No increment*/)
177 auto current = *attr_it;
179 if (current.is_derive ())
181 current.parse_attr_to_meta_item ();
182 attr_it = attrs.erase (attr_it);
183 // Get traits to derive in the current attribute
184 auto traits_to_derive = current.get_traits_to_derive ();
185 for (auto &to_derive : traits_to_derive)
187 auto maybe_builtin = MacroBuiltin::builtins.lookup (
188 to_derive.get ().as_string ());
189 if (MacroBuiltin::builtins.is_iter_ok (maybe_builtin))
191 auto new_item
192 = builtin_derive_item (*item, current,
193 maybe_builtin->second);
194 // this inserts the derive *before* the item - is it a
195 // problem?
196 it = items.insert (it, std::move (new_item));
198 else
200 auto new_items
201 = derive_item (*item, to_derive, expander);
202 std::move (new_items.begin (), new_items.end (),
203 std::inserter (items, it));
207 else /* Attribute */
209 if (is_builtin (current))
211 attr_it++;
213 else
215 attr_it = attrs.erase (attr_it);
216 auto new_items
217 = expand_item_attribute (*item, current.get_path (),
218 expander);
219 it = items.erase (it);
220 std::move (new_items.begin (), new_items.end (),
221 std::inserter (items, it));
222 // TODO: Improve this ?
223 // item is invalid since it refers to now deleted,
224 // cancel the loop increment and break.
225 it--;
226 break;
233 std::function<std::unique_ptr<AST::Item> (AST::SingleASTNode)> extractor
234 = [] (AST::SingleASTNode node) { return node.take_item (); };
236 expand_macro_children (items, extractor);
238 expander.pop_context ();
241 void
242 ExpandVisitor::expand_inner_stmts (AST::BlockExpr &expr)
244 auto &stmts = expr.get_statements ();
245 expander.push_context (MacroExpander::ContextType::STMT);
247 for (auto it = stmts.begin (); it != stmts.end (); it++)
249 auto &stmt = *it;
251 // skip all non-item statements
252 if (stmt->get_stmt_kind () != AST::Stmt::Kind::Item)
253 continue;
255 auto &item = static_cast<AST::Item &> (*stmt.get ());
257 if (item.has_outer_attrs ())
259 auto &attrs = item.get_outer_attrs ();
261 for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
262 /* erase => No increment*/)
264 auto current = *attr_it;
266 if (current.is_derive ())
268 attr_it = attrs.erase (attr_it);
269 // Get traits to derive in the current attribute
270 auto traits_to_derive = current.get_traits_to_derive ();
271 for (auto &to_derive : traits_to_derive)
273 auto maybe_builtin = MacroBuiltin::builtins.lookup (
274 to_derive.get ().as_string ());
275 if (MacroBuiltin::builtins.is_iter_ok (maybe_builtin))
277 auto new_item
278 = builtin_derive_item (item, current,
279 maybe_builtin->second);
280 // this inserts the derive *before* the item - is it a
281 // problem?
282 it = stmts.insert (it, std::move (new_item));
284 else
286 auto new_items
287 = derive_item (item, to_derive, expander);
288 std::move (new_items.begin (), new_items.end (),
289 std::inserter (stmts, it));
293 else /* Attribute */
295 if (is_builtin (current))
297 attr_it++;
299 else
301 attr_it = attrs.erase (attr_it);
302 auto new_items
303 = expand_stmt_attribute (item, current.get_path (),
304 expander);
305 it = stmts.erase (it);
306 std::move (new_items.begin (), new_items.end (),
307 std::inserter (stmts, it));
308 // TODO: Improve this ?
309 // item is invalid since it refers to now deleted,
310 // cancel the loop increment and break.
311 it--;
312 break;
319 if (!expr.has_tail_expr ())
320 expr.normalize_tail_expr ();
322 std::function<std::unique_ptr<AST::Stmt> (AST::SingleASTNode)> extractor
323 = [] (AST::SingleASTNode node) { return node.take_stmt (); };
325 expand_macro_children (stmts, extractor);
327 expander.pop_context ();
330 void
331 ExpandVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
333 expander.push_context (MacroExpander::ContextType::EXPR);
334 expr->accept_vis (*this);
335 expander.pop_context ();
337 auto final_fragment = expander.take_expanded_fragment ();
338 if (final_fragment.should_expand ()
339 && final_fragment.is_expression_fragment ())
340 expr = final_fragment.take_expression_fragment ();
343 void
344 ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::Type> &type)
346 expander.push_context (MacroExpander::ContextType::TYPE);
348 type->accept_vis (*this);
349 auto final_fragment = expander.take_expanded_fragment ();
350 if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
351 type = final_fragment.take_type_fragment ();
353 expander.pop_context ();
356 // FIXME: Can this be refactored into a `scoped` method? Which takes a
357 // ContextType as parameter and a lambda? And maybe just an std::vector<T>&?
358 void
359 ExpandVisitor::expand_struct_fields (std::vector<AST::StructField> &fields)
361 for (auto &field : fields)
363 maybe_expand_type (field.get_field_type ());
367 void
368 ExpandVisitor::expand_tuple_fields (std::vector<AST::TupleField> &fields)
370 for (auto &field : fields)
371 maybe_expand_type (field.get_field_type ());
374 // FIXME: This can definitely be refactored with the method above
375 void
376 ExpandVisitor::expand_function_params (
377 std::vector<std::unique_ptr<AST::Param>> &params)
379 for (auto &p : params)
380 visit (p);
383 void
384 ExpandVisitor::expand_generic_args (AST::GenericArgs &args)
386 for (auto &arg : args.get_generic_args ())
388 switch (arg.get_kind ())
390 case AST::GenericArg::Kind::Type:
391 maybe_expand_type (arg.get_type ());
392 break;
393 case AST::GenericArg::Kind::Const:
394 maybe_expand_expr (arg.get_expression ());
395 break;
396 default:
397 break;
398 // FIXME: Figure out what to do here if there is ambiguity. Since the
399 // resolver comes after the expansion, we need to figure out a way to
400 // strip ambiguous values here
401 // TODO: ARTHUR: Probably add a `mark_as_strip` method to `GenericArg`
402 // or something. This would clean up this whole thing
406 // FIXME: Can we have macro invocations in generic type bindings?
407 // expand binding args - strip sub-types only
408 // FIXME: ARTHUR: This needs a test! Foo<Item = macro!()>
409 for (auto &binding : args.get_binding_args ())
410 maybe_expand_type (binding.get_type ());
413 void
414 ExpandVisitor::expand_qualified_path_type (AST::QualifiedPathType &path_type)
416 maybe_expand_type (path_type.get_type ());
418 // FIXME: ARTHUR: Can we do macro expansion in there? Needs a test!
419 if (path_type.has_as_clause ())
420 path_type.get_as_type_path ().accept_vis (*this);
423 void
424 ExpandVisitor::expand_closure_params (std::vector<AST::ClosureParam> &params)
426 for (auto &param : params)
428 if (param.has_type_given ())
429 maybe_expand_type (param.get_type ());
433 void
434 ExpandVisitor::expand_where_clause (AST::WhereClause &where_clause)
436 for (auto &item : where_clause.get_items ())
437 visit (item);
440 void
441 ExpandVisitor::visit (AST::Crate &crate)
443 expand_inner_items (crate.items);
446 void
447 ExpandVisitor::visit (AST::DelimTokenTree &)
450 void
451 ExpandVisitor::visit (AST::AttrInputMetaItemContainer &)
454 void
455 ExpandVisitor::visit (AST::IdentifierExpr &ident_expr)
458 void
459 ExpandVisitor::visit (AST::LifetimeParam &)
462 void
463 ExpandVisitor::visit (AST::ConstGenericParam &)
466 void
467 ExpandVisitor::visit (AST::MacroInvocation &macro_invoc)
469 // TODO: Can we do the AST fragment replacing here? Probably not, right?
470 expander.expand_invoc (macro_invoc, macro_invoc.has_semicolon ());
473 void
474 ExpandVisitor::visit (AST::PathInExpression &path)
476 for (auto &segment : path.get_segments ())
477 if (segment.has_generic_args ())
478 expand_generic_args (segment.get_generic_args ());
481 void
482 ExpandVisitor::visit (AST::TypePathSegmentGeneric &segment)
485 void
486 ExpandVisitor::visit (AST::TypePathSegmentFunction &segment)
488 auto &type_path_function = segment.get_type_path_function ();
490 for (auto &type : type_path_function.get_params ())
491 visit (type);
493 if (type_path_function.has_return_type ())
494 maybe_expand_type (type_path_function.get_return_type ());
497 void
498 ExpandVisitor::visit (AST::QualifiedPathInExpression &path)
500 expand_qualified_path_type (path.get_qualified_path_type ());
502 for (auto &segment : path.get_segments ())
503 if (segment.has_generic_args ())
504 expand_generic_args (segment.get_generic_args ());
507 void
508 ExpandVisitor::visit (AST::QualifiedPathInType &path)
510 expand_qualified_path_type (path.get_qualified_path_type ());
512 // this shouldn't strip any segments, but can strip inside them
513 for (auto &segment : path.get_segments ())
514 visit (segment);
517 void
518 ExpandVisitor::visit (AST::LiteralExpr &expr)
521 void
522 ExpandVisitor::visit (AST::AttrInputLiteral &)
525 void
526 ExpandVisitor::visit (AST::AttrInputMacro &macro)
528 rust_sorry_at (UNDEF_LOCATION, "macros in attributes not supported");
531 void
532 ExpandVisitor::visit (AST::MetaItemLitExpr &)
535 void
536 ExpandVisitor::visit (AST::MetaItemPathLit &)
539 void
540 ExpandVisitor::visit (AST::ErrorPropagationExpr &expr)
542 visit (expr.get_propagating_expr ());
545 void
546 ExpandVisitor::visit (AST::ArithmeticOrLogicalExpr &expr)
548 maybe_expand_expr (expr.get_left_expr ());
549 maybe_expand_expr (expr.get_right_expr ());
552 void
553 ExpandVisitor::visit (AST::ComparisonExpr &expr)
555 maybe_expand_expr (expr.get_left_expr ());
556 maybe_expand_expr (expr.get_right_expr ());
559 void
560 ExpandVisitor::visit (AST::LazyBooleanExpr &expr)
562 maybe_expand_expr (expr.get_left_expr ());
563 maybe_expand_expr (expr.get_right_expr ());
566 void
567 ExpandVisitor::visit (AST::AssignmentExpr &expr)
569 maybe_expand_expr (expr.get_left_expr ());
570 maybe_expand_expr (expr.get_right_expr ());
573 void
574 ExpandVisitor::visit (AST::CompoundAssignmentExpr &expr)
576 maybe_expand_expr (expr.get_left_expr ());
577 maybe_expand_expr (expr.get_right_expr ());
580 void
581 ExpandVisitor::visit (AST::GroupedExpr &expr)
583 maybe_expand_expr (expr.get_expr_in_parens ());
586 void
587 ExpandVisitor::visit (AST::StructExprStruct &expr)
590 void
591 ExpandVisitor::visit (AST::CallExpr &expr)
593 visit (expr.get_function_expr ());
595 for (auto &param : expr.get_params ())
596 maybe_expand_expr (param);
599 void
600 ExpandVisitor::visit (AST::MethodCallExpr &expr)
602 visit (expr.get_receiver_expr ());
604 for (auto &param : expr.get_params ())
605 maybe_expand_expr (param);
608 void
609 ExpandVisitor::visit (AST::ClosureExprInner &expr)
611 expand_closure_params (expr.get_params ());
613 visit (expr.get_definition_expr ());
616 void
617 ExpandVisitor::visit (AST::BlockExpr &expr)
619 expand_inner_stmts (expr);
621 expand_tail_expr (expr, expander);
622 if (expr.has_tail_expr ())
623 maybe_expand_expr (expr.get_tail_expr ());
626 void
627 ExpandVisitor::visit (AST::ClosureExprInnerTyped &expr)
629 expand_closure_params (expr.get_params ());
631 maybe_expand_type (expr.get_return_type ());
633 visit (expr.get_definition_block ());
636 void
637 ExpandVisitor::visit (AST::ContinueExpr &expr)
640 void
641 ExpandVisitor::visit (AST::IfExpr &expr)
643 maybe_expand_expr (expr.get_condition_expr ());
645 visit (expr.get_if_block ());
648 void
649 ExpandVisitor::visit (AST::IfExprConseqElse &expr)
651 maybe_expand_expr (expr.get_condition_expr ());
653 visit (expr.get_if_block ());
654 visit (expr.get_else_block ());
657 void
658 ExpandVisitor::visit (AST::IfLetExpr &expr)
660 maybe_expand_expr (expr.get_value_expr ());
662 visit (expr.get_if_block ());
665 void
666 ExpandVisitor::visit (AST::IfLetExprConseqElse &expr)
668 maybe_expand_expr (expr.get_value_expr ());
670 visit (expr.get_if_block ());
671 visit (expr.get_else_block ());
674 void
675 ExpandVisitor::visit (AST::MatchExpr &expr)
677 visit (expr.get_scrutinee_expr ());
679 for (auto &match_case : expr.get_match_cases ())
681 auto &arm = match_case.get_arm ();
683 for (auto &pattern : arm.get_patterns ())
684 visit (pattern);
686 if (arm.has_match_arm_guard ())
687 maybe_expand_expr (arm.get_guard_expr ());
689 maybe_expand_expr (match_case.get_expr ());
693 void
694 ExpandVisitor::visit (AST::TypeParam &param)
696 for (auto &bound : param.get_type_param_bounds ())
697 visit (bound);
699 if (param.has_type ())
700 maybe_expand_type (param.get_type ());
703 void
704 ExpandVisitor::visit (AST::LifetimeWhereClauseItem &)
707 void
708 ExpandVisitor::visit (AST::TypeBoundWhereClauseItem &item)
710 maybe_expand_type (item.get_type ());
712 for (auto &bound : item.get_type_param_bounds ())
713 visit (bound);
716 void
717 ExpandVisitor::visit (AST::ExternCrate &crate)
720 void
721 ExpandVisitor::visit (AST::UseTreeGlob &)
724 void
725 ExpandVisitor::visit (AST::UseTreeList &)
728 void
729 ExpandVisitor::visit (AST::UseTreeRebind &)
732 void
733 ExpandVisitor::visit (AST::UseDeclaration &use_decl)
736 void
737 ExpandVisitor::visit (AST::Function &function)
739 if (function.has_body ())
740 visit_inner_using_attrs (
741 function, function.get_definition ().value ()->get_inner_attrs ());
742 for (auto &param : function.get_generic_params ())
743 visit (param);
745 expand_function_params (function.get_function_params ());
747 if (function.has_return_type ())
748 maybe_expand_type (function.get_return_type ());
750 if (function.has_where_clause ())
751 expand_where_clause (function.get_where_clause ());
753 if (function.has_body ())
754 visit (*function.get_definition ());
757 void
758 ExpandVisitor::visit (AST::StructStruct &struct_item)
760 for (auto &generic : struct_item.get_generic_params ())
761 visit (generic);
763 if (struct_item.has_where_clause ())
764 expand_where_clause (struct_item.get_where_clause ());
766 expand_struct_fields (struct_item.get_fields ());
769 void
770 ExpandVisitor::visit (AST::TupleStruct &tuple_struct)
772 for (auto &generic : tuple_struct.get_generic_params ())
773 visit (generic);
775 if (tuple_struct.has_where_clause ())
776 expand_where_clause (tuple_struct.get_where_clause ());
778 expand_tuple_fields (tuple_struct.get_fields ());
781 void
782 ExpandVisitor::visit (AST::EnumItem &item)
785 void
786 ExpandVisitor::visit (AST::EnumItemTuple &item)
788 expand_tuple_fields (item.get_tuple_fields ());
791 void
792 ExpandVisitor::visit (AST::EnumItemStruct &item)
794 expand_struct_fields (item.get_struct_fields ());
797 void
798 ExpandVisitor::visit (AST::EnumItemDiscriminant &item)
800 maybe_expand_expr (item.get_expr ());
803 void
804 ExpandVisitor::visit (AST::Union &union_item)
806 for (auto &generic : union_item.get_generic_params ())
807 visit (generic);
809 expand_struct_fields (union_item.get_variants ());
812 void
813 ExpandVisitor::visit (AST::ConstantItem &const_item)
815 maybe_expand_type (const_item.get_type ());
817 if (const_item.has_expr ())
818 maybe_expand_expr (const_item.get_expr ());
821 void
822 ExpandVisitor::visit (AST::StaticItem &static_item)
824 maybe_expand_type (static_item.get_type ());
826 maybe_expand_expr (static_item.get_expr ());
829 void
830 ExpandVisitor::visit (AST::TraitItemConst &const_item)
832 maybe_expand_type (const_item.get_type ());
834 if (const_item.has_expr ())
835 maybe_expand_expr (const_item.get_expr ());
838 void
839 ExpandVisitor::visit (AST::Trait &trait)
841 for (auto &generic : trait.get_generic_params ())
842 visit (generic);
844 for (auto &bound : trait.get_type_param_bounds ())
845 visit (bound);
847 if (trait.has_where_clause ())
848 expand_where_clause (trait.get_where_clause ());
850 expander.push_context (MacroExpander::ContextType::TRAIT);
852 std::function<std::unique_ptr<AST::AssociatedItem> (AST::SingleASTNode)>
853 extractor
854 = [] (AST::SingleASTNode node) { return node.take_trait_item (); };
856 expand_macro_children (MacroExpander::ContextType::TRAIT,
857 trait.get_trait_items (), extractor);
859 expander.pop_context ();
862 void
863 ExpandVisitor::visit (AST::InherentImpl &impl)
865 visit_inner_attrs (impl);
866 // just expand sub-stuff - can't actually strip generic params themselves
867 for (auto &generic : impl.get_generic_params ())
868 visit (generic);
870 // FIXME: Is that correct? How do we test that?
871 expander.push_context (MacroExpander::ContextType::ITEM);
873 maybe_expand_type (impl.get_type ());
875 expander.pop_context ();
877 if (impl.has_where_clause ())
878 expand_where_clause (impl.get_where_clause ());
880 std::function<std::unique_ptr<AST::AssociatedItem> (AST::SingleASTNode)>
881 extractor = [] (AST::SingleASTNode node) { return node.take_impl_item (); };
883 expand_macro_children (MacroExpander::ContextType::IMPL,
884 impl.get_impl_items (), extractor);
887 void
888 ExpandVisitor::visit (AST::TraitImpl &impl)
890 visit_inner_attrs (impl);
891 // just expand sub-stuff - can't actually strip generic params themselves
892 for (auto &param : impl.get_generic_params ())
893 visit (param);
895 // FIXME: Is that correct? How do we test that?
896 expander.push_context (MacroExpander::ContextType::ITEM);
898 maybe_expand_type (impl.get_type ());
900 expander.pop_context ();
902 visit (impl.get_trait_path ());
904 if (impl.has_where_clause ())
905 expand_where_clause (impl.get_where_clause ());
907 std::function<std::unique_ptr<AST::AssociatedItem> (AST::SingleASTNode)>
908 extractor
909 = [] (AST::SingleASTNode node) { return node.take_trait_impl_item (); };
911 expand_macro_children (MacroExpander::ContextType::TRAIT_IMPL,
912 impl.get_impl_items (), extractor);
915 void
916 ExpandVisitor::visit (AST::ExternalTypeItem &item)
919 void
920 ExpandVisitor::visit (AST::ExternalStaticItem &static_item)
922 maybe_expand_type (static_item.get_type ());
925 void
926 ExpandVisitor::visit (AST::ExternalFunctionItem &item)
928 for (auto &param : item.get_generic_params ())
929 visit (param);
931 for (auto &param : item.get_function_params ())
932 if (!param.is_variadic ())
933 maybe_expand_type (param.get_type ());
935 if (item.has_return_type ())
936 maybe_expand_type (item.get_return_type ());
938 if (item.has_where_clause ())
939 expand_where_clause (item.get_where_clause ());
942 void
943 ExpandVisitor::visit (AST::ExternBlock &block)
945 visit_inner_attrs (block);
946 std::function<std::unique_ptr<AST::ExternalItem> (AST::SingleASTNode)>
947 extractor
948 = [] (AST::SingleASTNode node) { return node.take_external_item (); };
950 expand_macro_children (MacroExpander::ContextType::EXTERN,
951 block.get_extern_items (), extractor);
954 void
955 ExpandVisitor::visit (AST::MacroMatchRepetition &)
958 void
959 ExpandVisitor::visit (AST::MacroMatcher &)
962 void
963 ExpandVisitor::visit (AST::MacroRulesDefinition &rules_def)
966 void
967 ExpandVisitor::visit (AST::MetaItemPath &)
970 void
971 ExpandVisitor::visit (AST::MetaItemSeq &)
974 void
975 ExpandVisitor::visit (AST::MetaListPaths &)
978 void
979 ExpandVisitor::visit (AST::MetaListNameValueStr &)
982 void
983 ExpandVisitor::visit (AST::StructPatternFieldIdent &field)
986 void
987 ExpandVisitor::visit (AST::GroupedPattern &pattern)
989 visit (pattern.get_pattern_in_parens ());
992 void
993 ExpandVisitor::visit (AST::LetStmt &stmt)
995 visit (stmt.get_pattern ());
997 if (stmt.has_type ())
998 maybe_expand_type (stmt.get_type ());
1000 if (stmt.has_init_expr ())
1001 maybe_expand_expr (stmt.get_init_expr ());
1004 void
1005 ExpandVisitor::visit (AST::ExprStmt &stmt)
1007 maybe_expand_expr (stmt.get_expr ());
1010 void
1011 ExpandVisitor::visit (AST::BareFunctionType &type)
1013 for (auto &param : type.get_function_params ())
1015 maybe_expand_type (param.get_type ());
1018 if (type.has_return_type ())
1019 visit (type.get_return_type ());
1022 void
1023 ExpandVisitor::visit (AST::FunctionParam &param)
1025 maybe_expand_type (param.get_type ());
1028 void
1029 ExpandVisitor::visit (AST::SelfParam &param)
1031 /* TODO: maybe check for invariants being violated - e.g. both type and
1032 * lifetime? */
1033 if (param.has_type ())
1034 maybe_expand_type (param.get_type ());
1037 template <typename T>
1038 void
1039 ExpandVisitor::expand_inner_attribute (T &item, AST::SimplePath &path)
1041 // FIXME: Retrieve path from segments + local use statements instead of string
1042 expander.expand_attribute_proc_macro (item, path);
1045 template <typename T>
1046 void
1047 ExpandVisitor::visit_inner_using_attrs (T &item,
1048 std::vector<AST::Attribute> &attrs)
1050 for (auto it = attrs.begin (); it != attrs.end (); /* erase => No increment*/)
1052 auto current = *it;
1054 if (!is_builtin (current) && !current.is_derive ())
1056 it = attrs.erase (it);
1057 expand_inner_attribute (item, current.get_path ());
1059 else
1061 it++;
1066 template <typename T>
1067 void
1068 ExpandVisitor::visit_inner_attrs (T &item)
1070 visit_inner_using_attrs (item, item.get_inner_attrs ());
1073 } // namespace Rust