Require target lra in gcc.dg/pr108095.c
[official-gcc.git] / gcc / rust / expand / rust-attribute-visitor.cc
blob3a94699558d9b8134d4af68131470bd9f973a87b
1 // Copyright (C) 2020-2023 Free Software Foundation, Inc.
3 // This file is part of GCC.
5 // GCC is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation; either version 3, or (at your option) any later
8 // version.
10 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 // for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with GCC; see the file COPYING3. If not see
17 // <http://www.gnu.org/licenses/>.
19 #include "rust-attribute-visitor.h"
20 #include "rust-session-manager.h"
22 namespace Rust {
24 // Visitor used to expand attributes.
25 void
26 AttrVisitor::expand_struct_fields (std::vector<AST::StructField> &fields)
28 for (auto it = fields.begin (); it != fields.end ();)
30 auto &field = *it;
32 auto &field_attrs = field.get_outer_attrs ();
33 expander.expand_cfg_attrs (field_attrs);
34 if (expander.fails_cfg_with_expand (field_attrs))
36 it = fields.erase (it);
37 continue;
40 expander.push_context (MacroExpander::ContextType::TYPE);
42 // expand sub-types of type, but can't strip type itself
43 auto &type = field.get_field_type ();
44 type->accept_vis (*this);
46 maybe_expand_type (type);
48 if (type->is_marked_for_strip ())
49 rust_error_at (type->get_locus (),
50 "cannot strip type in this position");
52 expander.pop_context ();
54 // if nothing else happens, increment
55 ++it;
59 void
60 AttrVisitor::expand_tuple_fields (std::vector<AST::TupleField> &fields)
62 for (auto it = fields.begin (); it != fields.end ();)
64 auto &field = *it;
66 auto &field_attrs = field.get_outer_attrs ();
67 expander.expand_cfg_attrs (field_attrs);
68 if (expander.fails_cfg_with_expand (field_attrs))
70 it = fields.erase (it);
71 continue;
74 // expand sub-types of type, but can't strip type itself
75 auto &type = field.get_field_type ();
76 type->accept_vis (*this);
77 if (type->is_marked_for_strip ())
78 rust_error_at (type->get_locus (),
79 "cannot strip type in this position");
81 // if nothing else happens, increment
82 ++it;
86 void
87 AttrVisitor::expand_function_params (std::vector<AST::FunctionParam> &params)
89 expander.push_context (MacroExpander::ContextType::TYPE);
91 for (auto it = params.begin (); it != params.end ();)
93 auto &param = *it;
95 auto &param_attrs = param.get_outer_attrs ();
96 expander.expand_cfg_attrs (param_attrs);
97 if (expander.fails_cfg_with_expand (param_attrs))
99 it = params.erase (it);
100 continue;
103 // TODO: should an unwanted strip lead to break out of loop?
104 auto &pattern = param.get_pattern ();
105 pattern->accept_vis (*this);
106 if (pattern->is_marked_for_strip ())
107 rust_error_at (pattern->get_locus (),
108 "cannot strip pattern in this position");
110 auto &type = param.get_type ();
111 type->accept_vis (*this);
113 maybe_expand_type (type);
115 if (type->is_marked_for_strip ())
116 rust_error_at (type->get_locus (),
117 "cannot strip type in this position");
119 // increment
120 ++it;
123 expander.pop_context ();
126 void
127 AttrVisitor::expand_generic_args (AST::GenericArgs &args)
129 // lifetime args can't be expanded
130 // FIXME: Can we have macro invocations for lifetimes?
132 expander.push_context (MacroExpander::ContextType::TYPE);
134 // expand type args - strip sub-types only
135 for (auto &arg : args.get_generic_args ())
137 switch (arg.get_kind ())
139 case AST::GenericArg::Kind::Type: {
140 auto &type = arg.get_type ();
141 type->accept_vis (*this);
142 maybe_expand_type (type);
144 if (type->is_marked_for_strip ())
145 rust_error_at (type->get_locus (),
146 "cannot strip type in this position");
147 break;
149 case AST::GenericArg::Kind::Const: {
150 auto &expr = arg.get_expression ();
151 expr->accept_vis (*this);
152 maybe_expand_expr (expr);
154 if (expr->is_marked_for_strip ())
155 rust_error_at (expr->get_locus (),
156 "cannot strip expression in this position");
157 break;
159 default:
160 break;
161 // FIXME: Figure out what to do here if there is ambiguity. Since the
162 // resolver comes after the expansion, we need to figure out a way to
163 // strip ambiguous values here
164 // TODO: Arthur: Probably add a `mark_as_strip` method to `GenericArg`
165 // or something. This would clean up this whole thing
169 expander.pop_context ();
171 // FIXME: Can we have macro invocations in generic type bindings?
172 // expand binding args - strip sub-types only
173 for (auto &binding : args.get_binding_args ())
175 auto &type = binding.get_type ();
176 type->accept_vis (*this);
178 if (type->is_marked_for_strip ())
179 rust_error_at (type->get_locus (),
180 "cannot strip type in this position");
184 void
185 AttrVisitor::expand_qualified_path_type (AST::QualifiedPathType &path_type)
187 expander.push_context (MacroExpander::ContextType::TYPE);
189 auto &type = path_type.get_type ();
190 type->accept_vis (*this);
192 maybe_expand_type (type);
194 expander.pop_context ();
196 if (type->is_marked_for_strip ())
197 rust_error_at (type->get_locus (), "cannot strip type in this position");
199 if (path_type.has_as_clause ())
201 auto &type_path = path_type.get_as_type_path ();
202 visit (type_path);
203 if (type_path.is_marked_for_strip ())
204 rust_error_at (type_path.get_locus (),
205 "cannot strip type path in this position");
209 void
210 AttrVisitor::AttrVisitor::expand_closure_params (
211 std::vector<AST::ClosureParam> &params)
213 for (auto it = params.begin (); it != params.end ();)
215 auto &param = *it;
217 auto &param_attrs = param.get_outer_attrs ();
218 expander.expand_cfg_attrs (param_attrs);
219 if (expander.fails_cfg_with_expand (param_attrs))
221 it = params.erase (it);
222 continue;
225 auto &pattern = param.get_pattern ();
226 pattern->accept_vis (*this);
227 if (pattern->is_marked_for_strip ())
228 rust_error_at (pattern->get_locus (),
229 "cannot strip pattern in this position");
231 if (param.has_type_given ())
233 expander.push_context (MacroExpander::ContextType::TYPE);
234 auto &type = param.get_type ();
235 type->accept_vis (*this);
237 maybe_expand_type (type);
239 if (type->is_marked_for_strip ())
240 rust_error_at (type->get_locus (),
241 "cannot strip type in this position");
243 expander.pop_context ();
246 // increment if found nothing else so far
247 ++it;
251 void
252 AttrVisitor::expand_self_param (AST::SelfParam &self_param)
254 if (self_param.has_type ())
256 expander.push_context (MacroExpander::ContextType::TYPE);
257 auto &type = self_param.get_type ();
258 type->accept_vis (*this);
260 maybe_expand_type (type);
262 if (type->is_marked_for_strip ())
263 rust_error_at (type->get_locus (),
264 "cannot strip type in this position");
266 expander.pop_context ();
268 /* TODO: maybe check for invariants being violated - e.g. both type and
269 * lifetime? */
272 void
273 AttrVisitor::expand_where_clause (AST::WhereClause &where_clause)
275 // items cannot be stripped conceptually, so just accept visitor
276 for (auto &item : where_clause.get_items ())
277 item->accept_vis (*this);
280 void
281 AttrVisitor::expand_trait_function_decl (AST::TraitFunctionDecl &decl)
283 // just expand sub-stuff - can't actually strip generic params themselves
284 for (auto &param : decl.get_generic_params ())
285 param->accept_vis (*this);
287 /* strip function parameters if required - this is specifically
288 * allowed by spec */
289 expand_function_params (decl.get_function_params ());
291 if (decl.has_return_type ())
293 expander.push_context (MacroExpander::ContextType::TYPE);
295 auto &return_type = decl.get_return_type ();
296 return_type->accept_vis (*this);
298 maybe_expand_type (return_type);
300 if (return_type->is_marked_for_strip ())
301 rust_error_at (return_type->get_locus (),
302 "cannot strip type in this position");
304 expander.pop_context ();
307 if (decl.has_where_clause ())
308 expand_where_clause (decl.get_where_clause ());
311 void
312 AttrVisitor::expand_trait_method_decl (AST::TraitMethodDecl &decl)
314 // just expand sub-stuff - can't actually strip generic params themselves
315 for (auto &param : decl.get_generic_params ())
316 param->accept_vis (*this);
318 /* assuming you can't strip self param - wouldn't be a method
319 * anymore. spec allows outer attrs on self param, but doesn't
320 * specify whether cfg is used. */
321 expand_self_param (decl.get_self_param ());
323 /* strip function parameters if required - this is specifically
324 * allowed by spec */
325 expand_function_params (decl.get_function_params ());
327 if (decl.has_return_type ())
329 expander.push_context (MacroExpander::ContextType::TYPE);
331 auto &return_type = decl.get_return_type ();
332 return_type->accept_vis (*this);
334 maybe_expand_type (return_type);
336 if (return_type->is_marked_for_strip ())
337 rust_error_at (return_type->get_locus (),
338 "cannot strip type in this position");
340 expander.pop_context ();
343 if (decl.has_where_clause ())
344 expand_where_clause (decl.get_where_clause ());
347 void
348 AttrVisitor::visit (AST::Token &)
350 // shouldn't require?
352 void
353 AttrVisitor::visit (AST::DelimTokenTree &)
355 // shouldn't require?
357 void
358 AttrVisitor::visit (AST::AttrInputMetaItemContainer &)
360 // shouldn't require?
362 void
363 AttrVisitor::visit (AST::IdentifierExpr &ident_expr)
365 // strip test based on outer attrs
366 expander.expand_cfg_attrs (ident_expr.get_outer_attrs ());
367 if (expander.fails_cfg_with_expand (ident_expr.get_outer_attrs ()))
369 ident_expr.mark_for_strip ();
370 return;
373 void
374 AttrVisitor::visit (AST::Lifetime &)
376 // shouldn't require?
378 void
379 AttrVisitor::visit (AST::LifetimeParam &)
381 // supposedly does not require - cfg does nothing
383 void
384 AttrVisitor::visit (AST::ConstGenericParam &)
386 // likewise
389 void
390 AttrVisitor::visit (AST::MacroInvocation &macro_invoc)
392 // initial strip test based on outer attrs
393 expander.expand_cfg_attrs (macro_invoc.get_outer_attrs ());
394 if (expander.fails_cfg_with_expand (macro_invoc.get_outer_attrs ()))
396 macro_invoc.mark_for_strip ();
397 return;
400 // can't strip simple path
402 // I don't think any macro token trees can be stripped in any way
404 // TODO: maybe have cfg! macro stripping behaviour here?
405 expander.expand_invoc (macro_invoc, macro_invoc.has_semicolon ());
408 void
409 AttrVisitor::visit (AST::PathInExpression &path)
411 // initial strip test based on outer attrs
412 expander.expand_cfg_attrs (path.get_outer_attrs ());
413 if (expander.fails_cfg_with_expand (path.get_outer_attrs ()))
415 path.mark_for_strip ();
416 return;
419 for (auto &segment : path.get_segments ())
421 if (segment.has_generic_args ())
422 expand_generic_args (segment.get_generic_args ());
425 void
426 AttrVisitor::visit (AST::TypePathSegment &)
428 // shouldn't require
430 void
431 AttrVisitor::visit (AST::TypePathSegmentGeneric &segment)
433 // TODO: strip inside generic args
435 if (!segment.has_generic_args ())
436 return;
438 expand_generic_args (segment.get_generic_args ());
440 void
441 AttrVisitor::visit (AST::TypePathSegmentFunction &segment)
443 auto &type_path_function = segment.get_type_path_function ();
445 for (auto &type : type_path_function.get_params ())
447 type->accept_vis (*this);
448 if (type->is_marked_for_strip ())
449 rust_error_at (type->get_locus (),
450 "cannot strip type in this position");
453 if (type_path_function.has_return_type ())
455 expander.push_context (MacroExpander::ContextType::TYPE);
457 auto &return_type = type_path_function.get_return_type ();
458 return_type->accept_vis (*this);
460 maybe_expand_type (return_type);
462 if (return_type->is_marked_for_strip ())
463 rust_error_at (return_type->get_locus (),
464 "cannot strip type in this position");
466 expander.pop_context ();
469 void
470 AttrVisitor::visit (AST::TypePath &path)
472 // this shouldn't strip any segments, but can strip inside them
473 for (auto &segment : path.get_segments ())
474 segment->accept_vis (*this);
476 void
477 AttrVisitor::visit (AST::QualifiedPathInExpression &path)
479 // initial strip test based on outer attrs
480 expander.expand_cfg_attrs (path.get_outer_attrs ());
481 if (expander.fails_cfg_with_expand (path.get_outer_attrs ()))
483 path.mark_for_strip ();
484 return;
487 expand_qualified_path_type (path.get_qualified_path_type ());
489 for (auto &segment : path.get_segments ())
491 if (segment.has_generic_args ())
492 expand_generic_args (segment.get_generic_args ());
495 void
496 AttrVisitor::visit (AST::QualifiedPathInType &path)
498 expand_qualified_path_type (path.get_qualified_path_type ());
500 // this shouldn't strip any segments, but can strip inside them
501 for (auto &segment : path.get_segments ())
502 segment->accept_vis (*this);
505 void
506 AttrVisitor::visit (AST::LiteralExpr &expr)
508 // initial strip test based on outer attrs
509 expander.expand_cfg_attrs (expr.get_outer_attrs ());
510 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
512 expr.mark_for_strip ();
513 return;
516 void
517 AttrVisitor::visit (AST::AttrInputLiteral &)
519 // shouldn't require?
521 void
522 AttrVisitor::visit (AST::MetaItemLitExpr &)
524 // shouldn't require?
526 void
527 AttrVisitor::visit (AST::MetaItemPathLit &)
529 // shouldn't require?
531 void
532 AttrVisitor::visit (AST::BorrowExpr &expr)
534 // initial strip test based on outer attrs
535 expander.expand_cfg_attrs (expr.get_outer_attrs ());
536 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
538 expr.mark_for_strip ();
539 return;
542 /* strip any internal sub-expressions - expression itself isn't
543 * allowed to have external attributes in this position so can't be
544 * stripped. */
545 auto &borrowed_expr = expr.get_borrowed_expr ();
546 borrowed_expr->accept_vis (*this);
547 if (borrowed_expr->is_marked_for_strip ())
548 rust_error_at (borrowed_expr->get_locus (),
549 "cannot strip expression in this position - outer "
550 "attributes not allowed");
552 void
553 AttrVisitor::visit (AST::DereferenceExpr &expr)
555 // initial strip test based on outer attrs
556 expander.expand_cfg_attrs (expr.get_outer_attrs ());
557 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
559 expr.mark_for_strip ();
560 return;
563 /* strip any internal sub-expressions - expression itself isn't
564 * allowed to have external attributes in this position so can't be
565 * stripped. */
566 auto &dereferenced_expr = expr.get_dereferenced_expr ();
567 dereferenced_expr->accept_vis (*this);
568 if (dereferenced_expr->is_marked_for_strip ())
569 rust_error_at (dereferenced_expr->get_locus (),
570 "cannot strip expression in this position - outer "
571 "attributes not allowed");
573 void
574 AttrVisitor::visit (AST::ErrorPropagationExpr &expr)
576 // initial strip test based on outer attrs
577 expander.expand_cfg_attrs (expr.get_outer_attrs ());
578 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
580 expr.mark_for_strip ();
581 return;
584 /* strip any internal sub-expressions - expression itself isn't
585 * allowed to have external attributes in this position so can't be
586 * stripped. */
587 auto &propagating_expr = expr.get_propagating_expr ();
588 propagating_expr->accept_vis (*this);
589 if (propagating_expr->is_marked_for_strip ())
590 rust_error_at (propagating_expr->get_locus (),
591 "cannot strip expression in this position - outer "
592 "attributes not allowed");
594 void
595 AttrVisitor::visit (AST::NegationExpr &expr)
597 // initial strip test based on outer attrs
598 expander.expand_cfg_attrs (expr.get_outer_attrs ());
599 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
601 expr.mark_for_strip ();
602 return;
605 /* strip any internal sub-expressions - expression itself isn't
606 * allowed to have external attributes in this position so can't be
607 * stripped. */
608 auto &negated_expr = expr.get_negated_expr ();
609 negated_expr->accept_vis (*this);
610 if (negated_expr->is_marked_for_strip ())
611 rust_error_at (negated_expr->get_locus (),
612 "cannot strip expression in this position - outer "
613 "attributes not allowed");
615 void
616 AttrVisitor::visit (AST::ArithmeticOrLogicalExpr &expr)
618 /* outer attributes never allowed before these. while cannot strip
619 * two direct descendant expressions, can strip ones below that */
621 /* should have no possibility for outer attrs as would be parsed
622 * with outer expr */
623 auto &l_expr = expr.get_left_expr ();
624 l_expr->accept_vis (*this);
625 maybe_expand_expr (l_expr);
627 /* should syntactically not have outer attributes, though this may
628 * not have worked in practice */
629 auto &r_expr = expr.get_right_expr ();
630 r_expr->accept_vis (*this);
631 maybe_expand_expr (r_expr);
633 // ensure that they are not marked for strip
634 if (expr.get_left_expr ()->is_marked_for_strip ())
635 rust_error_at (expr.get_left_expr ()->get_locus (),
636 "cannot strip expression in this position - outer "
637 "attributes are never allowed "
638 "before binary op exprs");
639 if (expr.get_right_expr ()->is_marked_for_strip ())
640 rust_error_at (expr.get_right_expr ()->get_locus (),
641 "cannot strip expression in this position - outer "
642 "attributes not allowed");
644 void
645 AttrVisitor::visit (AST::ComparisonExpr &expr)
647 /* outer attributes never allowed before these. while cannot strip
648 * two direct descendant expressions, can strip ones below that */
650 /* should have no possibility for outer attrs as would be parsed
651 * with outer expr */
652 auto &l_expr = expr.get_left_expr ();
653 l_expr->accept_vis (*this);
654 maybe_expand_expr (l_expr);
656 /* should syntactically not have outer attributes, though this may
657 * not have worked in practice */
658 auto &r_expr = expr.get_right_expr ();
659 r_expr->accept_vis (*this);
660 maybe_expand_expr (r_expr);
662 // ensure that they are not marked for strip
663 if (expr.get_left_expr ()->is_marked_for_strip ())
664 rust_error_at (expr.get_left_expr ()->get_locus (),
665 "cannot strip expression in this position - outer "
666 "attributes are never allowed "
667 "before binary op exprs");
668 if (expr.get_right_expr ()->is_marked_for_strip ())
669 rust_error_at (expr.get_right_expr ()->get_locus (),
670 "cannot strip expression in this position - outer "
671 "attributes not allowed");
673 void
674 AttrVisitor::visit (AST::LazyBooleanExpr &expr)
676 /* outer attributes never allowed before these. while cannot strip
677 * two direct descendant expressions, can strip ones below that */
679 /* should have no possibility for outer attrs as would be parsed
680 * with outer expr */
681 auto &l_expr = expr.get_left_expr ();
682 l_expr->accept_vis (*this);
683 maybe_expand_expr (l_expr);
685 /* should syntactically not have outer attributes, though this may
686 * not have worked in practice */
687 auto &r_expr = expr.get_right_expr ();
688 r_expr->accept_vis (*this);
689 maybe_expand_expr (r_expr);
691 // ensure that they are not marked for strip
692 if (expr.get_left_expr ()->is_marked_for_strip ())
693 rust_error_at (expr.get_left_expr ()->get_locus (),
694 "cannot strip expression in this position - outer "
695 "attributes are never allowed "
696 "before binary op exprs");
697 if (expr.get_right_expr ()->is_marked_for_strip ())
698 rust_error_at (expr.get_right_expr ()->get_locus (),
699 "cannot strip expression in this position - outer "
700 "attributes not allowed");
702 void
703 AttrVisitor::visit (AST::TypeCastExpr &expr)
705 /* outer attributes never allowed before these. while cannot strip
706 * direct descendant expression, can strip ones below that */
708 auto &casted_expr = expr.get_casted_expr ();
709 /* should have no possibility for outer attrs as would be parsed
710 * with outer expr */
711 casted_expr->accept_vis (*this);
713 // ensure that they are not marked for strip
714 if (casted_expr->is_marked_for_strip ())
715 rust_error_at (casted_expr->get_locus (),
716 "cannot strip expression in this position - outer "
717 "attributes are never allowed before cast exprs");
719 // TODO: strip sub-types of type
720 auto &type = expr.get_type_to_cast_to ();
721 type->accept_vis (*this);
722 if (type->is_marked_for_strip ())
723 rust_error_at (type->get_locus (), "cannot strip type in this position");
725 void
726 AttrVisitor::visit (AST::AssignmentExpr &expr)
728 expander.expand_cfg_attrs (expr.get_outer_attrs ());
729 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
731 expr.mark_for_strip ();
732 return;
735 /* should have no possibility for outer attrs as would be parsed
736 * with outer expr */
737 auto &l_expr = expr.get_left_expr ();
738 l_expr->accept_vis (*this);
739 maybe_expand_expr (l_expr);
741 /* should syntactically not have outer attributes, though this may
742 * not have worked in practice */
743 auto &r_expr = expr.get_right_expr ();
744 r_expr->accept_vis (*this);
745 maybe_expand_expr (r_expr);
747 // ensure that they are not marked for strip
748 if (expr.get_left_expr ()->is_marked_for_strip ())
749 rust_error_at (expr.get_left_expr ()->get_locus (),
750 "cannot strip expression in this position - outer "
751 "attributes are never allowed "
752 "before binary op exprs");
753 if (expr.get_right_expr ()->is_marked_for_strip ())
754 rust_error_at (expr.get_right_expr ()->get_locus (),
755 "cannot strip expression in this position - outer "
756 "attributes not allowed");
758 void
759 AttrVisitor::visit (AST::CompoundAssignmentExpr &expr)
761 /* outer attributes never allowed before these. while cannot strip
762 * two direct descendant expressions, can strip ones below that */
764 /* should have no possibility for outer attrs as would be parsed
765 * with outer expr */
766 auto &l_expr = expr.get_left_expr ();
767 l_expr->accept_vis (*this);
768 maybe_expand_expr (l_expr);
770 /* should syntactically not have outer attributes, though this may
771 * not have worked in practice */
772 auto &r_expr = expr.get_right_expr ();
773 r_expr->accept_vis (*this);
774 maybe_expand_expr (r_expr);
776 // ensure that they are not marked for strip
777 if (expr.get_left_expr ()->is_marked_for_strip ())
778 rust_error_at (expr.get_left_expr ()->get_locus (),
779 "cannot strip expression in this position - outer "
780 "attributes are never allowed "
781 "before binary op exprs");
782 if (expr.get_right_expr ()->is_marked_for_strip ())
783 rust_error_at (expr.get_right_expr ()->get_locus (),
784 "cannot strip expression in this position - outer "
785 "attributes not allowed");
787 void
788 AttrVisitor::visit (AST::GroupedExpr &expr)
790 // initial strip test based on outer attrs
791 expander.expand_cfg_attrs (expr.get_outer_attrs ());
792 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
794 expr.mark_for_strip ();
795 return;
798 /* strip test based on inner attrs - spec says these are inner
799 * attributes, not outer attributes of inner expr */
800 expander.expand_cfg_attrs (expr.get_inner_attrs ());
801 if (expander.fails_cfg_with_expand (expr.get_inner_attrs ()))
803 expr.mark_for_strip ();
804 return;
807 /* strip any internal sub-expressions - expression itself isn't
808 * allowed to have external attributes in this position so can't be
809 * stripped. */
810 auto &inner_expr = expr.get_expr_in_parens ();
811 inner_expr->accept_vis (*this);
812 if (inner_expr->is_marked_for_strip ())
813 rust_error_at (inner_expr->get_locus (),
814 "cannot strip expression in this position - outer "
815 "attributes not allowed");
817 void
818 AttrVisitor::visit (AST::ArrayElemsValues &elems)
820 /* apparently outer attributes are allowed in "elements of array
821 * expressions" according to spec */
822 expand_pointer_allow_strip (elems.get_values ());
824 void
825 AttrVisitor::visit (AST::ArrayElemsCopied &elems)
827 /* apparently outer attributes are allowed in "elements of array
828 * expressions" according to spec. on the other hand, it would not
829 * make conceptual sense to be able to remove either expression. As
830 * such, not implementing. TODO clear up the ambiguity here */
832 // only intend stripping for internal sub-expressions
833 auto &copied_expr = elems.get_elem_to_copy ();
834 copied_expr->accept_vis (*this);
835 if (copied_expr->is_marked_for_strip ())
836 rust_error_at (copied_expr->get_locus (),
837 "cannot strip expression in this position - outer "
838 "attributes not allowed");
840 auto &copy_count = elems.get_num_copies ();
841 copy_count->accept_vis (*this);
842 if (copy_count->is_marked_for_strip ())
843 rust_error_at (copy_count->get_locus (),
844 "cannot strip expression in this position - outer "
845 "attributes not allowed");
847 void
848 AttrVisitor::visit (AST::ArrayExpr &expr)
850 // initial strip test based on outer attrs
851 expander.expand_cfg_attrs (expr.get_outer_attrs ());
852 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
854 expr.mark_for_strip ();
855 return;
858 /* strip test based on inner attrs - spec says there are separate
859 * inner attributes, not just outer attributes of inner exprs */
860 expander.expand_cfg_attrs (expr.get_inner_attrs ());
861 if (expander.fails_cfg_with_expand (expr.get_inner_attrs ()))
863 expr.mark_for_strip ();
864 return;
867 /* assuming you can't strip away the ArrayElems type, but can strip
868 * internal expressions and whatever */
869 expr.get_array_elems ()->accept_vis (*this);
871 void
872 AttrVisitor::visit (AST::ArrayIndexExpr &expr)
874 /* it is unclear whether outer attributes are supposed to be
875 * allowed, but conceptually it wouldn't make much sense, but
876 * having expansion code anyway. TODO */
877 // initial strip test based on outer attrs
878 expander.expand_cfg_attrs (expr.get_outer_attrs ());
879 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
881 expr.mark_for_strip ();
882 return;
885 /* strip any internal sub-expressions - expression itself isn't
886 * allowed to have external attributes in this position so can't be
887 * stripped. */
888 auto &array_expr = expr.get_array_expr ();
889 array_expr->accept_vis (*this);
890 if (array_expr->is_marked_for_strip ())
891 rust_error_at (array_expr->get_locus (),
892 "cannot strip expression in this position - outer "
893 "attributes not allowed");
895 auto &index_expr = expr.get_index_expr ();
896 index_expr->accept_vis (*this);
897 if (index_expr->is_marked_for_strip ())
898 rust_error_at (index_expr->get_locus (),
899 "cannot strip expression in this position - outer "
900 "attributes not allowed");
902 void
903 AttrVisitor::visit (AST::TupleExpr &expr)
905 /* according to spec, outer attributes are allowed on "elements of
906 * tuple expressions" */
908 // initial strip test based on outer attrs
909 expander.expand_cfg_attrs (expr.get_outer_attrs ());
910 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
912 expr.mark_for_strip ();
913 return;
916 /* strip test based on inner attrs - spec says these are inner
917 * attributes, not outer attributes of inner expr */
918 expander.expand_cfg_attrs (expr.get_inner_attrs ());
919 if (expander.fails_cfg_with_expand (expr.get_inner_attrs ()))
921 expr.mark_for_strip ();
922 return;
925 /* apparently outer attributes are allowed in "elements of tuple
926 * expressions" according to spec */
927 expand_pointer_allow_strip (expr.get_tuple_elems ());
929 void
930 AttrVisitor::visit (AST::TupleIndexExpr &expr)
932 // initial strip test based on outer attrs
933 expander.expand_cfg_attrs (expr.get_outer_attrs ());
934 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
936 expr.mark_for_strip ();
937 return;
940 /* wouldn't strip this directly (as outer attrs should be
941 * associated with this level), but any sub-expressions would be
942 * stripped. Thus, no need to erase when strip check called. */
943 auto &tuple_expr = expr.get_tuple_expr ();
944 tuple_expr->accept_vis (*this);
945 if (tuple_expr->is_marked_for_strip ())
946 rust_error_at (tuple_expr->get_locus (),
947 "cannot strip expression in this position - outer "
948 "attributes not allowed");
950 void
951 AttrVisitor::visit (AST::StructExprStruct &expr)
953 // initial strip test based on outer attrs
954 expander.expand_cfg_attrs (expr.get_outer_attrs ());
955 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
957 expr.mark_for_strip ();
958 return;
961 /* strip test based on inner attrs - spec says these are inner
962 * attributes, not outer attributes of inner expr */
963 expander.expand_cfg_attrs (expr.get_inner_attrs ());
964 if (expander.fails_cfg_with_expand (expr.get_inner_attrs ()))
966 expr.mark_for_strip ();
967 return;
970 // strip sub-exprs of path
971 auto &struct_name = expr.get_struct_name ();
972 visit (struct_name);
973 if (struct_name.is_marked_for_strip ())
974 rust_error_at (struct_name.get_locus (),
975 "cannot strip path in this position");
977 void
978 AttrVisitor::visit (AST::StructExprFieldIdentifier &)
980 // as no attrs (at moment, at least), no stripping possible
982 void
983 AttrVisitor::visit (AST::StructExprFieldIdentifierValue &field)
985 /* as no attrs possible (at moment, at least), only sub-expression
986 * stripping is possible */
987 auto &value = field.get_value ();
988 value->accept_vis (*this);
989 if (value->is_marked_for_strip ())
990 rust_error_at (value->get_locus (),
991 "cannot strip expression in this position - outer "
992 "attributes not allowed");
994 void
995 AttrVisitor::visit (AST::StructExprFieldIndexValue &field)
997 /* as no attrs possible (at moment, at least), only sub-expression
998 * stripping is possible */
999 auto &value = field.get_value ();
1000 value->accept_vis (*this);
1001 if (value->is_marked_for_strip ())
1002 rust_error_at (value->get_locus (),
1003 "cannot strip expression in this position - outer "
1004 "attributes not allowed");
1006 void
1007 AttrVisitor::visit (AST::StructExprStructFields &expr)
1009 // initial strip test based on outer attrs
1010 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1011 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1013 expr.mark_for_strip ();
1014 return;
1017 /* strip test based on inner attrs - spec says these are inner
1018 * attributes, not outer attributes of inner expr */
1019 expander.expand_cfg_attrs (expr.get_inner_attrs ());
1020 if (expander.fails_cfg_with_expand (expr.get_inner_attrs ()))
1022 expr.mark_for_strip ();
1023 return;
1026 // strip sub-exprs of path
1027 auto &struct_name = expr.get_struct_name ();
1028 visit (struct_name);
1029 if (struct_name.is_marked_for_strip ())
1030 rust_error_at (struct_name.get_locus (),
1031 "cannot strip path in this position");
1033 /* spec does not specify whether expressions are allowed to be
1034 * stripped at top level of struct fields, but I wouldn't think
1035 * that they would be, so operating under the assumption that only
1036 * sub-expressions can be stripped. */
1037 for (auto &field : expr.get_fields ())
1039 field->accept_vis (*this);
1040 // shouldn't strip in this
1043 /* struct base presumably can't be stripped, as the '..' is before
1044 * the expression. as such, can only strip sub-expressions. */
1045 if (expr.has_struct_base ())
1047 auto &base_struct_expr = expr.get_struct_base ().get_base_struct ();
1048 base_struct_expr->accept_vis (*this);
1049 if (base_struct_expr->is_marked_for_strip ())
1050 rust_error_at (base_struct_expr->get_locus (),
1051 "cannot strip expression in this position - outer "
1052 "attributes not allowed");
1055 void
1056 AttrVisitor::visit (AST::StructExprStructBase &expr)
1058 // initial strip test based on outer attrs
1059 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1060 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1062 expr.mark_for_strip ();
1063 return;
1066 /* strip test based on inner attrs - spec says these are inner
1067 * attributes, not outer attributes of inner expr */
1068 expander.expand_cfg_attrs (expr.get_inner_attrs ());
1069 if (expander.fails_cfg_with_expand (expr.get_inner_attrs ()))
1071 expr.mark_for_strip ();
1072 return;
1075 // strip sub-exprs of path
1076 auto &struct_name = expr.get_struct_name ();
1077 visit (struct_name);
1078 if (struct_name.is_marked_for_strip ())
1079 rust_error_at (struct_name.get_locus (),
1080 "cannot strip path in this position");
1082 /* struct base presumably can't be stripped, as the '..' is before
1083 * the expression. as such, can only strip sub-expressions. */
1084 rust_assert (!expr.get_struct_base ().is_invalid ());
1085 auto &base_struct_expr = expr.get_struct_base ().get_base_struct ();
1086 base_struct_expr->accept_vis (*this);
1087 if (base_struct_expr->is_marked_for_strip ())
1088 rust_error_at (base_struct_expr->get_locus (),
1089 "cannot strip expression in this position - outer "
1090 "attributes not allowed");
1092 void
1093 AttrVisitor::visit (AST::CallExpr &expr)
1095 // initial strip test based on outer attrs
1096 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1097 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1099 expr.mark_for_strip ();
1100 return;
1103 /* should not be outer attrs on "function" expression - outer attrs
1104 * should be associated with call expr as a whole. only sub-expr
1105 * expansion is possible. */
1106 auto &function = expr.get_function_expr ();
1107 function->accept_vis (*this);
1108 if (function->is_marked_for_strip ())
1109 rust_error_at (function->get_locus (),
1110 "cannot strip expression in this position - outer "
1111 "attributes not allowed");
1113 /* spec says outer attributes are specifically allowed for elements
1114 * of call expressions, so full stripping possible */
1115 // FIXME: Arthur: Figure out how to refactor this - This is similar to
1116 // expanding items in the crate or stmts in blocks
1117 expand_pointer_allow_strip (expr.get_params ());
1118 auto &params = expr.get_params ();
1119 for (auto it = params.begin (); it != params.end ();)
1121 auto &stmt = *it;
1123 stmt->accept_vis (*this);
1125 auto final_fragment = expander.take_expanded_fragment ();
1126 if (final_fragment.should_expand ())
1128 // Remove the current expanded invocation
1129 it = params.erase (it);
1130 for (auto &node : final_fragment.get_nodes ())
1132 it = params.insert (it, node.take_expr ());
1133 it++;
1136 else if (stmt->is_marked_for_strip ())
1137 it = params.erase (it);
1138 else
1139 it++;
1142 void
1143 AttrVisitor::visit (AST::MethodCallExpr &expr)
1145 // initial strip test based on outer attrs
1146 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1147 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1149 expr.mark_for_strip ();
1150 return;
1153 /* should not be outer attrs on "receiver" expression - outer attrs
1154 * should be associated with call expr as a whole. only sub-expr
1155 * expansion is possible. */
1156 auto &receiver = expr.get_receiver_expr ();
1157 receiver->accept_vis (*this);
1158 if (receiver->is_marked_for_strip ())
1159 rust_error_at (receiver->get_locus (),
1160 "cannot strip expression in this position - outer "
1161 "attributes not allowed");
1163 auto &method_name = expr.get_method_name ();
1164 if (method_name.has_generic_args ())
1165 expand_generic_args (method_name.get_generic_args ());
1167 /* spec says outer attributes are specifically allowed for elements
1168 * of method call expressions, so full stripping possible */
1169 expand_pointer_allow_strip (expr.get_params ());
1171 void
1172 AttrVisitor::visit (AST::FieldAccessExpr &expr)
1174 // initial strip test based on outer attrs
1175 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1176 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1178 expr.mark_for_strip ();
1179 return;
1182 /* should not be outer attrs on "receiver" expression - outer attrs
1183 * should be associated with field expr as a whole. only sub-expr
1184 * expansion is possible. */
1185 auto &receiver = expr.get_receiver_expr ();
1186 receiver->accept_vis (*this);
1187 if (receiver->is_marked_for_strip ())
1188 rust_error_at (receiver->get_locus (),
1189 "cannot strip expression in this position - outer "
1190 "attributes not allowed");
1192 void
1193 AttrVisitor::visit (AST::ClosureExprInner &expr)
1195 // initial strip test based on outer attrs
1196 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1197 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1199 expr.mark_for_strip ();
1200 return;
1203 /* strip closure parameters if required - this is specifically
1204 * allowed by spec */
1205 expand_closure_params (expr.get_params ());
1207 // can't strip expression itself, but can strip sub-expressions
1208 auto &definition_expr = expr.get_definition_expr ();
1209 definition_expr->accept_vis (*this);
1210 if (definition_expr->is_marked_for_strip ())
1211 rust_error_at (definition_expr->get_locus (),
1212 "cannot strip expression in this position - outer "
1213 "attributes not allowed");
1216 void
1217 AttrVisitor::visit (AST::BlockExpr &expr)
1219 // initial strip test based on outer attrs
1220 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1221 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1223 expr.mark_for_strip ();
1224 return;
1227 /* strip test based on inner attrs - spec says there are inner
1228 * attributes, not just outer attributes of inner stmts */
1229 expander.expand_cfg_attrs (expr.get_inner_attrs ());
1230 if (expander.fails_cfg_with_expand (expr.get_inner_attrs ()))
1232 expr.mark_for_strip ();
1233 return;
1236 std::function<std::unique_ptr<AST::Stmt> (AST::SingleASTNode)> extractor
1237 = [] (AST::SingleASTNode node) { return node.take_stmt (); };
1239 expand_macro_children (MacroExpander::BLOCK, expr.get_statements (),
1240 extractor);
1242 expander.push_context (MacroExpander::BLOCK);
1244 // strip tail expression if exists - can actually fully remove it
1245 if (expr.has_tail_expr ())
1247 auto &tail_expr = expr.get_tail_expr ();
1249 tail_expr->accept_vis (*this);
1250 maybe_expand_expr (tail_expr);
1252 if (tail_expr->is_marked_for_strip ())
1253 expr.strip_tail_expr ();
1255 expander.pop_context ();
1258 void
1259 AttrVisitor::visit (AST::ClosureExprInnerTyped &expr)
1261 // initial strip test based on outer attrs
1262 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1263 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1265 expr.mark_for_strip ();
1266 return;
1269 /* strip closure parameters if required - this is specifically
1270 * allowed by spec */
1271 expand_closure_params (expr.get_params ());
1273 expander.push_context (MacroExpander::ContextType::TYPE);
1275 // can't strip return type, but can strip sub-types
1276 auto &type = expr.get_return_type ();
1277 type->accept_vis (*this);
1279 maybe_expand_type (type);
1281 if (type->is_marked_for_strip ())
1282 rust_error_at (type->get_locus (), "cannot strip type in this position");
1284 expander.pop_context ();
1286 // can't strip expression itself, but can strip sub-expressions
1287 auto &definition_block = expr.get_definition_block ();
1288 definition_block->accept_vis (*this);
1289 if (definition_block->is_marked_for_strip ())
1290 rust_error_at (definition_block->get_locus (),
1291 "cannot strip block expression in this position - outer "
1292 "attributes not allowed");
1294 void
1295 AttrVisitor::visit (AST::ContinueExpr &expr)
1297 // initial strip test based on outer attrs
1298 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1299 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1301 expr.mark_for_strip ();
1302 return;
1305 void
1306 AttrVisitor::visit (AST::BreakExpr &expr)
1308 // initial strip test based on outer attrs
1309 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1310 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1312 expr.mark_for_strip ();
1313 return;
1316 /* spec does not say that you can have outer attributes on
1317 * expression, so assuming you can't. stripping for sub-expressions
1318 * is the only thing that can be done */
1319 if (expr.has_break_expr ())
1321 auto &break_expr = expr.get_break_expr ();
1323 break_expr->accept_vis (*this);
1325 if (break_expr->is_marked_for_strip ())
1326 rust_error_at (break_expr->get_locus (),
1327 "cannot strip expression in this position - outer "
1328 "attributes not allowed");
1331 void
1332 AttrVisitor::visit (AST::RangeFromToExpr &expr)
1334 /* outer attributes never allowed before these. while cannot strip
1335 * two direct descendant expressions, can strip ones below that */
1337 /* should have no possibility for outer attrs as would be parsed
1338 * with outer expr */
1339 expr.get_from_expr ()->accept_vis (*this);
1340 /* should syntactically not have outer attributes, though this may
1341 * not have worked in practice */
1342 expr.get_to_expr ()->accept_vis (*this);
1344 // ensure that they are not marked for strip
1345 if (expr.get_from_expr ()->is_marked_for_strip ())
1346 rust_error_at (expr.get_from_expr ()->get_locus (),
1347 "cannot strip expression in this position - outer "
1348 "attributes are never allowed "
1349 "before range exprs");
1350 if (expr.get_to_expr ()->is_marked_for_strip ())
1351 rust_error_at (expr.get_to_expr ()->get_locus (),
1352 "cannot strip expression in this position - outer "
1353 "attributes not allowed");
1355 void
1356 AttrVisitor::visit (AST::RangeFromExpr &expr)
1358 /* outer attributes never allowed before these. while cannot strip
1359 * direct descendant expression, can strip ones below that */
1361 /* should have no possibility for outer attrs as would be parsed
1362 * with outer expr */
1363 auto &from_expr = expr.get_from_expr ();
1365 from_expr->accept_vis (*this);
1367 if (from_expr->is_marked_for_strip ())
1368 rust_error_at (from_expr->get_locus (),
1369 "cannot strip expression in this position - outer "
1370 "attributes are never allowed before range exprs");
1372 void
1373 AttrVisitor::visit (AST::RangeToExpr &expr)
1375 /* outer attributes never allowed before these. while cannot strip
1376 * direct descendant expression, can strip ones below that */
1378 /* should syntactically not have outer attributes, though this may
1379 * not have worked in practice */
1380 auto &to_expr = expr.get_to_expr ();
1382 to_expr->accept_vis (*this);
1384 if (to_expr->is_marked_for_strip ())
1385 rust_error_at (to_expr->get_locus (),
1386 "cannot strip expression in this position - outer "
1387 "attributes not allowed");
1389 void
1390 AttrVisitor::visit (AST::RangeFullExpr &)
1392 // outer attributes never allowed before these, so no stripping
1394 void
1395 AttrVisitor::visit (AST::RangeFromToInclExpr &expr)
1397 /* outer attributes never allowed before these. while cannot strip
1398 * two direct descendant expressions, can strip ones below that */
1400 /* should have no possibility for outer attrs as would be parsed
1401 * with outer expr */
1402 expr.get_from_expr ()->accept_vis (*this);
1403 /* should syntactically not have outer attributes, though this may
1404 * not have worked in practice */
1405 expr.get_to_expr ()->accept_vis (*this);
1407 // ensure that they are not marked for strip
1408 if (expr.get_from_expr ()->is_marked_for_strip ())
1409 rust_error_at (expr.get_from_expr ()->get_locus (),
1410 "cannot strip expression in this position - outer "
1411 "attributes are never allowed "
1412 "before range exprs");
1413 if (expr.get_to_expr ()->is_marked_for_strip ())
1414 rust_error_at (expr.get_to_expr ()->get_locus (),
1415 "cannot strip expression in this position - outer "
1416 "attributes not allowed");
1418 void
1419 AttrVisitor::visit (AST::RangeToInclExpr &expr)
1421 /* outer attributes never allowed before these. while cannot strip
1422 * direct descendant expression, can strip ones below that */
1424 /* should syntactically not have outer attributes, though this may
1425 * not have worked in practice */
1426 auto &to_expr = expr.get_to_expr ();
1428 to_expr->accept_vis (*this);
1430 if (to_expr->is_marked_for_strip ())
1431 rust_error_at (to_expr->get_locus (),
1432 "cannot strip expression in this position - outer "
1433 "attributes not allowed");
1435 void
1436 AttrVisitor::visit (AST::ReturnExpr &expr)
1438 // initial strip test based on outer attrs
1439 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1440 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1442 expr.mark_for_strip ();
1443 return;
1446 /* spec does not say that you can have outer attributes on
1447 * expression, so assuming you can't. stripping for sub-expressions
1448 * is the only thing that can be done */
1449 if (expr.has_returned_expr ())
1451 auto &returned_expr = expr.get_returned_expr ();
1453 returned_expr->accept_vis (*this);
1455 if (returned_expr->is_marked_for_strip ())
1456 rust_error_at (returned_expr->get_locus (),
1457 "cannot strip expression in this position - outer "
1458 "attributes not allowed");
1460 /* TODO: conceptually, you would maybe be able to remove a returned
1461 * expr - e.g. if you had conditional compilation returning void or
1462 * returning a type. On the other hand, I think that function
1463 * return type cannot be conditionally compiled, so I assumed you
1464 * can't do this either. */
1466 void
1467 AttrVisitor::visit (AST::UnsafeBlockExpr &expr)
1469 // initial strip test based on outer attrs
1470 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1471 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1473 expr.mark_for_strip ();
1474 return;
1477 // can't strip block itself, but can strip sub-expressions
1478 auto &block_expr = expr.get_block_expr ();
1479 block_expr->accept_vis (*this);
1480 if (block_expr->is_marked_for_strip ())
1481 rust_error_at (block_expr->get_locus (),
1482 "cannot strip block expression in this position - outer "
1483 "attributes not allowed");
1485 void
1486 AttrVisitor::visit (AST::LoopExpr &expr)
1488 // initial strip test based on outer attrs
1489 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1490 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1492 expr.mark_for_strip ();
1493 return;
1496 // can't strip block itself, but can strip sub-expressions
1497 auto &loop_block = expr.get_loop_block ();
1498 loop_block->accept_vis (*this);
1499 if (loop_block->is_marked_for_strip ())
1500 rust_error_at (loop_block->get_locus (),
1501 "cannot strip block expression in this position - outer "
1502 "attributes not allowed");
1504 void
1505 AttrVisitor::visit (AST::WhileLoopExpr &expr)
1507 // initial strip test based on outer attrs
1508 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1509 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1511 expr.mark_for_strip ();
1512 return;
1515 // can't strip predicate expr itself, but can strip sub-expressions
1516 auto &predicate_expr = expr.get_predicate_expr ();
1517 predicate_expr->accept_vis (*this);
1518 if (predicate_expr->is_marked_for_strip ())
1519 rust_error_at (predicate_expr->get_locus (),
1520 "cannot strip expression in this position - outer "
1521 "attributes not allowed");
1523 // can't strip block itself, but can strip sub-expressions
1524 auto &loop_block = expr.get_loop_block ();
1525 loop_block->accept_vis (*this);
1526 if (loop_block->is_marked_for_strip ())
1527 rust_error_at (loop_block->get_locus (),
1528 "cannot strip block expression in this position - outer "
1529 "attributes not allowed");
1531 void
1532 AttrVisitor::visit (AST::WhileLetLoopExpr &expr)
1534 // initial strip test based on outer attrs
1535 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1536 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1538 expr.mark_for_strip ();
1539 return;
1542 for (auto &pattern : expr.get_patterns ())
1544 pattern->accept_vis (*this);
1545 if (pattern->is_marked_for_strip ())
1546 rust_error_at (pattern->get_locus (),
1547 "cannot strip pattern in this position");
1550 // can't strip scrutinee expr itself, but can strip sub-expressions
1551 auto &scrutinee_expr = expr.get_scrutinee_expr ();
1552 scrutinee_expr->accept_vis (*this);
1553 if (scrutinee_expr->is_marked_for_strip ())
1554 rust_error_at (scrutinee_expr->get_locus (),
1555 "cannot strip expression in this position - outer "
1556 "attributes not allowed");
1558 // can't strip block itself, but can strip sub-expressions
1559 auto &loop_block = expr.get_loop_block ();
1560 loop_block->accept_vis (*this);
1561 if (loop_block->is_marked_for_strip ())
1562 rust_error_at (loop_block->get_locus (),
1563 "cannot strip block expression in this position - outer "
1564 "attributes not allowed");
1566 void
1567 AttrVisitor::visit (AST::ForLoopExpr &expr)
1569 // initial strip test based on outer attrs
1570 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1571 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1573 expr.mark_for_strip ();
1574 return;
1577 // strip sub-patterns of pattern
1578 auto &pattern = expr.get_pattern ();
1579 pattern->accept_vis (*this);
1580 if (pattern->is_marked_for_strip ())
1581 rust_error_at (pattern->get_locus (),
1582 "cannot strip pattern in this position");
1584 // can't strip scrutinee expr itself, but can strip sub-expressions
1585 auto &iterator_expr = expr.get_iterator_expr ();
1586 iterator_expr->accept_vis (*this);
1587 if (iterator_expr->is_marked_for_strip ())
1588 rust_error_at (iterator_expr->get_locus (),
1589 "cannot strip expression in this position - outer "
1590 "attributes not allowed");
1592 // can't strip block itself, but can strip sub-expressions
1593 auto &loop_block = expr.get_loop_block ();
1594 loop_block->accept_vis (*this);
1595 if (loop_block->is_marked_for_strip ())
1596 rust_error_at (loop_block->get_locus (),
1597 "cannot strip block expression in this position - outer "
1598 "attributes not allowed");
1600 void
1601 AttrVisitor::visit (AST::IfExpr &expr)
1603 // rust playground test shows that IfExpr does support outer attrs, at least
1604 // when used as statement
1606 // initial strip test based on outer attrs
1607 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1608 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1610 expr.mark_for_strip ();
1611 return;
1614 // can't strip condition expr itself, but can strip sub-expressions
1615 auto &condition_expr = expr.get_condition_expr ();
1616 condition_expr->accept_vis (*this);
1617 maybe_expand_expr (condition_expr);
1618 if (condition_expr->is_marked_for_strip ())
1619 rust_error_at (condition_expr->get_locus (),
1620 "cannot strip expression in this position - outer "
1621 "attributes not allowed");
1623 // can't strip if block itself, but can strip sub-expressions
1624 auto &if_block = expr.get_if_block ();
1625 if_block->accept_vis (*this);
1626 if (if_block->is_marked_for_strip ())
1627 rust_error_at (if_block->get_locus (),
1628 "cannot strip block expression in this position - outer "
1629 "attributes not allowed");
1631 void
1632 AttrVisitor::visit (AST::IfExprConseqElse &expr)
1634 // initial strip test based on outer attrs
1635 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1636 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1638 expr.mark_for_strip ();
1639 return;
1642 // can't strip condition expr itself, but can strip sub-expressions
1643 auto &condition_expr = expr.get_condition_expr ();
1644 condition_expr->accept_vis (*this);
1645 maybe_expand_expr (condition_expr);
1646 if (condition_expr->is_marked_for_strip ())
1647 rust_error_at (condition_expr->get_locus (),
1648 "cannot strip expression in this position - outer "
1649 "attributes not allowed");
1651 // can't strip if block itself, but can strip sub-expressions
1652 auto &if_block = expr.get_if_block ();
1653 if_block->accept_vis (*this);
1654 if (if_block->is_marked_for_strip ())
1655 rust_error_at (if_block->get_locus (),
1656 "cannot strip block expression in this position - outer "
1657 "attributes not allowed");
1659 // can't strip else block itself, but can strip sub-expressions
1660 auto &else_block = expr.get_else_block ();
1661 else_block->accept_vis (*this);
1662 if (else_block->is_marked_for_strip ())
1663 rust_error_at (else_block->get_locus (),
1664 "cannot strip block expression in this position - outer "
1665 "attributes not allowed");
1667 void
1668 AttrVisitor::visit (AST::IfExprConseqIf &expr)
1670 // initial strip test based on outer attrs
1671 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1672 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1674 expr.mark_for_strip ();
1675 return;
1678 // can't strip condition expr itself, but can strip sub-expressions
1679 auto &condition_expr = expr.get_condition_expr ();
1680 condition_expr->accept_vis (*this);
1681 maybe_expand_expr (condition_expr);
1682 if (condition_expr->is_marked_for_strip ())
1683 rust_error_at (condition_expr->get_locus (),
1684 "cannot strip expression in this position - outer "
1685 "attributes not allowed");
1687 // can't strip if block itself, but can strip sub-expressions
1688 auto &if_block = expr.get_if_block ();
1689 if_block->accept_vis (*this);
1690 if (if_block->is_marked_for_strip ())
1691 rust_error_at (if_block->get_locus (),
1692 "cannot strip block expression in this position - outer "
1693 "attributes not allowed");
1695 // can't strip if expr itself, but can strip sub-expressions
1696 auto &conseq_if_expr = expr.get_conseq_if_expr ();
1697 conseq_if_expr->accept_vis (*this);
1698 if (conseq_if_expr->is_marked_for_strip ())
1699 rust_error_at (conseq_if_expr->get_locus (),
1700 "cannot strip consequent if expression in this "
1701 "position - outer attributes not allowed");
1703 void
1704 AttrVisitor::visit (AST::IfExprConseqIfLet &expr)
1706 // initial strip test based on outer attrs
1707 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1708 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1710 expr.mark_for_strip ();
1711 return;
1714 // can't strip condition expr itself, but can strip sub-expressions
1715 auto &condition_expr = expr.get_condition_expr ();
1716 condition_expr->accept_vis (*this);
1717 maybe_expand_expr (condition_expr);
1718 if (condition_expr->is_marked_for_strip ())
1719 rust_error_at (condition_expr->get_locus (),
1720 "cannot strip expression in this position - outer "
1721 "attributes not allowed");
1723 // can't strip if block itself, but can strip sub-expressions
1724 auto &if_block = expr.get_if_block ();
1725 if_block->accept_vis (*this);
1726 if (if_block->is_marked_for_strip ())
1727 rust_error_at (if_block->get_locus (),
1728 "cannot strip block expression in this position - outer "
1729 "attributes not allowed");
1731 // can't strip if let expr itself, but can strip sub-expressions
1732 auto &conseq_if_let_expr = expr.get_conseq_if_let_expr ();
1733 conseq_if_let_expr->accept_vis (*this);
1734 if (conseq_if_let_expr->is_marked_for_strip ())
1735 rust_error_at (conseq_if_let_expr->get_locus (),
1736 "cannot strip consequent if let expression in this "
1737 "position - outer attributes not "
1738 "allowed");
1740 void
1741 AttrVisitor::visit (AST::IfLetExpr &expr)
1743 // initial strip test based on outer attrs
1744 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1745 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1747 expr.mark_for_strip ();
1748 return;
1751 for (auto &pattern : expr.get_patterns ())
1753 pattern->accept_vis (*this);
1754 if (pattern->is_marked_for_strip ())
1755 rust_error_at (pattern->get_locus (),
1756 "cannot strip pattern in this position");
1759 // can't strip value expr itself, but can strip sub-expressions
1760 auto &value_expr = expr.get_value_expr ();
1761 value_expr->accept_vis (*this);
1762 if (value_expr->is_marked_for_strip ())
1763 rust_error_at (value_expr->get_locus (),
1764 "cannot strip expression in this position - outer "
1765 "attributes not allowed");
1767 // can't strip if block itself, but can strip sub-expressions
1768 auto &if_block = expr.get_if_block ();
1769 if_block->accept_vis (*this);
1770 if (if_block->is_marked_for_strip ())
1771 rust_error_at (if_block->get_locus (),
1772 "cannot strip block expression in this position - outer "
1773 "attributes not allowed");
1775 void
1776 AttrVisitor::visit (AST::IfLetExprConseqElse &expr)
1778 // initial strip test based on outer attrs
1779 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1780 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1782 expr.mark_for_strip ();
1783 return;
1786 for (auto &pattern : expr.get_patterns ())
1788 pattern->accept_vis (*this);
1789 if (pattern->is_marked_for_strip ())
1790 rust_error_at (pattern->get_locus (),
1791 "cannot strip pattern in this position");
1794 // can't strip value expr itself, but can strip sub-expressions
1795 auto &value_expr = expr.get_value_expr ();
1796 value_expr->accept_vis (*this);
1797 if (value_expr->is_marked_for_strip ())
1798 rust_error_at (value_expr->get_locus (),
1799 "cannot strip expression in this position - outer "
1800 "attributes not allowed");
1802 // can't strip if block itself, but can strip sub-expressions
1803 auto &if_block = expr.get_if_block ();
1804 if_block->accept_vis (*this);
1805 if (if_block->is_marked_for_strip ())
1806 rust_error_at (if_block->get_locus (),
1807 "cannot strip block expression in this position - outer "
1808 "attributes not allowed");
1810 // can't strip else block itself, but can strip sub-expressions
1811 auto &else_block = expr.get_else_block ();
1812 else_block->accept_vis (*this);
1813 if (else_block->is_marked_for_strip ())
1814 rust_error_at (else_block->get_locus (),
1815 "cannot strip block expression in this position - outer "
1816 "attributes not allowed");
1818 void
1819 AttrVisitor::visit (AST::IfLetExprConseqIf &expr)
1821 // initial strip test based on outer attrs
1822 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1823 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1825 expr.mark_for_strip ();
1826 return;
1829 for (auto &pattern : expr.get_patterns ())
1831 pattern->accept_vis (*this);
1832 if (pattern->is_marked_for_strip ())
1833 rust_error_at (pattern->get_locus (),
1834 "cannot strip pattern in this position");
1837 // can't strip value expr itself, but can strip sub-expressions
1838 auto &value_expr = expr.get_value_expr ();
1839 value_expr->accept_vis (*this);
1840 if (value_expr->is_marked_for_strip ())
1841 rust_error_at (value_expr->get_locus (),
1842 "cannot strip expression in this position - outer "
1843 "attributes not allowed");
1845 // can't strip if block itself, but can strip sub-expressions
1846 auto &if_block = expr.get_if_block ();
1847 if_block->accept_vis (*this);
1848 if (if_block->is_marked_for_strip ())
1849 rust_error_at (if_block->get_locus (),
1850 "cannot strip block expression in this position - outer "
1851 "attributes not allowed");
1853 // can't strip if expr itself, but can strip sub-expressions
1854 auto &conseq_if_expr = expr.get_conseq_if_expr ();
1855 conseq_if_expr->accept_vis (*this);
1856 if (conseq_if_expr->is_marked_for_strip ())
1857 rust_error_at (conseq_if_expr->get_locus (),
1858 "cannot strip consequent if expression in this "
1859 "position - outer attributes not allowed");
1861 void
1862 AttrVisitor::visit (AST::IfLetExprConseqIfLet &expr)
1864 // initial strip test based on outer attrs
1865 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1866 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1868 expr.mark_for_strip ();
1869 return;
1872 for (auto &pattern : expr.get_patterns ())
1874 pattern->accept_vis (*this);
1875 if (pattern->is_marked_for_strip ())
1876 rust_error_at (pattern->get_locus (),
1877 "cannot strip pattern in this position");
1880 // can't strip value expr itself, but can strip sub-expressions
1881 auto &value_expr = expr.get_value_expr ();
1882 value_expr->accept_vis (*this);
1883 if (value_expr->is_marked_for_strip ())
1884 rust_error_at (value_expr->get_locus (),
1885 "cannot strip expression in this position - outer "
1886 "attributes not allowed");
1888 // can't strip if block itself, but can strip sub-expressions
1889 auto &if_block = expr.get_if_block ();
1890 if_block->accept_vis (*this);
1891 if (if_block->is_marked_for_strip ())
1892 rust_error_at (if_block->get_locus (),
1893 "cannot strip block expression in this position - outer "
1894 "attributes not allowed");
1896 // can't strip if let expr itself, but can strip sub-expressions
1897 auto &conseq_if_let_expr = expr.get_conseq_if_let_expr ();
1898 conseq_if_let_expr->accept_vis (*this);
1899 if (conseq_if_let_expr->is_marked_for_strip ())
1900 rust_error_at (conseq_if_let_expr->get_locus (),
1901 "cannot strip consequent if let expression in this "
1902 "position - outer attributes not "
1903 "allowed");
1905 void
1906 AttrVisitor::visit (AST::MatchExpr &expr)
1908 // initial strip test based on outer attrs
1909 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1910 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1912 expr.mark_for_strip ();
1913 return;
1916 // inner attr strip test
1917 expander.expand_cfg_attrs (expr.get_inner_attrs ());
1918 if (expander.fails_cfg_with_expand (expr.get_inner_attrs ()))
1920 expr.mark_for_strip ();
1921 return;
1924 // can't strip scrutinee expr itself, but can strip sub-expressions
1925 auto &scrutinee_expr = expr.get_scrutinee_expr ();
1926 scrutinee_expr->accept_vis (*this);
1927 if (scrutinee_expr->is_marked_for_strip ())
1928 rust_error_at (scrutinee_expr->get_locus (),
1929 "cannot strip expression in this position - outer "
1930 "attributes not allowed");
1932 // strip match cases
1933 auto &match_cases = expr.get_match_cases ();
1934 for (auto it = match_cases.begin (); it != match_cases.end ();)
1936 auto &match_case = *it;
1938 // strip match case based on outer attributes in match arm
1939 auto &match_arm = match_case.get_arm ();
1940 expander.expand_cfg_attrs (match_arm.get_outer_attrs ());
1941 if (expander.fails_cfg_with_expand (match_arm.get_outer_attrs ()))
1943 // strip match case
1944 it = match_cases.erase (it);
1945 continue;
1948 for (auto &pattern : match_arm.get_patterns ())
1950 pattern->accept_vis (*this);
1951 if (pattern->is_marked_for_strip ())
1952 rust_error_at (pattern->get_locus (),
1953 "cannot strip pattern in this position");
1956 /* assuming that guard expression cannot be stripped as
1957 * strictly speaking you would have to strip the whole guard to
1958 * make syntactical sense, which you can't do. as such, only
1959 * strip sub-expressions */
1960 if (match_arm.has_match_arm_guard ())
1962 auto &guard_expr = match_arm.get_guard_expr ();
1963 guard_expr->accept_vis (*this);
1964 if (guard_expr->is_marked_for_strip ())
1965 rust_error_at (guard_expr->get_locus (),
1966 "cannot strip expression in this position - outer "
1967 "attributes not allowed");
1970 // strip sub-expressions from match cases
1971 auto &case_expr = match_case.get_expr ();
1972 case_expr->accept_vis (*this);
1973 if (case_expr->is_marked_for_strip ())
1974 rust_error_at (case_expr->get_locus (),
1975 "cannot strip expression in this position - outer "
1976 "attributes not allowed");
1978 // increment to next case if haven't continued
1979 ++it;
1982 void
1983 AttrVisitor::visit (AST::AwaitExpr &expr)
1985 // initial strip test based on outer attrs
1986 expander.expand_cfg_attrs (expr.get_outer_attrs ());
1987 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
1989 expr.mark_for_strip ();
1990 return;
1993 /* can't strip awaited expr itself, but can strip sub-expressions
1994 * - this is because you can't have no expr to await */
1995 auto &awaited_expr = expr.get_awaited_expr ();
1996 awaited_expr->accept_vis (*this);
1997 if (awaited_expr->is_marked_for_strip ())
1998 rust_error_at (awaited_expr->get_locus (),
1999 "cannot strip expression in this position - outer "
2000 "attributes not allowed");
2002 void
2003 AttrVisitor::visit (AST::AsyncBlockExpr &expr)
2005 // initial strip test based on outer attrs
2006 expander.expand_cfg_attrs (expr.get_outer_attrs ());
2007 if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
2009 expr.mark_for_strip ();
2010 return;
2013 // can't strip block itself, but can strip sub-expressions
2014 auto &block_expr = expr.get_block_expr ();
2015 block_expr->accept_vis (*this);
2016 if (block_expr->is_marked_for_strip ())
2017 rust_error_at (block_expr->get_locus (),
2018 "cannot strip block expression in this position - outer "
2019 "attributes not allowed");
2022 void
2023 AttrVisitor::visit (AST::TypeParam &param)
2025 // outer attributes don't actually do anything, so ignore them
2027 if (param.has_type_param_bounds ())
2029 // don't strip directly, only components of bounds
2030 for (auto &bound : param.get_type_param_bounds ())
2031 bound->accept_vis (*this);
2034 if (param.has_type ())
2036 expander.push_context (MacroExpander::ContextType::TYPE);
2037 auto &type = param.get_type ();
2038 type->accept_vis (*this);
2040 maybe_expand_type (type);
2042 if (type->is_marked_for_strip ())
2043 rust_error_at (type->get_locus (),
2044 "cannot strip type in this position");
2046 expander.pop_context ();
2049 void
2050 AttrVisitor::visit (AST::LifetimeWhereClauseItem &)
2052 // shouldn't require
2054 void
2055 AttrVisitor::visit (AST::TypeBoundWhereClauseItem &item)
2057 // for lifetimes shouldn't require
2059 expander.push_context (MacroExpander::ContextType::TYPE);
2061 auto &type = item.get_type ();
2062 type->accept_vis (*this);
2064 maybe_expand_type (type);
2066 if (type->is_marked_for_strip ())
2067 rust_error_at (type->get_locus (), "cannot strip type in this position");
2069 expander.pop_context ();
2071 // don't strip directly, only components of bounds
2072 for (auto &bound : item.get_type_param_bounds ())
2073 bound->accept_vis (*this);
2075 void
2076 AttrVisitor::visit (AST::Method &method)
2078 // initial test based on outer attrs
2079 expander.expand_cfg_attrs (method.get_outer_attrs ());
2080 if (expander.fails_cfg_with_expand (method.get_outer_attrs ()))
2082 method.mark_for_strip ();
2083 return;
2086 // just expand sub-stuff - can't actually strip generic params themselves
2087 for (auto &param : method.get_generic_params ())
2088 param->accept_vis (*this);
2090 /* assuming you can't strip self param - wouldn't be a method
2091 * anymore. spec allows outer attrs on self param, but doesn't
2092 * specify whether cfg is used. */
2093 expand_self_param (method.get_self_param ());
2095 /* strip method parameters if required - this is specifically
2096 * allowed by spec */
2097 expand_function_params (method.get_function_params ());
2099 if (method.has_return_type ())
2101 expander.push_context (MacroExpander::ContextType::TYPE);
2103 auto &return_type = method.get_return_type ();
2104 return_type->accept_vis (*this);
2106 maybe_expand_type (return_type);
2108 if (return_type->is_marked_for_strip ())
2109 rust_error_at (return_type->get_locus (),
2110 "cannot strip type in this position");
2112 expander.pop_context ();
2115 if (method.has_where_clause ())
2116 expand_where_clause (method.get_where_clause ());
2118 /* body should always exist - if error state, should have returned
2119 * before now */
2120 // can't strip block itself, but can strip sub-expressions
2121 auto &block_expr = method.get_definition ();
2122 block_expr->accept_vis (*this);
2123 if (block_expr->is_marked_for_strip ())
2124 rust_error_at (block_expr->get_locus (),
2125 "cannot strip block expression in this position - outer "
2126 "attributes not allowed");
2128 void
2129 AttrVisitor::visit (AST::Module &module)
2131 // strip test based on outer attrs
2132 expander.expand_cfg_attrs (module.get_outer_attrs ());
2133 if (expander.fails_cfg_with_expand (module.get_outer_attrs ()))
2135 module.mark_for_strip ();
2136 return;
2139 // A loaded module might have inner attributes
2140 if (module.get_kind () == AST::Module::ModuleKind::LOADED)
2142 // strip test based on inner attrs
2143 expander.expand_cfg_attrs (module.get_inner_attrs ());
2144 if (expander.fails_cfg_with_expand (module.get_inner_attrs ()))
2146 module.mark_for_strip ();
2147 return;
2151 // Parse the module's items if they haven't been expanded and the file
2152 // should be parsed (i.e isn't hidden behind an untrue or impossible cfg
2153 // directive)
2154 if (!module.is_marked_for_strip ()
2155 && module.get_kind () == AST::Module::ModuleKind::UNLOADED)
2157 module.load_items ();
2160 // strip items if required
2161 expand_pointer_allow_strip (module.get_items ());
2163 void
2164 AttrVisitor::visit (AST::ExternCrate &extern_crate)
2166 // strip test based on outer attrs
2167 expander.expand_cfg_attrs (extern_crate.get_outer_attrs ());
2168 if (expander.fails_cfg_with_expand (extern_crate.get_outer_attrs ()))
2170 extern_crate.mark_for_strip ();
2171 return;
2174 if (!extern_crate.references_self ())
2176 Session &session = Session::get_instance ();
2177 session.load_extern_crate (extern_crate.get_referenced_crate (),
2178 extern_crate.get_locus ());
2181 void
2182 AttrVisitor::visit (AST::UseTreeGlob &)
2184 // shouldn't require?
2186 void
2187 AttrVisitor::visit (AST::UseTreeList &)
2189 // shouldn't require?
2191 void
2192 AttrVisitor::visit (AST::UseTreeRebind &)
2194 // shouldn't require?
2196 void
2197 AttrVisitor::visit (AST::UseDeclaration &use_decl)
2199 // strip test based on outer attrs
2200 expander.expand_cfg_attrs (use_decl.get_outer_attrs ());
2201 if (expander.fails_cfg_with_expand (use_decl.get_outer_attrs ()))
2203 use_decl.mark_for_strip ();
2204 return;
2207 void
2208 AttrVisitor::visit (AST::Function &function)
2210 // initial test based on outer attrs
2211 expander.expand_cfg_attrs (function.get_outer_attrs ());
2212 if (expander.fails_cfg_with_expand (function.get_outer_attrs ()))
2214 function.mark_for_strip ();
2215 return;
2218 // just expand sub-stuff - can't actually strip generic params themselves
2219 for (auto &param : function.get_generic_params ())
2220 param->accept_vis (*this);
2222 /* strip function parameters if required - this is specifically
2223 * allowed by spec */
2224 expand_function_params (function.get_function_params ());
2226 if (function.has_return_type ())
2228 expander.push_context (MacroExpander::ContextType::TYPE);
2230 auto &return_type = function.get_return_type ();
2231 return_type->accept_vis (*this);
2233 maybe_expand_type (return_type);
2235 if (return_type->is_marked_for_strip ())
2236 rust_error_at (return_type->get_locus (),
2237 "cannot strip type in this position");
2239 expander.pop_context ();
2242 if (function.has_where_clause ())
2243 expand_where_clause (function.get_where_clause ());
2245 /* body should always exist - if error state, should have returned
2246 * before now */
2247 // can't strip block itself, but can strip sub-expressions
2248 auto &block_expr = function.get_definition ();
2249 block_expr->accept_vis (*this);
2250 if (block_expr->is_marked_for_strip ())
2251 rust_error_at (block_expr->get_locus (),
2252 "cannot strip block expression in this position - outer "
2253 "attributes not allowed");
2255 void
2256 AttrVisitor::visit (AST::TypeAlias &type_alias)
2258 // initial test based on outer attrs
2259 expander.expand_cfg_attrs (type_alias.get_outer_attrs ());
2260 if (expander.fails_cfg_with_expand (type_alias.get_outer_attrs ()))
2262 type_alias.mark_for_strip ();
2263 return;
2266 // just expand sub-stuff - can't actually strip generic params themselves
2267 for (auto &param : type_alias.get_generic_params ())
2268 param->accept_vis (*this);
2270 if (type_alias.has_where_clause ())
2271 expand_where_clause (type_alias.get_where_clause ());
2273 auto &type = type_alias.get_type_aliased ();
2274 type->accept_vis (*this);
2275 if (type->is_marked_for_strip ())
2276 rust_error_at (type->get_locus (), "cannot strip type in this position");
2278 void
2279 AttrVisitor::visit (AST::StructStruct &struct_item)
2281 // initial test based on outer attrs
2282 expander.expand_cfg_attrs (struct_item.get_outer_attrs ());
2283 if (expander.fails_cfg_with_expand (struct_item.get_outer_attrs ()))
2285 struct_item.mark_for_strip ();
2286 return;
2289 // just expand sub-stuff - can't actually strip generic params themselves
2290 for (auto &param : struct_item.get_generic_params ())
2291 param->accept_vis (*this);
2293 if (struct_item.has_where_clause ())
2294 expand_where_clause (struct_item.get_where_clause ());
2296 /* strip struct fields if required - this is presumably
2297 * allowed by spec */
2298 expand_struct_fields (struct_item.get_fields ());
2300 void
2301 AttrVisitor::visit (AST::TupleStruct &tuple_struct)
2303 // initial test based on outer attrs
2304 expander.expand_cfg_attrs (tuple_struct.get_outer_attrs ());
2305 if (expander.fails_cfg_with_expand (tuple_struct.get_outer_attrs ()))
2307 tuple_struct.mark_for_strip ();
2308 return;
2311 // just expand sub-stuff - can't actually strip generic params themselves
2312 for (auto &param : tuple_struct.get_generic_params ())
2313 param->accept_vis (*this);
2315 /* strip struct fields if required - this is presumably
2316 * allowed by spec */
2317 expand_tuple_fields (tuple_struct.get_fields ());
2319 if (tuple_struct.has_where_clause ())
2320 expand_where_clause (tuple_struct.get_where_clause ());
2322 void
2323 AttrVisitor::visit (AST::EnumItem &item)
2325 // initial test based on outer attrs
2326 expander.expand_cfg_attrs (item.get_outer_attrs ());
2327 if (expander.fails_cfg_with_expand (item.get_outer_attrs ()))
2329 item.mark_for_strip ();
2330 return;
2333 void
2334 AttrVisitor::visit (AST::EnumItemTuple &item)
2336 // initial test based on outer attrs
2337 expander.expand_cfg_attrs (item.get_outer_attrs ());
2338 if (expander.fails_cfg_with_expand (item.get_outer_attrs ()))
2340 item.mark_for_strip ();
2341 return;
2344 /* strip item fields if required - this is presumably
2345 * allowed by spec */
2346 expand_tuple_fields (item.get_tuple_fields ());
2348 void
2349 AttrVisitor::visit (AST::EnumItemStruct &item)
2351 // initial test based on outer attrs
2352 expander.expand_cfg_attrs (item.get_outer_attrs ());
2353 if (expander.fails_cfg_with_expand (item.get_outer_attrs ()))
2355 item.mark_for_strip ();
2356 return;
2359 /* strip item fields if required - this is presumably
2360 * allowed by spec */
2361 expand_struct_fields (item.get_struct_fields ());
2363 void
2364 AttrVisitor::visit (AST::EnumItemDiscriminant &item)
2366 // initial test based on outer attrs
2367 expander.expand_cfg_attrs (item.get_outer_attrs ());
2368 if (expander.fails_cfg_with_expand (item.get_outer_attrs ()))
2370 item.mark_for_strip ();
2371 return;
2374 /* strip any internal sub-expressions - expression itself isn't
2375 * allowed to have external attributes in this position so can't be
2376 * stripped. */
2377 auto &expr = item.get_expr ();
2378 expr->accept_vis (*this);
2379 if (expr->is_marked_for_strip ())
2380 rust_error_at (expr->get_locus (),
2381 "cannot strip expression in this position - outer "
2382 "attributes not allowed");
2384 void
2385 AttrVisitor::visit (AST::Enum &enum_item)
2387 // initial test based on outer attrs
2388 expander.expand_cfg_attrs (enum_item.get_outer_attrs ());
2389 if (expander.fails_cfg_with_expand (enum_item.get_outer_attrs ()))
2391 enum_item.mark_for_strip ();
2392 return;
2395 // just expand sub-stuff - can't actually strip generic params themselves
2396 for (auto &param : enum_item.get_generic_params ())
2397 param->accept_vis (*this);
2399 if (enum_item.has_where_clause ())
2400 expand_where_clause (enum_item.get_where_clause ());
2402 /* strip enum fields if required - this is presumably
2403 * allowed by spec */
2404 expand_pointer_allow_strip (enum_item.get_variants ());
2406 void
2407 AttrVisitor::visit (AST::Union &union_item)
2409 // initial test based on outer attrs
2410 expander.expand_cfg_attrs (union_item.get_outer_attrs ());
2411 if (expander.fails_cfg_with_expand (union_item.get_outer_attrs ()))
2413 union_item.mark_for_strip ();
2414 return;
2417 // just expand sub-stuff - can't actually strip generic params themselves
2418 for (auto &param : union_item.get_generic_params ())
2419 param->accept_vis (*this);
2421 if (union_item.has_where_clause ())
2422 expand_where_clause (union_item.get_where_clause ());
2424 /* strip union fields if required - this is presumably
2425 * allowed by spec */
2426 expand_struct_fields (union_item.get_variants ());
2428 void
2429 AttrVisitor::visit (AST::ConstantItem &const_item)
2431 // initial test based on outer attrs
2432 expander.expand_cfg_attrs (const_item.get_outer_attrs ());
2433 if (expander.fails_cfg_with_expand (const_item.get_outer_attrs ()))
2435 const_item.mark_for_strip ();
2436 return;
2439 expander.push_context (MacroExpander::ContextType::TYPE);
2441 // strip any sub-types
2442 auto &type = const_item.get_type ();
2443 type->accept_vis (*this);
2445 maybe_expand_type (type);
2447 if (type->is_marked_for_strip ())
2448 rust_error_at (type->get_locus (), "cannot strip type in this position");
2450 expander.pop_context ();
2452 /* strip any internal sub-expressions - expression itself isn't
2453 * allowed to have external attributes in this position so can't be
2454 * stripped. */
2455 auto &expr = const_item.get_expr ();
2456 expr->accept_vis (*this);
2457 if (expr->is_marked_for_strip ())
2458 rust_error_at (expr->get_locus (),
2459 "cannot strip expression in this position - outer "
2460 "attributes not allowed");
2462 void
2463 AttrVisitor::visit (AST::StaticItem &static_item)
2465 // initial test based on outer attrs
2466 expander.expand_cfg_attrs (static_item.get_outer_attrs ());
2467 if (expander.fails_cfg_with_expand (static_item.get_outer_attrs ()))
2469 static_item.mark_for_strip ();
2470 return;
2473 expander.push_context (MacroExpander::ContextType::TYPE);
2475 // strip any sub-types
2476 auto &type = static_item.get_type ();
2477 type->accept_vis (*this);
2479 maybe_expand_type (type);
2481 if (type->is_marked_for_strip ())
2482 rust_error_at (type->get_locus (), "cannot strip type in this position");
2484 expander.pop_context ();
2486 /* strip any internal sub-expressions - expression itself isn't
2487 * allowed to have external attributes in this position so can't be
2488 * stripped. */
2489 auto &expr = static_item.get_expr ();
2490 expr->accept_vis (*this);
2491 if (expr->is_marked_for_strip ())
2492 rust_error_at (expr->get_locus (),
2493 "cannot strip expression in this position - outer "
2494 "attributes not allowed");
2496 void
2497 AttrVisitor::visit (AST::TraitItemFunc &item)
2499 // initial test based on outer attrs
2500 expander.expand_cfg_attrs (item.get_outer_attrs ());
2501 if (expander.fails_cfg_with_expand (item.get_outer_attrs ()))
2503 item.mark_for_strip ();
2504 return;
2507 expand_trait_function_decl (item.get_trait_function_decl ());
2509 if (item.has_definition ())
2511 /* strip any internal sub-expressions - expression itself isn't
2512 * allowed to have external attributes in this position so can't be
2513 * stripped. */
2514 auto &block = item.get_definition ();
2515 block->accept_vis (*this);
2516 if (block->is_marked_for_strip ())
2517 rust_error_at (block->get_locus (),
2518 "cannot strip block expression in this "
2519 "position - outer attributes not allowed");
2522 void
2523 AttrVisitor::visit (AST::TraitItemMethod &item)
2525 // initial test based on outer attrs
2526 expander.expand_cfg_attrs (item.get_outer_attrs ());
2527 if (expander.fails_cfg_with_expand (item.get_outer_attrs ()))
2529 item.mark_for_strip ();
2530 return;
2533 expand_trait_method_decl (item.get_trait_method_decl ());
2535 if (item.has_definition ())
2537 /* strip any internal sub-expressions - expression itself isn't
2538 * allowed to have external attributes in this position so can't be
2539 * stripped. */
2540 auto &block = item.get_definition ();
2541 block->accept_vis (*this);
2542 if (block->is_marked_for_strip ())
2543 rust_error_at (block->get_locus (),
2544 "cannot strip block expression in this "
2545 "position - outer attributes not allowed");
2548 void
2549 AttrVisitor::visit (AST::TraitItemConst &item)
2551 // initial test based on outer attrs
2552 expander.expand_cfg_attrs (item.get_outer_attrs ());
2553 if (expander.fails_cfg_with_expand (item.get_outer_attrs ()))
2555 item.mark_for_strip ();
2556 return;
2559 expander.push_context (MacroExpander::ContextType::TYPE);
2561 // strip any sub-types
2562 auto &type = item.get_type ();
2563 type->accept_vis (*this);
2565 maybe_expand_type (type);
2567 if (type->is_marked_for_strip ())
2568 rust_error_at (type->get_locus (), "cannot strip type in this position");
2570 expander.pop_context ();
2572 /* strip any internal sub-expressions - expression itself isn't
2573 * allowed to have external attributes in this position so can't be
2574 * stripped */
2575 if (item.has_expression ())
2577 auto &expr = item.get_expr ();
2578 expr->accept_vis (*this);
2579 if (expr->is_marked_for_strip ())
2580 rust_error_at (expr->get_locus (),
2581 "cannot strip expression in this position - outer "
2582 "attributes not allowed");
2585 void
2586 AttrVisitor::visit (AST::TraitItemType &item)
2588 // initial test based on outer attrs
2589 expander.expand_cfg_attrs (item.get_outer_attrs ());
2590 if (expander.fails_cfg_with_expand (item.get_outer_attrs ()))
2592 item.mark_for_strip ();
2593 return;
2596 if (item.has_type_param_bounds ())
2598 // don't strip directly, only components of bounds
2599 for (auto &bound : item.get_type_param_bounds ())
2600 bound->accept_vis (*this);
2603 void
2604 AttrVisitor::visit (AST::Trait &trait)
2606 // initial strip test based on outer attrs
2607 expander.expand_cfg_attrs (trait.get_outer_attrs ());
2608 if (expander.fails_cfg_with_expand (trait.get_outer_attrs ()))
2610 trait.mark_for_strip ();
2611 return;
2614 // strip test based on inner attrs
2615 expander.expand_cfg_attrs (trait.get_inner_attrs ());
2616 if (expander.fails_cfg_with_expand (trait.get_inner_attrs ()))
2618 trait.mark_for_strip ();
2619 return;
2622 // just expand sub-stuff - can't actually strip generic params themselves
2623 for (auto &param : trait.get_generic_params ())
2624 param->accept_vis (*this);
2626 if (trait.has_type_param_bounds ())
2628 // don't strip directly, only components of bounds
2629 for (auto &bound : trait.get_type_param_bounds ())
2630 bound->accept_vis (*this);
2633 if (trait.has_where_clause ())
2634 expand_where_clause (trait.get_where_clause ());
2636 std::function<std::unique_ptr<AST::TraitItem> (AST::SingleASTNode)> extractor
2637 = [] (AST::SingleASTNode node) { return node.take_trait_item (); };
2639 expand_macro_children (MacroExpander::TRAIT, trait.get_trait_items (),
2640 extractor);
2642 void
2643 AttrVisitor::visit (AST::InherentImpl &impl)
2645 // initial strip test based on outer attrs
2646 expander.expand_cfg_attrs (impl.get_outer_attrs ());
2647 if (expander.fails_cfg_with_expand (impl.get_outer_attrs ()))
2649 impl.mark_for_strip ();
2650 return;
2653 // strip test based on inner attrs
2654 expander.expand_cfg_attrs (impl.get_inner_attrs ());
2655 if (expander.fails_cfg_with_expand (impl.get_inner_attrs ()))
2657 impl.mark_for_strip ();
2658 return;
2661 // just expand sub-stuff - can't actually strip generic params themselves
2662 for (auto &param : impl.get_generic_params ())
2663 param->accept_vis (*this);
2665 expander.push_context (MacroExpander::ContextType::ITEM);
2667 auto &type = impl.get_type ();
2668 type->accept_vis (*this);
2670 maybe_expand_type (type);
2672 if (type->is_marked_for_strip ())
2673 rust_error_at (type->get_locus (), "cannot strip type in this position");
2675 expander.pop_context ();
2677 if (impl.has_where_clause ())
2678 expand_where_clause (impl.get_where_clause ());
2680 std::function<std::unique_ptr<AST::InherentImplItem> (AST::SingleASTNode)>
2681 extractor = [] (AST::SingleASTNode node) { return node.take_impl_item (); };
2683 expand_macro_children (MacroExpander::IMPL, impl.get_impl_items (),
2684 extractor);
2686 void
2687 AttrVisitor::visit (AST::TraitImpl &impl)
2689 // initial strip test based on outer attrs
2690 expander.expand_cfg_attrs (impl.get_outer_attrs ());
2691 if (expander.fails_cfg_with_expand (impl.get_outer_attrs ()))
2693 impl.mark_for_strip ();
2694 return;
2697 // strip test based on inner attrs
2698 expander.expand_cfg_attrs (impl.get_inner_attrs ());
2699 if (expander.fails_cfg_with_expand (impl.get_inner_attrs ()))
2701 impl.mark_for_strip ();
2702 return;
2705 // just expand sub-stuff - can't actually strip generic params themselves
2706 for (auto &param : impl.get_generic_params ())
2707 param->accept_vis (*this);
2709 expander.push_context (MacroExpander::ContextType::ITEM);
2711 auto &type = impl.get_type ();
2712 type->accept_vis (*this);
2714 maybe_expand_type (type);
2716 if (type->is_marked_for_strip ())
2717 rust_error_at (type->get_locus (), "cannot strip type in this position");
2719 expander.pop_context ();
2721 auto &trait_path = impl.get_trait_path ();
2722 visit (trait_path);
2723 if (trait_path.is_marked_for_strip ())
2724 rust_error_at (trait_path.get_locus (),
2725 "cannot strip typepath in this position");
2727 if (impl.has_where_clause ())
2728 expand_where_clause (impl.get_where_clause ());
2730 std::function<std::unique_ptr<AST::TraitImplItem> (AST::SingleASTNode)>
2731 extractor
2732 = [] (AST::SingleASTNode node) { return node.take_trait_impl_item (); };
2734 expand_macro_children (MacroExpander::TRAIT_IMPL, impl.get_impl_items (),
2735 extractor);
2737 void
2738 AttrVisitor::visit (AST::ExternalStaticItem &item)
2740 // strip test based on outer attrs
2741 expander.expand_cfg_attrs (item.get_outer_attrs ());
2742 if (expander.fails_cfg_with_expand (item.get_outer_attrs ()))
2744 item.mark_for_strip ();
2745 return;
2748 expander.push_context (MacroExpander::ContextType::TYPE);
2750 auto &type = item.get_type ();
2751 type->accept_vis (*this);
2753 maybe_expand_type (type);
2755 if (type->is_marked_for_strip ())
2756 rust_error_at (type->get_locus (), "cannot strip type in this position");
2758 expander.pop_context ();
2760 void
2761 AttrVisitor::visit (AST::ExternalFunctionItem &item)
2763 // strip test based on outer attrs
2764 expander.expand_cfg_attrs (item.get_outer_attrs ());
2765 if (expander.fails_cfg_with_expand (item.get_outer_attrs ()))
2767 item.mark_for_strip ();
2768 return;
2771 // just expand sub-stuff - can't actually strip generic params themselves
2772 for (auto &param : item.get_generic_params ())
2773 param->accept_vis (*this);
2775 /* strip function parameters if required - this is specifically
2776 * allowed by spec */
2777 auto &params = item.get_function_params ();
2778 for (auto it = params.begin (); it != params.end ();)
2780 auto &param = *it;
2782 auto &param_attrs = param.get_outer_attrs ();
2783 expander.expand_cfg_attrs (param_attrs);
2784 if (expander.fails_cfg_with_expand (param_attrs))
2786 it = params.erase (it);
2787 continue;
2790 expander.push_context (MacroExpander::ContextType::TYPE);
2792 auto &type = param.get_type ();
2793 type->accept_vis (*this);
2795 maybe_expand_type (type);
2797 if (type->is_marked_for_strip ())
2798 rust_error_at (type->get_locus (),
2799 "cannot strip type in this position");
2801 expander.pop_context ();
2803 // increment if nothing else happens
2804 ++it;
2806 /* NOTE: these are extern function params, which may have different
2807 * rules and restrictions to "normal" function params. So expansion
2808 * handled separately. */
2810 /* TODO: assuming that variadic nature cannot be stripped. If this
2811 * is not true, then have code here to do so. */
2813 if (item.has_return_type ())
2815 expander.push_context (MacroExpander::ContextType::TYPE);
2817 auto &return_type = item.get_return_type ();
2818 return_type->accept_vis (*this);
2820 maybe_expand_type (return_type);
2822 if (return_type->is_marked_for_strip ())
2823 rust_error_at (return_type->get_locus (),
2824 "cannot strip type in this position");
2826 expander.pop_context ();
2829 if (item.has_where_clause ())
2830 expand_where_clause (item.get_where_clause ());
2833 void
2834 AttrVisitor::visit (AST::ExternBlock &block)
2836 // initial strip test based on outer attrs
2837 expander.expand_cfg_attrs (block.get_outer_attrs ());
2838 if (expander.fails_cfg_with_expand (block.get_outer_attrs ()))
2840 block.mark_for_strip ();
2841 return;
2844 // strip test based on inner attrs
2845 expander.expand_cfg_attrs (block.get_inner_attrs ());
2846 if (expander.fails_cfg_with_expand (block.get_inner_attrs ()))
2848 block.mark_for_strip ();
2849 return;
2852 std::function<std::unique_ptr<AST::ExternalItem> (AST::SingleASTNode)>
2853 extractor
2854 = [] (AST::SingleASTNode node) { return node.take_external_item (); };
2856 expand_macro_children (MacroExpander::EXTERN, block.get_extern_items (),
2857 extractor);
2860 // I don't think it would be possible to strip macros without expansion
2861 void
2862 AttrVisitor::visit (AST::MacroMatchFragment &)
2864 void
2865 AttrVisitor::visit (AST::MacroMatchRepetition &)
2867 void
2868 AttrVisitor::visit (AST::MacroMatcher &)
2870 void
2871 AttrVisitor::visit (AST::MacroRulesDefinition &rules_def)
2873 // initial strip test based on outer attrs
2874 expander.expand_cfg_attrs (rules_def.get_outer_attrs ());
2875 if (expander.fails_cfg_with_expand (rules_def.get_outer_attrs ()))
2877 rules_def.mark_for_strip ();
2878 return;
2882 void
2883 AttrVisitor::visit (AST::MetaItemPath &)
2885 void
2886 AttrVisitor::visit (AST::MetaItemSeq &)
2888 void
2889 AttrVisitor::visit (AST::MetaWord &)
2891 void
2892 AttrVisitor::visit (AST::MetaNameValueStr &)
2894 void
2895 AttrVisitor::visit (AST::MetaListPaths &)
2897 void
2898 AttrVisitor::visit (AST::MetaListNameValueStr &)
2901 void
2902 AttrVisitor::visit (AST::LiteralPattern &)
2904 // not possible
2906 void
2907 AttrVisitor::visit (AST::IdentifierPattern &pattern)
2909 // can only strip sub-patterns of the inner pattern to bind
2910 if (!pattern.has_pattern_to_bind ())
2911 return;
2913 auto &sub_pattern = pattern.get_pattern_to_bind ();
2914 sub_pattern->accept_vis (*this);
2915 if (sub_pattern->is_marked_for_strip ())
2916 rust_error_at (sub_pattern->get_locus (),
2917 "cannot strip pattern in this position");
2919 void
2920 AttrVisitor::visit (AST::WildcardPattern &)
2922 // not possible
2924 void
2925 AttrVisitor::visit (AST::RangePatternBoundLiteral &)
2927 // not possible
2929 void
2930 AttrVisitor::visit (AST::RangePatternBoundPath &bound)
2932 // can expand path, but not strip it directly
2933 auto &path = bound.get_path ();
2934 visit (path);
2935 if (path.is_marked_for_strip ())
2936 rust_error_at (path.get_locus (), "cannot strip path in this position");
2938 void
2939 AttrVisitor::visit (AST::RangePatternBoundQualPath &bound)
2941 // can expand path, but not strip it directly
2942 auto &path = bound.get_qualified_path ();
2943 visit (path);
2944 if (path.is_marked_for_strip ())
2945 rust_error_at (path.get_locus (), "cannot strip path in this position");
2947 void
2948 AttrVisitor::visit (AST::RangePattern &pattern)
2950 // should have no capability to strip lower or upper bounds, only expand
2951 pattern.get_lower_bound ()->accept_vis (*this);
2952 pattern.get_upper_bound ()->accept_vis (*this);
2954 void
2955 AttrVisitor::visit (AST::ReferencePattern &pattern)
2957 auto &sub_pattern = pattern.get_referenced_pattern ();
2958 sub_pattern->accept_vis (*this);
2959 if (sub_pattern->is_marked_for_strip ())
2960 rust_error_at (sub_pattern->get_locus (),
2961 "cannot strip pattern in this position");
2963 void
2964 AttrVisitor::visit (AST::StructPatternFieldTuplePat &field)
2966 // initial strip test based on outer attrs
2967 expander.expand_cfg_attrs (field.get_outer_attrs ());
2968 if (expander.fails_cfg_with_expand (field.get_outer_attrs ()))
2970 field.mark_for_strip ();
2971 return;
2974 // strip sub-patterns (can't strip top-level pattern)
2975 auto &sub_pattern = field.get_index_pattern ();
2976 sub_pattern->accept_vis (*this);
2977 if (sub_pattern->is_marked_for_strip ())
2978 rust_error_at (sub_pattern->get_locus (),
2979 "cannot strip pattern in this position");
2981 void
2982 AttrVisitor::visit (AST::StructPatternFieldIdentPat &field)
2984 // initial strip test based on outer attrs
2985 expander.expand_cfg_attrs (field.get_outer_attrs ());
2986 if (expander.fails_cfg_with_expand (field.get_outer_attrs ()))
2988 field.mark_for_strip ();
2989 return;
2992 // strip sub-patterns (can't strip top-level pattern)
2993 auto &sub_pattern = field.get_ident_pattern ();
2994 sub_pattern->accept_vis (*this);
2995 if (sub_pattern->is_marked_for_strip ())
2996 rust_error_at (sub_pattern->get_locus (),
2997 "cannot strip pattern in this position");
2999 void
3000 AttrVisitor::visit (AST::StructPatternFieldIdent &field)
3002 // initial strip test based on outer attrs
3003 expander.expand_cfg_attrs (field.get_outer_attrs ());
3004 if (expander.fails_cfg_with_expand (field.get_outer_attrs ()))
3006 field.mark_for_strip ();
3007 return;
3010 void
3011 AttrVisitor::visit (AST::StructPattern &pattern)
3013 // expand (but don't strip) path
3014 auto &path = pattern.get_path ();
3015 visit (path);
3016 if (path.is_marked_for_strip ())
3017 rust_error_at (path.get_locus (), "cannot strip path in this position");
3019 /* TODO: apparently struct pattern fields can have outer attrs. so can they
3020 * be stripped? */
3021 if (!pattern.has_struct_pattern_elems ())
3022 return;
3024 auto &elems = pattern.get_struct_pattern_elems ();
3026 // assuming you can strip struct pattern fields
3027 expand_pointer_allow_strip (elems.get_struct_pattern_fields ());
3029 // assuming you can strip the ".." part
3030 if (elems.has_etc ())
3032 expander.expand_cfg_attrs (elems.get_etc_outer_attrs ());
3033 if (expander.fails_cfg_with_expand (elems.get_etc_outer_attrs ()))
3034 elems.strip_etc ();
3037 void
3038 AttrVisitor::visit (AST::TupleStructItemsNoRange &tuple_items)
3040 // can't strip individual patterns, only sub-patterns
3041 for (auto &pattern : tuple_items.get_patterns ())
3043 pattern->accept_vis (*this);
3045 if (pattern->is_marked_for_strip ())
3046 rust_error_at (pattern->get_locus (),
3047 "cannot strip pattern in this position");
3048 // TODO: quit stripping now? or keep going?
3051 void
3052 AttrVisitor::visit (AST::TupleStructItemsRange &tuple_items)
3054 // can't strip individual patterns, only sub-patterns
3055 for (auto &lower_pattern : tuple_items.get_lower_patterns ())
3057 lower_pattern->accept_vis (*this);
3059 if (lower_pattern->is_marked_for_strip ())
3060 rust_error_at (lower_pattern->get_locus (),
3061 "cannot strip pattern in this position");
3062 // TODO: quit stripping now? or keep going?
3064 for (auto &upper_pattern : tuple_items.get_upper_patterns ())
3066 upper_pattern->accept_vis (*this);
3068 if (upper_pattern->is_marked_for_strip ())
3069 rust_error_at (upper_pattern->get_locus (),
3070 "cannot strip pattern in this position");
3071 // TODO: quit stripping now? or keep going?
3074 void
3075 AttrVisitor::visit (AST::TupleStructPattern &pattern)
3077 // expand (but don't strip) path
3078 auto &path = pattern.get_path ();
3079 visit (path);
3080 if (path.is_marked_for_strip ())
3081 rust_error_at (path.get_locus (), "cannot strip path in this position");
3083 if (pattern.has_items ())
3084 pattern.get_items ()->accept_vis (*this);
3086 void
3087 AttrVisitor::visit (AST::TuplePatternItemsMultiple &tuple_items)
3089 // can't strip individual patterns, only sub-patterns
3090 for (auto &pattern : tuple_items.get_patterns ())
3092 pattern->accept_vis (*this);
3094 if (pattern->is_marked_for_strip ())
3095 rust_error_at (pattern->get_locus (),
3096 "cannot strip pattern in this position");
3097 // TODO: quit stripping now? or keep going?
3100 void
3101 AttrVisitor::visit (AST::TuplePatternItemsRanged &tuple_items)
3103 // can't strip individual patterns, only sub-patterns
3104 for (auto &lower_pattern : tuple_items.get_lower_patterns ())
3106 lower_pattern->accept_vis (*this);
3108 if (lower_pattern->is_marked_for_strip ())
3109 rust_error_at (lower_pattern->get_locus (),
3110 "cannot strip pattern in this position");
3111 // TODO: quit stripping now? or keep going?
3113 for (auto &upper_pattern : tuple_items.get_upper_patterns ())
3115 upper_pattern->accept_vis (*this);
3117 if (upper_pattern->is_marked_for_strip ())
3118 rust_error_at (upper_pattern->get_locus (),
3119 "cannot strip pattern in this position");
3120 // TODO: quit stripping now? or keep going?
3123 void
3124 AttrVisitor::visit (AST::TuplePattern &pattern)
3126 if (pattern.has_tuple_pattern_items ())
3127 pattern.get_items ()->accept_vis (*this);
3129 void
3130 AttrVisitor::visit (AST::GroupedPattern &pattern)
3132 // can't strip inner pattern, only sub-patterns
3133 auto &pattern_in_parens = pattern.get_pattern_in_parens ();
3135 pattern_in_parens->accept_vis (*this);
3137 if (pattern_in_parens->is_marked_for_strip ())
3138 rust_error_at (pattern_in_parens->get_locus (),
3139 "cannot strip pattern in this position");
3141 void
3142 AttrVisitor::visit (AST::SlicePattern &pattern)
3144 // can't strip individual patterns, only sub-patterns
3145 for (auto &item : pattern.get_items ())
3147 item->accept_vis (*this);
3149 if (item->is_marked_for_strip ())
3150 rust_error_at (item->get_locus (),
3151 "cannot strip pattern in this position");
3152 // TODO: quit stripping now? or keep going?
3155 void
3156 AttrVisitor::visit (AST::AltPattern &pattern)
3158 // can't strip individual patterns, only sub-patterns
3159 for (auto &alt : pattern.get_alts ())
3161 alt->accept_vis (*this);
3163 if (alt->is_marked_for_strip ())
3164 rust_error_at (alt->get_locus (),
3165 "cannot strip pattern in this position");
3166 // TODO: quit stripping now? or keep going?
3170 void
3171 AttrVisitor::visit (AST::EmptyStmt &)
3173 // assuming no outer attributes, so nothing can happen
3175 void
3176 AttrVisitor::visit (AST::LetStmt &stmt)
3178 // initial strip test based on outer attrs
3179 expander.expand_cfg_attrs (stmt.get_outer_attrs ());
3180 if (expander.fails_cfg_with_expand (stmt.get_outer_attrs ()))
3182 stmt.mark_for_strip ();
3183 return;
3186 // can't strip pattern, but call for sub-patterns
3187 auto &pattern = stmt.get_pattern ();
3188 pattern->accept_vis (*this);
3189 if (pattern->is_marked_for_strip ())
3190 rust_error_at (pattern->get_locus (),
3191 "cannot strip pattern in this position");
3193 // similar for type
3194 if (stmt.has_type ())
3196 expander.push_context (MacroExpander::ContextType::TYPE);
3198 auto &type = stmt.get_type ();
3199 type->accept_vis (*this);
3201 maybe_expand_type (type);
3203 if (type->is_marked_for_strip ())
3204 rust_error_at (type->get_locus (),
3205 "cannot strip type in this position");
3207 expander.pop_context ();
3210 /* strip any internal sub-expressions - expression itself isn't
3211 * allowed to have external attributes in this position so can't be
3212 * stripped */
3213 if (stmt.has_init_expr ())
3215 auto &init_expr = stmt.get_init_expr ();
3216 init_expr->accept_vis (*this);
3218 if (init_expr->is_marked_for_strip ())
3219 rust_error_at (init_expr->get_locus (),
3220 "cannot strip expression in this position - outer "
3221 "attributes not allowed");
3223 maybe_expand_expr (init_expr);
3226 void
3227 AttrVisitor::visit (AST::ExprStmtWithoutBlock &stmt)
3229 // outer attributes associated with expr, so rely on expr
3231 // guard - should prevent null pointer expr
3232 if (stmt.is_marked_for_strip ())
3233 return;
3235 // strip if expr is to be stripped
3236 auto &expr = stmt.get_expr ();
3237 expr->accept_vis (*this);
3238 if (expr->is_marked_for_strip ())
3240 stmt.mark_for_strip ();
3241 return;
3244 void
3245 AttrVisitor::visit (AST::ExprStmtWithBlock &stmt)
3247 // outer attributes associated with expr, so rely on expr
3249 // guard - should prevent null pointer expr
3250 if (stmt.is_marked_for_strip ())
3251 return;
3253 // strip if expr is to be stripped
3254 auto &expr = stmt.get_expr ();
3255 expr->accept_vis (*this);
3256 if (expr->is_marked_for_strip ())
3258 stmt.mark_for_strip ();
3259 return;
3263 void
3264 AttrVisitor::visit (AST::TraitBound &bound)
3266 // nothing in for lifetimes to strip
3268 // expand but don't strip type path
3269 auto &path = bound.get_type_path ();
3270 visit (path);
3271 if (path.is_marked_for_strip ())
3272 rust_error_at (path.get_locus (),
3273 "cannot strip type path in this position");
3275 void
3276 AttrVisitor::visit (AST::ImplTraitType &type)
3278 // don't strip directly, only components of bounds
3279 for (auto &bound : type.get_type_param_bounds ())
3280 bound->accept_vis (*this);
3282 void
3283 AttrVisitor::visit (AST::TraitObjectType &type)
3285 // don't strip directly, only components of bounds
3286 for (auto &bound : type.get_type_param_bounds ())
3287 bound->accept_vis (*this);
3289 void
3290 AttrVisitor::visit (AST::ParenthesisedType &type)
3292 // expand but don't strip inner type
3293 auto &inner_type = type.get_type_in_parens ();
3294 inner_type->accept_vis (*this);
3295 if (inner_type->is_marked_for_strip ())
3296 rust_error_at (inner_type->get_locus (),
3297 "cannot strip type in this position");
3299 void
3300 AttrVisitor::visit (AST::ImplTraitTypeOneBound &type)
3302 // no stripping possible
3303 visit (type.get_trait_bound ());
3305 void
3306 AttrVisitor::visit (AST::TraitObjectTypeOneBound &type)
3308 // no stripping possible
3309 visit (type.get_trait_bound ());
3311 void
3312 AttrVisitor::visit (AST::TupleType &type)
3314 // TODO: assuming that types can't be stripped as types don't have outer
3315 // attributes
3316 for (auto &elem_type : type.get_elems ())
3318 elem_type->accept_vis (*this);
3319 if (elem_type->is_marked_for_strip ())
3320 rust_error_at (elem_type->get_locus (),
3321 "cannot strip type in this position");
3324 void
3325 AttrVisitor::visit (AST::NeverType &)
3327 // no stripping possible
3329 void
3330 AttrVisitor::visit (AST::RawPointerType &type)
3332 // expand but don't strip type pointed to
3333 auto &pointed_type = type.get_type_pointed_to ();
3334 pointed_type->accept_vis (*this);
3335 if (pointed_type->is_marked_for_strip ())
3336 rust_error_at (pointed_type->get_locus (),
3337 "cannot strip type in this position");
3339 void
3340 AttrVisitor::visit (AST::ReferenceType &type)
3342 // expand but don't strip type referenced
3343 auto &referenced_type = type.get_type_referenced ();
3344 referenced_type->accept_vis (*this);
3345 if (referenced_type->is_marked_for_strip ())
3346 rust_error_at (referenced_type->get_locus (),
3347 "cannot strip type in this position");
3349 void
3350 AttrVisitor::visit (AST::ArrayType &type)
3352 // expand but don't strip type referenced
3353 auto &base_type = type.get_elem_type ();
3354 base_type->accept_vis (*this);
3355 if (base_type->is_marked_for_strip ())
3356 rust_error_at (base_type->get_locus (),
3357 "cannot strip type in this position");
3359 // same for expression
3360 auto &size_expr = type.get_size_expr ();
3361 size_expr->accept_vis (*this);
3362 if (size_expr->is_marked_for_strip ())
3363 rust_error_at (size_expr->get_locus (),
3364 "cannot strip expression in this position");
3366 void
3367 AttrVisitor::visit (AST::SliceType &type)
3369 // expand but don't strip elem type
3370 auto &elem_type = type.get_elem_type ();
3371 elem_type->accept_vis (*this);
3372 if (elem_type->is_marked_for_strip ())
3373 rust_error_at (elem_type->get_locus (),
3374 "cannot strip type in this position");
3376 void
3377 AttrVisitor::visit (AST::InferredType &)
3379 // none possible
3381 void
3382 AttrVisitor::visit (AST::BareFunctionType &type)
3384 // seem to be no generics
3386 // presumably function params can be stripped
3387 auto &params = type.get_function_params ();
3388 for (auto it = params.begin (); it != params.end ();)
3390 auto &param = *it;
3392 auto &param_attrs = param.get_outer_attrs ();
3393 expander.expand_cfg_attrs (param_attrs);
3394 if (expander.fails_cfg_with_expand (param_attrs))
3396 it = params.erase (it);
3397 continue;
3400 expander.push_context (MacroExpander::ContextType::TYPE);
3402 auto &type = param.get_type ();
3403 type->accept_vis (*this);
3405 maybe_expand_type (type);
3407 if (type->is_marked_for_strip ())
3408 rust_error_at (type->get_locus (),
3409 "cannot strip type in this position");
3411 expander.pop_context ();
3413 // increment if nothing else happens
3414 ++it;
3417 /* TODO: assuming that variadic nature cannot be stripped. If this
3418 * is not true, then have code here to do so. */
3420 if (type.has_return_type ())
3422 // FIXME: Can we have type expansion in this position?
3423 // In that case, we need to handle AST::TypeNoBounds on top of just
3424 // AST::Types
3425 auto &return_type = type.get_return_type ();
3426 return_type->accept_vis (*this);
3427 if (return_type->is_marked_for_strip ())
3428 rust_error_at (return_type->get_locus (),
3429 "cannot strip type in this position");
3432 // no where clause, apparently
3435 void
3436 AttrVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
3438 auto final_fragment = expander.take_expanded_fragment ();
3439 if (final_fragment.should_expand ()
3440 && final_fragment.is_expression_fragment ())
3441 expr = final_fragment.take_expression_fragment ();
3444 void
3445 AttrVisitor::maybe_expand_type (std::unique_ptr<AST::Type> &type)
3447 auto final_fragment = expander.take_expanded_fragment ();
3448 if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
3449 type = final_fragment.take_type_fragment ();
3452 } // namespace Rust