go: update builtin function attributes
[official-gcc.git] / gcc / rust / expand / rust-cfg-strip.cc
blob8abc5cb766e84b7ab923dccfeff980deb8c5d206
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
8 // version.
10 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 // for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with GCC; see the file COPYING3. If not see
17 // <http://www.gnu.org/licenses/>.
19 #include "rust-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"
25 namespace Rust {
27 /**
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.
31 bool
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))
40 return true;
42 return false;
45 /**
46 * Determines whether any cfg predicate is false and hence item with attributes
47 * should be stripped. Will expand attributes as well.
49 bool
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 ();
62 // DEBUG
63 if (!attr.is_parsed_to_meta_item ())
64 rust_debug ("failed to parse attr to meta item, right before "
65 "cfg predicate check");
66 else
67 rust_debug ("attr has been successfully parsed to meta item, "
68 "right before cfg predicate check");
70 if (!attr.check_cfg_predicate (session))
72 // DEBUG
73 rust_debug (
74 "cfg predicate failed for attribute: \033[0;31m'%s'\033[0m",
75 attr.as_string ().c_str ());
77 return true;
79 else
81 // DEBUG
82 rust_debug ("cfg predicate succeeded for attribute: "
83 "\033[0;31m'%s'\033[0m",
84 attr.as_string ().c_str ());
88 return false;
91 /**
92 * Expands cfg_attr attributes.
94 void
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? */
128 else
130 i++;
133 attrs.shrink_to_fit ();
136 void
137 CfgStrip::go (AST::Crate &crate)
139 visit (crate);
142 void
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 ();)
160 auto &item = *it;
161 if (item->is_marked_for_strip ())
162 it = items.erase (it);
163 else
164 it++;
166 // expand module attributes?
169 // Visitor used to expand attributes.
170 void
171 CfgStrip::maybe_strip_struct_fields (std::vector<AST::StructField> &fields)
173 for (auto it = fields.begin (); it != fields.end ();)
175 auto &field = *it;
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);
182 continue;
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
193 ++it;
197 void
198 CfgStrip::maybe_strip_tuple_fields (std::vector<AST::TupleField> &fields)
200 for (auto it = fields.begin (); it != fields.end ();)
202 auto &field = *it;
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);
209 continue;
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
219 ++it;
223 void
224 CfgStrip::maybe_strip_function_params (
225 std::vector<std::unique_ptr<AST::Param>> &params)
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 &param_attrs = param->get_outer_attrs ();
234 expand_cfg_attrs (param_attrs);
235 if (fails_cfg_with_expand (param_attrs))
237 it = params.erase (it);
238 continue;
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");
255 // increment
256 ++it;
260 void
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");
278 break;
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");
287 break;
289 default:
290 break;
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");
311 void
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 ();
323 visit (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");
330 void
331 CfgStrip::CfgStrip::maybe_strip_closure_params (
332 std::vector<AST::ClosureParam> &params)
334 for (auto it = params.begin (); it != params.end ();)
336 auto &param = *it;
338 auto &param_attrs = param.get_outer_attrs ();
339 expand_cfg_attrs (param_attrs);
340 if (fails_cfg_with_expand (param_attrs))
342 it = params.erase (it);
343 continue;
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
363 ++it;
367 void
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);
375 void
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 ();
384 return;
388 void
389 CfgStrip::visit (AST::MacroInvocation &macro_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 ();
396 return;
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?
406 void
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 ();
414 return;
417 for (auto &segment : path.get_segments ())
419 if (segment.has_generic_args ())
420 maybe_strip_generic_args (segment.get_generic_args ());
424 void
425 CfgStrip::visit (AST::TypePathSegmentGeneric &segment)
427 // TODO: strip inside generic args
429 if (!segment.has_generic_args ())
430 return;
432 maybe_strip_generic_args (segment.get_generic_args ());
434 void
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");
457 void
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 ();
467 return;
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 ());
479 void
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);
488 void
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 ();
496 return;
500 void
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 ();
509 return;
512 /* strip any internal sub-expressions - expression itself isn't
513 * allowed to have external attributes in this position so can't be
514 * stripped. */
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");
521 void
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 ();
529 return;
532 /* strip any internal sub-expressions - expression itself isn't
533 * allowed to have external attributes in this position so can't be
534 * stripped. */
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");
542 void
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 ();
552 return;
555 /* strip any internal sub-expressions - expression itself isn't
556 * allowed to have external attributes in this position so can't be
557 * stripped. */
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");
564 void
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 ();
573 return;
576 /* strip any internal sub-expressions - expression itself isn't
577 * allowed to have external attributes in this position so can't be
578 * stripped. */
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");
585 void
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");
604 void
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");
623 void
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");
642 void
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");
661 void
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 ();
668 return;
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");
683 void
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");
701 void
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 ();
709 return;
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 ();
718 return;
721 /* strip any internal sub-expressions - expression itself isn't
722 * allowed to have external attributes in this position so can't be
723 * stripped. */
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");
732 void
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 ());
739 void
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 &copy_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");
762 void
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 ();
770 return;
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 ();
779 return;
782 /* assuming you can't strip away the ArrayElems type, but can strip
783 * internal expressions and whatever */
784 AST::DefaultASTVisitor::visit (expr);
787 void
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 ();
798 return;
801 /* strip any internal sub-expressions - expression itself isn't
802 * allowed to have external attributes in this position so can't be
803 * stripped. */
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");
818 void
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 ();
829 return;
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 ();
838 return;
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 ());
845 void
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 ();
853 return;
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");
867 void
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 ();
875 return;
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 ();
884 return;
887 // strip sub-exprs of path
888 auto &struct_name = expr.get_struct_name ();
889 visit (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");
895 void
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");
908 void
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");
921 void
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 ();
929 return;
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 ();
938 return;
941 // strip sub-exprs of path
942 auto &struct_name = expr.get_struct_name ();
943 visit (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");
967 void
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 ();
975 return;
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 ();
984 return;
987 // strip sub-exprs of path
988 auto &struct_name = expr.get_struct_name ();
989 visit (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");
1004 void
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 ();
1012 return;
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 ());
1032 void
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 ();
1040 return;
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 ());
1062 void
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 ();
1070 return;
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");
1084 void
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 ();
1092 return;
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");
1109 void
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 ();
1117 return;
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 ();
1126 return;
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 ();
1143 void
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 ();
1151 return;
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");
1174 void
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 ();
1182 return;
1185 void
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 ();
1193 return;
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");
1210 void
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");
1228 void
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");
1243 void
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");
1259 void
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");
1278 void
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");
1293 void
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 ();
1301 return;
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. */
1323 void
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 ();
1331 return;
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");
1343 void
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 ();
1351 return;
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");
1363 void
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 ();
1371 return;
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");
1389 void
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 ();
1397 return;
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");
1421 void
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 ();
1429 return;
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");
1453 void
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 ();
1464 return;
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");
1484 void
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 ();
1492 return;
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");
1519 void
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 ();
1527 return;
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");
1551 void
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 ();
1559 return;
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");
1590 void
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 ();
1598 return;
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 ();
1606 return;
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 ()))
1629 // strip match case
1630 it = match_cases.erase (it);
1631 continue;
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
1660 ++it;
1664 void
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 ();
1672 return;
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");
1685 void
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 ();
1693 return;
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");
1706 void
1707 CfgStrip::visit (AST::TypeParam &param)
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");
1718 void
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");
1729 void
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 ();
1737 return;
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 ();
1748 return;
1752 // strip items if required
1753 maybe_strip_pointer_allow_strip (module.get_items ());
1756 void
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 ();
1764 return;
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 ());
1775 void
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 ();
1783 return;
1787 void
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 ();
1795 return;
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
1813 * before now */
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");
1825 void
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 ();
1833 return;
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");
1843 void
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 ();
1851 return;
1854 AST::DefaultASTVisitor::visit (struct_item);
1856 void
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 ();
1864 return;
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 ());
1873 void
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 ();
1881 return;
1885 void
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 ();
1893 return;
1896 /* strip item fields if required - this is presumably
1897 * allowed by spec */
1898 maybe_strip_tuple_fields (item.get_tuple_fields ());
1901 void
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 ();
1909 return;
1912 /* strip item fields if required - this is presumably
1913 * allowed by spec */
1914 maybe_strip_struct_fields (item.get_struct_fields ());
1917 void
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 ();
1925 return;
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
1931 * stripped. */
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");
1938 void
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 ();
1946 return;
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 ());
1955 void
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 ();
1963 return;
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 ());
1972 void
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 ();
1980 return;
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
1992 * stripped. */
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");
2002 void
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 ();
2010 return;
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
2023 * stripped. */
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");
2031 void
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 ();
2039 return;
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
2052 * stripped */
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");
2063 void
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 ();
2071 return;
2074 AST::DefaultASTVisitor::visit (item);
2077 void
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 ();
2085 return;
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 ();
2093 return;
2096 AST::DefaultASTVisitor::visit (trait);
2098 maybe_strip_pointer_allow_strip (trait.get_trait_items ());
2101 void
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 ();
2109 return;
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 ();
2117 return;
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 ());
2130 void
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 ();
2138 return;
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 ();
2146 return;
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 ();
2156 visit (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 ());
2164 void
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!(); }
2174 // ?
2177 void
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 ();
2185 return;
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");
2195 void
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 ();
2203 return;
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 ();
2211 return;
2214 maybe_strip_pointer_allow_strip (block.get_extern_items ());
2217 void
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 ();
2225 return;
2229 void
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 ())
2234 return;
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");
2244 void
2245 CfgStrip::visit (AST::RangePatternBoundPath &bound)
2247 // can expand path, but not strip it directly
2248 auto &path = bound.get_path ();
2249 visit (path);
2250 if (path.is_marked_for_strip ())
2251 rust_error_at (path.get_locus (), "cannot strip path in this position");
2254 void
2255 CfgStrip::visit (AST::RangePatternBoundQualPath &bound)
2257 // can expand path, but not strip it directly
2258 auto &path = bound.get_qualified_path ();
2259 visit (path);
2260 if (path.is_marked_for_strip ())
2261 rust_error_at (path.get_locus (), "cannot strip path in this position");
2264 void
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");
2274 void
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 ();
2282 return;
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");
2294 void
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 ();
2302 return;
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");
2312 void
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 ();
2320 return;
2324 void
2325 CfgStrip::visit (AST::StructPattern &pattern)
2327 // expand (but don't strip) path
2328 auto &path = pattern.get_path ();
2329 visit (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
2334 * be stripped? */
2335 if (!pattern.has_struct_pattern_elems ())
2336 return;
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 ()))
2348 elems.strip_etc ();
2352 void
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?
2365 void
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?
2386 void
2387 CfgStrip::visit (AST::TupleStructPattern &pattern)
2389 // expand (but don't strip) path
2390 auto &path = pattern.get_path ();
2391 visit (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);
2398 void
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?
2413 void
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?
2435 void
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");
2447 void
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?
2461 void
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?
2475 void
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 ();
2483 return;
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");
2493 // similar for type
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
2504 * stripped */
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");
2516 void
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 ())
2523 return;
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 ();
2531 return;
2535 void
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 ();
2542 visit (path);
2543 if (path.is_marked_for_strip ())
2544 rust_error_at (path.get_locus (),
2545 "cannot strip type path in this position");
2548 void
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");
2559 void
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
2564 // attributes
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");
2573 void
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");
2584 void
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");
2595 void
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");
2611 void
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");
2622 void
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 &params = type.get_function_params ();
2630 for (auto it = params.begin (); it != params.end ();)
2632 auto &param = *it;
2634 auto &param_attrs = param.get_outer_attrs ();
2635 expand_cfg_attrs (param_attrs);
2636 if (fails_cfg_with_expand (param_attrs))
2638 it = params.erase (it);
2639 continue;
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
2647 ++it;
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
2657 // AST::Types
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
2667 void
2668 CfgStrip::visit (AST::SelfParam &param)
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
2679 * lifetime? */
2682 } // namespace Rust