Branch data Line data Source code
1 : : // Copyright (C) 2020-2025 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-item.h"
22 : : #include "rust-proc-macro.h"
23 : : #include "rust-attributes.h"
24 : : #include "rust-ast.h"
25 : : #include "rust-type.h"
26 : : #include "rust-derive.h"
27 : :
28 : : namespace Rust {
29 : :
30 : : bool
31 : 1253057 : is_builtin (AST::Attribute &attr)
32 : : {
33 : 1253057 : auto &segments = attr.get_path ().get_segments ();
34 : 1253057 : return !segments.empty ()
35 : 1253057 : && !Analysis::BuiltinAttributeMappings::get ()
36 : 1253057 : ->lookup_builtin (segments[0].get_segment_name ())
37 : 1253057 : .is_error ();
38 : : }
39 : :
40 : : /* Expand all of the macro invocations currently contained in a crate */
41 : : void
42 : 10288 : ExpandVisitor::go (AST::Crate &crate)
43 : : {
44 : 10288 : visit (crate);
45 : 10288 : }
46 : :
47 : : static std::vector<std::unique_ptr<AST::Item>>
48 : 1046 : builtin_derive_item (AST::Item &item, const AST::Attribute &derive,
49 : : BuiltinMacro to_derive)
50 : : {
51 : 0 : return AST::DeriveVisitor::derive (item, derive, to_derive);
52 : : }
53 : :
54 : : static std::vector<std::unique_ptr<AST::Item>>
55 : 0 : derive_item (AST::Item &item, AST::SimplePath &to_derive,
56 : : MacroExpander &expander)
57 : : {
58 : 0 : std::vector<std::unique_ptr<AST::Item>> result;
59 : 0 : auto frag = expander.expand_derive_proc_macro (item, to_derive);
60 : 0 : if (!frag.is_error ())
61 : : {
62 : 0 : for (auto &node : frag.get_nodes ())
63 : : {
64 : 0 : switch (node.get_kind ())
65 : : {
66 : 0 : case AST::SingleASTNode::Kind::Item:
67 : 0 : result.push_back (node.take_item ());
68 : 0 : break;
69 : 0 : default:
70 : 0 : rust_unreachable ();
71 : : }
72 : : }
73 : : }
74 : 0 : return result;
75 : 0 : }
76 : :
77 : : static std::vector<std::unique_ptr<AST::Item>>
78 : 0 : expand_item_attribute (AST::Item &item, AST::SimplePath &name,
79 : : MacroExpander &expander)
80 : : {
81 : 0 : std::vector<std::unique_ptr<AST::Item>> result;
82 : 0 : auto frag = expander.expand_attribute_proc_macro (item, name);
83 : 0 : if (!frag.is_error ())
84 : : {
85 : 0 : for (auto &node : frag.get_nodes ())
86 : : {
87 : 0 : switch (node.get_kind ())
88 : : {
89 : 0 : case AST::SingleASTNode::Kind::Item:
90 : 0 : result.push_back (node.take_item ());
91 : 0 : break;
92 : 0 : default:
93 : 0 : rust_unreachable ();
94 : : }
95 : : }
96 : : }
97 : 0 : return result;
98 : 0 : }
99 : :
100 : : /* Helper function to expand a given attribute on a statement and collect back
101 : : * statements.
102 : : * T should be anything that can be used as a statement accepting outer
103 : : * attributes.
104 : : */
105 : : template <typename T>
106 : : static std::vector<std::unique_ptr<AST::Stmt>>
107 : 1 : expand_stmt_attribute (T &statement, AST::SimplePath &attribute,
108 : : MacroExpander &expander)
109 : : {
110 : 1 : std::vector<std::unique_ptr<AST::Stmt>> result;
111 : 1 : auto frag = expander.expand_attribute_proc_macro (statement, attribute);
112 : 1 : if (!frag.is_error ())
113 : : {
114 : 0 : for (auto &node : frag.get_nodes ())
115 : : {
116 : 0 : switch (node.get_kind ())
117 : : {
118 : 0 : case AST::SingleASTNode::Kind::Stmt:
119 : 0 : result.push_back (node.take_stmt ());
120 : : break;
121 : 0 : default:
122 : 0 : rust_unreachable ();
123 : : }
124 : : }
125 : : }
126 : 1 : return result;
127 : 1 : }
128 : :
129 : : void
130 : 608947 : expand_tail_expr (AST::BlockExpr &block_expr, MacroExpander &expander)
131 : : {
132 : 608947 : if (block_expr.has_tail_expr ())
133 : : {
134 : 532171 : auto tail = block_expr.take_tail_expr ();
135 : 532171 : auto attrs = tail->get_outer_attrs ();
136 : 532171 : bool changed = false;
137 : 534738 : for (auto it = attrs.begin (); it != attrs.end ();)
138 : : {
139 : 2567 : auto current = *it;
140 : 2567 : if (is_builtin (current))
141 : : {
142 : 2567 : it++;
143 : : }
144 : : else
145 : : {
146 : 0 : it = attrs.erase (it);
147 : 0 : changed = true;
148 : 0 : auto new_stmts
149 : : = expand_stmt_attribute (block_expr, current.get_path (),
150 : 0 : expander);
151 : 0 : auto &stmts = block_expr.get_statements ();
152 : 0 : std::move (new_stmts.begin (), new_stmts.end (),
153 : : std::inserter (stmts, stmts.end ()));
154 : 0 : }
155 : 2567 : }
156 : 532171 : if (changed)
157 : 0 : block_expr.normalize_tail_expr ();
158 : : else
159 : 532171 : block_expr.set_tail_expr (std::move (tail));
160 : 532171 : }
161 : 608947 : }
162 : :
163 : : void
164 : 21726 : ExpandVisitor::expand_inner_items (
165 : : std::vector<std::unique_ptr<AST::Item>> &items)
166 : : {
167 : 21726 : expander.push_context (MacroExpander::ContextType::ITEM);
168 : :
169 : 458337 : for (auto it = items.begin (); it != items.end (); it++)
170 : : {
171 : 436611 : Rust::AST::Item &item = **it;
172 : 436611 : if (item.has_outer_attrs ())
173 : : {
174 : 296757 : auto &attrs = item.get_outer_attrs ();
175 : :
176 : 1533273 : for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
177 : : /* erase => No increment*/)
178 : : {
179 : 1236516 : auto current = *attr_it;
180 : :
181 : 1236516 : if (current.is_derive ())
182 : : {
183 : 392 : current.parse_attr_to_meta_item ();
184 : 392 : attr_it = attrs.erase (attr_it);
185 : : // Get traits to derive in the current attribute
186 : 392 : auto traits_to_derive = current.get_traits_to_derive ();
187 : 1438 : for (auto &to_derive : traits_to_derive)
188 : : {
189 : 1046 : auto maybe_builtin = MacroBuiltin::builtins.lookup (
190 : 1046 : to_derive.get ().as_string ());
191 : 1046 : if (maybe_builtin.has_value ())
192 : : {
193 : 1046 : auto new_items
194 : : = builtin_derive_item (item, current,
195 : 1046 : maybe_builtin.value ());
196 : :
197 : 2401 : for (auto &&new_item : new_items)
198 : 1355 : it = items.insert (it, std::move (new_item));
199 : 1046 : }
200 : : else
201 : : {
202 : : // Macro is not a builtin, so it must be a
203 : : // user-defined derive macro.
204 : 0 : auto new_items
205 : 0 : = derive_item (item, to_derive, expander);
206 : 0 : std::move (new_items.begin (), new_items.end (),
207 : : std::inserter (items, it));
208 : 0 : }
209 : : }
210 : 392 : }
211 : : else /* Attribute */
212 : : {
213 : 1236124 : if (is_builtin (current))
214 : : {
215 : 1236124 : attr_it++;
216 : : }
217 : : else
218 : : {
219 : 0 : attr_it = attrs.erase (attr_it);
220 : 0 : auto new_items
221 : : = expand_item_attribute (item, current.get_path (),
222 : 0 : expander);
223 : 0 : it = items.erase (it);
224 : 0 : std::move (new_items.begin (), new_items.end (),
225 : : std::inserter (items, it));
226 : : // TODO: Improve this ?
227 : : // item is invalid since it refers to now deleted,
228 : : // cancel the loop increment and break.
229 : 0 : it--;
230 : 0 : break;
231 : 0 : }
232 : : }
233 : 1236516 : }
234 : : }
235 : : }
236 : :
237 : 21726 : expand_macro_children (items, &AST::SingleASTNode::take_item);
238 : :
239 : 21726 : expander.pop_context ();
240 : 21726 : }
241 : :
242 : : void
243 : 608947 : ExpandVisitor::expand_inner_stmts (AST::BlockExpr &expr)
244 : : {
245 : 608947 : auto &stmts = expr.get_statements ();
246 : 608947 : expander.push_context (MacroExpander::ContextType::STMT);
247 : :
248 : 954819 : for (auto it = stmts.begin (); it != stmts.end (); it++)
249 : : {
250 : 345872 : auto &stmt = *it;
251 : :
252 : : // skip all non-item statements
253 : 345872 : if (stmt->get_stmt_kind () != AST::Stmt::Kind::Item)
254 : 301493 : continue;
255 : :
256 : 44379 : auto &item = static_cast<AST::Item &> (*stmt.get ());
257 : :
258 : 44379 : if (item.has_outer_attrs ())
259 : : {
260 : 13561 : auto &attrs = item.get_outer_attrs ();
261 : :
262 : 27891 : for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
263 : : /* erase => No increment*/)
264 : : {
265 : 14331 : auto current = *attr_it;
266 : :
267 : 14331 : if (current.is_derive ())
268 : : {
269 : 0 : attr_it = attrs.erase (attr_it);
270 : : // Get traits to derive in the current attribute
271 : 0 : auto traits_to_derive = current.get_traits_to_derive ();
272 : 0 : for (auto &to_derive : traits_to_derive)
273 : : {
274 : 0 : auto maybe_builtin = MacroBuiltin::builtins.lookup (
275 : 0 : to_derive.get ().as_string ());
276 : 0 : if (maybe_builtin.has_value ())
277 : : {
278 : 0 : auto new_items
279 : : = builtin_derive_item (item, current,
280 : 0 : maybe_builtin.value ());
281 : :
282 : : // this inserts the derive *before* the item - is it a
283 : : // problem?
284 : 0 : for (auto &&new_item : new_items)
285 : 0 : it = stmts.insert (it, std::move (new_item));
286 : 0 : }
287 : : else
288 : : {
289 : 0 : auto new_items
290 : 0 : = derive_item (item, to_derive, expander);
291 : 0 : std::move (new_items.begin (), new_items.end (),
292 : : std::inserter (stmts, it));
293 : 0 : }
294 : : }
295 : 0 : }
296 : : else /* Attribute */
297 : : {
298 : 14331 : if (is_builtin (current))
299 : : {
300 : 14330 : attr_it++;
301 : : }
302 : : else
303 : : {
304 : 1 : attr_it = attrs.erase (attr_it);
305 : 1 : auto new_items
306 : : = expand_stmt_attribute (item, current.get_path (),
307 : 1 : expander);
308 : 1 : it = stmts.erase (it);
309 : 1 : std::move (new_items.begin (), new_items.end (),
310 : : std::inserter (stmts, it));
311 : : // TODO: Improve this ?
312 : : // item is invalid since it refers to now deleted,
313 : : // cancel the loop increment and break.
314 : 1 : it--;
315 : 1 : break;
316 : 1 : }
317 : : }
318 : 14331 : }
319 : : }
320 : : }
321 : :
322 : 608947 : if (!expr.has_tail_expr ())
323 : 76861 : expr.normalize_tail_expr ();
324 : :
325 : 608947 : expand_macro_children (stmts, &AST::SingleASTNode::take_stmt);
326 : :
327 : 608947 : expander.pop_context ();
328 : 608947 : }
329 : :
330 : : void
331 : 16892932 : ExpandVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
332 : : {
333 : 16892932 : NodeId old_expect = expr->get_node_id ();
334 : 16892932 : std::swap (macro_invoc_expect_id, old_expect);
335 : :
336 : 16892932 : expander.push_context (MacroExpander::ContextType::EXPR);
337 : 16892932 : expr->accept_vis (*this);
338 : 16892932 : expander.pop_context ();
339 : :
340 : 16892932 : std::swap (macro_invoc_expect_id, old_expect);
341 : :
342 : 16892932 : auto final_fragment = expander.take_expanded_fragment ();
343 : 16892932 : if (final_fragment.should_expand ()
344 : 16892932 : && final_fragment.is_expression_fragment ())
345 : 49659 : expr = final_fragment.take_expression_fragment ();
346 : 16892932 : }
347 : :
348 : : void
349 : 1886096 : ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::Type> &type)
350 : : {
351 : 1886096 : NodeId old_expect = type->get_node_id ();
352 : 1886096 : std::swap (macro_invoc_expect_id, old_expect);
353 : :
354 : 1886096 : expander.push_context (MacroExpander::ContextType::TYPE);
355 : 1886096 : type->accept_vis (*this);
356 : 1886096 : expander.pop_context ();
357 : :
358 : 1886096 : std::swap (macro_invoc_expect_id, old_expect);
359 : :
360 : 1886096 : auto final_fragment = expander.take_expanded_fragment ();
361 : 1886096 : if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
362 : 496 : type = final_fragment.take_type_fragment ();
363 : 1886096 : }
364 : :
365 : : // HACK: maybe we shouldn't have TypeNoBounds as a base class
366 : : void
367 : 445569 : ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::TypeNoBounds> &type)
368 : : {
369 : 445569 : NodeId old_expect = type->get_node_id ();
370 : 445569 : std::swap (macro_invoc_expect_id, old_expect);
371 : :
372 : 445569 : expander.push_context (MacroExpander::ContextType::TYPE);
373 : 445569 : type->accept_vis (*this);
374 : 445569 : expander.pop_context ();
375 : :
376 : 445569 : std::swap (macro_invoc_expect_id, old_expect);
377 : :
378 : 445569 : auto final_fragment = expander.take_expanded_fragment ();
379 : 445569 : if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
380 : 2 : type = std::make_unique<AST::ParenthesisedType> (
381 : 3 : final_fragment.take_type_fragment (), BUILTINS_LOCATION);
382 : 445569 : }
383 : :
384 : : void
385 : 2542741 : ExpandVisitor::maybe_expand_pattern (std::unique_ptr<AST::Pattern> &pattern)
386 : : {
387 : 2542741 : NodeId old_expect = pattern->get_node_id ();
388 : 2542741 : std::swap (macro_invoc_expect_id, old_expect);
389 : :
390 : 2542741 : expander.push_context (MacroExpander::ContextType::PATTERN);
391 : 2542741 : pattern->accept_vis (*this);
392 : 2542741 : expander.pop_context ();
393 : :
394 : 2542741 : std::swap (macro_invoc_expect_id, old_expect);
395 : :
396 : 2542741 : auto final_fragment = expander.take_expanded_fragment ();
397 : 2542741 : if (final_fragment.should_expand () && final_fragment.is_pattern_fragment ())
398 : 1 : pattern = final_fragment.take_pattern_fragment ();
399 : 2542741 : }
400 : :
401 : : // FIXME: Can this be refactored into a `scoped` method? Which takes a
402 : : // ContextType as parameter and a lambda? And maybe just an std::vector<T>&?
403 : : void
404 : 23955 : ExpandVisitor::expand_struct_fields (std::vector<AST::StructField> &fields)
405 : : {
406 : 42478 : for (auto &field : fields)
407 : : {
408 : 18523 : maybe_expand_type (field.get_field_type_ptr ());
409 : : }
410 : 23955 : }
411 : :
412 : : void
413 : 7593 : ExpandVisitor::expand_tuple_fields (std::vector<AST::TupleField> &fields)
414 : : {
415 : 29061 : for (auto &field : fields)
416 : 21468 : maybe_expand_type (field.get_field_type_ptr ());
417 : 7593 : }
418 : :
419 : : // FIXME: This can definitely be refactored with the method above
420 : : void
421 : 457516 : ExpandVisitor::expand_function_params (
422 : : std::vector<std::unique_ptr<AST::Param>> ¶ms)
423 : : {
424 : 1279436 : for (auto &p : params)
425 : 821920 : visit (p);
426 : 457516 : }
427 : :
428 : : void
429 : 495055 : ExpandVisitor::expand_generic_args (AST::GenericArgs &args)
430 : : {
431 : 981166 : for (auto &arg : args.get_generic_args ())
432 : : {
433 : 486111 : switch (arg.get_kind ())
434 : : {
435 : 153841 : case AST::GenericArg::Kind::Type:
436 : 153841 : maybe_expand_type (arg.get_type_ptr ());
437 : 153841 : 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 : 504076 : for (auto &binding : args.get_binding_args ())
455 : 9021 : maybe_expand_type (binding.get_type_ptr ());
456 : 495055 : }
457 : :
458 : : void
459 : 106670 : ExpandVisitor::expand_qualified_path_type (AST::QualifiedPathType &path_type)
460 : : {
461 : 106670 : maybe_expand_type (path_type.get_type_ptr ());
462 : :
463 : : // FIXME: ARTHUR: Can we do macro expansion in there? Needs a test!
464 : 106670 : if (path_type.has_as_clause ())
465 : 104039 : path_type.get_as_type_path ().accept_vis (*this);
466 : 106670 : }
467 : :
468 : : void
469 : 10459 : ExpandVisitor::expand_closure_params (std::vector<AST::ClosureParam> ¶ms)
470 : : {
471 : 22975 : for (auto ¶m : params)
472 : : {
473 : 12516 : maybe_expand_pattern (param.get_pattern_ptr ());
474 : :
475 : 12516 : if (param.has_type_given ())
476 : 711 : maybe_expand_type (param.get_type_ptr ());
477 : : }
478 : 10459 : }
479 : :
480 : : void
481 : 28084 : ExpandVisitor::expand_where_clause (AST::WhereClause &where_clause)
482 : : {
483 : 66002 : for (auto &item : where_clause.get_items ())
484 : 37918 : visit (item);
485 : 28084 : }
486 : :
487 : : void
488 : 10288 : ExpandVisitor::visit (AST::Crate &crate)
489 : : {
490 : 10288 : expand_inner_items (crate.items);
491 : 10288 : }
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 : 4023838 : ExpandVisitor::visit (AST::IdentifierExpr &ident_expr)
503 : 4023838 : {}
504 : :
505 : : void
506 : 40403 : ExpandVisitor::visit (AST::LifetimeParam &)
507 : 40403 : {}
508 : :
509 : : void
510 : 2819 : ExpandVisitor::visit (AST::ConstGenericParam &)
511 : 2819 : {}
512 : :
513 : : void
514 : 61667 : ExpandVisitor::visit (AST::MacroInvocation ¯o_invoc)
515 : : {
516 : 61667 : 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 : 111845 : expander.expand_invoc (macro_invoc, macro_invoc.has_semicolon ()
526 : : ? AST::InvocKind::Semicoloned
527 : : : AST::InvocKind::Expr);
528 : 61667 : }
529 : :
530 : : void
531 : 2479380 : ExpandVisitor::visit (AST::PathInExpression &path)
532 : : {
533 : 2479380 : if (!path.is_lang_item ())
534 : 5283412 : for (auto &segment : path.get_segments ())
535 : 5621022 : if (segment.has_generic_args ())
536 : 16491 : expand_generic_args (segment.get_generic_args ());
537 : 2479380 : }
538 : :
539 : : void
540 : 478566 : ExpandVisitor::visit (AST::TypePathSegmentGeneric &segment)
541 : : {
542 : 478566 : if (segment.has_generic_args ())
543 : 478564 : expand_generic_args (segment.get_generic_args ());
544 : 478566 : }
545 : :
546 : : void
547 : 17671 : ExpandVisitor::visit (AST::TypePathSegmentFunction &segment)
548 : : {
549 : 17671 : auto &type_path_function = segment.get_type_path_function ();
550 : :
551 : 42234 : for (auto &type : type_path_function.get_params ())
552 : 24563 : visit (type);
553 : :
554 : 17671 : if (type_path_function.has_return_type ())
555 : 17074 : maybe_expand_type (type_path_function.get_return_type_ptr ());
556 : 17671 : }
557 : :
558 : : void
559 : 3640 : ExpandVisitor::visit (AST::QualifiedPathInExpression &path)
560 : : {
561 : 3640 : expand_qualified_path_type (path.get_qualified_path_type ());
562 : :
563 : 7280 : for (auto &segment : path.get_segments ())
564 : 7280 : if (segment.has_generic_args ())
565 : 0 : expand_generic_args (segment.get_generic_args ());
566 : 3640 : }
567 : :
568 : : void
569 : 103030 : ExpandVisitor::visit (AST::QualifiedPathInType &path)
570 : : {
571 : 103030 : expand_qualified_path_type (path.get_qualified_path_type ());
572 : :
573 : : // this shouldn't strip any segments, but can strip inside them
574 : 103030 : for (auto &segment : path.get_segments ())
575 : 0 : visit (segment);
576 : 103030 : }
577 : :
578 : : void
579 : 6309163 : ExpandVisitor::visit (AST::LiteralExpr &expr)
580 : 6309163 : {}
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 : 1192664 : ExpandVisitor::visit (AST::ArithmeticOrLogicalExpr &expr)
602 : : {
603 : 1192664 : maybe_expand_expr (expr.get_left_expr_ptr ());
604 : 1192664 : maybe_expand_expr (expr.get_right_expr_ptr ());
605 : 1192664 : }
606 : :
607 : : void
608 : 91729 : ExpandVisitor::visit (AST::ComparisonExpr &expr)
609 : : {
610 : 91729 : maybe_expand_expr (expr.get_left_expr_ptr ());
611 : 91729 : maybe_expand_expr (expr.get_right_expr_ptr ());
612 : 91729 : }
613 : :
614 : : void
615 : 25243 : ExpandVisitor::visit (AST::LazyBooleanExpr &expr)
616 : : {
617 : 25243 : maybe_expand_expr (expr.get_left_expr_ptr ());
618 : 25243 : maybe_expand_expr (expr.get_right_expr_ptr ());
619 : 25243 : }
620 : :
621 : : void
622 : 127841 : ExpandVisitor::visit (AST::TypeCastExpr &expr)
623 : : {
624 : 127841 : maybe_expand_expr (expr.get_casted_expr_ptr ());
625 : 127841 : maybe_expand_type (expr.get_type_to_cast_to_ptr ());
626 : 127841 : }
627 : :
628 : : void
629 : 39383 : ExpandVisitor::visit (AST::AssignmentExpr &expr)
630 : : {
631 : 39383 : maybe_expand_expr (expr.get_left_expr_ptr ());
632 : 39383 : maybe_expand_expr (expr.get_right_expr_ptr ());
633 : 39383 : }
634 : :
635 : : void
636 : 28987 : ExpandVisitor::visit (AST::CompoundAssignmentExpr &expr)
637 : : {
638 : 28987 : maybe_expand_expr (expr.get_left_expr_ptr ());
639 : 28987 : maybe_expand_expr (expr.get_right_expr_ptr ());
640 : 28987 : }
641 : :
642 : : void
643 : 211515 : ExpandVisitor::visit (AST::GroupedExpr &expr)
644 : : {
645 : 211515 : maybe_expand_expr (expr.get_expr_in_parens_ptr ());
646 : 211515 : }
647 : :
648 : : void
649 : 990 : ExpandVisitor::visit (AST::StructExprStruct &expr)
650 : 990 : {}
651 : :
652 : : void
653 : 2020278 : ExpandVisitor::visit (AST::CallExpr &expr)
654 : : {
655 : 2020278 : visit (expr.get_function_expr ());
656 : :
657 : 7332134 : for (auto ¶m : expr.get_params ())
658 : 5311856 : maybe_expand_expr (param);
659 : 2020278 : }
660 : :
661 : : void
662 : 10364 : ExpandVisitor::visit (AST::ClosureExprInner &expr)
663 : : {
664 : 10364 : expand_closure_params (expr.get_params ());
665 : :
666 : 10364 : maybe_expand_expr (expr.get_definition_expr_ptr ());
667 : 10364 : }
668 : :
669 : : void
670 : 608947 : ExpandVisitor::visit (AST::BlockExpr &expr)
671 : : {
672 : 608947 : expand_inner_stmts (expr);
673 : :
674 : 608947 : expand_tail_expr (expr, expander);
675 : 608947 : if (expr.has_tail_expr ())
676 : 532171 : maybe_expand_expr (expr.get_tail_expr_ptr ());
677 : 608947 : }
678 : :
679 : : void
680 : 95 : ExpandVisitor::visit (AST::ClosureExprInnerTyped &expr)
681 : : {
682 : 95 : expand_closure_params (expr.get_params ());
683 : :
684 : 95 : maybe_expand_type (expr.get_return_type_ptr ());
685 : :
686 : 95 : visit (expr.get_definition_expr ());
687 : 95 : }
688 : :
689 : : void
690 : 512 : ExpandVisitor::visit (AST::ContinueExpr &expr)
691 : 512 : {}
692 : :
693 : : void
694 : 22734 : ExpandVisitor::visit (AST::IfExpr &expr)
695 : : {
696 : 22734 : maybe_expand_expr (expr.get_condition_expr_ptr ());
697 : :
698 : 22734 : visit (expr.get_if_block ());
699 : 22734 : }
700 : :
701 : : void
702 : 39583 : ExpandVisitor::visit (AST::IfExprConseqElse &expr)
703 : : {
704 : 39583 : maybe_expand_expr (expr.get_condition_expr_ptr ());
705 : :
706 : 39583 : visit (expr.get_if_block ());
707 : 39583 : visit (expr.get_else_block ());
708 : 39583 : }
709 : :
710 : : void
711 : 2169 : ExpandVisitor::visit (AST::IfLetExpr &expr)
712 : : {
713 : 2169 : maybe_expand_expr (expr.get_value_expr_ptr ());
714 : :
715 : 2169 : visit (expr.get_if_block ());
716 : 2169 : }
717 : :
718 : : void
719 : 1074 : ExpandVisitor::visit (AST::IfLetExprConseqElse &expr)
720 : : {
721 : 1074 : maybe_expand_expr (expr.get_value_expr_ptr ());
722 : :
723 : 1074 : visit (expr.get_if_block ());
724 : 1074 : visit (expr.get_else_block ());
725 : 1074 : }
726 : :
727 : : void
728 : 139152 : ExpandVisitor::visit (AST::TupleExpr &expr)
729 : : {
730 : 398206 : for (auto &sub : expr.get_tuple_elems ())
731 : 259054 : maybe_expand_expr (sub);
732 : 139152 : }
733 : :
734 : : void
735 : 262988 : ExpandVisitor::visit (AST::TypeParam ¶m)
736 : : {
737 : 340134 : for (auto &bound : param.get_type_param_bounds ())
738 : 77146 : visit (bound);
739 : :
740 : 262988 : if (param.has_type ())
741 : 2043 : maybe_expand_type (param.get_type_ptr ());
742 : 262988 : }
743 : :
744 : : void
745 : 39 : ExpandVisitor::visit (AST::LifetimeWhereClauseItem &)
746 : 39 : {}
747 : :
748 : : void
749 : 37879 : ExpandVisitor::visit (AST::TypeBoundWhereClauseItem &item)
750 : : {
751 : 37879 : maybe_expand_type (item.get_type_ptr ());
752 : :
753 : 77504 : for (auto &bound : item.get_type_param_bounds ())
754 : 39625 : visit (bound);
755 : 37879 : }
756 : :
757 : : void
758 : 11438 : ExpandVisitor::visit (AST::Module &module)
759 : : {
760 : 11438 : expand_inner_items (module.get_items ());
761 : 11438 : }
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 : 25431 : ExpandVisitor::visit (AST::UseDeclaration &use_decl)
781 : 25431 : {}
782 : :
783 : : void
784 : 457516 : ExpandVisitor::visit (AST::Function &function)
785 : : {
786 : 457516 : if (function.has_body ())
787 : 413547 : visit_inner_using_attrs (
788 : 413547 : function, function.get_definition ().value ()->get_inner_attrs ());
789 : 513243 : for (auto ¶m : function.get_generic_params ())
790 : 55727 : visit (param);
791 : :
792 : 457516 : expand_function_params (function.get_function_params ());
793 : :
794 : 457516 : if (function.has_return_type ())
795 : 392668 : maybe_expand_type (function.get_return_type_ptr ());
796 : :
797 : 457516 : if (function.has_where_clause ())
798 : 15123 : expand_where_clause (function.get_where_clause ());
799 : :
800 : 457516 : if (function.has_body ())
801 : 413547 : visit (*function.get_definition ());
802 : 457516 : }
803 : :
804 : : void
805 : 23466 : ExpandVisitor::visit (AST::StructStruct &struct_item)
806 : : {
807 : 33589 : for (auto &generic : struct_item.get_generic_params ())
808 : 10123 : visit (generic);
809 : :
810 : 23466 : if (struct_item.has_where_clause ())
811 : 389 : expand_where_clause (struct_item.get_where_clause ());
812 : :
813 : 23466 : expand_struct_fields (struct_item.get_fields ());
814 : 23466 : }
815 : :
816 : : void
817 : 5540 : ExpandVisitor::visit (AST::TupleStruct &tuple_struct)
818 : : {
819 : 7728 : for (auto &generic : tuple_struct.get_generic_params ())
820 : 2188 : visit (generic);
821 : :
822 : 5540 : if (tuple_struct.has_where_clause ())
823 : 35 : expand_where_clause (tuple_struct.get_where_clause ());
824 : :
825 : 5540 : expand_tuple_fields (tuple_struct.get_fields ());
826 : 5540 : }
827 : :
828 : : void
829 : 3085 : ExpandVisitor::visit (AST::EnumItem &item)
830 : 3085 : {}
831 : :
832 : : void
833 : 2053 : ExpandVisitor::visit (AST::EnumItemTuple &item)
834 : : {
835 : 2053 : expand_tuple_fields (item.get_tuple_fields ());
836 : 2053 : }
837 : :
838 : : void
839 : 202 : ExpandVisitor::visit (AST::EnumItemStruct &item)
840 : : {
841 : 202 : expand_struct_fields (item.get_struct_fields ());
842 : 202 : }
843 : :
844 : : void
845 : 780 : ExpandVisitor::visit (AST::EnumItemDiscriminant &item)
846 : : {
847 : 780 : maybe_expand_expr (item.get_expr_ptr ());
848 : 780 : }
849 : :
850 : : void
851 : 287 : ExpandVisitor::visit (AST::Union &union_item)
852 : : {
853 : 514 : for (auto &generic : union_item.get_generic_params ())
854 : 227 : visit (generic);
855 : :
856 : 287 : expand_struct_fields (union_item.get_variants ());
857 : 287 : }
858 : :
859 : : void
860 : 25571 : ExpandVisitor::visit (AST::ConstantItem &const_item)
861 : : {
862 : 25571 : maybe_expand_type (const_item.get_type_ptr ());
863 : :
864 : 25571 : if (const_item.has_expr ())
865 : 24837 : maybe_expand_expr (const_item.get_expr_ptr ());
866 : 25571 : }
867 : :
868 : : void
869 : 1332 : ExpandVisitor::visit (AST::StaticItem &static_item)
870 : : {
871 : 1332 : maybe_expand_type (static_item.get_type_ptr ());
872 : :
873 : 1332 : maybe_expand_expr (static_item.get_expr_ptr ());
874 : 1332 : }
875 : :
876 : : void
877 : 13231 : ExpandVisitor::visit (AST::Trait &trait)
878 : : {
879 : 16937 : for (auto &generic : trait.get_generic_params ())
880 : 3706 : visit (generic);
881 : :
882 : 17388 : for (auto &bound : trait.get_type_param_bounds ())
883 : 4157 : visit (bound);
884 : :
885 : 13231 : if (trait.has_where_clause ())
886 : 21 : expand_where_clause (trait.get_where_clause ());
887 : :
888 : 13231 : expander.push_context (MacroExpander::ContextType::TRAIT);
889 : :
890 : 13231 : expand_macro_children (MacroExpander::ContextType::TRAIT,
891 : : trait.get_trait_items (),
892 : : &AST::SingleASTNode::take_assoc_item);
893 : :
894 : 13231 : expander.pop_context ();
895 : 13231 : }
896 : :
897 : : void
898 : 12255 : ExpandVisitor::visit (AST::InherentImpl &impl)
899 : : {
900 : 24510 : visit_inner_attrs (impl);
901 : : // just expand sub-stuff - can't actually strip generic params themselves
902 : 22191 : for (auto &generic : impl.get_generic_params ())
903 : 9936 : visit (generic);
904 : :
905 : : // FIXME: Is that correct? How do we test that?
906 : 12255 : expander.push_context (MacroExpander::ContextType::ITEM);
907 : :
908 : 12255 : maybe_expand_type (impl.get_type_ptr ());
909 : :
910 : 12255 : expander.pop_context ();
911 : :
912 : 12255 : if (impl.has_where_clause ())
913 : 107 : expand_where_clause (impl.get_where_clause ());
914 : :
915 : 12255 : expand_macro_children (MacroExpander::ContextType::IMPL,
916 : : impl.get_impl_items (),
917 : : &AST::SingleASTNode::take_assoc_item);
918 : 12255 : }
919 : :
920 : : void
921 : 234770 : ExpandVisitor::visit (AST::TraitImpl &impl)
922 : : {
923 : 469540 : visit_inner_attrs (impl);
924 : : // just expand sub-stuff - can't actually strip generic params themselves
925 : 457854 : for (auto ¶m : impl.get_generic_params ())
926 : 223084 : visit (param);
927 : :
928 : : // FIXME: Is that correct? How do we test that?
929 : 234770 : expander.push_context (MacroExpander::ContextType::ITEM);
930 : :
931 : 234770 : maybe_expand_type (impl.get_type_ptr ());
932 : :
933 : 234770 : expander.pop_context ();
934 : :
935 : 234770 : visit (impl.get_trait_path ());
936 : :
937 : 234770 : if (impl.has_where_clause ())
938 : 12409 : expand_where_clause (impl.get_where_clause ());
939 : :
940 : 234770 : expand_macro_children (MacroExpander::ContextType::TRAIT_IMPL,
941 : : impl.get_impl_items (),
942 : : &AST::SingleASTNode::take_assoc_item);
943 : 234770 : }
944 : :
945 : : void
946 : 37 : ExpandVisitor::visit (AST::ExternalTypeItem &item)
947 : 37 : {}
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 : 4789 : ExpandVisitor::visit (AST::ExternBlock &block)
957 : : {
958 : 9578 : visit_inner_attrs (block);
959 : :
960 : 4789 : expand_macro_children (MacroExpander::ContextType::EXTERN,
961 : : block.get_extern_items (),
962 : : &AST::SingleASTNode::take_external_item);
963 : 4789 : }
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 : 28855 : ExpandVisitor::visit (AST::MacroRulesDefinition &rules_def)
975 : 28855 : {}
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 : 635 : ExpandVisitor::visit (AST::StructPatternFieldIdent &field)
995 : 635 : {}
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 : 204 : ExpandVisitor::visit (AST::SlicePatternItemsNoRest &items)
1005 : : {
1006 : 367 : for (auto &sub : items.get_patterns ())
1007 : 163 : maybe_expand_pattern (sub);
1008 : 204 : }
1009 : :
1010 : : void
1011 : 228 : ExpandVisitor::visit (AST::SlicePatternItemsHasRest &items)
1012 : : {
1013 : 664 : for (auto &sub : items.get_lower_patterns ())
1014 : 436 : maybe_expand_pattern (sub);
1015 : 314 : for (auto &sub : items.get_upper_patterns ())
1016 : 86 : maybe_expand_pattern (sub);
1017 : 228 : }
1018 : :
1019 : : void
1020 : 1644 : ExpandVisitor::visit (AST::AltPattern &pattern)
1021 : : {
1022 : 5762 : for (auto &alt : pattern.get_alts ())
1023 : 4118 : maybe_expand_pattern (alt);
1024 : 1644 : }
1025 : :
1026 : : void
1027 : 26655 : ExpandVisitor::visit (AST::TupleStructItemsNoRest &tuple_items)
1028 : : {
1029 : 54503 : for (auto &sub : tuple_items.get_patterns ())
1030 : 27848 : maybe_expand_pattern (sub);
1031 : 26655 : }
1032 : :
1033 : : void
1034 : 323 : ExpandVisitor::visit (AST::TupleStructItemsHasRest &tuple_items)
1035 : : {
1036 : 385 : for (auto &sub : tuple_items.get_lower_patterns ())
1037 : 62 : maybe_expand_pattern (sub);
1038 : :
1039 : 361 : for (auto &sub : tuple_items.get_upper_patterns ())
1040 : 38 : maybe_expand_pattern (sub);
1041 : 323 : }
1042 : :
1043 : : void
1044 : 85899 : ExpandVisitor::visit (AST::TuplePatternItemsNoRest &tuple_items)
1045 : : {
1046 : 285443 : for (auto &sub : tuple_items.get_patterns ())
1047 : 199544 : maybe_expand_pattern (sub);
1048 : 85899 : }
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 : 151426 : ExpandVisitor::visit (AST::LetStmt &stmt)
1062 : : {
1063 : 151426 : maybe_expand_pattern (stmt.get_pattern_ptr ());
1064 : :
1065 : 151426 : if (stmt.has_type ())
1066 : 18307 : maybe_expand_type (stmt.get_type_ptr ());
1067 : :
1068 : 151426 : if (stmt.has_init_expr ())
1069 : 145411 : maybe_expand_expr (stmt.get_init_expr_ptr ());
1070 : 151426 : }
1071 : :
1072 : : void
1073 : 149822 : ExpandVisitor::visit (AST::ExprStmt &stmt)
1074 : : {
1075 : 149822 : maybe_expand_expr (stmt.get_expr_ptr ());
1076 : 149822 : }
1077 : :
1078 : : void
1079 : 18212 : ExpandVisitor::visit (AST::BareFunctionType &type)
1080 : : {
1081 : 127048 : for (auto ¶m : type.get_function_params ())
1082 : : {
1083 : 108836 : maybe_expand_type (param.get_type_ptr ());
1084 : : }
1085 : :
1086 : 18212 : if (type.has_return_type ())
1087 : 17898 : visit (type.get_return_type ());
1088 : 18212 : }
1089 : :
1090 : : void
1091 : 526990 : ExpandVisitor::visit (AST::FunctionParam ¶m)
1092 : : {
1093 : 526990 : maybe_expand_pattern (param.get_pattern_ptr ());
1094 : 526990 : maybe_expand_type (param.get_type_ptr ());
1095 : 526990 : }
1096 : :
1097 : : void
1098 : 1749 : ExpandVisitor::visit (AST::VariadicParam ¶m)
1099 : : {
1100 : 1749 : if (param.has_pattern ())
1101 : 22 : maybe_expand_pattern (param.get_pattern_ptr ());
1102 : 1749 : }
1103 : :
1104 : : void
1105 : 293181 : ExpandVisitor::visit (AST::SelfParam ¶m)
1106 : : {
1107 : : /* TODO: maybe check for invariants being violated - e.g. both type and
1108 : : * lifetime? */
1109 : 293181 : if (param.has_type ())
1110 : 457 : maybe_expand_type (param.get_type_ptr ());
1111 : 293181 : }
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 : 665361 : ExpandVisitor::visit_inner_using_attrs (T &item,
1124 : : std::vector<AST::Attribute> &attrs)
1125 : : {
1126 : 665396 : for (auto it = attrs.begin (); it != attrs.end (); /* erase => No increment*/)
1127 : : {
1128 : 35 : auto current = *it;
1129 : :
1130 : 35 : 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 : 35 : it++;
1138 : : }
1139 : : }
1140 : 665361 : }
1141 : :
1142 : : template <typename T>
1143 : : void
1144 : 4789 : ExpandVisitor::visit_inner_attrs (T &item)
1145 : : {
1146 : 251814 : visit_inner_using_attrs (item, item.get_inner_attrs ());
1147 : : }
1148 : :
1149 : : } // namespace Rust
|