Line data Source code
1 : // Copyright (C) 2020-2026 Free Software Foundation, Inc.
2 :
3 : // This file is part of GCC.
4 :
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.
9 :
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.
14 :
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/>.
18 :
19 : #include "rust-expand-visitor.h"
20 : #include "rust-ast-fragment.h"
21 : #include "rust-hir-map.h"
22 : #include "rust-item.h"
23 : #include "rust-proc-macro.h"
24 : #include "rust-attributes.h"
25 : #include "rust-ast.h"
26 : #include "rust-type.h"
27 : #include "rust-derive.h"
28 :
29 : namespace Rust {
30 :
31 : bool
32 12736 : is_builtin (AST::Attribute &attr)
33 : {
34 12736 : auto &segments = attr.get_path ().get_segments ();
35 12736 : return !segments.empty ()
36 12736 : && !Analysis::BuiltinAttributeMappings::get ()
37 12736 : ->lookup_builtin (segments[0].get_segment_name ())
38 12736 : .is_error ();
39 : }
40 :
41 : /* Expand all of the macro invocations currently contained in a crate */
42 : void
43 10347 : ExpandVisitor::go (AST::Crate &crate)
44 : {
45 10347 : visit (crate);
46 10347 : }
47 :
48 : static std::vector<std::unique_ptr<AST::Item>>
49 291 : builtin_derive_item (AST::Item &item, const AST::Attribute &derive,
50 : BuiltinMacro to_derive)
51 : {
52 291 : auto items = AST::DeriveVisitor::derive (item, derive, to_derive);
53 722 : for (auto &item : items)
54 431 : Analysis::Mappings::get ().add_derived_node (item->get_node_id ());
55 291 : return items;
56 : }
57 :
58 : static std::vector<std::unique_ptr<AST::Item>>
59 0 : derive_item (AST::Item &item, AST::SimplePath &to_derive,
60 : MacroExpander &expander)
61 : {
62 0 : std::vector<std::unique_ptr<AST::Item>> result;
63 0 : auto frag = expander.expand_derive_proc_macro (item, to_derive);
64 0 : if (!frag.is_error ())
65 : {
66 0 : for (auto &node : frag.get_nodes ())
67 : {
68 0 : switch (node.get_kind ())
69 : {
70 0 : case AST::SingleASTNode::Kind::Item:
71 0 : Analysis::Mappings::get ().add_derived_node (
72 0 : node.get_item ()->get_node_id ());
73 0 : result.push_back (node.take_item ());
74 0 : break;
75 0 : default:
76 0 : rust_unreachable ();
77 : }
78 : }
79 : }
80 0 : return result;
81 0 : }
82 :
83 : static std::vector<std::unique_ptr<AST::Item>>
84 0 : expand_item_attribute (AST::Item &item, AST::SimplePath &name,
85 : MacroExpander &expander)
86 : {
87 0 : std::vector<std::unique_ptr<AST::Item>> result;
88 0 : auto frag = expander.expand_attribute_proc_macro (item, name);
89 0 : if (!frag.is_error ())
90 : {
91 0 : for (auto &node : frag.get_nodes ())
92 : {
93 0 : switch (node.get_kind ())
94 : {
95 0 : case AST::SingleASTNode::Kind::Item:
96 0 : result.push_back (node.take_item ());
97 0 : break;
98 0 : default:
99 0 : rust_unreachable ();
100 : }
101 : }
102 : }
103 0 : return result;
104 0 : }
105 :
106 : /* Helper function to expand a given attribute on a statement and collect back
107 : * statements.
108 : * T should be anything that can be used as a statement accepting outer
109 : * attributes.
110 : */
111 : template <typename T>
112 : static std::vector<std::unique_ptr<AST::Stmt>>
113 1 : expand_stmt_attribute (T &statement, AST::SimplePath &attribute,
114 : MacroExpander &expander)
115 : {
116 1 : std::vector<std::unique_ptr<AST::Stmt>> result;
117 1 : auto frag = expander.expand_attribute_proc_macro (statement, attribute);
118 1 : if (!frag.is_error ())
119 : {
120 0 : for (auto &node : frag.get_nodes ())
121 : {
122 0 : switch (node.get_kind ())
123 : {
124 0 : case AST::SingleASTNode::Kind::Stmt:
125 0 : result.push_back (node.take_stmt ());
126 : break;
127 0 : default:
128 0 : rust_unreachable ();
129 : }
130 : }
131 : }
132 1 : return result;
133 1 : }
134 :
135 : void
136 52814 : expand_tail_expr (AST::BlockExpr &block_expr, MacroExpander &expander)
137 : {
138 52814 : if (block_expr.has_tail_expr ())
139 : {
140 39875 : auto tail = block_expr.take_tail_expr ();
141 39875 : auto attrs = tail->get_outer_attrs ();
142 39875 : bool changed = false;
143 40753 : for (auto it = attrs.begin (); it != attrs.end ();)
144 : {
145 878 : auto current = *it;
146 878 : if (is_builtin (current))
147 : {
148 878 : it++;
149 : }
150 : else
151 : {
152 0 : it = attrs.erase (it);
153 0 : changed = true;
154 0 : auto new_stmts
155 : = expand_stmt_attribute (block_expr, current.get_path (),
156 0 : expander);
157 0 : auto &stmts = block_expr.get_statements ();
158 0 : std::move (new_stmts.begin (), new_stmts.end (),
159 : std::inserter (stmts, stmts.end ()));
160 0 : }
161 878 : }
162 39875 : if (changed)
163 0 : block_expr.normalize_tail_expr ();
164 : else
165 39875 : block_expr.set_tail_expr (std::move (tail));
166 39875 : }
167 52814 : }
168 :
169 : void
170 13535 : ExpandVisitor::expand_inner_items (
171 : std::vector<std::unique_ptr<AST::Item>> &items)
172 : {
173 13535 : expander.push_context (MacroExpander::ContextType::ITEM);
174 :
175 70469 : for (auto it = items.begin (); it != items.end (); it++)
176 : {
177 56934 : Rust::AST::Item &item = **it;
178 56934 : if (item.has_outer_attrs ())
179 : {
180 8881 : auto &attrs = item.get_outer_attrs ();
181 :
182 20889 : for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
183 : /* erase => No increment*/)
184 : {
185 12008 : auto current = *attr_it;
186 :
187 12008 : if (current.is_derive ())
188 : {
189 160 : current.parse_attr_to_meta_item ();
190 160 : attr_it = attrs.erase (attr_it);
191 : // Get traits to derive in the current attribute
192 160 : auto traits_to_derive = current.get_traits_to_derive ();
193 451 : for (auto &to_derive : traits_to_derive)
194 : {
195 291 : auto maybe_builtin = MacroBuiltin::builtins.lookup (
196 291 : to_derive.get ().as_string ());
197 291 : if (maybe_builtin.has_value ())
198 : {
199 291 : auto new_items
200 : = builtin_derive_item (item, current,
201 291 : maybe_builtin.value ());
202 :
203 722 : for (auto &&new_item : new_items)
204 431 : it = items.insert (it, std::move (new_item));
205 291 : }
206 : else
207 : {
208 : // Macro is not a builtin, so it must be a
209 : // user-defined derive macro.
210 0 : auto new_items
211 0 : = derive_item (item, to_derive, expander);
212 0 : std::move (new_items.begin (), new_items.end (),
213 : std::inserter (items, it));
214 0 : }
215 : }
216 160 : }
217 : else /* Attribute */
218 : {
219 11848 : if (is_builtin (current))
220 : {
221 11848 : attr_it++;
222 : }
223 : else
224 : {
225 0 : attr_it = attrs.erase (attr_it);
226 0 : auto new_items
227 : = expand_item_attribute (item, current.get_path (),
228 0 : expander);
229 0 : it = items.erase (it);
230 0 : std::move (new_items.begin (), new_items.end (),
231 : std::inserter (items, it));
232 : // TODO: Improve this ?
233 : // item is invalid since it refers to now deleted,
234 : // cancel the loop increment and break.
235 0 : it--;
236 0 : break;
237 0 : }
238 : }
239 12008 : }
240 : }
241 : }
242 :
243 13535 : expand_macro_children (items, &AST::SingleASTNode::take_item);
244 :
245 13535 : expander.pop_context ();
246 13535 : }
247 :
248 : void
249 52814 : ExpandVisitor::expand_inner_stmts (AST::BlockExpr &expr)
250 : {
251 52814 : auto &stmts = expr.get_statements ();
252 52814 : expander.push_context (MacroExpander::ContextType::STMT);
253 :
254 101305 : for (auto it = stmts.begin (); it != stmts.end (); it++)
255 : {
256 48491 : auto &stmt = *it;
257 :
258 : // skip all non-item statements
259 48491 : if (stmt->get_stmt_kind () != AST::Stmt::Kind::Item)
260 46890 : continue;
261 :
262 1601 : auto &item = static_cast<AST::Item &> (*stmt.get ());
263 :
264 1601 : if (item.has_outer_attrs ())
265 : {
266 10 : auto &attrs = item.get_outer_attrs ();
267 :
268 19 : for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
269 : /* erase => No increment*/)
270 : {
271 10 : auto current = *attr_it;
272 :
273 10 : if (current.is_derive ())
274 : {
275 0 : attr_it = attrs.erase (attr_it);
276 : // Get traits to derive in the current attribute
277 0 : auto traits_to_derive = current.get_traits_to_derive ();
278 0 : for (auto &to_derive : traits_to_derive)
279 : {
280 0 : auto maybe_builtin = MacroBuiltin::builtins.lookup (
281 0 : to_derive.get ().as_string ());
282 0 : if (maybe_builtin.has_value ())
283 : {
284 0 : auto new_items
285 : = builtin_derive_item (item, current,
286 0 : maybe_builtin.value ());
287 :
288 : // this inserts the derive *before* the item - is it a
289 : // problem?
290 0 : for (auto &&new_item : new_items)
291 0 : it = stmts.insert (it, std::move (new_item));
292 0 : }
293 : else
294 : {
295 0 : auto new_items
296 0 : = derive_item (item, to_derive, expander);
297 0 : std::move (new_items.begin (), new_items.end (),
298 : std::inserter (stmts, it));
299 0 : }
300 : }
301 0 : }
302 : else /* Attribute */
303 : {
304 10 : if (is_builtin (current))
305 : {
306 9 : attr_it++;
307 : }
308 : else
309 : {
310 1 : attr_it = attrs.erase (attr_it);
311 1 : auto new_items
312 : = expand_stmt_attribute (item, current.get_path (),
313 1 : expander);
314 1 : it = stmts.erase (it);
315 1 : std::move (new_items.begin (), new_items.end (),
316 : std::inserter (stmts, it));
317 : // TODO: Improve this ?
318 : // item is invalid since it refers to now deleted,
319 : // cancel the loop increment and break.
320 1 : it--;
321 1 : break;
322 1 : }
323 : }
324 10 : }
325 : }
326 : }
327 :
328 52814 : if (!expr.has_tail_expr ())
329 12998 : expr.normalize_tail_expr ();
330 :
331 52814 : expand_macro_children (stmts, &AST::SingleASTNode::take_stmt);
332 :
333 52814 : expander.pop_context ();
334 52814 : }
335 :
336 : void
337 1285533 : ExpandVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
338 : {
339 1285533 : NodeId old_expect = expr->get_node_id ();
340 1285533 : std::swap (macro_invoc_expect_id, old_expect);
341 :
342 1285533 : expander.push_context (MacroExpander::ContextType::EXPR);
343 1285533 : expr->accept_vis (*this);
344 1285533 : expander.pop_context ();
345 :
346 1285533 : std::swap (macro_invoc_expect_id, old_expect);
347 :
348 1285533 : auto final_fragment = expander.take_expanded_fragment ();
349 1285533 : if (final_fragment.should_expand ()
350 1285533 : && final_fragment.is_expression_fragment ())
351 1892 : expr = final_fragment.take_expression_fragment ();
352 1285533 : }
353 :
354 : void
355 104231 : ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::Type> &type)
356 : {
357 104231 : NodeId old_expect = type->get_node_id ();
358 104231 : std::swap (macro_invoc_expect_id, old_expect);
359 :
360 104231 : expander.push_context (MacroExpander::ContextType::TYPE);
361 104231 : type->accept_vis (*this);
362 104231 : expander.pop_context ();
363 :
364 104231 : std::swap (macro_invoc_expect_id, old_expect);
365 :
366 104231 : auto final_fragment = expander.take_expanded_fragment ();
367 104231 : if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
368 28 : type = final_fragment.take_type_fragment ();
369 104231 : }
370 :
371 : // HACK: maybe we shouldn't have TypeNoBounds as a base class
372 : void
373 37310 : ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::TypeNoBounds> &type)
374 : {
375 37310 : NodeId old_expect = type->get_node_id ();
376 37310 : std::swap (macro_invoc_expect_id, old_expect);
377 :
378 37310 : expander.push_context (MacroExpander::ContextType::TYPE);
379 37310 : type->accept_vis (*this);
380 37310 : expander.pop_context ();
381 :
382 37310 : std::swap (macro_invoc_expect_id, old_expect);
383 :
384 37310 : auto final_fragment = expander.take_expanded_fragment ();
385 37310 : if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
386 2 : type = std::make_unique<AST::ParenthesisedType> (
387 3 : final_fragment.take_type_fragment (), BUILTINS_LOCATION);
388 37310 : }
389 :
390 : void
391 68786 : ExpandVisitor::maybe_expand_pattern (std::unique_ptr<AST::Pattern> &pattern)
392 : {
393 68786 : NodeId old_expect = pattern->get_node_id ();
394 68786 : std::swap (macro_invoc_expect_id, old_expect);
395 :
396 68786 : expander.push_context (MacroExpander::ContextType::PATTERN);
397 68786 : pattern->accept_vis (*this);
398 68786 : expander.pop_context ();
399 :
400 68786 : std::swap (macro_invoc_expect_id, old_expect);
401 :
402 68786 : auto final_fragment = expander.take_expanded_fragment ();
403 68786 : if (final_fragment.should_expand () && final_fragment.is_pattern_fragment ())
404 1 : pattern = final_fragment.take_pattern_fragment ();
405 68786 : }
406 :
407 : void
408 3920 : ExpandVisitor::expand_struct_fields (std::vector<AST::StructField> &fields)
409 : {
410 3920 : expand_fields (fields);
411 3920 : }
412 :
413 : void
414 3188 : ExpandVisitor::expand_tuple_fields (std::vector<AST::TupleField> &fields)
415 : {
416 3188 : expand_fields (fields);
417 3188 : }
418 :
419 : // FIXME: This can definitely be refactored with the method above
420 : void
421 44012 : ExpandVisitor::expand_function_params (
422 : std::vector<std::unique_ptr<AST::Param>> ¶ms)
423 : {
424 93200 : for (auto &p : params)
425 49188 : visit (p);
426 44012 : }
427 :
428 : void
429 9101 : ExpandVisitor::expand_generic_args (AST::GenericArgs &args)
430 : {
431 18610 : for (auto &arg : args.get_generic_args ())
432 : {
433 9509 : switch (arg.get_kind ())
434 : {
435 3842 : case AST::GenericArg::Kind::Type:
436 3842 : maybe_expand_type (arg.get_type_ptr ());
437 3842 : break;
438 138 : case AST::GenericArg::Kind::Const:
439 138 : maybe_expand_expr (arg.get_expression_ptr ());
440 138 : break;
441 : default:
442 : break;
443 : // FIXME: Figure out what to do here if there is ambiguity. Since the
444 : // resolver comes after the expansion, we need to figure out a way to
445 : // strip ambiguous values here
446 : // TODO: ARTHUR: Probably add a `mark_as_strip` method to `GenericArg`
447 : // or something. This would clean up this whole thing
448 : }
449 : }
450 :
451 : // FIXME: Can we have macro invocations in generic type bindings?
452 : // expand binding args - strip sub-types only
453 : // FIXME: ARTHUR: This needs a test! Foo<Item = macro!()>
454 9295 : for (auto &binding : args.get_binding_args ())
455 194 : maybe_expand_type (binding.get_type_ptr ());
456 9101 : }
457 :
458 : void
459 978 : ExpandVisitor::expand_qualified_path_type (AST::QualifiedPathType &path_type)
460 : {
461 978 : maybe_expand_type (path_type.get_type_ptr ());
462 :
463 : // FIXME: ARTHUR: Can we do macro expansion in there? Needs a test!
464 978 : if (path_type.has_as_clause ())
465 884 : path_type.get_as_type_path ().accept_vis (*this);
466 978 : }
467 :
468 : void
469 134 : ExpandVisitor::expand_closure_params (std::vector<AST::ClosureParam> ¶ms)
470 : {
471 260 : for (auto ¶m : params)
472 : {
473 126 : maybe_expand_pattern (param.get_pattern_ptr ());
474 :
475 126 : if (param.has_type_given ())
476 116 : maybe_expand_type (param.get_type_ptr ());
477 : }
478 134 : }
479 :
480 : void
481 761 : ExpandVisitor::expand_where_clause (AST::WhereClause &where_clause)
482 : {
483 1542 : for (auto &item : where_clause.get_items ())
484 781 : visit (item);
485 761 : }
486 :
487 : void
488 10347 : ExpandVisitor::visit (AST::Crate &crate)
489 : {
490 10347 : expand_inner_items (crate.items);
491 10347 : }
492 :
493 : void
494 0 : ExpandVisitor::visit (AST::DelimTokenTree &)
495 0 : {}
496 :
497 : void
498 0 : ExpandVisitor::visit (AST::AttrInputMetaItemContainer &)
499 0 : {}
500 :
501 : void
502 54996 : ExpandVisitor::visit (AST::IdentifierExpr &ident_expr)
503 54996 : {}
504 :
505 : void
506 540 : ExpandVisitor::visit (AST::LifetimeParam &)
507 540 : {}
508 :
509 : void
510 194 : ExpandVisitor::visit (AST::ConstGenericParam &)
511 194 : {}
512 :
513 : void
514 2793 : ExpandVisitor::visit (AST::MacroInvocation ¯o_invoc)
515 : {
516 2793 : if (macro_invoc_expect_id != macro_invoc.get_node_id ())
517 : {
518 0 : rust_internal_error_at (
519 : macro_invoc.get_locus (),
520 : "attempting to expand node with id %d into position with node id %d",
521 0 : (int) macro_invoc.get_node_id (), (int) macro_invoc_expect_id);
522 : }
523 :
524 : // TODO: Can we do the AST fragment replacing here? Probably not, right?
525 4742 : expander.expand_invoc (macro_invoc, macro_invoc.has_semicolon ()
526 : ? AST::InvocKind::Semicoloned
527 : : AST::InvocKind::Expr);
528 2793 : }
529 :
530 : void
531 58952 : ExpandVisitor::visit (AST::PathInExpression &path)
532 : {
533 58952 : if (!path.is_lang_item ())
534 142507 : for (auto &segment : path.get_segments ())
535 167504 : if (segment.has_generic_args ())
536 2102 : expand_generic_args (segment.get_generic_args ());
537 58952 : }
538 :
539 : void
540 7001 : ExpandVisitor::visit (AST::TypePathSegmentGeneric &segment)
541 : {
542 7001 : if (segment.has_generic_args ())
543 6999 : expand_generic_args (segment.get_generic_args ());
544 7001 : }
545 :
546 : void
547 60 : ExpandVisitor::visit (AST::TypePathSegmentFunction &segment)
548 : {
549 60 : auto &type_path_function = segment.get_type_path_function ();
550 :
551 124 : for (auto &type : type_path_function.get_params ())
552 64 : visit (type);
553 :
554 60 : if (type_path_function.has_return_type ())
555 56 : maybe_expand_type (type_path_function.get_return_type_ptr ());
556 60 : }
557 :
558 : void
559 269 : ExpandVisitor::visit (AST::QualifiedPathInExpression &path)
560 : {
561 269 : expand_qualified_path_type (path.get_qualified_path_type ());
562 :
563 538 : for (auto &segment : path.get_segments ())
564 538 : if (segment.has_generic_args ())
565 0 : expand_generic_args (segment.get_generic_args ());
566 269 : }
567 :
568 : void
569 709 : ExpandVisitor::visit (AST::QualifiedPathInType &path)
570 : {
571 709 : expand_qualified_path_type (path.get_qualified_path_type ());
572 :
573 : // this shouldn't strip any segments, but can strip inside them
574 709 : for (auto &segment : path.get_segments ())
575 0 : visit (segment);
576 709 : }
577 :
578 : void
579 562466 : ExpandVisitor::visit (AST::LiteralExpr &expr)
580 562466 : {}
581 :
582 : void
583 0 : ExpandVisitor::visit (AST::AttrInputLiteral &)
584 0 : {}
585 :
586 : void
587 0 : ExpandVisitor::visit (AST::AttrInputMacro ¯o)
588 : {
589 0 : rust_sorry_at (UNDEF_LOCATION, "macros in attributes not supported");
590 0 : }
591 :
592 : void
593 0 : ExpandVisitor::visit (AST::MetaItemLitExpr &)
594 0 : {}
595 :
596 : void
597 0 : ExpandVisitor::visit (AST::MetaItemPathExpr &)
598 0 : {}
599 :
600 : void
601 531673 : ExpandVisitor::visit (AST::ArithmeticOrLogicalExpr &expr)
602 : {
603 531673 : maybe_expand_expr (expr.get_left_expr_ptr ());
604 531673 : maybe_expand_expr (expr.get_right_expr_ptr ());
605 531673 : }
606 :
607 : void
608 6898 : ExpandVisitor::visit (AST::ComparisonExpr &expr)
609 : {
610 6898 : maybe_expand_expr (expr.get_left_expr_ptr ());
611 6898 : maybe_expand_expr (expr.get_right_expr_ptr ());
612 6898 : }
613 :
614 : void
615 846 : ExpandVisitor::visit (AST::LazyBooleanExpr &expr)
616 : {
617 846 : maybe_expand_expr (expr.get_left_expr_ptr ());
618 846 : maybe_expand_expr (expr.get_right_expr_ptr ());
619 846 : }
620 :
621 : void
622 11769 : ExpandVisitor::visit (AST::TypeCastExpr &expr)
623 : {
624 11769 : maybe_expand_expr (expr.get_casted_expr_ptr ());
625 11769 : maybe_expand_type (expr.get_type_to_cast_to_ptr ());
626 11769 : }
627 :
628 : void
629 4531 : ExpandVisitor::visit (AST::AssignmentExpr &expr)
630 : {
631 4531 : maybe_expand_expr (expr.get_left_expr_ptr ());
632 4531 : maybe_expand_expr (expr.get_right_expr_ptr ());
633 4531 : }
634 :
635 : void
636 1275 : ExpandVisitor::visit (AST::CompoundAssignmentExpr &expr)
637 : {
638 1275 : maybe_expand_expr (expr.get_left_expr_ptr ());
639 1275 : maybe_expand_expr (expr.get_right_expr_ptr ());
640 1275 : }
641 :
642 : void
643 753 : ExpandVisitor::visit (AST::GroupedExpr &expr)
644 : {
645 753 : maybe_expand_expr (expr.get_expr_in_parens_ptr ());
646 753 : }
647 :
648 : void
649 165 : ExpandVisitor::visit (AST::StructExprStruct &expr)
650 165 : {}
651 :
652 : void
653 26324 : ExpandVisitor::visit (AST::CallExpr &expr)
654 : {
655 26324 : visit (expr.get_function_expr ());
656 :
657 58647 : for (auto ¶m : expr.get_params ())
658 32323 : maybe_expand_expr (param);
659 26324 : }
660 :
661 : void
662 74 : ExpandVisitor::visit (AST::ClosureExprInner &expr)
663 : {
664 74 : expand_closure_params (expr.get_params ());
665 :
666 74 : maybe_expand_expr (expr.get_definition_expr_ptr ());
667 74 : }
668 :
669 : void
670 52814 : ExpandVisitor::visit (AST::BlockExpr &expr)
671 : {
672 52814 : expand_inner_stmts (expr);
673 :
674 52814 : expand_tail_expr (expr, expander);
675 52814 : if (expr.has_tail_expr ())
676 39875 : maybe_expand_expr (expr.get_tail_expr_ptr ());
677 52814 : }
678 :
679 : void
680 60 : ExpandVisitor::visit (AST::ClosureExprInnerTyped &expr)
681 : {
682 60 : expand_closure_params (expr.get_params ());
683 :
684 60 : maybe_expand_type (expr.get_return_type_ptr ());
685 :
686 60 : visit (expr.get_definition_expr ());
687 60 : }
688 :
689 : void
690 34 : ExpandVisitor::visit (AST::ContinueExpr &expr)
691 34 : {}
692 :
693 : void
694 1057 : ExpandVisitor::visit (AST::IfExpr &expr)
695 : {
696 1057 : maybe_expand_expr (expr.get_condition_expr_ptr ());
697 :
698 1057 : visit (expr.get_if_block ());
699 1057 : }
700 :
701 : void
702 3162 : ExpandVisitor::visit (AST::IfExprConseqElse &expr)
703 : {
704 3162 : maybe_expand_expr (expr.get_condition_expr_ptr ());
705 :
706 3162 : visit (expr.get_if_block ());
707 3162 : visit (expr.get_else_block ());
708 3162 : }
709 :
710 : void
711 36 : ExpandVisitor::visit (AST::IfLetExpr &expr)
712 : {
713 36 : maybe_expand_expr (expr.get_value_expr_ptr ());
714 :
715 36 : visit (expr.get_if_block ());
716 36 : }
717 :
718 : void
719 24 : ExpandVisitor::visit (AST::IfLetExprConseqElse &expr)
720 : {
721 24 : maybe_expand_expr (expr.get_value_expr_ptr ());
722 :
723 24 : visit (expr.get_if_block ());
724 24 : visit (expr.get_else_block ());
725 24 : }
726 :
727 : void
728 1282 : ExpandVisitor::visit (AST::TupleExpr &expr)
729 : {
730 3542 : for (auto &sub : expr.get_tuple_elems ())
731 2260 : maybe_expand_expr (sub);
732 1282 : }
733 :
734 : void
735 10821 : ExpandVisitor::visit (AST::TypeParam ¶m)
736 : {
737 12797 : for (auto &bound : param.get_type_param_bounds ())
738 1976 : visit (bound);
739 :
740 10821 : if (param.has_type ())
741 923 : maybe_expand_type (param.get_type_ptr ());
742 10821 : }
743 :
744 : void
745 4 : ExpandVisitor::visit (AST::LifetimeWhereClauseItem &)
746 4 : {}
747 :
748 : void
749 777 : ExpandVisitor::visit (AST::TypeBoundWhereClauseItem &item)
750 : {
751 777 : maybe_expand_type (item.get_type_ptr ());
752 :
753 1554 : for (auto &bound : item.get_type_param_bounds ())
754 777 : visit (bound);
755 777 : }
756 :
757 : void
758 3188 : ExpandVisitor::visit (AST::Module &module)
759 : {
760 3188 : expand_inner_items (module.get_items ());
761 3188 : }
762 :
763 : void
764 48 : ExpandVisitor::visit (AST::ExternCrate &crate)
765 48 : {}
766 :
767 : void
768 0 : ExpandVisitor::visit (AST::UseTreeGlob &)
769 0 : {}
770 :
771 : void
772 0 : ExpandVisitor::visit (AST::UseTreeList &)
773 0 : {}
774 :
775 : void
776 0 : ExpandVisitor::visit (AST::UseTreeRebind &)
777 0 : {}
778 :
779 : void
780 1837 : ExpandVisitor::visit (AST::UseDeclaration &use_decl)
781 1837 : {}
782 :
783 : void
784 44012 : ExpandVisitor::visit (AST::Function &function)
785 : {
786 44012 : if (function.has_body ())
787 34337 : visit_inner_using_attrs (
788 34337 : function, function.get_definition ().value ()->get_inner_attrs ());
789 48362 : for (auto ¶m : function.get_generic_params ())
790 4350 : visit (param);
791 :
792 44012 : expand_function_params (function.get_function_params ());
793 :
794 44012 : if (function.has_return_type ())
795 32204 : maybe_expand_type (function.get_return_type_ptr ());
796 :
797 44012 : if (function.has_where_clause ())
798 520 : expand_where_clause (function.get_where_clause ());
799 :
800 44012 : if (function.has_body ())
801 34337 : visit (*function.get_definition ());
802 44012 : }
803 :
804 : void
805 3495 : ExpandVisitor::visit (AST::StructStruct &struct_item)
806 : {
807 4682 : for (auto &generic : struct_item.get_generic_params ())
808 1187 : visit (generic);
809 :
810 3495 : if (struct_item.has_where_clause ())
811 4 : expand_where_clause (struct_item.get_where_clause ());
812 :
813 3495 : expand_struct_fields (struct_item.get_fields ());
814 3495 : }
815 :
816 : void
817 2076 : ExpandVisitor::visit (AST::TupleStruct &tuple_struct)
818 : {
819 2815 : for (auto &generic : tuple_struct.get_generic_params ())
820 739 : visit (generic);
821 :
822 2076 : if (tuple_struct.has_where_clause ())
823 0 : expand_where_clause (tuple_struct.get_where_clause ());
824 :
825 2076 : expand_tuple_fields (tuple_struct.get_fields ());
826 2076 : }
827 :
828 : void
829 1028 : ExpandVisitor::visit (AST::EnumItem &item)
830 1028 : {}
831 :
832 : void
833 1112 : ExpandVisitor::visit (AST::EnumItemTuple &item)
834 : {
835 1112 : expand_tuple_fields (item.get_tuple_fields ());
836 1112 : }
837 :
838 : void
839 208 : ExpandVisitor::visit (AST::EnumItemStruct &item)
840 : {
841 208 : expand_struct_fields (item.get_struct_fields ());
842 208 : }
843 :
844 : void
845 675 : ExpandVisitor::visit (AST::EnumItemDiscriminant &item)
846 : {
847 675 : maybe_expand_expr (item.get_expr_ptr ());
848 675 : }
849 :
850 : void
851 217 : ExpandVisitor::visit (AST::Union &union_item)
852 : {
853 374 : for (auto &generic : union_item.get_generic_params ())
854 157 : visit (generic);
855 :
856 217 : expand_struct_fields (union_item.get_variants ());
857 217 : }
858 :
859 : void
860 1151 : ExpandVisitor::visit (AST::ConstantItem &const_item)
861 : {
862 1151 : maybe_expand_type (const_item.get_type_ptr ());
863 :
864 1151 : if (const_item.has_expr ())
865 1082 : maybe_expand_expr (const_item.get_expr_ptr ());
866 1151 : }
867 :
868 : void
869 111 : ExpandVisitor::visit (AST::StaticItem &static_item)
870 : {
871 111 : maybe_expand_type (static_item.get_type_ptr ());
872 :
873 111 : maybe_expand_expr (static_item.get_expr_ptr ());
874 111 : }
875 :
876 : void
877 8654 : ExpandVisitor::visit (AST::Trait &trait)
878 : {
879 10295 : for (auto &generic : trait.get_generic_params ())
880 1641 : visit (generic);
881 :
882 10328 : for (auto &bound : trait.get_type_param_bounds ())
883 1674 : visit (bound);
884 :
885 8654 : if (trait.has_where_clause ())
886 21 : expand_where_clause (trait.get_where_clause ());
887 :
888 8654 : expander.push_context (MacroExpander::ContextType::TRAIT);
889 :
890 8654 : expand_macro_children (MacroExpander::ContextType::TRAIT,
891 : trait.get_trait_items (),
892 : &AST::SingleASTNode::take_assoc_item);
893 :
894 8654 : expander.pop_context ();
895 8654 : }
896 :
897 : void
898 2189 : ExpandVisitor::visit (AST::InherentImpl &impl)
899 : {
900 4378 : visit_inner_attrs (impl);
901 : // just expand sub-stuff - can't actually strip generic params themselves
902 2959 : for (auto &generic : impl.get_generic_params ())
903 770 : visit (generic);
904 :
905 : // FIXME: Is that correct? How do we test that?
906 2189 : expander.push_context (MacroExpander::ContextType::ITEM);
907 :
908 2189 : maybe_expand_type (impl.get_type_ptr ());
909 :
910 2189 : expander.pop_context ();
911 :
912 2189 : if (impl.has_where_clause ())
913 2 : expand_where_clause (impl.get_where_clause ());
914 :
915 2189 : expand_macro_children (MacroExpander::ContextType::IMPL,
916 : impl.get_impl_items (),
917 : &AST::SingleASTNode::take_assoc_item);
918 2189 : }
919 :
920 : void
921 11576 : ExpandVisitor::visit (AST::TraitImpl &impl)
922 : {
923 23152 : visit_inner_attrs (impl);
924 : // just expand sub-stuff - can't actually strip generic params themselves
925 13474 : for (auto ¶m : impl.get_generic_params ())
926 1898 : visit (param);
927 :
928 : // FIXME: Is that correct? How do we test that?
929 11576 : expander.push_context (MacroExpander::ContextType::ITEM);
930 :
931 11576 : maybe_expand_type (impl.get_type_ptr ());
932 :
933 11576 : expander.pop_context ();
934 :
935 11576 : visit (impl.get_trait_path ());
936 :
937 11576 : if (impl.has_where_clause ())
938 214 : expand_where_clause (impl.get_where_clause ());
939 :
940 11576 : expand_macro_children (MacroExpander::ContextType::TRAIT_IMPL,
941 : impl.get_impl_items (),
942 : &AST::SingleASTNode::take_assoc_item);
943 11576 : }
944 :
945 : void
946 2 : ExpandVisitor::visit (AST::ExternalTypeItem &item)
947 2 : {}
948 :
949 : void
950 2 : ExpandVisitor::visit (AST::ExternalStaticItem &static_item)
951 : {
952 2 : maybe_expand_type (static_item.get_type_ptr ());
953 2 : }
954 :
955 : void
956 3288 : ExpandVisitor::visit (AST::ExternBlock &block)
957 : {
958 6576 : visit_inner_attrs (block);
959 :
960 3288 : expand_macro_children (MacroExpander::ContextType::EXTERN,
961 : block.get_extern_items (),
962 : &AST::SingleASTNode::take_external_item);
963 3288 : }
964 :
965 : void
966 0 : ExpandVisitor::visit (AST::MacroMatchRepetition &)
967 0 : {}
968 :
969 : void
970 0 : ExpandVisitor::visit (AST::MacroMatcher &)
971 0 : {}
972 :
973 : void
974 3774 : ExpandVisitor::visit (AST::MacroRulesDefinition &rules_def)
975 3774 : {}
976 :
977 : void
978 0 : ExpandVisitor::visit (AST::MetaItemPath &)
979 0 : {}
980 :
981 : void
982 0 : ExpandVisitor::visit (AST::MetaItemSeq &)
983 0 : {}
984 :
985 : void
986 0 : ExpandVisitor::visit (AST::MetaListPaths &)
987 0 : {}
988 :
989 : void
990 0 : ExpandVisitor::visit (AST::MetaListNameValueStr &)
991 0 : {}
992 :
993 : void
994 219 : ExpandVisitor::visit (AST::StructPatternFieldIdent &field)
995 219 : {}
996 :
997 : void
998 88 : ExpandVisitor::visit (AST::GroupedPattern &pattern)
999 : {
1000 88 : maybe_expand_pattern (pattern.get_pattern_in_parens_ptr ());
1001 88 : }
1002 :
1003 : void
1004 64 : ExpandVisitor::visit (AST::SlicePatternItemsNoRest &items)
1005 : {
1006 192 : for (auto &sub : items.get_patterns ())
1007 128 : maybe_expand_pattern (sub);
1008 64 : }
1009 :
1010 : void
1011 88 : ExpandVisitor::visit (AST::SlicePatternItemsHasRest &items)
1012 : {
1013 174 : for (auto &sub : items.get_lower_patterns ())
1014 86 : maybe_expand_pattern (sub);
1015 174 : for (auto &sub : items.get_upper_patterns ())
1016 86 : maybe_expand_pattern (sub);
1017 88 : }
1018 :
1019 : void
1020 470 : ExpandVisitor::visit (AST::AltPattern &pattern)
1021 : {
1022 1449 : for (auto &alt : pattern.get_alts ())
1023 979 : maybe_expand_pattern (alt);
1024 470 : }
1025 :
1026 : void
1027 2556 : ExpandVisitor::visit (AST::TupleStructItemsNoRest &tuple_items)
1028 : {
1029 5432 : for (auto &sub : tuple_items.get_patterns ())
1030 2876 : maybe_expand_pattern (sub);
1031 2556 : }
1032 :
1033 : void
1034 78 : ExpandVisitor::visit (AST::TupleStructItemsHasRest &tuple_items)
1035 : {
1036 140 : for (auto &sub : tuple_items.get_lower_patterns ())
1037 62 : maybe_expand_pattern (sub);
1038 :
1039 116 : for (auto &sub : tuple_items.get_upper_patterns ())
1040 38 : maybe_expand_pattern (sub);
1041 78 : }
1042 :
1043 : void
1044 1172 : ExpandVisitor::visit (AST::TuplePatternItemsNoRest &tuple_items)
1045 : {
1046 3550 : for (auto &sub : tuple_items.get_patterns ())
1047 2378 : maybe_expand_pattern (sub);
1048 1172 : }
1049 :
1050 : void
1051 54 : ExpandVisitor::visit (AST::TuplePatternItemsHasRest &tuple_items)
1052 : {
1053 110 : for (auto &sub : tuple_items.get_lower_patterns ())
1054 56 : maybe_expand_pattern (sub);
1055 :
1056 118 : for (auto &sub : tuple_items.get_upper_patterns ())
1057 64 : maybe_expand_pattern (sub);
1058 54 : }
1059 :
1060 : void
1061 27445 : ExpandVisitor::visit (AST::LetStmt &stmt)
1062 : {
1063 27445 : maybe_expand_pattern (stmt.get_pattern_ptr ());
1064 :
1065 27445 : if (stmt.has_type ())
1066 4503 : maybe_expand_type (stmt.get_type_ptr ());
1067 :
1068 27445 : if (stmt.has_init_expr ())
1069 25022 : maybe_expand_expr (stmt.get_init_expr_ptr ());
1070 27445 : }
1071 :
1072 : void
1073 19224 : ExpandVisitor::visit (AST::ExprStmt &stmt)
1074 : {
1075 19224 : maybe_expand_expr (stmt.get_expr_ptr ());
1076 19224 : }
1077 :
1078 : void
1079 131 : ExpandVisitor::visit (AST::BareFunctionType &type)
1080 : {
1081 229 : for (auto ¶m : type.get_function_params ())
1082 : {
1083 98 : maybe_expand_type (param.get_type_ptr ());
1084 : }
1085 :
1086 131 : if (type.has_return_type ())
1087 97 : visit (type.get_return_type ());
1088 131 : }
1089 :
1090 : void
1091 27367 : ExpandVisitor::visit (AST::FunctionParam ¶m)
1092 : {
1093 27367 : maybe_expand_pattern (param.get_pattern_ptr ());
1094 27367 : maybe_expand_type (param.get_type_ptr ());
1095 27367 : }
1096 :
1097 : void
1098 1751 : ExpandVisitor::visit (AST::VariadicParam ¶m)
1099 : {
1100 1751 : if (param.has_pattern ())
1101 22 : maybe_expand_pattern (param.get_pattern_ptr ());
1102 1751 : }
1103 :
1104 : void
1105 20070 : ExpandVisitor::visit (AST::SelfParam ¶m)
1106 : {
1107 : /* TODO: maybe check for invariants being violated - e.g. both type and
1108 : * lifetime? */
1109 20070 : if (param.has_type ())
1110 2 : maybe_expand_type (param.get_type_ptr ());
1111 20070 : }
1112 :
1113 : template <typename T>
1114 : void
1115 0 : ExpandVisitor::expand_inner_attribute (T &item, AST::SimplePath &path)
1116 : {
1117 : // FIXME: Retrieve path from segments + local use statements instead of string
1118 0 : expander.expand_attribute_proc_macro (item, path);
1119 0 : }
1120 :
1121 : template <typename T>
1122 : void
1123 51390 : ExpandVisitor::visit_inner_using_attrs (T &item,
1124 : std::vector<AST::Attribute> &attrs)
1125 : {
1126 51390 : for (auto it = attrs.begin (); it != attrs.end (); /* erase => No increment*/)
1127 : {
1128 0 : auto current = *it;
1129 :
1130 0 : if (!is_builtin (current) && !current.is_derive ())
1131 : {
1132 0 : it = attrs.erase (it);
1133 0 : expand_inner_attribute (item, current.get_path ());
1134 : }
1135 : else
1136 : {
1137 0 : it++;
1138 : }
1139 : }
1140 51390 : }
1141 :
1142 : template <typename T>
1143 : void
1144 3288 : ExpandVisitor::visit_inner_attrs (T &item)
1145 : {
1146 17053 : visit_inner_using_attrs (item, item.get_inner_attrs ());
1147 : }
1148 :
1149 : } // namespace Rust
|