1 // Copyright (C) 2020-2025 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-cfg-strip.h"
20 #include "rust-ast-full.h"
21 #include "rust-ast-visitor.h"
22 #include "rust-session-manager.h"
23 #include "rust-attribute-values.h"
28 * Determines whether any cfg predicate is false and hence item with attributes
29 * should be stripped. Note that attributes must be expanded before calling.
32 fails_cfg (const AST::AttrVec
&attrs
)
34 auto &session
= Session::get_instance ();
36 for (const auto &attr
: attrs
)
38 if (attr
.get_path () == Values::Attributes::CFG
39 && !attr
.check_cfg_predicate (session
))
46 * Determines whether any cfg predicate is false and hence item with attributes
47 * should be stripped. Will expand attributes as well.
50 fails_cfg_with_expand (AST::AttrVec
&attrs
)
52 auto &session
= Session::get_instance ();
54 // TODO: maybe have something that strips cfg attributes that evaluate true?
55 for (auto &attr
: attrs
)
57 if (attr
.get_path () == Values::Attributes::CFG
)
59 if (!attr
.is_parsed_to_meta_item ())
60 attr
.parse_attr_to_meta_item ();
63 if (!attr
.is_parsed_to_meta_item ())
64 rust_debug ("failed to parse attr to meta item, right before "
65 "cfg predicate check");
67 rust_debug ("attr has been successfully parsed to meta item, "
68 "right before cfg predicate check");
70 if (!attr
.check_cfg_predicate (session
))
74 "cfg predicate failed for attribute: \033[0;31m'%s'\033[0m",
75 attr
.as_string ().c_str ());
82 rust_debug ("cfg predicate succeeded for attribute: "
83 "\033[0;31m'%s'\033[0m",
84 attr
.as_string ().c_str ());
92 * Expands cfg_attr attributes.
95 expand_cfg_attrs (AST::AttrVec
&attrs
)
97 auto &session
= Session::get_instance ();
99 for (std::size_t i
= 0; i
< attrs
.size (); i
++)
101 auto &attr
= attrs
[i
];
102 if (attr
.get_path () == Values::Attributes::CFG_ATTR
)
104 if (!attr
.is_parsed_to_meta_item ())
105 attr
.parse_attr_to_meta_item ();
107 if (attr
.check_cfg_predicate (session
))
109 // split off cfg_attr
110 AST::AttrVec new_attrs
= attr
.separate_cfg_attrs ();
112 // remove attr from vector
113 attrs
.erase (attrs
.begin () + i
);
115 // add new attrs to vector
116 attrs
.insert (attrs
.begin () + i
,
117 std::make_move_iterator (new_attrs
.begin ()),
118 std::make_move_iterator (new_attrs
.end ()));
121 /* do something - if feature (first token in tree) is in fact enabled,
122 * make tokens listed afterwards into attributes. i.e.: for
123 * [cfg_attr(feature = "wow", wow1, wow2)], if "wow" is true, then add
124 * attributes [wow1] and [wow2] to attribute list. This can also be
125 * recursive, so check for expanded attributes being recursive and
126 * possibly recursively call the expand_attrs? */
133 attrs
.shrink_to_fit ();
137 CfgStrip::go (AST::Crate
&crate
)
143 CfgStrip::visit (AST::Crate
&crate
)
145 // expand crate cfg_attr attributes
146 expand_cfg_attrs (crate
.inner_attrs
);
148 if (fails_cfg_with_expand (crate
.inner_attrs
))
150 // basically, delete whole crate
151 crate
.strip_crate ();
152 // TODO: maybe create warning here? probably not desired behaviour
155 auto &items
= crate
.items
;
157 AST::DefaultASTVisitor::visit (crate
);
158 for (auto it
= items
.begin (); it
!= items
.end ();)
161 if (item
->is_marked_for_strip ())
162 it
= items
.erase (it
);
166 // expand module attributes?
169 // Visitor used to expand attributes.
171 CfgStrip::maybe_strip_struct_fields (std::vector
<AST::StructField
> &fields
)
173 for (auto it
= fields
.begin (); it
!= fields
.end ();)
177 auto &field_attrs
= field
.get_outer_attrs ();
178 expand_cfg_attrs (field_attrs
);
179 if (fails_cfg_with_expand (field_attrs
))
181 it
= fields
.erase (it
);
185 // expand sub-types of type, but can't strip type itself
186 auto &type
= field
.get_field_type ();
187 type
.accept_vis (*this);
189 if (type
.is_marked_for_strip ())
190 rust_error_at (type
.get_locus (), "cannot strip type in this position");
192 // if nothing else happens, increment
198 CfgStrip::maybe_strip_tuple_fields (std::vector
<AST::TupleField
> &fields
)
200 for (auto it
= fields
.begin (); it
!= fields
.end ();)
204 auto &field_attrs
= field
.get_outer_attrs ();
205 expand_cfg_attrs (field_attrs
);
206 if (fails_cfg_with_expand (field_attrs
))
208 it
= fields
.erase (it
);
212 // expand sub-types of type, but can't strip type itself
213 auto &type
= field
.get_field_type ();
214 type
.accept_vis (*this);
215 if (type
.is_marked_for_strip ())
216 rust_error_at (type
.get_locus (), "cannot strip type in this position");
218 // if nothing else happens, increment
224 CfgStrip::maybe_strip_function_params (
225 std::vector
<std::unique_ptr
<AST::Param
>> ¶ms
)
227 for (auto it
= params
.begin (); it
!= params
.end ();)
229 if (!(*it
)->is_self () && !(*it
)->is_variadic ())
231 auto param
= static_cast<AST::FunctionParam
*> (it
->get ());
233 auto ¶m_attrs
= param
->get_outer_attrs ();
234 expand_cfg_attrs (param_attrs
);
235 if (fails_cfg_with_expand (param_attrs
))
237 it
= params
.erase (it
);
241 // TODO: should an unwanted strip lead to break out of loop?
242 auto &pattern
= param
->get_pattern ();
243 pattern
.accept_vis (*this);
244 if (pattern
.is_marked_for_strip ())
245 rust_error_at (pattern
.get_locus (),
246 "cannot strip pattern in this position");
248 auto &type
= param
->get_type ();
249 type
.accept_vis (*this);
251 if (type
.is_marked_for_strip ())
252 rust_error_at (type
.get_locus (),
253 "cannot strip type in this position");
261 CfgStrip::maybe_strip_generic_args (AST::GenericArgs
&args
)
263 // lifetime args can't be expanded
264 // FIXME: Can we have macro invocations for lifetimes?
266 // expand type args - strip sub-types only
267 for (auto &arg
: args
.get_generic_args ())
269 switch (arg
.get_kind ())
271 case AST::GenericArg::Kind::Type
: {
272 auto &type
= arg
.get_type ();
273 type
.accept_vis (*this);
275 if (type
.is_marked_for_strip ())
276 rust_error_at (type
.get_locus (),
277 "cannot strip type in this position");
280 case AST::GenericArg::Kind::Const
: {
281 auto &expr
= arg
.get_expression ();
282 expr
.accept_vis (*this);
284 if (expr
.is_marked_for_strip ())
285 rust_error_at (expr
.get_locus (),
286 "cannot strip expression in this position");
291 // FIXME: Figure out what to do here if there is ambiguity. Since the
292 // resolver comes after the expansion, we need to figure out a way to
293 // strip ambiguous values here
294 // TODO: Arthur: Probably add a `mark_as_strip` method to `GenericArg`
295 // or something. This would clean up this whole thing
299 // FIXME: Can we have macro invocations in generic type bindings?
300 // expand binding args - strip sub-types only
301 for (auto &binding
: args
.get_binding_args ())
303 auto &type
= binding
.get_type ();
304 type
.accept_vis (*this);
306 if (type
.is_marked_for_strip ())
307 rust_error_at (type
.get_locus (), "cannot strip type in this position");
312 CfgStrip::maybe_strip_qualified_path_type (AST::QualifiedPathType
&path_type
)
314 auto &type
= path_type
.get_type ();
315 type
.accept_vis (*this);
317 if (type
.is_marked_for_strip ())
318 rust_error_at (type
.get_locus (), "cannot strip type in this position");
320 if (path_type
.has_as_clause ())
322 auto &type_path
= path_type
.get_as_type_path ();
324 if (type_path
.is_marked_for_strip ())
325 rust_error_at (type_path
.get_locus (),
326 "cannot strip type path in this position");
331 CfgStrip::CfgStrip::maybe_strip_closure_params (
332 std::vector
<AST::ClosureParam
> ¶ms
)
334 for (auto it
= params
.begin (); it
!= params
.end ();)
338 auto ¶m_attrs
= param
.get_outer_attrs ();
339 expand_cfg_attrs (param_attrs
);
340 if (fails_cfg_with_expand (param_attrs
))
342 it
= params
.erase (it
);
346 auto &pattern
= param
.get_pattern ();
347 pattern
.accept_vis (*this);
348 if (pattern
.is_marked_for_strip ())
349 rust_error_at (pattern
.get_locus (),
350 "cannot strip pattern in this position");
352 if (param
.has_type_given ())
354 auto &type
= param
.get_type ();
355 type
.accept_vis (*this);
357 if (type
.is_marked_for_strip ())
358 rust_error_at (type
.get_locus (),
359 "cannot strip type in this position");
362 // increment if found nothing else so far
368 CfgStrip::maybe_strip_where_clause (AST::WhereClause
&where_clause
)
370 // items cannot be stripped conceptually, so just accept visitor
371 for (auto &item
: where_clause
.get_items ())
372 item
->accept_vis (*this);
376 CfgStrip::visit (AST::IdentifierExpr
&ident_expr
)
378 // strip test based on outer attrs
379 AST::DefaultASTVisitor::visit (ident_expr
);
380 expand_cfg_attrs (ident_expr
.get_outer_attrs ());
381 if (fails_cfg_with_expand (ident_expr
.get_outer_attrs ()))
383 ident_expr
.mark_for_strip ();
389 CfgStrip::visit (AST::MacroInvocation
¯o_invoc
)
391 // initial strip test based on outer attrs
392 expand_cfg_attrs (macro_invoc
.get_outer_attrs ());
393 if (fails_cfg_with_expand (macro_invoc
.get_outer_attrs ()))
395 macro_invoc
.mark_for_strip ();
399 // can't strip simple path
401 // I don't think any macro token trees can be stripped in any way
403 // TODO: maybe have cfg! macro stripping behaviour here?
407 CfgStrip::visit (AST::PathInExpression
&path
)
409 // initial strip test based on outer attrs
410 expand_cfg_attrs (path
.get_outer_attrs ());
411 if (fails_cfg_with_expand (path
.get_outer_attrs ()))
413 path
.mark_for_strip ();
417 for (auto &segment
: path
.get_segments ())
419 if (segment
.has_generic_args ())
420 maybe_strip_generic_args (segment
.get_generic_args ());
425 CfgStrip::visit (AST::TypePathSegmentGeneric
&segment
)
427 // TODO: strip inside generic args
429 if (!segment
.has_generic_args ())
432 maybe_strip_generic_args (segment
.get_generic_args ());
435 CfgStrip::visit (AST::TypePathSegmentFunction
&segment
)
437 AST::DefaultASTVisitor::visit (segment
);
438 auto &type_path_function
= segment
.get_type_path_function ();
440 for (auto &type
: type_path_function
.get_params ())
442 if (type
->is_marked_for_strip ())
443 rust_error_at (type
->get_locus (),
444 "cannot strip type in this position");
447 if (type_path_function
.has_return_type ())
449 auto &return_type
= type_path_function
.get_return_type ();
451 if (return_type
.is_marked_for_strip ())
452 rust_error_at (return_type
.get_locus (),
453 "cannot strip type in this position");
458 CfgStrip::visit (AST::QualifiedPathInExpression
&path
)
460 // initial strip test based on outer attrs
461 AST::DefaultASTVisitor::visit (path
);
463 expand_cfg_attrs (path
.get_outer_attrs ());
464 if (fails_cfg_with_expand (path
.get_outer_attrs ()))
466 path
.mark_for_strip ();
470 maybe_strip_qualified_path_type (path
.get_qualified_path_type ());
472 for (auto &segment
: path
.get_segments ())
474 if (segment
.has_generic_args ())
475 maybe_strip_generic_args (segment
.get_generic_args ());
480 CfgStrip::visit (AST::QualifiedPathInType
&path
)
482 maybe_strip_qualified_path_type (path
.get_qualified_path_type ());
484 // this shouldn't strip any segments, but can strip inside them
485 AST::DefaultASTVisitor::visit (path
);
489 CfgStrip::visit (AST::LiteralExpr
&expr
)
491 // initial strip test based on outer attrs
492 expand_cfg_attrs (expr
.get_outer_attrs ());
493 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
495 expr
.mark_for_strip ();
501 CfgStrip::visit (AST::BorrowExpr
&expr
)
503 AST::DefaultASTVisitor::visit (expr
);
504 // initial strip test based on outer attrs
505 expand_cfg_attrs (expr
.get_outer_attrs ());
506 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
508 expr
.mark_for_strip ();
512 /* strip any internal sub-expressions - expression itself isn't
513 * allowed to have external attributes in this position so can't be
515 auto &borrowed_expr
= expr
.get_borrowed_expr ();
516 if (borrowed_expr
.is_marked_for_strip ())
517 rust_error_at (borrowed_expr
.get_locus (),
518 "cannot strip expression in this position - outer "
519 "attributes not allowed");
522 CfgStrip::visit (AST::DereferenceExpr
&expr
)
524 // initial strip test based on outer attrs
525 expand_cfg_attrs (expr
.get_outer_attrs ());
526 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
528 expr
.mark_for_strip ();
532 /* strip any internal sub-expressions - expression itself isn't
533 * allowed to have external attributes in this position so can't be
535 auto &dereferenced_expr
= expr
.get_dereferenced_expr ();
536 dereferenced_expr
.accept_vis (*this);
537 if (dereferenced_expr
.is_marked_for_strip ())
538 rust_error_at (dereferenced_expr
.get_locus (),
539 "cannot strip expression in this position - outer "
540 "attributes not allowed");
543 CfgStrip::visit (AST::ErrorPropagationExpr
&expr
)
545 AST::DefaultASTVisitor::visit (expr
);
547 // initial strip test based on outer attrs
548 expand_cfg_attrs (expr
.get_outer_attrs ());
549 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
551 expr
.mark_for_strip ();
555 /* strip any internal sub-expressions - expression itself isn't
556 * allowed to have external attributes in this position so can't be
558 auto &propagating_expr
= expr
.get_propagating_expr ();
559 if (propagating_expr
.is_marked_for_strip ())
560 rust_error_at (propagating_expr
.get_locus (),
561 "cannot strip expression in this position - outer "
562 "attributes not allowed");
565 CfgStrip::visit (AST::NegationExpr
&expr
)
567 AST::DefaultASTVisitor::visit (expr
);
568 // initial strip test based on outer attrs
569 expand_cfg_attrs (expr
.get_outer_attrs ());
570 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
572 expr
.mark_for_strip ();
576 /* strip any internal sub-expressions - expression itself isn't
577 * allowed to have external attributes in this position so can't be
579 auto &negated_expr
= expr
.get_negated_expr ();
580 if (negated_expr
.is_marked_for_strip ())
581 rust_error_at (negated_expr
.get_locus (),
582 "cannot strip expression in this position - outer "
583 "attributes not allowed");
586 CfgStrip::visit (AST::ArithmeticOrLogicalExpr
&expr
)
588 AST::DefaultASTVisitor::visit (expr
);
589 /* outer attributes never allowed before these. while cannot strip
590 * two direct descendant expressions, can strip ones below that */
592 // ensure that they are not marked for strip
593 if (expr
.get_left_expr ().is_marked_for_strip ())
594 rust_error_at (expr
.get_left_expr ().get_locus (),
595 "cannot strip expression in this position - outer "
596 "attributes are never allowed "
597 "before binary op exprs");
598 if (expr
.get_right_expr ().is_marked_for_strip ())
599 rust_error_at (expr
.get_right_expr ().get_locus (),
600 "cannot strip expression in this position - outer "
601 "attributes not allowed");
605 CfgStrip::visit (AST::ComparisonExpr
&expr
)
607 /* outer attributes never allowed before these. while cannot strip
608 * two direct descendant expressions, can strip ones below that */
609 AST::DefaultASTVisitor::visit (expr
);
611 // ensure that they are not marked for strip
612 if (expr
.get_left_expr ().is_marked_for_strip ())
613 rust_error_at (expr
.get_left_expr ().get_locus (),
614 "cannot strip expression in this position - outer "
615 "attributes are never allowed "
616 "before binary op exprs");
617 if (expr
.get_right_expr ().is_marked_for_strip ())
618 rust_error_at (expr
.get_right_expr ().get_locus (),
619 "cannot strip expression in this position - outer "
620 "attributes not allowed");
624 CfgStrip::visit (AST::LazyBooleanExpr
&expr
)
626 /* outer attributes never allowed before these. while cannot strip
627 * two direct descendant expressions, can strip ones below that */
628 AST::DefaultASTVisitor::visit (expr
);
630 // ensure that they are not marked for strip
631 if (expr
.get_left_expr ().is_marked_for_strip ())
632 rust_error_at (expr
.get_left_expr ().get_locus (),
633 "cannot strip expression in this position - outer "
634 "attributes are never allowed "
635 "before binary op exprs");
636 if (expr
.get_right_expr ().is_marked_for_strip ())
637 rust_error_at (expr
.get_right_expr ().get_locus (),
638 "cannot strip expression in this position - outer "
639 "attributes not allowed");
643 CfgStrip::visit (AST::TypeCastExpr
&expr
)
645 /* outer attributes never allowed before these. while cannot strip
646 * direct descendant expression, can strip ones below that */
647 AST::DefaultASTVisitor::visit (expr
);
649 auto &casted_expr
= expr
.get_casted_expr ();
650 // ensure that they are not marked for strip
651 if (casted_expr
.is_marked_for_strip ())
652 rust_error_at (casted_expr
.get_locus (),
653 "cannot strip expression in this position - outer "
654 "attributes are never allowed before cast exprs");
656 // TODO: strip sub-types of type
657 auto &type
= expr
.get_type_to_cast_to ();
658 if (type
.is_marked_for_strip ())
659 rust_error_at (type
.get_locus (), "cannot strip type in this position");
662 CfgStrip::visit (AST::AssignmentExpr
&expr
)
664 expand_cfg_attrs (expr
.get_outer_attrs ());
665 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
667 expr
.mark_for_strip ();
670 AST::DefaultASTVisitor::visit (expr
);
672 // ensure that they are not marked for strip
673 if (expr
.get_left_expr ().is_marked_for_strip ())
674 rust_error_at (expr
.get_left_expr ().get_locus (),
675 "cannot strip expression in this position - outer "
676 "attributes are never allowed "
677 "before binary op exprs");
678 if (expr
.get_right_expr ().is_marked_for_strip ())
679 rust_error_at (expr
.get_right_expr ().get_locus (),
680 "cannot strip expression in this position - outer "
681 "attributes not allowed");
684 CfgStrip::visit (AST::CompoundAssignmentExpr
&expr
)
686 /* outer attributes never allowed before these. while cannot strip
687 * two direct descendant expressions, can strip ones below that */
688 AST::DefaultASTVisitor::visit (expr
);
690 // ensure that they are not marked for strip
691 if (expr
.get_left_expr ().is_marked_for_strip ())
692 rust_error_at (expr
.get_left_expr ().get_locus (),
693 "cannot strip expression in this position - outer "
694 "attributes are never allowed "
695 "before binary op exprs");
696 if (expr
.get_right_expr ().is_marked_for_strip ())
697 rust_error_at (expr
.get_right_expr ().get_locus (),
698 "cannot strip expression in this position - outer "
699 "attributes not allowed");
702 CfgStrip::visit (AST::GroupedExpr
&expr
)
704 // initial strip test based on outer attrs
705 expand_cfg_attrs (expr
.get_outer_attrs ());
706 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
708 expr
.mark_for_strip ();
712 /* strip test based on inner attrs - spec says these are inner
713 * attributes, not outer attributes of inner expr */
714 expand_cfg_attrs (expr
.get_inner_attrs ());
715 if (fails_cfg_with_expand (expr
.get_inner_attrs ()))
717 expr
.mark_for_strip ();
721 /* strip any internal sub-expressions - expression itself isn't
722 * allowed to have external attributes in this position so can't be
724 AST::DefaultASTVisitor::visit (expr
);
726 auto &inner_expr
= expr
.get_expr_in_parens ();
727 if (inner_expr
.is_marked_for_strip ())
728 rust_error_at (inner_expr
.get_locus (),
729 "cannot strip expression in this position - outer "
730 "attributes not allowed");
733 CfgStrip::visit (AST::ArrayElemsValues
&elems
)
735 /* apparently outer attributes are allowed in "elements of array
736 * expressions" according to spec */
737 maybe_strip_pointer_allow_strip (elems
.get_values ());
740 CfgStrip::visit (AST::ArrayElemsCopied
&elems
)
742 /* apparently outer attributes are allowed in "elements of array
743 * expressions" according to spec. on the other hand, it would not
744 * make conceptual sense to be able to remove either expression. As
745 * such, not implementing. TODO clear up the ambiguity here */
746 AST::DefaultASTVisitor::visit (elems
);
748 // only intend stripping for internal sub-expressions
749 auto &copied_expr
= elems
.get_elem_to_copy ();
750 if (copied_expr
.is_marked_for_strip ())
751 rust_error_at (copied_expr
.get_locus (),
752 "cannot strip expression in this position - outer "
753 "attributes not allowed");
755 auto ©_count
= elems
.get_num_copies ();
756 copy_count
.accept_vis (*this);
757 if (copy_count
.is_marked_for_strip ())
758 rust_error_at (copy_count
.get_locus (),
759 "cannot strip expression in this position - outer "
760 "attributes not allowed");
763 CfgStrip::visit (AST::ArrayExpr
&expr
)
765 // initial strip test based on outer attrs
766 expand_cfg_attrs (expr
.get_outer_attrs ());
767 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
769 expr
.mark_for_strip ();
773 /* strip test based on inner attrs - spec says there are separate
774 * inner attributes, not just outer attributes of inner exprs */
775 expand_cfg_attrs (expr
.get_inner_attrs ());
776 if (fails_cfg_with_expand (expr
.get_inner_attrs ()))
778 expr
.mark_for_strip ();
782 /* assuming you can't strip away the ArrayElems type, but can strip
783 * internal expressions and whatever */
784 AST::DefaultASTVisitor::visit (expr
);
788 CfgStrip::visit (AST::ArrayIndexExpr
&expr
)
790 /* it is unclear whether outer attributes are supposed to be
791 * allowed, but conceptually it wouldn't make much sense, but
792 * having expansion code anyway. TODO */
793 // initial strip test based on outer attrs
794 expand_cfg_attrs (expr
.get_outer_attrs ());
795 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
797 expr
.mark_for_strip ();
801 /* strip any internal sub-expressions - expression itself isn't
802 * allowed to have external attributes in this position so can't be
804 AST::DefaultASTVisitor::visit (expr
);
806 const auto &array_expr
= expr
.get_array_expr ();
807 if (array_expr
.is_marked_for_strip ())
808 rust_error_at (array_expr
.get_locus (),
809 "cannot strip expression in this position - outer "
810 "attributes not allowed");
812 const auto &index_expr
= expr
.get_index_expr ();
813 if (index_expr
.is_marked_for_strip ())
814 rust_error_at (index_expr
.get_locus (),
815 "cannot strip expression in this position - outer "
816 "attributes not allowed");
819 CfgStrip::visit (AST::TupleExpr
&expr
)
821 /* according to spec, outer attributes are allowed on "elements of
822 * tuple expressions" */
824 // initial strip test based on outer attrs
825 expand_cfg_attrs (expr
.get_outer_attrs ());
826 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
828 expr
.mark_for_strip ();
832 /* strip test based on inner attrs - spec says these are inner
833 * attributes, not outer attributes of inner expr */
834 expand_cfg_attrs (expr
.get_inner_attrs ());
835 if (fails_cfg_with_expand (expr
.get_inner_attrs ()))
837 expr
.mark_for_strip ();
841 /* apparently outer attributes are allowed in "elements of tuple
842 * expressions" according to spec */
843 maybe_strip_pointer_allow_strip (expr
.get_tuple_elems ());
846 CfgStrip::visit (AST::TupleIndexExpr
&expr
)
848 // initial strip test based on outer attrs
849 expand_cfg_attrs (expr
.get_outer_attrs ());
850 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
852 expr
.mark_for_strip ();
856 AST::DefaultASTVisitor::visit (expr
);
857 /* wouldn't strip this directly (as outer attrs should be
858 * associated with this level), but any sub-expressions would be
859 * stripped. Thus, no need to erase when strip check called. */
860 auto &tuple_expr
= expr
.get_tuple_expr ();
861 if (tuple_expr
.is_marked_for_strip ())
862 rust_error_at (tuple_expr
.get_locus (),
863 "cannot strip expression in this position - outer "
864 "attributes not allowed");
868 CfgStrip::visit (AST::StructExprStruct
&expr
)
870 // initial strip test based on outer attrs
871 expand_cfg_attrs (expr
.get_outer_attrs ());
872 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
874 expr
.mark_for_strip ();
878 /* strip test based on inner attrs - spec says these are inner
879 * attributes, not outer attributes of inner expr */
880 expand_cfg_attrs (expr
.get_inner_attrs ());
881 if (fails_cfg_with_expand (expr
.get_inner_attrs ()))
883 expr
.mark_for_strip ();
887 // strip sub-exprs of path
888 auto &struct_name
= expr
.get_struct_name ();
890 if (struct_name
.is_marked_for_strip ())
891 rust_error_at (struct_name
.get_locus (),
892 "cannot strip path in this position");
896 CfgStrip::visit (AST::StructExprFieldIdentifierValue
&field
)
898 /* as no attrs possible (at moment, at least), only sub-expression
899 * stripping is possible */
900 AST::DefaultASTVisitor::visit (field
);
902 auto &value
= field
.get_value ();
903 if (value
.is_marked_for_strip ())
904 rust_error_at (value
.get_locus (),
905 "cannot strip expression in this position - outer "
906 "attributes not allowed");
909 CfgStrip::visit (AST::StructExprFieldIndexValue
&field
)
911 /* as no attrs possible (at moment, at least), only sub-expression
912 * stripping is possible */
913 AST::DefaultASTVisitor::visit (field
);
915 auto &value
= field
.get_value ();
916 if (value
.is_marked_for_strip ())
917 rust_error_at (value
.get_locus (),
918 "cannot strip expression in this position - outer "
919 "attributes not allowed");
922 CfgStrip::visit (AST::StructExprStructFields
&expr
)
924 // initial strip test based on outer attrs
925 expand_cfg_attrs (expr
.get_outer_attrs ());
926 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
928 expr
.mark_for_strip ();
932 /* strip test based on inner attrs - spec says these are inner
933 * attributes, not outer attributes of inner expr */
934 expand_cfg_attrs (expr
.get_inner_attrs ());
935 if (fails_cfg_with_expand (expr
.get_inner_attrs ()))
937 expr
.mark_for_strip ();
941 // strip sub-exprs of path
942 auto &struct_name
= expr
.get_struct_name ();
944 if (struct_name
.is_marked_for_strip ())
945 rust_error_at (struct_name
.get_locus (),
946 "cannot strip path in this position");
948 /* spec does not specify whether expressions are allowed to be
949 * stripped at top level of struct fields, but I wouldn't think
950 * that they would be, so operating under the assumption that only
951 * sub-expressions can be stripped. */
952 AST::DefaultASTVisitor::visit (expr
);
954 /* struct base presumably can't be stripped, as the '..' is before
955 * the expression. as such, can only strip sub-expressions. */
956 if (expr
.has_struct_base ())
958 auto &base_struct_expr
= expr
.get_struct_base ().get_base_struct ();
959 base_struct_expr
.accept_vis (*this);
960 if (base_struct_expr
.is_marked_for_strip ())
961 rust_error_at (base_struct_expr
.get_locus (),
962 "cannot strip expression in this position - outer "
963 "attributes not allowed");
968 CfgStrip::visit (AST::StructExprStructBase
&expr
)
970 // initial strip test based on outer attrs
971 expand_cfg_attrs (expr
.get_outer_attrs ());
972 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
974 expr
.mark_for_strip ();
978 /* strip test based on inner attrs - spec says these are inner
979 * attributes, not outer attributes of inner expr */
980 expand_cfg_attrs (expr
.get_inner_attrs ());
981 if (fails_cfg_with_expand (expr
.get_inner_attrs ()))
983 expr
.mark_for_strip ();
987 // strip sub-exprs of path
988 auto &struct_name
= expr
.get_struct_name ();
990 if (struct_name
.is_marked_for_strip ())
991 rust_error_at (struct_name
.get_locus (),
992 "cannot strip path in this position");
994 /* struct base presumably can't be stripped, as the '..' is before
995 * the expression. as such, can only strip sub-expressions. */
996 rust_assert (!expr
.get_struct_base ().is_invalid ());
997 auto &base_struct_expr
= expr
.get_struct_base ().get_base_struct ();
998 base_struct_expr
.accept_vis (*this);
999 if (base_struct_expr
.is_marked_for_strip ())
1000 rust_error_at (base_struct_expr
.get_locus (),
1001 "cannot strip expression in this position - outer "
1002 "attributes not allowed");
1005 CfgStrip::visit (AST::CallExpr
&expr
)
1007 // initial strip test based on outer attrs
1008 expand_cfg_attrs (expr
.get_outer_attrs ());
1009 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1011 expr
.mark_for_strip ();
1015 /* should not be outer attrs on "function" expression - outer attrs
1016 * should be associated with call expr as a whole. only sub-expr
1017 * expansion is possible. */
1018 AST::DefaultASTVisitor::visit (expr
);
1020 auto &function
= expr
.get_function_expr ();
1021 if (function
.is_marked_for_strip ())
1022 rust_error_at (function
.get_locus (),
1023 "cannot strip expression in this position - outer "
1024 "attributes not allowed");
1026 /* spec says outer attributes are specifically allowed for elements
1027 * of call expressions, so full stripping possible */
1028 // FIXME: Arthur: Figure out how to refactor this - This is similar to
1029 // expanding items in the crate or stmts in blocks
1030 maybe_strip_pointer_allow_strip (expr
.get_params ());
1033 CfgStrip::visit (AST::MethodCallExpr
&expr
)
1035 // initial strip test based on outer attrs
1036 expand_cfg_attrs (expr
.get_outer_attrs ());
1037 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1039 expr
.mark_for_strip ();
1043 /* should not be outer attrs on "receiver" expression - outer attrs
1044 * should be associated with call expr as a whole. only sub-expr
1045 * expansion is possible. */
1046 AST::DefaultASTVisitor::visit (expr
);
1048 auto &receiver
= expr
.get_receiver_expr ();
1049 if (receiver
.is_marked_for_strip ())
1050 rust_error_at (receiver
.get_locus (),
1051 "cannot strip expression in this position - outer "
1052 "attributes not allowed");
1054 auto &method_name
= expr
.get_method_name ();
1055 if (method_name
.has_generic_args ())
1056 maybe_strip_generic_args (method_name
.get_generic_args ());
1058 /* spec says outer attributes are specifically allowed for elements
1059 * of method call expressions, so full stripping possible */
1060 maybe_strip_pointer_allow_strip (expr
.get_params ());
1063 CfgStrip::visit (AST::FieldAccessExpr
&expr
)
1065 // initial strip test based on outer attrs
1066 expand_cfg_attrs (expr
.get_outer_attrs ());
1067 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1069 expr
.mark_for_strip ();
1073 /* should not be outer attrs on "receiver" expression - outer attrs
1074 * should be associated with field expr as a whole. only sub-expr
1075 * expansion is possible. */
1076 AST::DefaultASTVisitor::visit (expr
);
1078 auto &receiver
= expr
.get_receiver_expr ();
1079 if (receiver
.is_marked_for_strip ())
1080 rust_error_at (receiver
.get_locus (),
1081 "cannot strip expression in this position - outer "
1082 "attributes not allowed");
1085 CfgStrip::visit (AST::ClosureExprInner
&expr
)
1087 // initial strip test based on outer attrs
1088 expand_cfg_attrs (expr
.get_outer_attrs ());
1089 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1091 expr
.mark_for_strip ();
1095 /* strip closure parameters if required - this is specifically
1096 * allowed by spec */
1097 maybe_strip_closure_params (expr
.get_params ());
1099 AST::DefaultASTVisitor::visit (expr
);
1101 // can't strip expression itself, but can strip sub-expressions
1102 auto &definition_expr
= expr
.get_definition_expr ();
1103 if (definition_expr
.is_marked_for_strip ())
1104 rust_error_at (definition_expr
.get_locus (),
1105 "cannot strip expression in this position - outer "
1106 "attributes not allowed");
1110 CfgStrip::visit (AST::BlockExpr
&expr
)
1112 // initial strip test based on outer attrs
1113 expand_cfg_attrs (expr
.get_outer_attrs ());
1114 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1116 expr
.mark_for_strip ();
1120 /* strip test based on inner attrs - spec says there are inner
1121 * attributes, not just outer attributes of inner stmts */
1122 expand_cfg_attrs (expr
.get_inner_attrs ());
1123 if (fails_cfg_with_expand (expr
.get_inner_attrs ()))
1125 expr
.mark_for_strip ();
1129 maybe_strip_pointer_allow_strip (expr
.get_statements ());
1131 AST::DefaultASTVisitor::visit (expr
);
1133 // strip tail expression if exists - can actually fully remove it
1134 if (expr
.has_tail_expr ())
1136 auto &tail_expr
= expr
.get_tail_expr ();
1138 if (tail_expr
.is_marked_for_strip ())
1139 expr
.strip_tail_expr ();
1144 CfgStrip::visit (AST::ClosureExprInnerTyped
&expr
)
1146 // initial strip test based on outer attrs
1147 expand_cfg_attrs (expr
.get_outer_attrs ());
1148 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1150 expr
.mark_for_strip ();
1154 /* strip closure parameters if required - this is specifically
1155 * allowed by spec */
1156 maybe_strip_closure_params (expr
.get_params ());
1158 AST::DefaultASTVisitor::visit (expr
);
1160 // can't strip return type, but can strip sub-types
1161 auto &type
= expr
.get_return_type ();
1163 if (type
.is_marked_for_strip ())
1164 rust_error_at (type
.get_locus (), "cannot strip type in this position");
1166 // can't strip expression itself, but can strip sub-expressions
1167 auto &definition_block
= expr
.get_definition_block ();
1168 definition_block
.accept_vis (*this);
1169 if (definition_block
.is_marked_for_strip ())
1170 rust_error_at (definition_block
.get_locus (),
1171 "cannot strip block expression in this position - outer "
1172 "attributes not allowed");
1175 CfgStrip::visit (AST::ContinueExpr
&expr
)
1177 // initial strip test based on outer attrs
1178 expand_cfg_attrs (expr
.get_outer_attrs ());
1179 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1181 expr
.mark_for_strip ();
1186 CfgStrip::visit (AST::BreakExpr
&expr
)
1188 // initial strip test based on outer attrs
1189 expand_cfg_attrs (expr
.get_outer_attrs ());
1190 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1192 expr
.mark_for_strip ();
1195 AST::DefaultASTVisitor::visit (expr
);
1197 /* spec does not say that you can have outer attributes on
1198 * expression, so assuming you can't. stripping for sub-expressions
1199 * is the only thing that can be done */
1200 if (expr
.has_break_expr ())
1202 auto &break_expr
= expr
.get_break_expr ();
1204 if (break_expr
.is_marked_for_strip ())
1205 rust_error_at (break_expr
.get_locus (),
1206 "cannot strip expression in this position - outer "
1207 "attributes not allowed");
1211 CfgStrip::visit (AST::RangeFromToExpr
&expr
)
1213 /* outer attributes never allowed before these. while cannot strip
1214 * two direct descendant expressions, can strip ones below that */
1215 AST::DefaultASTVisitor::visit (expr
);
1217 // ensure that they are not marked for strip
1218 if (expr
.get_from_expr ().is_marked_for_strip ())
1219 rust_error_at (expr
.get_from_expr ().get_locus (),
1220 "cannot strip expression in this position - outer "
1221 "attributes are never allowed "
1222 "before range exprs");
1223 if (expr
.get_to_expr ().is_marked_for_strip ())
1224 rust_error_at (expr
.get_to_expr ().get_locus (),
1225 "cannot strip expression in this position - outer "
1226 "attributes not allowed");
1229 CfgStrip::visit (AST::RangeFromExpr
&expr
)
1231 /* outer attributes never allowed before these. while cannot strip
1232 * direct descendant expression, can strip ones below that */
1234 AST::DefaultASTVisitor::visit (expr
);
1235 /* should have no possibility for outer attrs as would be parsed
1236 * with outer expr */
1237 auto &from_expr
= expr
.get_from_expr ();
1238 if (from_expr
.is_marked_for_strip ())
1239 rust_error_at (from_expr
.get_locus (),
1240 "cannot strip expression in this position - outer "
1241 "attributes are never allowed before range exprs");
1244 CfgStrip::visit (AST::RangeToExpr
&expr
)
1246 /* outer attributes never allowed before these. while cannot strip
1247 * direct descendant expression, can strip ones below that */
1249 AST::DefaultASTVisitor::visit (expr
);
1250 /* should syntactically not have outer attributes, though this may
1251 * not have worked in practice */
1252 auto &to_expr
= expr
.get_to_expr ();
1253 if (to_expr
.is_marked_for_strip ())
1254 rust_error_at (to_expr
.get_locus (),
1255 "cannot strip expression in this position - outer "
1256 "attributes not allowed");
1260 CfgStrip::visit (AST::RangeFromToInclExpr
&expr
)
1262 /* outer attributes never allowed before these. while cannot strip
1263 * two direct descendant expressions, can strip ones below that */
1265 AST::DefaultASTVisitor::visit (expr
);
1267 // ensure that they are not marked for strip
1268 if (expr
.get_from_expr ().is_marked_for_strip ())
1269 rust_error_at (expr
.get_from_expr ().get_locus (),
1270 "cannot strip expression in this position - outer "
1271 "attributes are never allowed "
1272 "before range exprs");
1273 if (expr
.get_to_expr ().is_marked_for_strip ())
1274 rust_error_at (expr
.get_to_expr ().get_locus (),
1275 "cannot strip expression in this position - outer "
1276 "attributes not allowed");
1279 CfgStrip::visit (AST::RangeToInclExpr
&expr
)
1281 /* outer attributes never allowed before these. while cannot strip
1282 * direct descendant expression, can strip ones below that */
1284 AST::DefaultASTVisitor::visit (expr
);
1285 /* should syntactically not have outer attributes, though this may
1286 * not have worked in practice */
1287 auto &to_expr
= expr
.get_to_expr ();
1288 if (to_expr
.is_marked_for_strip ())
1289 rust_error_at (to_expr
.get_locus (),
1290 "cannot strip expression in this position - outer "
1291 "attributes not allowed");
1294 CfgStrip::visit (AST::ReturnExpr
&expr
)
1296 // initial strip test based on outer attrs
1297 expand_cfg_attrs (expr
.get_outer_attrs ());
1298 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1300 expr
.mark_for_strip ();
1304 AST::DefaultASTVisitor::visit (expr
);
1306 /* spec does not say that you can have outer attributes on
1307 * expression, so assuming you can't. stripping for sub-expressions
1308 * is the only thing that can be done */
1309 if (expr
.has_returned_expr ())
1311 auto &returned_expr
= expr
.get_returned_expr ();
1312 if (returned_expr
.is_marked_for_strip ())
1313 rust_error_at (returned_expr
.get_locus (),
1314 "cannot strip expression in this position - outer "
1315 "attributes not allowed");
1317 /* TODO: conceptually, you would maybe be able to remove a returned
1318 * expr - e.g. if you had conditional compilation returning void or
1319 * returning a type. On the other hand, I think that function
1320 * return type cannot be conditionally compiled, so I assumed you
1321 * can't do this either. */
1324 CfgStrip::visit (AST::UnsafeBlockExpr
&expr
)
1326 // initial strip test based on outer attrs
1327 expand_cfg_attrs (expr
.get_outer_attrs ());
1328 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1330 expr
.mark_for_strip ();
1334 AST::DefaultASTVisitor::visit (expr
);
1336 // can't strip block itself, but can strip sub-expressions
1337 auto &block_expr
= expr
.get_block_expr ();
1338 if (block_expr
.is_marked_for_strip ())
1339 rust_error_at (block_expr
.get_locus (),
1340 "cannot strip block expression in this position - outer "
1341 "attributes not allowed");
1344 CfgStrip::visit (AST::LoopExpr
&expr
)
1346 // initial strip test based on outer attrs
1347 expand_cfg_attrs (expr
.get_outer_attrs ());
1348 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1350 expr
.mark_for_strip ();
1354 AST::DefaultASTVisitor::visit (expr
);
1356 // can't strip block itself, but can strip sub-expressions
1357 auto &loop_block
= expr
.get_loop_block ();
1358 if (loop_block
.is_marked_for_strip ())
1359 rust_error_at (loop_block
.get_locus (),
1360 "cannot strip block expression in this position - outer "
1361 "attributes not allowed");
1364 CfgStrip::visit (AST::WhileLoopExpr
&expr
)
1366 // initial strip test based on outer attrs
1367 expand_cfg_attrs (expr
.get_outer_attrs ());
1368 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1370 expr
.mark_for_strip ();
1374 AST::DefaultASTVisitor::visit (expr
);
1375 // can't strip predicate expr itself, but can strip sub-expressions
1376 auto &predicate_expr
= expr
.get_predicate_expr ();
1377 if (predicate_expr
.is_marked_for_strip ())
1378 rust_error_at (predicate_expr
.get_locus (),
1379 "cannot strip expression in this position - outer "
1380 "attributes not allowed");
1382 // can't strip block itself, but can strip sub-expressions
1383 auto &loop_block
= expr
.get_loop_block ();
1384 if (loop_block
.is_marked_for_strip ())
1385 rust_error_at (loop_block
.get_locus (),
1386 "cannot strip block expression in this position - outer "
1387 "attributes not allowed");
1390 CfgStrip::visit (AST::WhileLetLoopExpr
&expr
)
1392 // initial strip test based on outer attrs
1393 expand_cfg_attrs (expr
.get_outer_attrs ());
1394 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1396 expr
.mark_for_strip ();
1400 AST::DefaultASTVisitor::visit (expr
);
1402 for (auto &pattern
: expr
.get_patterns ())
1403 if (pattern
->is_marked_for_strip ())
1404 rust_error_at (pattern
->get_locus (),
1405 "cannot strip pattern in this position");
1407 // can't strip scrutinee expr itself, but can strip sub-expressions
1408 auto &scrutinee_expr
= expr
.get_scrutinee_expr ();
1409 if (scrutinee_expr
.is_marked_for_strip ())
1410 rust_error_at (scrutinee_expr
.get_locus (),
1411 "cannot strip expression in this position - outer "
1412 "attributes not allowed");
1414 // can't strip block itself, but can strip sub-expressions
1415 auto &loop_block
= expr
.get_loop_block ();
1416 if (loop_block
.is_marked_for_strip ())
1417 rust_error_at (loop_block
.get_locus (),
1418 "cannot strip block expression in this position - outer "
1419 "attributes not allowed");
1422 CfgStrip::visit (AST::ForLoopExpr
&expr
)
1424 // initial strip test based on outer attrs
1425 expand_cfg_attrs (expr
.get_outer_attrs ());
1426 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1428 expr
.mark_for_strip ();
1432 AST::DefaultASTVisitor::visit (expr
);
1433 // strip sub-patterns of pattern
1434 auto &pattern
= expr
.get_pattern ();
1435 if (pattern
.is_marked_for_strip ())
1436 rust_error_at (pattern
.get_locus (),
1437 "cannot strip pattern in this position");
1439 // can't strip scrutinee expr itself, but can strip sub-expressions
1440 auto &iterator_expr
= expr
.get_iterator_expr ();
1441 if (iterator_expr
.is_marked_for_strip ())
1442 rust_error_at (iterator_expr
.get_locus (),
1443 "cannot strip expression in this position - outer "
1444 "attributes not allowed");
1446 // can't strip block itself, but can strip sub-expressions
1447 auto &loop_block
= expr
.get_loop_block ();
1448 if (loop_block
.is_marked_for_strip ())
1449 rust_error_at (loop_block
.get_locus (),
1450 "cannot strip block expression in this position - outer "
1451 "attributes not allowed");
1454 CfgStrip::visit (AST::IfExpr
&expr
)
1456 // rust playground test shows that IfExpr does support outer attrs, at least
1457 // when used as statement
1459 // initial strip test based on outer attrs
1460 expand_cfg_attrs (expr
.get_outer_attrs ());
1461 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1463 expr
.mark_for_strip ();
1467 AST::DefaultASTVisitor::visit (expr
);
1469 // can't strip condition expr itself, but can strip sub-expressions
1470 auto &condition_expr
= expr
.get_condition_expr ();
1471 if (condition_expr
.is_marked_for_strip ())
1472 rust_error_at (condition_expr
.get_locus (),
1473 "cannot strip expression in this position - outer "
1474 "attributes not allowed");
1476 // can't strip if block itself, but can strip sub-expressions
1477 auto &if_block
= expr
.get_if_block ();
1478 if (if_block
.is_marked_for_strip ())
1479 rust_error_at (if_block
.get_locus (),
1480 "cannot strip block expression in this position - outer "
1481 "attributes not allowed");
1485 CfgStrip::visit (AST::IfExprConseqElse
&expr
)
1487 // initial strip test based on outer attrs
1488 expand_cfg_attrs (expr
.get_outer_attrs ());
1489 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1491 expr
.mark_for_strip ();
1495 AST::DefaultASTVisitor::visit (expr
);
1497 // can't strip condition expr itself, but can strip sub-expressions
1498 auto &condition_expr
= expr
.get_condition_expr ();
1499 if (condition_expr
.is_marked_for_strip ())
1500 rust_error_at (condition_expr
.get_locus (),
1501 "cannot strip expression in this position - outer "
1502 "attributes not allowed");
1504 // can't strip if block itself, but can strip sub-expressions
1505 auto &if_block
= expr
.get_if_block ();
1506 if (if_block
.is_marked_for_strip ())
1507 rust_error_at (if_block
.get_locus (),
1508 "cannot strip block expression in this position - outer "
1509 "attributes not allowed");
1511 // can't strip else block itself, but can strip sub-expressions
1512 auto &else_block
= expr
.get_else_block ();
1513 if (else_block
.is_marked_for_strip ())
1514 rust_error_at (else_block
.get_locus (),
1515 "cannot strip block expression in this position - outer "
1516 "attributes not allowed");
1520 CfgStrip::visit (AST::IfLetExpr
&expr
)
1522 // initial strip test based on outer attrs
1523 expand_cfg_attrs (expr
.get_outer_attrs ());
1524 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1526 expr
.mark_for_strip ();
1530 AST::DefaultASTVisitor::visit (expr
);
1532 for (auto &pattern
: expr
.get_patterns ())
1533 if (pattern
->is_marked_for_strip ())
1534 rust_error_at (pattern
->get_locus (),
1535 "cannot strip pattern in this position");
1537 // can't strip value expr itself, but can strip sub-expressions
1538 auto &value_expr
= expr
.get_value_expr ();
1539 if (value_expr
.is_marked_for_strip ())
1540 rust_error_at (value_expr
.get_locus (),
1541 "cannot strip expression in this position - outer "
1542 "attributes not allowed");
1544 // can't strip if block itself, but can strip sub-expressions
1545 auto &if_block
= expr
.get_if_block ();
1546 if (if_block
.is_marked_for_strip ())
1547 rust_error_at (if_block
.get_locus (),
1548 "cannot strip block expression in this position - outer "
1549 "attributes not allowed");
1552 CfgStrip::visit (AST::IfLetExprConseqElse
&expr
)
1554 // initial strip test based on outer attrs
1555 expand_cfg_attrs (expr
.get_outer_attrs ());
1556 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1558 expr
.mark_for_strip ();
1562 AST::DefaultASTVisitor::visit (expr
);
1564 for (auto &pattern
: expr
.get_patterns ())
1565 if (pattern
->is_marked_for_strip ())
1566 rust_error_at (pattern
->get_locus (),
1567 "cannot strip pattern in this position");
1569 // can't strip value expr itself, but can strip sub-expressions
1570 auto &value_expr
= expr
.get_value_expr ();
1571 if (value_expr
.is_marked_for_strip ())
1572 rust_error_at (value_expr
.get_locus (),
1573 "cannot strip expression in this position - outer "
1574 "attributes not allowed");
1576 // can't strip if block itself, but can strip sub-expressions
1577 auto &if_block
= expr
.get_if_block ();
1578 if (if_block
.is_marked_for_strip ())
1579 rust_error_at (if_block
.get_locus (),
1580 "cannot strip block expression in this position - outer "
1581 "attributes not allowed");
1583 // can't strip else block itself, but can strip sub-expressions
1584 auto &else_block
= expr
.get_else_block ();
1585 if (else_block
.is_marked_for_strip ())
1586 rust_error_at (else_block
.get_locus (),
1587 "cannot strip block expression in this position - outer "
1588 "attributes not allowed");
1591 CfgStrip::visit (AST::MatchExpr
&expr
)
1593 // initial strip test based on outer attrs
1594 expand_cfg_attrs (expr
.get_outer_attrs ());
1595 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1597 expr
.mark_for_strip ();
1601 // inner attr strip test
1602 expand_cfg_attrs (expr
.get_inner_attrs ());
1603 if (fails_cfg_with_expand (expr
.get_inner_attrs ()))
1605 expr
.mark_for_strip ();
1609 AST::DefaultASTVisitor::visit (expr
);
1611 // can't strip scrutinee expr itself, but can strip sub-expressions
1612 auto &scrutinee_expr
= expr
.get_scrutinee_expr ();
1613 if (scrutinee_expr
.is_marked_for_strip ())
1614 rust_error_at (scrutinee_expr
.get_locus (),
1615 "cannot strip expression in this position - outer "
1616 "attributes not allowed");
1618 // strip match cases
1619 auto &match_cases
= expr
.get_match_cases ();
1620 for (auto it
= match_cases
.begin (); it
!= match_cases
.end ();)
1622 auto &match_case
= *it
;
1624 // strip match case based on outer attributes in match arm
1625 auto &match_arm
= match_case
.get_arm ();
1626 expand_cfg_attrs (match_arm
.get_outer_attrs ());
1627 if (fails_cfg_with_expand (match_arm
.get_outer_attrs ()))
1630 it
= match_cases
.erase (it
);
1634 for (auto &pattern
: match_arm
.get_patterns ())
1635 if (pattern
->is_marked_for_strip ())
1636 rust_error_at (pattern
->get_locus (),
1637 "cannot strip pattern in this position");
1639 /* assuming that guard expression cannot be stripped as
1640 * strictly speaking you would have to strip the whole guard to
1641 * make syntactical sense, which you can't do. as such, only
1642 * strip sub-expressions */
1643 if (match_arm
.has_match_arm_guard ())
1645 auto &guard_expr
= match_arm
.get_guard_expr ();
1646 if (guard_expr
.is_marked_for_strip ())
1647 rust_error_at (guard_expr
.get_locus (),
1648 "cannot strip expression in this position - outer "
1649 "attributes not allowed");
1652 // strip sub-expressions from match cases
1653 auto &case_expr
= match_case
.get_expr ();
1654 if (case_expr
.is_marked_for_strip ())
1655 rust_error_at (case_expr
.get_locus (),
1656 "cannot strip expression in this position - outer "
1657 "attributes not allowed");
1659 // increment to next case if haven't continued
1665 CfgStrip::visit (AST::AwaitExpr
&expr
)
1667 // initial strip test based on outer attrs
1668 expand_cfg_attrs (expr
.get_outer_attrs ());
1669 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1671 expr
.mark_for_strip ();
1675 /* can't strip awaited expr itself, but can strip sub-expressions
1676 * - this is because you can't have no expr to await */
1677 auto &awaited_expr
= expr
.get_awaited_expr ();
1678 awaited_expr
->accept_vis (*this);
1679 if (awaited_expr
->is_marked_for_strip ())
1680 rust_error_at (awaited_expr
->get_locus (),
1681 "cannot strip expression in this position - outer "
1682 "attributes not allowed");
1686 CfgStrip::visit (AST::AsyncBlockExpr
&expr
)
1688 // initial strip test based on outer attrs
1689 expand_cfg_attrs (expr
.get_outer_attrs ());
1690 if (fails_cfg_with_expand (expr
.get_outer_attrs ()))
1692 expr
.mark_for_strip ();
1696 AST::DefaultASTVisitor::visit (expr
);
1698 // can't strip block itself, but can strip sub-expressions
1699 auto &block_expr
= expr
.get_block_expr ();
1700 if (block_expr
->is_marked_for_strip ())
1701 rust_error_at (block_expr
->get_locus (),
1702 "cannot strip block expression in this position - outer "
1703 "attributes not allowed");
1707 CfgStrip::visit (AST::TypeParam
¶m
)
1709 // outer attributes don't actually do anything, so ignore them
1711 AST::DefaultASTVisitor::visit (param
);
1713 if (param
.has_type () && param
.get_type ().is_marked_for_strip ())
1714 rust_error_at (param
.get_type ().get_locus (),
1715 "cannot strip type in this position");
1719 CfgStrip::visit (AST::TypeBoundWhereClauseItem
&item
)
1721 // for lifetimes shouldn't require
1722 AST::DefaultASTVisitor::visit (item
);
1724 auto &type
= item
.get_type ();
1725 if (type
.is_marked_for_strip ())
1726 rust_error_at (type
.get_locus (), "cannot strip type in this position");
1730 CfgStrip::visit (AST::Module
&module
)
1732 // strip test based on outer attrs
1733 expand_cfg_attrs (module
.get_outer_attrs ());
1734 if (fails_cfg_with_expand (module
.get_outer_attrs ()))
1736 module
.mark_for_strip ();
1740 // A loaded module might have inner attributes
1741 if (module
.get_kind () == AST::Module::ModuleKind::LOADED
)
1743 // strip test based on inner attrs
1744 expand_cfg_attrs (module
.get_inner_attrs ());
1745 if (fails_cfg_with_expand (module
.get_inner_attrs ()))
1747 module
.mark_for_strip ();
1752 // strip items if required
1753 maybe_strip_pointer_allow_strip (module
.get_items ());
1757 CfgStrip::visit (AST::ExternCrate
&extern_crate
)
1759 // strip test based on outer attrs
1760 expand_cfg_attrs (extern_crate
.get_outer_attrs ());
1761 if (fails_cfg_with_expand (extern_crate
.get_outer_attrs ()))
1763 extern_crate
.mark_for_strip ();
1767 if (!extern_crate
.references_self ())
1769 Session
&session
= Session::get_instance ();
1770 session
.load_extern_crate (extern_crate
.get_referenced_crate (),
1771 extern_crate
.get_locus ());
1776 CfgStrip::visit (AST::UseDeclaration
&use_decl
)
1778 // strip test based on outer attrs
1779 expand_cfg_attrs (use_decl
.get_outer_attrs ());
1780 if (fails_cfg_with_expand (use_decl
.get_outer_attrs ()))
1782 use_decl
.mark_for_strip ();
1788 CfgStrip::visit (AST::Function
&function
)
1790 // initial test based on outer attrs
1791 expand_cfg_attrs (function
.get_outer_attrs ());
1792 if (fails_cfg_with_expand (function
.get_outer_attrs ()))
1794 function
.mark_for_strip ();
1798 AST::DefaultASTVisitor::visit (function
);
1800 /* strip function parameters if required - this is specifically
1801 * allowed by spec */
1802 maybe_strip_function_params (function
.get_function_params ());
1804 if (function
.has_return_type ())
1806 auto &return_type
= function
.get_return_type ();
1807 if (return_type
.is_marked_for_strip ())
1808 rust_error_at (return_type
.get_locus (),
1809 "cannot strip type in this position");
1812 /* body should always exist - if error state, should have returned
1814 // can't strip block itself, but can strip sub-expressions
1815 if (function
.has_body ())
1817 auto &block_expr
= function
.get_definition ();
1818 if (block_expr
.value ()->is_marked_for_strip ())
1819 rust_error_at (block_expr
.value ()->get_locus (),
1820 "cannot strip block expression in this position - outer "
1821 "attributes not allowed");
1826 CfgStrip::visit (AST::TypeAlias
&type_alias
)
1828 // initial test based on outer attrs
1829 expand_cfg_attrs (type_alias
.get_outer_attrs ());
1830 if (fails_cfg_with_expand (type_alias
.get_outer_attrs ()))
1832 type_alias
.mark_for_strip ();
1836 AST::DefaultASTVisitor::visit (type_alias
);
1838 auto &type
= type_alias
.get_type_aliased ();
1839 if (type
.is_marked_for_strip ())
1840 rust_error_at (type
.get_locus (), "cannot strip type in this position");
1844 CfgStrip::visit (AST::StructStruct
&struct_item
)
1846 // initial test based on outer attrs
1847 expand_cfg_attrs (struct_item
.get_outer_attrs ());
1848 if (fails_cfg_with_expand (struct_item
.get_outer_attrs ()))
1850 struct_item
.mark_for_strip ();
1854 AST::DefaultASTVisitor::visit (struct_item
);
1857 CfgStrip::visit (AST::TupleStruct
&tuple_struct
)
1859 // initial test based on outer attrs
1860 expand_cfg_attrs (tuple_struct
.get_outer_attrs ());
1861 if (fails_cfg_with_expand (tuple_struct
.get_outer_attrs ()))
1863 tuple_struct
.mark_for_strip ();
1867 AST::DefaultASTVisitor::visit (tuple_struct
);
1869 /* strip struct fields if required - this is presumably
1870 * allowed by spec */
1871 maybe_strip_tuple_fields (tuple_struct
.get_fields ());
1874 CfgStrip::visit (AST::EnumItem
&item
)
1876 // initial test based on outer attrs
1877 expand_cfg_attrs (item
.get_outer_attrs ());
1878 if (fails_cfg_with_expand (item
.get_outer_attrs ()))
1880 item
.mark_for_strip ();
1886 CfgStrip::visit (AST::EnumItemTuple
&item
)
1888 // initial test based on outer attrs
1889 expand_cfg_attrs (item
.get_outer_attrs ());
1890 if (fails_cfg_with_expand (item
.get_outer_attrs ()))
1892 item
.mark_for_strip ();
1896 /* strip item fields if required - this is presumably
1897 * allowed by spec */
1898 maybe_strip_tuple_fields (item
.get_tuple_fields ());
1902 CfgStrip::visit (AST::EnumItemStruct
&item
)
1904 // initial test based on outer attrs
1905 expand_cfg_attrs (item
.get_outer_attrs ());
1906 if (fails_cfg_with_expand (item
.get_outer_attrs ()))
1908 item
.mark_for_strip ();
1912 /* strip item fields if required - this is presumably
1913 * allowed by spec */
1914 maybe_strip_struct_fields (item
.get_struct_fields ());
1918 CfgStrip::visit (AST::EnumItemDiscriminant
&item
)
1920 // initial test based on outer attrs
1921 expand_cfg_attrs (item
.get_outer_attrs ());
1922 if (fails_cfg_with_expand (item
.get_outer_attrs ()))
1924 item
.mark_for_strip ();
1928 AST::DefaultASTVisitor::visit (item
);
1929 /* strip any internal sub-expressions - expression itself isn't
1930 * allowed to have external attributes in this position so can't be
1932 auto &expr
= item
.get_expr ();
1933 if (expr
.is_marked_for_strip ())
1934 rust_error_at (expr
.get_locus (),
1935 "cannot strip expression in this position - outer "
1936 "attributes not allowed");
1939 CfgStrip::visit (AST::Enum
&enum_item
)
1941 // initial test based on outer attrs
1942 expand_cfg_attrs (enum_item
.get_outer_attrs ());
1943 if (fails_cfg_with_expand (enum_item
.get_outer_attrs ()))
1945 enum_item
.mark_for_strip ();
1949 AST::DefaultASTVisitor::visit (enum_item
);
1951 /* strip enum fields if required - this is presumably
1952 * allowed by spec */
1953 maybe_strip_pointer_allow_strip (enum_item
.get_variants ());
1956 CfgStrip::visit (AST::Union
&union_item
)
1958 // initial test based on outer attrs
1959 expand_cfg_attrs (union_item
.get_outer_attrs ());
1960 if (fails_cfg_with_expand (union_item
.get_outer_attrs ()))
1962 union_item
.mark_for_strip ();
1966 AST::DefaultASTVisitor::visit (union_item
);
1968 /* strip union fields if required - this is presumably
1969 * allowed by spec */
1970 maybe_strip_struct_fields (union_item
.get_variants ());
1973 CfgStrip::visit (AST::ConstantItem
&const_item
)
1975 // initial test based on outer attrs
1976 expand_cfg_attrs (const_item
.get_outer_attrs ());
1977 if (fails_cfg_with_expand (const_item
.get_outer_attrs ()))
1979 const_item
.mark_for_strip ();
1983 AST::DefaultASTVisitor::visit (const_item
);
1985 // strip any sub-types
1986 auto &type
= const_item
.get_type ();
1987 if (type
.is_marked_for_strip ())
1988 rust_error_at (type
.get_locus (), "cannot strip type in this position");
1990 /* strip any internal sub-expressions - expression itself isn't
1991 * allowed to have external attributes in this position so can't be
1993 if (const_item
.has_expr ())
1995 auto &expr
= const_item
.get_expr ();
1996 if (expr
.is_marked_for_strip ())
1997 rust_error_at (expr
.get_locus (),
1998 "cannot strip expression in this position - outer "
1999 "attributes not allowed");
2003 CfgStrip::visit (AST::StaticItem
&static_item
)
2005 // initial test based on outer attrs
2006 expand_cfg_attrs (static_item
.get_outer_attrs ());
2007 if (fails_cfg_with_expand (static_item
.get_outer_attrs ()))
2009 static_item
.mark_for_strip ();
2013 AST::DefaultASTVisitor::visit (static_item
);
2015 // strip any sub-types
2016 auto &type
= static_item
.get_type ();
2018 if (type
.is_marked_for_strip ())
2019 rust_error_at (type
.get_locus (), "cannot strip type in this position");
2021 /* strip any internal sub-expressions - expression itself isn't
2022 * allowed to have external attributes in this position so can't be
2024 auto &expr
= static_item
.get_expr ();
2025 if (expr
.is_marked_for_strip ())
2026 rust_error_at (expr
.get_locus (),
2027 "cannot strip expression in this position - outer "
2028 "attributes not allowed");
2032 CfgStrip::visit (AST::TraitItemConst
&item
)
2034 // initial test based on outer attrs
2035 expand_cfg_attrs (item
.get_outer_attrs ());
2036 if (fails_cfg_with_expand (item
.get_outer_attrs ()))
2038 item
.mark_for_strip ();
2042 AST::DefaultASTVisitor::visit (item
);
2044 // strip any sub-types
2045 auto &type
= item
.get_type ();
2047 if (type
.is_marked_for_strip ())
2048 rust_error_at (type
.get_locus (), "cannot strip type in this position");
2050 /* strip any internal sub-expressions - expression itself isn't
2051 * allowed to have external attributes in this position so can't be
2053 if (item
.has_expression ())
2055 auto &expr
= item
.get_expr ();
2056 if (expr
.is_marked_for_strip ())
2057 rust_error_at (expr
.get_locus (),
2058 "cannot strip expression in this position - outer "
2059 "attributes not allowed");
2064 CfgStrip::visit (AST::TraitItemType
&item
)
2066 // initial test based on outer attrs
2067 expand_cfg_attrs (item
.get_outer_attrs ());
2068 if (fails_cfg_with_expand (item
.get_outer_attrs ()))
2070 item
.mark_for_strip ();
2074 AST::DefaultASTVisitor::visit (item
);
2078 CfgStrip::visit (AST::Trait
&trait
)
2080 // initial strip test based on outer attrs
2081 expand_cfg_attrs (trait
.get_outer_attrs ());
2082 if (fails_cfg_with_expand (trait
.get_outer_attrs ()))
2084 trait
.mark_for_strip ();
2088 // strip test based on inner attrs
2089 expand_cfg_attrs (trait
.get_inner_attrs ());
2090 if (fails_cfg_with_expand (trait
.get_inner_attrs ()))
2092 trait
.mark_for_strip ();
2096 AST::DefaultASTVisitor::visit (trait
);
2098 maybe_strip_pointer_allow_strip (trait
.get_trait_items ());
2102 CfgStrip::visit (AST::InherentImpl
&impl
)
2104 // initial strip test based on outer attrs
2105 expand_cfg_attrs (impl
.get_outer_attrs ());
2106 if (fails_cfg_with_expand (impl
.get_outer_attrs ()))
2108 impl
.mark_for_strip ();
2112 // strip test based on inner attrs
2113 expand_cfg_attrs (impl
.get_inner_attrs ());
2114 if (fails_cfg_with_expand (impl
.get_inner_attrs ()))
2116 impl
.mark_for_strip ();
2120 AST::DefaultASTVisitor::visit (impl
);
2122 auto &type
= impl
.get_type ();
2124 if (type
.is_marked_for_strip ())
2125 rust_error_at (type
.get_locus (), "cannot strip type in this position");
2127 maybe_strip_pointer_allow_strip (impl
.get_impl_items ());
2131 CfgStrip::visit (AST::TraitImpl
&impl
)
2133 // initial strip test based on outer attrs
2134 expand_cfg_attrs (impl
.get_outer_attrs ());
2135 if (fails_cfg_with_expand (impl
.get_outer_attrs ()))
2137 impl
.mark_for_strip ();
2141 // strip test based on inner attrs
2142 expand_cfg_attrs (impl
.get_inner_attrs ());
2143 if (fails_cfg_with_expand (impl
.get_inner_attrs ()))
2145 impl
.mark_for_strip ();
2149 AST::DefaultASTVisitor::visit (impl
);
2151 auto &type
= impl
.get_type ();
2152 if (type
.is_marked_for_strip ())
2153 rust_error_at (type
.get_locus (), "cannot strip type in this position");
2155 auto &trait_path
= impl
.get_trait_path ();
2157 if (trait_path
.is_marked_for_strip ())
2158 rust_error_at (trait_path
.get_locus (),
2159 "cannot strip typepath in this position");
2161 maybe_strip_pointer_allow_strip (impl
.get_impl_items ());
2165 CfgStrip::visit (AST::ExternalTypeItem
&item
)
2167 expand_cfg_attrs (item
.get_outer_attrs ());
2169 if (fails_cfg_with_expand (item
.get_outer_attrs ()))
2170 item
.mark_for_strip ();
2172 // TODO: Can we do anything like expand a macro here?
2173 // extern "C" { type ffi_ty!(); }
2178 CfgStrip::visit (AST::ExternalStaticItem
&item
)
2180 // strip test based on outer attrs
2181 expand_cfg_attrs (item
.get_outer_attrs ());
2182 if (fails_cfg_with_expand (item
.get_outer_attrs ()))
2184 item
.mark_for_strip ();
2188 AST::DefaultASTVisitor::visit (item
);
2190 auto &type
= item
.get_type ();
2191 if (type
.is_marked_for_strip ())
2192 rust_error_at (type
.get_locus (), "cannot strip type in this position");
2196 CfgStrip::visit (AST::ExternBlock
&block
)
2198 // initial strip test based on outer attrs
2199 expand_cfg_attrs (block
.get_outer_attrs ());
2200 if (fails_cfg_with_expand (block
.get_outer_attrs ()))
2202 block
.mark_for_strip ();
2206 // strip test based on inner attrs
2207 expand_cfg_attrs (block
.get_inner_attrs ());
2208 if (fails_cfg_with_expand (block
.get_inner_attrs ()))
2210 block
.mark_for_strip ();
2214 maybe_strip_pointer_allow_strip (block
.get_extern_items ());
2218 CfgStrip::visit (AST::MacroRulesDefinition
&rules_def
)
2220 // initial strip test based on outer attrs
2221 expand_cfg_attrs (rules_def
.get_outer_attrs ());
2222 if (fails_cfg_with_expand (rules_def
.get_outer_attrs ()))
2224 rules_def
.mark_for_strip ();
2230 CfgStrip::visit (AST::IdentifierPattern
&pattern
)
2232 // can only strip sub-patterns of the inner pattern to bind
2233 if (!pattern
.has_pattern_to_bind ())
2236 AST::DefaultASTVisitor::visit (pattern
);
2238 auto &sub_pattern
= pattern
.get_pattern_to_bind ();
2239 if (sub_pattern
.is_marked_for_strip ())
2240 rust_error_at (sub_pattern
.get_locus (),
2241 "cannot strip pattern in this position");
2245 CfgStrip::visit (AST::RangePatternBoundPath
&bound
)
2247 // can expand path, but not strip it directly
2248 auto &path
= bound
.get_path ();
2250 if (path
.is_marked_for_strip ())
2251 rust_error_at (path
.get_locus (), "cannot strip path in this position");
2255 CfgStrip::visit (AST::RangePatternBoundQualPath
&bound
)
2257 // can expand path, but not strip it directly
2258 auto &path
= bound
.get_qualified_path ();
2260 if (path
.is_marked_for_strip ())
2261 rust_error_at (path
.get_locus (), "cannot strip path in this position");
2265 CfgStrip::visit (AST::ReferencePattern
&pattern
)
2267 AST::DefaultASTVisitor::visit (pattern
);
2269 auto &sub_pattern
= pattern
.get_referenced_pattern ();
2270 if (sub_pattern
.is_marked_for_strip ())
2271 rust_error_at (sub_pattern
.get_locus (),
2272 "cannot strip pattern in this position");
2275 CfgStrip::visit (AST::StructPatternFieldTuplePat
&field
)
2277 // initial strip test based on outer attrs
2278 expand_cfg_attrs (field
.get_outer_attrs ());
2279 if (fails_cfg_with_expand (field
.get_outer_attrs ()))
2281 field
.mark_for_strip ();
2285 AST::DefaultASTVisitor::visit (field
);
2287 // strip sub-patterns (can't strip top-level pattern)
2288 auto &sub_pattern
= field
.get_index_pattern ();
2289 if (sub_pattern
.is_marked_for_strip ())
2290 rust_error_at (sub_pattern
.get_locus (),
2291 "cannot strip pattern in this position");
2295 CfgStrip::visit (AST::StructPatternFieldIdentPat
&field
)
2297 // initial strip test based on outer attrs
2298 expand_cfg_attrs (field
.get_outer_attrs ());
2299 if (fails_cfg_with_expand (field
.get_outer_attrs ()))
2301 field
.mark_for_strip ();
2305 AST::DefaultASTVisitor::visit (field
);
2306 // strip sub-patterns (can't strip top-level pattern)
2307 auto &sub_pattern
= field
.get_ident_pattern ();
2308 if (sub_pattern
.is_marked_for_strip ())
2309 rust_error_at (sub_pattern
.get_locus (),
2310 "cannot strip pattern in this position");
2313 CfgStrip::visit (AST::StructPatternFieldIdent
&field
)
2315 // initial strip test based on outer attrs
2316 expand_cfg_attrs (field
.get_outer_attrs ());
2317 if (fails_cfg_with_expand (field
.get_outer_attrs ()))
2319 field
.mark_for_strip ();
2325 CfgStrip::visit (AST::StructPattern
&pattern
)
2327 // expand (but don't strip) path
2328 auto &path
= pattern
.get_path ();
2330 if (path
.is_marked_for_strip ())
2331 rust_error_at (path
.get_locus (), "cannot strip path in this position");
2333 /* TODO: apparently struct pattern fields can have outer attrs. so can they
2335 if (!pattern
.has_struct_pattern_elems ())
2338 auto &elems
= pattern
.get_struct_pattern_elems ();
2340 // assuming you can strip struct pattern fields
2341 maybe_strip_pointer_allow_strip (elems
.get_struct_pattern_fields ());
2343 // assuming you can strip the ".." part
2344 if (elems
.has_etc ())
2346 expand_cfg_attrs (elems
.get_etc_outer_attrs ());
2347 if (fails_cfg_with_expand (elems
.get_etc_outer_attrs ()))
2353 CfgStrip::visit (AST::TupleStructItemsNoRange
&tuple_items
)
2355 AST::DefaultASTVisitor::visit (tuple_items
);
2356 // can't strip individual patterns, only sub-patterns
2357 for (auto &pattern
: tuple_items
.get_patterns ())
2359 if (pattern
->is_marked_for_strip ())
2360 rust_error_at (pattern
->get_locus (),
2361 "cannot strip pattern in this position");
2362 // TODO: quit stripping now? or keep going?
2366 CfgStrip::visit (AST::TupleStructItemsRange
&tuple_items
)
2368 AST::DefaultASTVisitor::visit (tuple_items
);
2369 // can't strip individual patterns, only sub-patterns
2370 for (auto &lower_pattern
: tuple_items
.get_lower_patterns ())
2372 if (lower_pattern
->is_marked_for_strip ())
2373 rust_error_at (lower_pattern
->get_locus (),
2374 "cannot strip pattern in this position");
2375 // TODO: quit stripping now? or keep going?
2377 for (auto &upper_pattern
: tuple_items
.get_upper_patterns ())
2379 if (upper_pattern
->is_marked_for_strip ())
2380 rust_error_at (upper_pattern
->get_locus (),
2381 "cannot strip pattern in this position");
2382 // TODO: quit stripping now? or keep going?
2387 CfgStrip::visit (AST::TupleStructPattern
&pattern
)
2389 // expand (but don't strip) path
2390 auto &path
= pattern
.get_path ();
2392 if (path
.is_marked_for_strip ())
2393 rust_error_at (path
.get_locus (), "cannot strip path in this position");
2395 AST::DefaultASTVisitor::visit (pattern
);
2399 CfgStrip::visit (AST::TuplePatternItemsMultiple
&tuple_items
)
2401 AST::DefaultASTVisitor::visit (tuple_items
);
2403 // can't strip individual patterns, only sub-patterns
2404 for (auto &pattern
: tuple_items
.get_patterns ())
2406 if (pattern
->is_marked_for_strip ())
2407 rust_error_at (pattern
->get_locus (),
2408 "cannot strip pattern in this position");
2409 // TODO: quit stripping now? or keep going?
2414 CfgStrip::visit (AST::TuplePatternItemsRanged
&tuple_items
)
2416 AST::DefaultASTVisitor::visit (tuple_items
);
2418 // can't strip individual patterns, only sub-patterns
2419 for (auto &lower_pattern
: tuple_items
.get_lower_patterns ())
2421 if (lower_pattern
->is_marked_for_strip ())
2422 rust_error_at (lower_pattern
->get_locus (),
2423 "cannot strip pattern in this position");
2424 // TODO: quit stripping now? or keep going?
2426 for (auto &upper_pattern
: tuple_items
.get_upper_patterns ())
2428 if (upper_pattern
->is_marked_for_strip ())
2429 rust_error_at (upper_pattern
->get_locus (),
2430 "cannot strip pattern in this position");
2431 // TODO: quit stripping now? or keep going?
2436 CfgStrip::visit (AST::GroupedPattern
&pattern
)
2438 AST::DefaultASTVisitor::visit (pattern
);
2439 // can't strip inner pattern, only sub-patterns
2440 auto &pattern_in_parens
= pattern
.get_pattern_in_parens ();
2442 if (pattern_in_parens
.is_marked_for_strip ())
2443 rust_error_at (pattern_in_parens
.get_locus (),
2444 "cannot strip pattern in this position");
2448 CfgStrip::visit (AST::SlicePattern
&pattern
)
2450 AST::DefaultASTVisitor::visit (pattern
);
2451 // can't strip individual patterns, only sub-patterns
2452 for (auto &item
: pattern
.get_items ())
2454 if (item
->is_marked_for_strip ())
2455 rust_error_at (item
->get_locus (),
2456 "cannot strip pattern in this position");
2457 // TODO: quit stripping now? or keep going?
2462 CfgStrip::visit (AST::AltPattern
&pattern
)
2464 AST::DefaultASTVisitor::visit (pattern
);
2465 // can't strip individual patterns, only sub-patterns
2466 for (auto &alt
: pattern
.get_alts ())
2468 if (alt
->is_marked_for_strip ())
2469 rust_error_at (alt
->get_locus (),
2470 "cannot strip pattern in this position");
2471 // TODO: quit stripping now? or keep going?
2476 CfgStrip::visit (AST::LetStmt
&stmt
)
2478 // initial strip test based on outer attrs
2479 expand_cfg_attrs (stmt
.get_outer_attrs ());
2480 if (fails_cfg_with_expand (stmt
.get_outer_attrs ()))
2482 stmt
.mark_for_strip ();
2486 AST::DefaultASTVisitor::visit (stmt
);
2487 // can't strip pattern, but call for sub-patterns
2488 auto &pattern
= stmt
.get_pattern ();
2489 if (pattern
.is_marked_for_strip ())
2490 rust_error_at (pattern
.get_locus (),
2491 "cannot strip pattern in this position");
2494 if (stmt
.has_type ())
2496 auto &type
= stmt
.get_type ();
2498 if (type
.is_marked_for_strip ())
2499 rust_error_at (type
.get_locus (), "cannot strip type in this position");
2502 /* strip any internal sub-expressions - expression itself isn't
2503 * allowed to have external attributes in this position so can't be
2505 if (stmt
.has_init_expr ())
2507 auto &init_expr
= stmt
.get_init_expr ();
2509 if (init_expr
.is_marked_for_strip ())
2510 rust_error_at (init_expr
.get_locus (),
2511 "cannot strip expression in this position - outer "
2512 "attributes not allowed");
2517 CfgStrip::visit (AST::ExprStmt
&stmt
)
2519 // outer attributes associated with expr, so rely on expr
2521 // guard - should prevent null pointer expr
2522 if (stmt
.is_marked_for_strip ())
2525 AST::DefaultASTVisitor::visit (stmt
);
2526 // strip if expr is to be stripped
2527 auto &expr
= stmt
.get_expr ();
2528 if (expr
.is_marked_for_strip ())
2530 stmt
.mark_for_strip ();
2536 CfgStrip::visit (AST::TraitBound
&bound
)
2538 // nothing in for lifetimes to strip
2540 // expand but don't strip type path
2541 auto &path
= bound
.get_type_path ();
2543 if (path
.is_marked_for_strip ())
2544 rust_error_at (path
.get_locus (),
2545 "cannot strip type path in this position");
2549 CfgStrip::visit (AST::ParenthesisedType
&type
)
2551 AST::DefaultASTVisitor::visit (type
);
2552 // expand but don't strip inner type
2553 auto &inner_type
= type
.get_type_in_parens ();
2554 if (inner_type
->is_marked_for_strip ())
2555 rust_error_at (inner_type
->get_locus (),
2556 "cannot strip type in this position");
2560 CfgStrip::visit (AST::TupleType
&type
)
2562 AST::DefaultASTVisitor::visit (type
);
2563 // TODO: assuming that types can't be stripped as types don't have outer
2565 for (auto &elem_type
: type
.get_elems ())
2567 if (elem_type
->is_marked_for_strip ())
2568 rust_error_at (elem_type
->get_locus (),
2569 "cannot strip type in this position");
2574 CfgStrip::visit (AST::RawPointerType
&type
)
2576 AST::DefaultASTVisitor::visit (type
);
2577 // expand but don't strip type pointed to
2578 auto &pointed_type
= type
.get_type_pointed_to ();
2579 if (pointed_type
.is_marked_for_strip ())
2580 rust_error_at (pointed_type
.get_locus (),
2581 "cannot strip type in this position");
2585 CfgStrip::visit (AST::ReferenceType
&type
)
2587 AST::DefaultASTVisitor::visit (type
);
2588 // expand but don't strip type referenced
2589 auto &referenced_type
= type
.get_type_referenced ();
2590 if (referenced_type
.is_marked_for_strip ())
2591 rust_error_at (referenced_type
.get_locus (),
2592 "cannot strip type in this position");
2596 CfgStrip::visit (AST::ArrayType
&type
)
2598 AST::DefaultASTVisitor::visit (type
);
2599 // expand but don't strip type referenced
2600 auto &base_type
= type
.get_elem_type ();
2601 if (base_type
.is_marked_for_strip ())
2602 rust_error_at (base_type
.get_locus (),
2603 "cannot strip type in this position");
2605 // same for expression
2606 auto &size_expr
= type
.get_size_expr ();
2607 if (size_expr
.is_marked_for_strip ())
2608 rust_error_at (size_expr
.get_locus (),
2609 "cannot strip expression in this position");
2612 CfgStrip::visit (AST::SliceType
&type
)
2614 AST::DefaultASTVisitor::visit (type
);
2615 // expand but don't strip elem type
2616 auto &elem_type
= type
.get_elem_type ();
2617 if (elem_type
.is_marked_for_strip ())
2618 rust_error_at (elem_type
.get_locus (),
2619 "cannot strip type in this position");
2623 CfgStrip::visit (AST::BareFunctionType
&type
)
2625 // seem to be no generics
2626 AST::DefaultASTVisitor::visit (type
);
2628 // presumably function params can be stripped
2629 auto ¶ms
= type
.get_function_params ();
2630 for (auto it
= params
.begin (); it
!= params
.end ();)
2634 auto ¶m_attrs
= param
.get_outer_attrs ();
2635 expand_cfg_attrs (param_attrs
);
2636 if (fails_cfg_with_expand (param_attrs
))
2638 it
= params
.erase (it
);
2642 auto &type
= param
.get_type ();
2643 if (type
.is_marked_for_strip ())
2644 rust_error_at (type
.get_locus (), "cannot strip type in this position");
2646 // increment if nothing else happens
2650 /* TODO: assuming that variadic nature cannot be stripped. If this
2651 * is not true, then have code here to do so. */
2653 if (type
.has_return_type ())
2655 // FIXME: Can we have type expansion in this position?
2656 // In that case, we need to handle AST::TypeNoBounds on top of just
2658 auto &return_type
= type
.get_return_type ();
2659 if (return_type
.is_marked_for_strip ())
2660 rust_error_at (return_type
.get_locus (),
2661 "cannot strip type in this position");
2664 // no where clause, apparently
2668 CfgStrip::visit (AST::SelfParam
¶m
)
2670 AST::DefaultASTVisitor::visit (param
);
2672 if (param
.has_type ())
2674 auto &type
= param
.get_type ();
2675 if (type
.is_marked_for_strip ())
2676 rust_error_at (type
.get_locus (), "cannot strip type in this position");
2678 /* TODO: maybe check for invariants being violated - e.g. both type and