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
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
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"
24 // Visitor used to expand attributes.
26 AttrVisitor::expand_struct_fields (std::vector
<AST::StructField
> &fields
)
28 for (auto it
= fields
.begin (); it
!= fields
.end ();)
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
);
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
60 AttrVisitor::expand_tuple_fields (std::vector
<AST::TupleField
> &fields
)
62 for (auto it
= fields
.begin (); it
!= fields
.end ();)
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
);
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
87 AttrVisitor::expand_function_params (std::vector
<AST::FunctionParam
> ¶ms
)
89 expander
.push_context (MacroExpander::ContextType::TYPE
);
91 for (auto it
= params
.begin (); it
!= params
.end ();)
95 auto ¶m_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
);
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");
123 expander
.pop_context ();
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");
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");
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");
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 ();
203 if (type_path
.is_marked_for_strip ())
204 rust_error_at (type_path
.get_locus (),
205 "cannot strip type path in this position");
210 AttrVisitor::AttrVisitor::expand_closure_params (
211 std::vector
<AST::ClosureParam
> ¶ms
)
213 for (auto it
= params
.begin (); it
!= params
.end ();)
217 auto ¶m_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
);
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
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
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);
281 AttrVisitor::expand_trait_function_decl (AST::TraitFunctionDecl
&decl
)
283 // just expand sub-stuff - can't actually strip generic params themselves
284 for (auto ¶m
: decl
.get_generic_params ())
285 param
->accept_vis (*this);
287 /* strip function parameters if required - this is specifically
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 ());
312 AttrVisitor::expand_trait_method_decl (AST::TraitMethodDecl
&decl
)
314 // just expand sub-stuff - can't actually strip generic params themselves
315 for (auto ¶m
: 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
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 ());
348 AttrVisitor::visit (AST::Token
&)
350 // shouldn't require?
353 AttrVisitor::visit (AST::DelimTokenTree
&)
355 // shouldn't require?
358 AttrVisitor::visit (AST::AttrInputMetaItemContainer
&)
360 // shouldn't require?
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 ();
374 AttrVisitor::visit (AST::Lifetime
&)
376 // shouldn't require?
379 AttrVisitor::visit (AST::LifetimeParam
&)
381 // supposedly does not require - cfg does nothing
384 AttrVisitor::visit (AST::ConstGenericParam
&)
390 AttrVisitor::visit (AST::MacroInvocation
¯o_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 ();
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 ());
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 ();
419 for (auto &segment
: path
.get_segments ())
421 if (segment
.has_generic_args ())
422 expand_generic_args (segment
.get_generic_args ());
426 AttrVisitor::visit (AST::TypePathSegment
&)
431 AttrVisitor::visit (AST::TypePathSegmentGeneric
&segment
)
433 // TODO: strip inside generic args
435 if (!segment
.has_generic_args ())
438 expand_generic_args (segment
.get_generic_args ());
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 ();
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);
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 ();
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 ());
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);
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 ();
517 AttrVisitor::visit (AST::AttrInputLiteral
&)
519 // shouldn't require?
522 AttrVisitor::visit (AST::MetaItemLitExpr
&)
524 // shouldn't require?
527 AttrVisitor::visit (AST::MetaItemPathLit
&)
529 // shouldn't require?
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 ();
542 /* strip any internal sub-expressions - expression itself isn't
543 * allowed to have external attributes in this position so can't be
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");
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 ();
563 /* strip any internal sub-expressions - expression itself isn't
564 * allowed to have external attributes in this position so can't be
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");
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 ();
584 /* strip any internal sub-expressions - expression itself isn't
585 * allowed to have external attributes in this position so can't be
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");
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 ();
605 /* strip any internal sub-expressions - expression itself isn't
606 * allowed to have external attributes in this position so can't be
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");
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
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");
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
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");
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
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");
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
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");
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 ();
735 /* should have no possibility for outer attrs as would be parsed
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");
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
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");
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 ();
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 ();
807 /* strip any internal sub-expressions - expression itself isn't
808 * allowed to have external attributes in this position so can't be
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");
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 ());
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 ©_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");
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 ();
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 ();
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);
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 ();
885 /* strip any internal sub-expressions - expression itself isn't
886 * allowed to have external attributes in this position so can't be
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");
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 ();
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 ();
925 /* apparently outer attributes are allowed in "elements of tuple
926 * expressions" according to spec */
927 expand_pointer_allow_strip (expr
.get_tuple_elems ());
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 ();
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");
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 ();
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 ();
970 // strip sub-exprs of path
971 auto &struct_name
= expr
.get_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");
978 AttrVisitor::visit (AST::StructExprFieldIdentifier
&)
980 // as no attrs (at moment, at least), no stripping possible
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");
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");
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 ();
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 ();
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");
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 ();
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 ();
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");
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 ();
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 ¶ms
= expr
.get_params ();
1119 for (auto it
= params
.begin (); it
!= params
.end ();)
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 ());
1136 else if (stmt
->is_marked_for_strip ())
1137 it
= params
.erase (it
);
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 ();
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 ());
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 ();
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");
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 ();
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");
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 ();
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 ();
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 (),
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 ();
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 ();
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");
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 ();
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 ();
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");
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");
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");
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");
1390 AttrVisitor::visit (AST::RangeFullExpr
&)
1392 // outer attributes never allowed before these, so no stripping
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");
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");
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 ();
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. */
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 ();
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");
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 ();
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");
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 ();
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");
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 ();
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");
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 ();
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");
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 ();
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");
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 ();
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");
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 ();
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");
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 ();
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 "
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 ();
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");
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 ();
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");
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 ();
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");
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 ();
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 "
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 ();
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 ();
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 ()))
1944 it
= match_cases
.erase (it
);
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
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 ();
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");
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 ();
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");
2023 AttrVisitor::visit (AST::TypeParam
¶m
)
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 ();
2050 AttrVisitor::visit (AST::LifetimeWhereClauseItem
&)
2052 // shouldn't require
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);
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 ();
2086 // just expand sub-stuff - can't actually strip generic params themselves
2087 for (auto ¶m
: 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
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");
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 ();
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 ();
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
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 ());
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 ();
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 ());
2182 AttrVisitor::visit (AST::UseTreeGlob
&)
2184 // shouldn't require?
2187 AttrVisitor::visit (AST::UseTreeList
&)
2189 // shouldn't require?
2192 AttrVisitor::visit (AST::UseTreeRebind
&)
2194 // shouldn't require?
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 ();
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 ();
2218 // just expand sub-stuff - can't actually strip generic params themselves
2219 for (auto ¶m
: 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
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");
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 ();
2266 // just expand sub-stuff - can't actually strip generic params themselves
2267 for (auto ¶m
: 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");
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 ();
2289 // just expand sub-stuff - can't actually strip generic params themselves
2290 for (auto ¶m
: 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 ());
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 ();
2311 // just expand sub-stuff - can't actually strip generic params themselves
2312 for (auto ¶m
: 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 ());
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 ();
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 ();
2344 /* strip item fields if required - this is presumably
2345 * allowed by spec */
2346 expand_tuple_fields (item
.get_tuple_fields ());
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 ();
2359 /* strip item fields if required - this is presumably
2360 * allowed by spec */
2361 expand_struct_fields (item
.get_struct_fields ());
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 ();
2374 /* strip any internal sub-expressions - expression itself isn't
2375 * allowed to have external attributes in this position so can't be
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");
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 ();
2395 // just expand sub-stuff - can't actually strip generic params themselves
2396 for (auto ¶m
: 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 ());
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 ();
2417 // just expand sub-stuff - can't actually strip generic params themselves
2418 for (auto ¶m
: 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 ());
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 ();
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
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");
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 ();
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
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");
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 ();
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
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");
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 ();
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
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");
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 ();
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
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");
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 ();
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);
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 ();
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 ();
2622 // just expand sub-stuff - can't actually strip generic params themselves
2623 for (auto ¶m
: 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 (),
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 ();
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 ();
2661 // just expand sub-stuff - can't actually strip generic params themselves
2662 for (auto ¶m
: 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 (),
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 ();
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 ();
2705 // just expand sub-stuff - can't actually strip generic params themselves
2706 for (auto ¶m
: 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 ();
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
)>
2732 = [] (AST::SingleASTNode node
) { return node
.take_trait_impl_item (); };
2734 expand_macro_children (MacroExpander::TRAIT_IMPL
, impl
.get_impl_items (),
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 ();
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 ();
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 ();
2771 // just expand sub-stuff - can't actually strip generic params themselves
2772 for (auto ¶m
: item
.get_generic_params ())
2773 param
->accept_vis (*this);
2775 /* strip function parameters if required - this is specifically
2776 * allowed by spec */
2777 auto ¶ms
= item
.get_function_params ();
2778 for (auto it
= params
.begin (); it
!= params
.end ();)
2782 auto ¶m_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
);
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
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 ());
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 ();
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 ();
2852 std::function
<std::unique_ptr
<AST::ExternalItem
> (AST::SingleASTNode
)>
2854 = [] (AST::SingleASTNode node
) { return node
.take_external_item (); };
2856 expand_macro_children (MacroExpander::EXTERN
, block
.get_extern_items (),
2860 // I don't think it would be possible to strip macros without expansion
2862 AttrVisitor::visit (AST::MacroMatchFragment
&)
2865 AttrVisitor::visit (AST::MacroMatchRepetition
&)
2868 AttrVisitor::visit (AST::MacroMatcher
&)
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 ();
2883 AttrVisitor::visit (AST::MetaItemPath
&)
2886 AttrVisitor::visit (AST::MetaItemSeq
&)
2889 AttrVisitor::visit (AST::MetaWord
&)
2892 AttrVisitor::visit (AST::MetaNameValueStr
&)
2895 AttrVisitor::visit (AST::MetaListPaths
&)
2898 AttrVisitor::visit (AST::MetaListNameValueStr
&)
2902 AttrVisitor::visit (AST::LiteralPattern
&)
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 ())
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");
2920 AttrVisitor::visit (AST::WildcardPattern
&)
2925 AttrVisitor::visit (AST::RangePatternBoundLiteral
&)
2930 AttrVisitor::visit (AST::RangePatternBoundPath
&bound
)
2932 // can expand path, but not strip it directly
2933 auto &path
= bound
.get_path ();
2935 if (path
.is_marked_for_strip ())
2936 rust_error_at (path
.get_locus (), "cannot strip path in this position");
2939 AttrVisitor::visit (AST::RangePatternBoundQualPath
&bound
)
2941 // can expand path, but not strip it directly
2942 auto &path
= bound
.get_qualified_path ();
2944 if (path
.is_marked_for_strip ())
2945 rust_error_at (path
.get_locus (), "cannot strip path in this position");
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);
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");
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 ();
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");
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 ();
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");
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 ();
3011 AttrVisitor::visit (AST::StructPattern
&pattern
)
3013 // expand (but don't strip) path
3014 auto &path
= pattern
.get_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
3021 if (!pattern
.has_struct_pattern_elems ())
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 ()))
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?
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?
3075 AttrVisitor::visit (AST::TupleStructPattern
&pattern
)
3077 // expand (but don't strip) path
3078 auto &path
= pattern
.get_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);
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?
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?
3124 AttrVisitor::visit (AST::TuplePattern
&pattern
)
3126 if (pattern
.has_tuple_pattern_items ())
3127 pattern
.get_items ()->accept_vis (*this);
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");
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?
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?
3171 AttrVisitor::visit (AST::EmptyStmt
&)
3173 // assuming no outer attributes, so nothing can happen
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 ();
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");
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
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
);
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 ())
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 ();
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 ())
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 ();
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 ();
3271 if (path
.is_marked_for_strip ())
3272 rust_error_at (path
.get_locus (),
3273 "cannot strip type path in this position");
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);
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);
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");
3300 AttrVisitor::visit (AST::ImplTraitTypeOneBound
&type
)
3302 // no stripping possible
3303 visit (type
.get_trait_bound ());
3306 AttrVisitor::visit (AST::TraitObjectTypeOneBound
&type
)
3308 // no stripping possible
3309 visit (type
.get_trait_bound ());
3312 AttrVisitor::visit (AST::TupleType
&type
)
3314 // TODO: assuming that types can't be stripped as types don't have outer
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");
3325 AttrVisitor::visit (AST::NeverType
&)
3327 // no stripping possible
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");
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");
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");
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");
3377 AttrVisitor::visit (AST::InferredType
&)
3382 AttrVisitor::visit (AST::BareFunctionType
&type
)
3384 // seem to be no generics
3386 // presumably function params can be stripped
3387 auto ¶ms
= type
.get_function_params ();
3388 for (auto it
= params
.begin (); it
!= params
.end ();)
3392 auto ¶m_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
);
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
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
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
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 ();
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 ();