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 1197800 : is_builtin (AST::Attribute &attr)
33 : {
34 1197800 : auto &segments = attr.get_path ().get_segments ();
35 1197800 : return !segments.empty ()
36 1197800 : && !Analysis::BuiltinAttributeMappings::get ()
37 1197800 : ->lookup_builtin (segments[0].get_segment_name ())
38 1197800 : .is_error ();
39 : }
40 :
41 : /* Expand all of the macro invocations currently contained in a crate */
42 : void
43 11133 : ExpandVisitor::go (AST::Crate &crate)
44 : {
45 11133 : visit (crate);
46 11133 : }
47 :
48 : static std::vector<std::unique_ptr<AST::Item>>
49 1055 : builtin_derive_item (AST::Item &item, const AST::Attribute &derive,
50 : BuiltinMacro to_derive, MacroExpander &expander)
51 : {
52 1055 : auto item_source = AST::Builder::get_item_source (expander.crate);
53 :
54 1055 : auto items
55 1055 : = AST::DeriveVisitor::derive (item, derive, to_derive, item_source);
56 :
57 2414 : for (auto &item : items)
58 1359 : Analysis::Mappings::get ().add_derived_node (item->get_node_id ());
59 :
60 1055 : return items;
61 : }
62 :
63 : static std::vector<std::unique_ptr<AST::Item>>
64 5 : derive_item (AST::Item &item, AST::SimplePath &to_derive,
65 : MacroExpander &expander)
66 : {
67 5 : std::vector<std::unique_ptr<AST::Item>> result;
68 5 : auto frag = expander.expand_derive_proc_macro (item, to_derive);
69 5 : if (!frag.is_error ())
70 : {
71 0 : for (auto &node : frag.get_nodes ())
72 : {
73 0 : switch (node.get_kind ())
74 : {
75 0 : case AST::SingleASTNode::Kind::Item:
76 0 : Analysis::Mappings::get ().add_derived_node (
77 0 : node.get_item ()->get_node_id ());
78 0 : result.push_back (node.take_item ());
79 0 : break;
80 0 : default:
81 0 : rust_unreachable ();
82 : }
83 : }
84 : }
85 5 : return result;
86 5 : }
87 :
88 : static std::vector<std::unique_ptr<AST::Item>>
89 0 : expand_item_attribute (AST::Item &item, AST::SimplePath &name,
90 : MacroExpander &expander)
91 : {
92 0 : std::vector<std::unique_ptr<AST::Item>> result;
93 0 : auto frag = expander.expand_attribute_proc_macro (item, name);
94 0 : if (!frag.is_error ())
95 : {
96 0 : for (auto &node : frag.get_nodes ())
97 : {
98 0 : switch (node.get_kind ())
99 : {
100 0 : case AST::SingleASTNode::Kind::Item:
101 0 : result.push_back (node.take_item ());
102 0 : break;
103 0 : default:
104 0 : rust_unreachable ();
105 : }
106 : }
107 : }
108 0 : return result;
109 0 : }
110 :
111 : /* Helper function to expand a given attribute on a statement and collect back
112 : * statements.
113 : * T should be anything that can be used as a statement accepting outer
114 : * attributes.
115 : */
116 : template <typename T>
117 : static std::vector<std::unique_ptr<AST::Stmt>>
118 1 : expand_stmt_attribute (T &statement, AST::SimplePath &attribute,
119 : MacroExpander &expander)
120 : {
121 1 : std::vector<std::unique_ptr<AST::Stmt>> result;
122 1 : auto frag = expander.expand_attribute_proc_macro (statement, attribute);
123 1 : if (!frag.is_error ())
124 : {
125 0 : for (auto &node : frag.get_nodes ())
126 : {
127 0 : switch (node.get_kind ())
128 : {
129 0 : case AST::SingleASTNode::Kind::Stmt:
130 0 : result.push_back (node.take_stmt ());
131 : break;
132 0 : default:
133 0 : rust_unreachable ();
134 : }
135 : }
136 : }
137 1 : return result;
138 1 : }
139 :
140 : void
141 612554 : expand_tail_expr (AST::BlockExpr &block_expr, MacroExpander &expander)
142 : {
143 612554 : if (block_expr.has_tail_expr ())
144 : {
145 533588 : auto tail = block_expr.take_tail_expr ();
146 533588 : auto attrs = tail->get_outer_attrs ();
147 533588 : bool changed = false;
148 536155 : for (auto it = attrs.begin (); it != attrs.end ();)
149 : {
150 2567 : auto current = *it;
151 2567 : if (is_builtin (current))
152 : {
153 2567 : it++;
154 : }
155 : else
156 : {
157 0 : it = attrs.erase (it);
158 0 : changed = true;
159 0 : auto new_stmts
160 : = expand_stmt_attribute (block_expr, current.get_path (),
161 0 : expander);
162 0 : auto &stmts = block_expr.get_statements ();
163 0 : std::move (new_stmts.begin (), new_stmts.end (),
164 : std::inserter (stmts, stmts.end ()));
165 0 : }
166 2567 : }
167 533588 : if (changed)
168 0 : block_expr.normalize_tail_expr ();
169 : else
170 533588 : block_expr.set_tail_expr (std::move (tail));
171 533588 : }
172 612554 : }
173 :
174 : void
175 22544 : ExpandVisitor::expand_inner_items (
176 : std::vector<std::unique_ptr<AST::Item>> &items)
177 : {
178 22544 : expander.push_context (MacroExpander::ContextType::ITEM);
179 :
180 462168 : for (auto it = items.begin (); it != items.end (); it++)
181 : {
182 439624 : Rust::AST::Item &item = **it;
183 439624 : if (item.has_outer_attrs ())
184 : {
185 297549 : auto &attrs = item.get_outer_attrs ();
186 :
187 1478818 : for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
188 : /* erase => No increment*/)
189 : {
190 1181269 : auto current = *attr_it;
191 :
192 1181269 : if (current.is_derive ())
193 : {
194 402 : current.parse_attr_to_meta_item ();
195 402 : attr_it = attrs.erase (attr_it);
196 : // Get traits to derive in the current attribute
197 402 : auto traits_to_derive = current.get_traits_to_derive ();
198 1462 : for (auto &to_derive : traits_to_derive)
199 : {
200 1060 : auto maybe_builtin = MacroBuiltin::builtins.lookup (
201 1060 : to_derive.get ().as_string ());
202 1060 : if (maybe_builtin.has_value ())
203 : {
204 1055 : auto new_items
205 : = builtin_derive_item (item, current,
206 1055 : maybe_builtin.value (),
207 1055 : expander);
208 :
209 2414 : for (auto &&new_item : new_items)
210 1359 : it = items.insert (it, std::move (new_item));
211 1055 : }
212 : else
213 : {
214 : // Macro is not a builtin, so it must be a
215 : // user-defined derive macro.
216 5 : auto new_items
217 5 : = derive_item (item, to_derive, expander);
218 5 : std::move (new_items.begin (), new_items.end (),
219 : std::inserter (items, it));
220 5 : }
221 : }
222 402 : }
223 : else /* Attribute */
224 : {
225 1180867 : if (is_builtin (current))
226 : {
227 1180867 : visit (*attr_it);
228 1180867 : attr_it++;
229 : }
230 : else
231 : {
232 0 : attr_it = attrs.erase (attr_it);
233 0 : auto new_items
234 : = expand_item_attribute (item, current.get_path (),
235 0 : expander);
236 0 : it = items.erase (it);
237 0 : std::move (new_items.begin (), new_items.end (),
238 : std::inserter (items, it));
239 : // TODO: Improve this ?
240 : // item is invalid since it refers to now deleted,
241 : // cancel the loop increment and break.
242 0 : it--;
243 0 : break;
244 0 : }
245 : }
246 1181269 : }
247 : }
248 : }
249 :
250 22544 : expand_macro_children (items, &AST::SingleASTNode::take_item);
251 :
252 22544 : expander.pop_context ();
253 22544 : }
254 :
255 : void
256 612554 : ExpandVisitor::expand_inner_stmts (AST::BlockExpr &expr)
257 : {
258 612554 : auto &stmts = expr.get_statements ();
259 612554 : expander.push_context (MacroExpander::ContextType::STMT);
260 :
261 957253 : for (auto it = stmts.begin (); it != stmts.end (); it++)
262 : {
263 344699 : auto &stmt = *it;
264 :
265 : // skip all non-item statements
266 344699 : if (stmt->get_stmt_kind () != AST::Stmt::Kind::Item)
267 305990 : continue;
268 :
269 38709 : auto &item = static_cast<AST::Item &> (*stmt.get ());
270 :
271 38709 : if (item.has_outer_attrs ())
272 : {
273 13561 : auto &attrs = item.get_outer_attrs ();
274 :
275 27891 : for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
276 : /* erase => No increment*/)
277 : {
278 14331 : auto current = *attr_it;
279 :
280 14331 : if (current.is_derive ())
281 : {
282 0 : attr_it = attrs.erase (attr_it);
283 : // Get traits to derive in the current attribute
284 0 : auto traits_to_derive = current.get_traits_to_derive ();
285 0 : for (auto &to_derive : traits_to_derive)
286 : {
287 0 : auto maybe_builtin = MacroBuiltin::builtins.lookup (
288 0 : to_derive.get ().as_string ());
289 0 : if (maybe_builtin.has_value ())
290 : {
291 0 : auto new_items
292 : = builtin_derive_item (item, current,
293 0 : maybe_builtin.value (),
294 0 : expander);
295 :
296 : // this inserts the derive *before* the item - is it a
297 : // problem?
298 0 : for (auto &&new_item : new_items)
299 0 : it = stmts.insert (it, std::move (new_item));
300 0 : }
301 : else
302 : {
303 0 : auto new_items
304 0 : = derive_item (item, to_derive, expander);
305 0 : std::move (new_items.begin (), new_items.end (),
306 : std::inserter (stmts, it));
307 0 : }
308 : }
309 0 : }
310 : else /* Attribute */
311 : {
312 14331 : if (is_builtin (current))
313 : {
314 14330 : visit (*attr_it);
315 14330 : attr_it++;
316 : }
317 : else
318 : {
319 1 : attr_it = attrs.erase (attr_it);
320 1 : auto new_items
321 : = expand_stmt_attribute (item, current.get_path (),
322 1 : expander);
323 1 : it = stmts.erase (it);
324 1 : std::move (new_items.begin (), new_items.end (),
325 : std::inserter (stmts, it));
326 : // TODO: Improve this ?
327 : // item is invalid since it refers to now deleted,
328 : // cancel the loop increment and break.
329 1 : it--;
330 1 : break;
331 1 : }
332 : }
333 14331 : }
334 : }
335 : }
336 :
337 612554 : if (!expr.has_tail_expr ())
338 79051 : expr.normalize_tail_expr ();
339 :
340 612554 : expand_macro_children (stmts, &AST::SingleASTNode::take_stmt);
341 :
342 612554 : expander.pop_context ();
343 612554 : }
344 :
345 : void
346 1245970 : ExpandVisitor::visit (AST::Attribute &attr)
347 : {
348 : // An attribute input containing a macro may have been expanded to a literal
349 1245970 : if (attr.has_attr_input ()
350 1245970 : && attr.get_attr_input ().get_attr_input_type ()
351 : == AST::AttrInput::AttrInputType::EXPR)
352 : {
353 936 : auto &expr = static_cast<AST::AttrInputExpr &> (attr.get_attr_input ());
354 936 : if (expr.get_expr ().is_literal ())
355 : {
356 300 : auto &lit = static_cast<AST::LiteralExpr &> (expr.get_expr ());
357 300 : attr.set_attr_input (std::make_unique<AST::AttrInputLiteral> (lit));
358 : }
359 : }
360 1245970 : AST::DefaultASTVisitor::visit (attr);
361 1245970 : }
362 :
363 : void
364 18933249 : ExpandVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
365 : {
366 18933249 : NodeId old_expect = expr->get_node_id ();
367 18933249 : std::swap (macro_invoc_expect_id, old_expect);
368 :
369 18933249 : expander.push_context (MacroExpander::ContextType::EXPR);
370 18933249 : expr->accept_vis (*this);
371 18933249 : expander.pop_context ();
372 :
373 18933249 : std::swap (macro_invoc_expect_id, old_expect);
374 :
375 18933249 : auto final_fragment = expander.take_expanded_fragment ();
376 18933249 : if (final_fragment.should_expand ()
377 18933249 : && final_fragment.is_expression_fragment ())
378 50267 : expr = final_fragment.take_expression_fragment ();
379 18933249 : }
380 :
381 : void
382 1889483 : ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::Type> &type)
383 : {
384 1889483 : NodeId old_expect = type->get_node_id ();
385 1889483 : std::swap (macro_invoc_expect_id, old_expect);
386 :
387 1889483 : expander.push_context (MacroExpander::ContextType::TYPE);
388 1889483 : type->accept_vis (*this);
389 1889483 : expander.pop_context ();
390 :
391 1889483 : std::swap (macro_invoc_expect_id, old_expect);
392 :
393 1889483 : auto final_fragment = expander.take_expanded_fragment ();
394 1889483 : if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
395 496 : type = final_fragment.take_type_fragment ();
396 1889483 : }
397 :
398 : // HACK: maybe we shouldn't have TypeNoBounds as a base class
399 : void
400 446762 : ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::TypeNoBounds> &type)
401 : {
402 446762 : NodeId old_expect = type->get_node_id ();
403 446762 : std::swap (macro_invoc_expect_id, old_expect);
404 :
405 446762 : expander.push_context (MacroExpander::ContextType::TYPE);
406 446762 : type->accept_vis (*this);
407 446762 : expander.pop_context ();
408 :
409 446762 : std::swap (macro_invoc_expect_id, old_expect);
410 :
411 446762 : auto final_fragment = expander.take_expanded_fragment ();
412 446762 : if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
413 2 : type = std::make_unique<AST::ParenthesisedType> (
414 3 : final_fragment.take_type_fragment (), BUILTINS_LOCATION);
415 446762 : }
416 :
417 : void
418 2545135 : ExpandVisitor::maybe_expand_pattern (std::unique_ptr<AST::Pattern> &pattern)
419 : {
420 2545135 : NodeId old_expect = pattern->get_node_id ();
421 2545135 : std::swap (macro_invoc_expect_id, old_expect);
422 :
423 2545135 : expander.push_context (MacroExpander::ContextType::PATTERN);
424 2545135 : pattern->accept_vis (*this);
425 2545135 : expander.pop_context ();
426 :
427 2545135 : std::swap (macro_invoc_expect_id, old_expect);
428 :
429 2545135 : auto final_fragment = expander.take_expanded_fragment ();
430 2545135 : if (final_fragment.should_expand () && final_fragment.is_pattern_fragment ())
431 1 : pattern = final_fragment.take_pattern_fragment ();
432 2545135 : }
433 :
434 : void
435 24280 : ExpandVisitor::expand_struct_fields (std::vector<AST::StructField> &fields)
436 : {
437 24280 : expand_fields (fields);
438 24280 : }
439 :
440 : void
441 7654 : ExpandVisitor::expand_tuple_fields (std::vector<AST::TupleField> &fields)
442 : {
443 7654 : expand_fields (fields);
444 7654 : }
445 :
446 : // FIXME: This can definitely be refactored with the method above
447 : void
448 459657 : ExpandVisitor::expand_function_params (
449 : std::vector<std::unique_ptr<AST::Param>> ¶ms)
450 : {
451 1282833 : for (auto &p : params)
452 823176 : visit (p);
453 459657 : }
454 :
455 : void
456 495322 : ExpandVisitor::expand_generic_args (AST::GenericArgs &args)
457 : {
458 981685 : for (auto &arg : args.get_generic_args ())
459 : {
460 486363 : switch (arg.get_kind ())
461 : {
462 153683 : case AST::GenericArg::Kind::Type:
463 153683 : maybe_expand_type (arg.get_type_ptr ());
464 153683 : break;
465 323 : case AST::GenericArg::Kind::Const:
466 323 : maybe_expand_expr (arg.get_expression_ptr ());
467 323 : break;
468 : default:
469 : break;
470 : // FIXME: Figure out what to do here if there is ambiguity. Since the
471 : // resolver comes after the expansion, we need to figure out a way to
472 : // strip ambiguous values here
473 : // TODO: ARTHUR: Probably add a `mark_as_strip` method to `GenericArg`
474 : // or something. This would clean up this whole thing
475 : }
476 : }
477 :
478 : // FIXME: Can we have macro invocations in generic type bindings?
479 : // expand binding args - strip sub-types only
480 : // FIXME: ARTHUR: This needs a test! Foo<Item = macro!()>
481 504343 : for (auto &binding : args.get_binding_args ())
482 9021 : maybe_expand_type (binding.get_type_ptr ());
483 495322 : }
484 :
485 : void
486 106688 : ExpandVisitor::expand_qualified_path_type (AST::QualifiedPathType &path_type)
487 : {
488 106688 : maybe_expand_type (path_type.get_type_ptr ());
489 :
490 : // FIXME: ARTHUR: Can we do macro expansion in there? Needs a test!
491 106688 : if (path_type.has_as_clause ())
492 104057 : path_type.get_as_type_path ().accept_vis (*this);
493 106688 : }
494 :
495 : void
496 10459 : ExpandVisitor::expand_closure_params (std::vector<AST::ClosureParam> ¶ms)
497 : {
498 22975 : for (auto ¶m : params)
499 : {
500 12516 : maybe_expand_pattern (param.get_pattern_ptr ());
501 :
502 12516 : if (param.has_type_given ())
503 711 : maybe_expand_type (param.get_type_ptr ());
504 : }
505 10459 : }
506 :
507 : void
508 28088 : ExpandVisitor::expand_where_clause (AST::WhereClause &where_clause)
509 : {
510 66010 : for (auto &item : where_clause.get_items ())
511 37922 : visit (item);
512 28088 : }
513 :
514 : void
515 11133 : ExpandVisitor::visit (AST::Crate &crate)
516 : {
517 11133 : expand_inner_items (crate.items);
518 11133 : }
519 :
520 : void
521 367766 : ExpandVisitor::visit (AST::DelimTokenTree &)
522 367766 : {}
523 :
524 : void
525 1850 : ExpandVisitor::visit (AST::AttrInputMetaItemContainer &)
526 1850 : {}
527 :
528 : void
529 4025150 : ExpandVisitor::visit (AST::IdentifierExpr &ident_expr)
530 4025150 : {}
531 :
532 : void
533 40385 : ExpandVisitor::visit (AST::LifetimeParam &)
534 40385 : {}
535 :
536 : void
537 2840 : ExpandVisitor::visit (AST::ConstGenericParam &)
538 2840 : {}
539 :
540 : void
541 56637 : ExpandVisitor::visit (AST::MacroInvocation ¯o_invoc)
542 : {
543 56637 : if (macro_invoc_expect_id != macro_invoc.get_node_id ())
544 : {
545 0 : rust_internal_error_at (
546 : macro_invoc.get_locus (),
547 : "attempting to expand node with id %d into position with node id %d",
548 0 : (int) macro_invoc.get_node_id (), (int) macro_invoc_expect_id);
549 : }
550 :
551 : // TODO: Can we do the AST fragment replacing here? Probably not, right?
552 107481 : expander.expand_invoc (macro_invoc, macro_invoc.has_semicolon ()
553 : ? AST::InvocKind::Semicoloned
554 : : AST::InvocKind::Expr);
555 56637 : }
556 :
557 : void
558 2499356 : ExpandVisitor::visit (AST::PathInExpression &path)
559 : {
560 2499356 : if (!path.is_lang_item ())
561 5366539 : for (auto &segment : path.get_segments ())
562 5747324 : if (segment.has_generic_args ())
563 16503 : expand_generic_args (segment.get_generic_args ());
564 2499356 : }
565 :
566 : void
567 478821 : ExpandVisitor::visit (AST::TypePathSegmentGeneric &segment)
568 : {
569 478821 : if (segment.has_generic_args ())
570 478819 : expand_generic_args (segment.get_generic_args ());
571 478821 : }
572 :
573 : void
574 17671 : ExpandVisitor::visit (AST::TypePathSegmentFunction &segment)
575 : {
576 17671 : auto &type_path_function = segment.get_type_path_function ();
577 :
578 42234 : for (auto &type : type_path_function.get_params ())
579 24563 : visit (type);
580 :
581 17671 : if (type_path_function.has_return_type ())
582 17074 : maybe_expand_type (type_path_function.get_return_type_ptr ());
583 17671 : }
584 :
585 : void
586 3644 : ExpandVisitor::visit (AST::QualifiedPathInExpression &path)
587 : {
588 3644 : expand_qualified_path_type (path.get_qualified_path_type ());
589 :
590 7288 : for (auto &segment : path.get_segments ())
591 7288 : if (segment.has_generic_args ())
592 0 : expand_generic_args (segment.get_generic_args ());
593 3644 : }
594 :
595 : void
596 103044 : ExpandVisitor::visit (AST::QualifiedPathInType &path)
597 : {
598 103044 : expand_qualified_path_type (path.get_qualified_path_type ());
599 :
600 : // this shouldn't strip any segments, but can strip inside them
601 103044 : for (auto &segment : path.get_segments ())
602 0 : visit (segment);
603 103044 : }
604 :
605 : void
606 6314066 : ExpandVisitor::visit (AST::LiteralExpr &expr)
607 6314066 : {}
608 :
609 : void
610 803752 : ExpandVisitor::visit (AST::AttrInputLiteral &)
611 803752 : {}
612 :
613 : void
614 636 : ExpandVisitor::visit (AST::AttrInputExpr &attr_input)
615 : {
616 636 : maybe_expand_expr (attr_input.get_expr_ptr ());
617 636 : }
618 :
619 : void
620 0 : ExpandVisitor::visit (AST::MetaItemLitExpr &)
621 0 : {}
622 :
623 : void
624 0 : ExpandVisitor::visit (AST::MetaItemPathExpr &)
625 0 : {}
626 :
627 : void
628 997 : ExpandVisitor::visit (AST::StructExprStruct &expr)
629 997 : {}
630 :
631 : void
632 10364 : ExpandVisitor::visit (AST::ClosureExprInner &expr)
633 : {
634 10364 : expand_closure_params (expr.get_params ());
635 :
636 10364 : maybe_expand_expr (expr.get_definition_expr_ptr ());
637 10364 : }
638 :
639 : void
640 612554 : ExpandVisitor::visit (AST::BlockExpr &expr)
641 : {
642 612554 : expand_inner_stmts (expr);
643 :
644 612554 : expand_tail_expr (expr, expander);
645 612554 : if (expr.has_tail_expr ())
646 533588 : maybe_expand_expr (expr.get_tail_expr_ptr ());
647 612554 : }
648 :
649 : void
650 95 : ExpandVisitor::visit (AST::ClosureExprInnerTyped &expr)
651 : {
652 95 : expand_closure_params (expr.get_params ());
653 :
654 95 : maybe_expand_type (expr.get_return_type_ptr ());
655 :
656 95 : visit (expr.get_definition_expr ());
657 95 : }
658 :
659 : void
660 24302 : ExpandVisitor::visit (AST::IfExpr &expr)
661 : {
662 24302 : maybe_expand_expr (expr.get_condition_expr_ptr ());
663 :
664 24302 : visit (expr.get_if_block ());
665 24302 : }
666 :
667 : void
668 39699 : ExpandVisitor::visit (AST::IfExprConseqElse &expr)
669 : {
670 39699 : maybe_expand_expr (expr.get_condition_expr_ptr ());
671 :
672 39699 : visit (expr.get_if_block ());
673 39699 : visit (expr.get_else_block ());
674 39699 : }
675 :
676 : void
677 2169 : ExpandVisitor::visit (AST::IfLetExpr &expr)
678 : {
679 2169 : maybe_expand_expr (expr.get_value_expr_ptr ());
680 :
681 2169 : visit (expr.get_if_block ());
682 2169 : }
683 :
684 : void
685 1074 : ExpandVisitor::visit (AST::IfLetExprConseqElse &expr)
686 : {
687 1074 : maybe_expand_expr (expr.get_value_expr_ptr ());
688 :
689 1074 : visit (expr.get_if_block ());
690 1074 : visit (expr.get_else_block ());
691 1074 : }
692 :
693 : void
694 263552 : ExpandVisitor::visit (AST::TypeParam ¶m)
695 : {
696 340734 : for (auto &bound : param.get_type_param_bounds ())
697 77182 : visit (bound);
698 :
699 263552 : if (param.has_type ())
700 2045 : maybe_expand_type (param.get_type_ptr ());
701 263552 : }
702 :
703 : void
704 39 : ExpandVisitor::visit (AST::LifetimeWhereClauseItem &)
705 39 : {}
706 :
707 : void
708 37883 : ExpandVisitor::visit (AST::TypeBoundWhereClauseItem &item)
709 : {
710 37883 : maybe_expand_type (item.get_type_ptr ());
711 :
712 77512 : for (auto &bound : item.get_type_param_bounds ())
713 39629 : visit (bound);
714 37883 : }
715 :
716 : void
717 11411 : ExpandVisitor::visit (AST::Module &module)
718 : {
719 11411 : expand_inner_items (module.get_items ());
720 11411 : }
721 :
722 : void
723 74 : ExpandVisitor::visit (AST::ExternCrate &crate)
724 74 : {}
725 :
726 : void
727 0 : ExpandVisitor::visit (AST::UseTreeGlob &)
728 0 : {}
729 :
730 : void
731 0 : ExpandVisitor::visit (AST::UseTreeList &)
732 0 : {}
733 :
734 : void
735 0 : ExpandVisitor::visit (AST::UseTreeRebind &)
736 0 : {}
737 :
738 : void
739 25548 : ExpandVisitor::visit (AST::UseDeclaration &use_decl)
740 25548 : {}
741 :
742 : void
743 459657 : ExpandVisitor::visit (AST::Function &function)
744 : {
745 459657 : if (function.has_body ())
746 414841 : visit_inner_using_attrs (
747 414841 : function, function.get_definition ().value ()->get_inner_attrs ());
748 515787 : for (auto ¶m : function.get_generic_params ())
749 56130 : visit (param);
750 :
751 459657 : expand_function_params (function.get_function_params ());
752 :
753 459657 : if (function.has_return_type ())
754 394171 : maybe_expand_type (function.get_return_type_ptr ());
755 :
756 459657 : if (function.has_where_clause ())
757 15125 : expand_where_clause (function.get_where_clause ());
758 :
759 459657 : if (function.has_body ())
760 414841 : visit (*function.get_definition ());
761 459657 : }
762 :
763 : void
764 23775 : ExpandVisitor::visit (AST::StructStruct &struct_item)
765 : {
766 33928 : for (auto &generic : struct_item.get_generic_params ())
767 10153 : visit (generic);
768 :
769 23775 : if (struct_item.has_where_clause ())
770 389 : expand_where_clause (struct_item.get_where_clause ());
771 :
772 23775 : expand_struct_fields (struct_item.get_fields ());
773 23775 : }
774 :
775 : void
776 5583 : ExpandVisitor::visit (AST::TupleStruct &tuple_struct)
777 : {
778 7782 : for (auto &generic : tuple_struct.get_generic_params ())
779 2199 : visit (generic);
780 :
781 5583 : if (tuple_struct.has_where_clause ())
782 35 : expand_where_clause (tuple_struct.get_where_clause ());
783 :
784 5583 : expand_tuple_fields (tuple_struct.get_fields ());
785 5583 : }
786 :
787 : void
788 3145 : ExpandVisitor::visit (AST::EnumItem &item)
789 3145 : {}
790 :
791 : void
792 2071 : ExpandVisitor::visit (AST::EnumItemTuple &item)
793 : {
794 2071 : expand_tuple_fields (item.get_tuple_fields ());
795 2071 : }
796 :
797 : void
798 208 : ExpandVisitor::visit (AST::EnumItemStruct &item)
799 : {
800 208 : expand_struct_fields (item.get_struct_fields ());
801 208 : }
802 :
803 : void
804 792 : ExpandVisitor::visit (AST::EnumItemDiscriminant &item)
805 : {
806 792 : maybe_expand_expr (item.get_expr_ptr ());
807 792 : }
808 :
809 : void
810 297 : ExpandVisitor::visit (AST::Union &union_item)
811 : {
812 526 : for (auto &generic : union_item.get_generic_params ())
813 229 : visit (generic);
814 :
815 297 : expand_struct_fields (union_item.get_variants ());
816 297 : }
817 :
818 : void
819 13826 : ExpandVisitor::visit (AST::Trait &trait)
820 : {
821 17526 : for (auto &generic : trait.get_generic_params ())
822 3700 : visit (generic);
823 :
824 17997 : for (auto &bound : trait.get_type_param_bounds ())
825 4171 : visit (bound);
826 :
827 13826 : if (trait.has_where_clause ())
828 21 : expand_where_clause (trait.get_where_clause ());
829 :
830 13826 : expander.push_context (MacroExpander::ContextType::TRAIT);
831 :
832 13826 : expand_macro_children (MacroExpander::ContextType::TRAIT,
833 : trait.get_trait_items (),
834 : &AST::SingleASTNode::take_assoc_item);
835 :
836 13826 : expander.pop_context ();
837 13826 : }
838 :
839 : void
840 12351 : ExpandVisitor::visit (AST::InherentImpl &impl)
841 : {
842 24702 : visit_inner_attrs (impl);
843 : // just expand sub-stuff - can't actually strip generic params themselves
844 22332 : for (auto &generic : impl.get_generic_params ())
845 9981 : visit (generic);
846 :
847 : // FIXME: Is that correct? How do we test that?
848 12351 : expander.push_context (MacroExpander::ContextType::ITEM);
849 :
850 12351 : maybe_expand_type (impl.get_type_ptr ());
851 :
852 12351 : expander.pop_context ();
853 :
854 12351 : if (impl.has_where_clause ())
855 107 : expand_where_clause (impl.get_where_clause ());
856 :
857 12351 : expand_macro_children (MacroExpander::ContextType::IMPL,
858 : impl.get_impl_items (),
859 : &AST::SingleASTNode::take_assoc_item);
860 12351 : }
861 :
862 : void
863 234968 : ExpandVisitor::visit (AST::TraitImpl &impl)
864 : {
865 469936 : visit_inner_attrs (impl);
866 : // just expand sub-stuff - can't actually strip generic params themselves
867 458074 : for (auto ¶m : impl.get_generic_params ())
868 223106 : visit (param);
869 :
870 : // FIXME: Is that correct? How do we test that?
871 234968 : expander.push_context (MacroExpander::ContextType::ITEM);
872 :
873 234968 : maybe_expand_type (impl.get_type_ptr ());
874 :
875 234968 : expander.pop_context ();
876 :
877 234968 : visit (impl.get_trait_path ());
878 :
879 234968 : if (impl.has_where_clause ())
880 12411 : expand_where_clause (impl.get_where_clause ());
881 :
882 234968 : expand_macro_children (MacroExpander::ContextType::TRAIT_IMPL,
883 : impl.get_impl_items (),
884 : &AST::SingleASTNode::take_assoc_item);
885 234968 : }
886 :
887 : void
888 39 : ExpandVisitor::visit (AST::ExternalTypeItem &item)
889 39 : {}
890 :
891 : void
892 2 : ExpandVisitor::visit (AST::ExternalStaticItem &static_item)
893 : {
894 2 : maybe_expand_type (static_item.get_type_ptr ());
895 2 : }
896 :
897 : void
898 5244 : ExpandVisitor::visit (AST::ExternBlock &block)
899 : {
900 10488 : visit_inner_attrs (block);
901 :
902 5244 : expand_macro_children (MacroExpander::ContextType::EXTERN,
903 : block.get_extern_items (),
904 : &AST::SingleASTNode::take_external_item);
905 5244 : }
906 :
907 : void
908 0 : ExpandVisitor::visit (AST::MacroMatchRepetition &)
909 0 : {}
910 :
911 : void
912 0 : ExpandVisitor::visit (AST::MacroMatcher &)
913 0 : {}
914 :
915 : void
916 28895 : ExpandVisitor::visit (AST::MacroRulesDefinition &rules_def)
917 28895 : {}
918 :
919 : void
920 0 : ExpandVisitor::visit (AST::MetaItemPath &)
921 0 : {}
922 :
923 : void
924 0 : ExpandVisitor::visit (AST::MetaItemSeq &)
925 0 : {}
926 :
927 : void
928 0 : ExpandVisitor::visit (AST::MetaListPaths &)
929 0 : {}
930 :
931 : void
932 0 : ExpandVisitor::visit (AST::MetaListNameValueStr &)
933 0 : {}
934 :
935 : void
936 651 : ExpandVisitor::visit (AST::StructPatternFieldIdent &field)
937 651 : {}
938 :
939 : void
940 18218 : ExpandVisitor::visit (AST::BareFunctionType &type)
941 : {
942 127062 : for (auto ¶m : type.get_function_params ())
943 : {
944 108844 : maybe_expand_type (param.get_type_ptr ());
945 : }
946 :
947 18218 : if (type.has_return_type ())
948 17898 : visit (type.get_return_type ());
949 18218 : }
950 :
951 : void
952 527785 : ExpandVisitor::visit (AST::FunctionParam ¶m)
953 : {
954 527785 : maybe_expand_pattern (param.get_pattern_ptr ());
955 527785 : maybe_expand_type (param.get_type_ptr ());
956 527785 : }
957 :
958 : void
959 1859 : ExpandVisitor::visit (AST::VariadicParam ¶m)
960 : {
961 1859 : if (param.has_pattern ())
962 22 : maybe_expand_pattern (param.get_pattern_ptr ());
963 1859 : }
964 :
965 : void
966 293532 : ExpandVisitor::visit (AST::SelfParam ¶m)
967 : {
968 : /* TODO: maybe check for invariants being violated - e.g. both type and
969 : * lifetime? */
970 293532 : if (param.has_type ())
971 457 : maybe_expand_type (param.get_type_ptr ());
972 293532 : }
973 :
974 : template <typename T>
975 : void
976 0 : ExpandVisitor::expand_inner_attribute (T &item, AST::SimplePath &path)
977 : {
978 : // FIXME: Retrieve path from segments + local use statements instead of string
979 0 : expander.expand_attribute_proc_macro (item, path);
980 0 : }
981 :
982 : template <typename T>
983 : void
984 667404 : ExpandVisitor::visit_inner_using_attrs (T &item,
985 : std::vector<AST::Attribute> &attrs)
986 : {
987 667474 : for (auto it = attrs.begin (); it != attrs.end (); /* erase => No increment*/)
988 : {
989 35 : auto current = *it;
990 :
991 35 : if (!is_builtin (current) && !current.is_derive ())
992 : {
993 0 : it = attrs.erase (it);
994 0 : expand_inner_attribute (item, current.get_path ());
995 : }
996 : else
997 : {
998 35 : it++;
999 : }
1000 : }
1001 667404 : }
1002 :
1003 : template <typename T>
1004 : void
1005 5244 : ExpandVisitor::visit_inner_attrs (T &item)
1006 : {
1007 252563 : visit_inner_using_attrs (item, item.get_inner_attrs ());
1008 : }
1009 :
1010 : } // namespace Rust
|