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