Line data Source code
1 : // Copyright (C) 2020-2026 Free Software Foundation, Inc.
2 :
3 : // This file is part of GCC.
4 :
5 : // GCC is free software; you can redistribute it and/or modify it under
6 : // the terms of the GNU General Public License as published by the Free
7 : // Software Foundation; either version 3, or (at your option) any later
8 : // version.
9 :
10 : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : // for more details.
14 :
15 : // You should have received a copy of the GNU General Public License
16 : // along with GCC; see the file COPYING3. If not see
17 : // <http://www.gnu.org/licenses/>.
18 :
19 : #include "rust-cfg-strip.h"
20 : #include "rust-ast-full.h"
21 : #include "rust-ast-visitor.h"
22 : #include "rust-path.h"
23 : #include "rust-session-manager.h"
24 : #include "rust-attribute-values.h"
25 : #include "rust-macro-expand.h"
26 :
27 : namespace Rust {
28 :
29 : /**
30 : * Determines whether any cfg predicate is false and hence item with attributes
31 : * should be stripped. Note that attributes must be expanded before calling.
32 : */
33 : bool
34 0 : CfgStrip::fails_cfg (const AST::AttrVec &attrs) const
35 : {
36 0 : auto &session = Session::get_instance ();
37 :
38 0 : for (const auto &attr : attrs)
39 : {
40 0 : if (attr.get_path () == Values::Attributes::CFG
41 0 : && !attr.check_cfg_predicate (session))
42 : return true;
43 0 : else if (!expansion_cfg.should_test
44 0 : && attr.get_path () == Values::Attributes::TEST)
45 : return true;
46 : }
47 : return false;
48 : }
49 :
50 : /**
51 : * Determines whether any cfg predicate is false and hence item with attributes
52 : * should be stripped. Will expand attributes as well.
53 : */
54 : bool
55 1771029 : CfgStrip::fails_cfg_with_expand (AST::AttrVec &attrs) const
56 : {
57 1771029 : auto &session = Session::get_instance ();
58 :
59 : // TODO: maybe have something that strips cfg attributes that evaluate true?
60 1871185 : for (auto &attr : attrs)
61 : {
62 100269 : if (attr.get_path () == Values::Attributes::CFG)
63 : {
64 2116 : if (!attr.is_parsed_to_meta_item ())
65 479 : attr.parse_attr_to_meta_item ();
66 :
67 : // DEBUG
68 2116 : if (!attr.is_parsed_to_meta_item ())
69 1 : rust_debug ("failed to parse attr to meta item, right before "
70 : "cfg predicate check");
71 : else
72 2115 : rust_debug ("attr has been successfully parsed to meta item, "
73 : "right before cfg predicate check");
74 :
75 2116 : if (!attr.check_cfg_predicate (session))
76 : {
77 : // DEBUG
78 112 : rust_debug (
79 : "cfg predicate failed for attribute: \033[0;31m'%s'\033[0m",
80 : attr.as_string ().c_str ());
81 :
82 112 : return true;
83 : }
84 : else
85 : {
86 : // DEBUG
87 2004 : rust_debug ("cfg predicate succeeded for attribute: "
88 : "\033[0;31m'%s'\033[0m",
89 : attr.as_string ().c_str ());
90 : }
91 : }
92 98153 : else if (!expansion_cfg.should_test
93 196306 : && attr.get_path () == Values::Attributes::TEST)
94 : return true;
95 : }
96 : return false;
97 : }
98 :
99 : /**
100 : * Expands cfg_attr attributes.
101 : */
102 : void
103 1771029 : expand_cfg_attrs (AST::AttrVec &attrs)
104 : {
105 1771029 : auto &session = Session::get_instance ();
106 :
107 1871306 : for (std::size_t i = 0; i < attrs.size (); i++)
108 : {
109 100277 : auto &attr = attrs[i];
110 100277 : if (attr.get_path () == Values::Attributes::CFG_ATTR)
111 : {
112 23 : if (!attr.is_parsed_to_meta_item ())
113 16 : attr.parse_attr_to_meta_item ();
114 :
115 23 : if (attr.check_cfg_predicate (session))
116 : {
117 : // split off cfg_attr
118 8 : AST::AttrVec new_attrs = attr.separate_cfg_attrs ();
119 :
120 : // remove attr from vector
121 8 : attrs.erase (attrs.begin () + i);
122 :
123 : // add new attrs to vector
124 8 : attrs.insert (attrs.begin () + i,
125 : std::make_move_iterator (new_attrs.begin ()),
126 : std::make_move_iterator (new_attrs.end ()));
127 :
128 : /* Decrement i so that the for loop's i++ will bring us back to
129 : * position i, allowing us to reprocess the newly inserted
130 : * attribute (in case it's also a cfg_attr that needs expansion)
131 : */
132 8 : i--;
133 8 : }
134 :
135 : /* do something - if feature (first token in tree) is in fact enabled,
136 : * make tokens listed afterwards into attributes. i.e.: for
137 : * [cfg_attr(feature = "wow", wow1, wow2)], if "wow" is true, then add
138 : * attributes [wow1] and [wow2] to attribute list. This can also be
139 : * recursive, so check for expanded attributes being recursive and
140 : * possibly recursively call the expand_attrs? */
141 : }
142 : }
143 1771029 : attrs.shrink_to_fit ();
144 1771029 : }
145 :
146 : void
147 10411 : CfgStrip::go (AST::Crate &crate)
148 : {
149 10411 : visit (crate);
150 10411 : }
151 :
152 : void
153 10411 : CfgStrip::visit (AST::Crate &crate)
154 : {
155 : // expand crate cfg_attr attributes
156 10411 : expand_cfg_attrs (crate.inner_attrs);
157 :
158 10411 : if (fails_cfg_with_expand (crate.inner_attrs))
159 : {
160 : // basically, delete whole crate
161 1 : crate.strip_crate ();
162 : // TODO: maybe create warning here? probably not desired behaviour
163 : }
164 :
165 10411 : auto &items = crate.items;
166 :
167 10411 : AST::DefaultASTVisitor::visit (crate);
168 55566 : for (auto it = items.begin (); it != items.end ();)
169 : {
170 45155 : auto &item = *it;
171 45155 : if (item->is_marked_for_strip ())
172 19 : it = items.erase (it);
173 : else
174 45136 : it++;
175 : }
176 : // expand module attributes?
177 10411 : }
178 :
179 : // Visitor used to expand attributes.
180 : void
181 4734 : CfgStrip::maybe_strip_struct_fields (std::vector<AST::StructField> &fields)
182 : {
183 10520 : for (auto it = fields.begin (); it != fields.end ();)
184 : {
185 5786 : auto &field = *it;
186 :
187 5786 : auto &field_attrs = field.get_outer_attrs ();
188 5786 : expand_cfg_attrs (field_attrs);
189 5786 : if (fails_cfg_with_expand (field_attrs))
190 : {
191 1 : it = fields.erase (it);
192 1 : continue;
193 : }
194 :
195 : // expand sub-types of type, but can't strip type itself
196 5785 : auto &type = field.get_field_type ();
197 5785 : type.accept_vis (*this);
198 :
199 5785 : if (type.is_marked_for_strip ())
200 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
201 :
202 : // if nothing else happens, increment
203 5785 : ++it;
204 : }
205 4734 : }
206 :
207 : void
208 5732 : CfgStrip::maybe_strip_struct_expr_fields (
209 : std::vector<std::unique_ptr<AST::StructExprField>> &fields)
210 : {
211 15993 : for (auto it = fields.begin (); it != fields.end ();)
212 : {
213 10261 : auto &field = *it;
214 :
215 10261 : auto &field_attrs = field->get_outer_attrs ();
216 10261 : expand_cfg_attrs (field_attrs);
217 10261 : if (fails_cfg_with_expand (field_attrs))
218 : {
219 1 : it = fields.erase (it);
220 1 : continue;
221 : }
222 :
223 10260 : ++it;
224 : }
225 5732 : }
226 :
227 : void
228 4704 : CfgStrip::maybe_strip_tuple_fields (std::vector<AST::TupleField> &fields)
229 : {
230 12197 : for (auto it = fields.begin (); it != fields.end ();)
231 : {
232 7493 : auto &field = *it;
233 :
234 7493 : auto &field_attrs = field.get_outer_attrs ();
235 7493 : expand_cfg_attrs (field_attrs);
236 7493 : if (fails_cfg_with_expand (field_attrs))
237 : {
238 0 : it = fields.erase (it);
239 0 : continue;
240 : }
241 :
242 : // expand sub-types of type, but can't strip type itself
243 7493 : auto &type = field.get_field_type ();
244 7493 : type.accept_vis (*this);
245 7493 : if (type.is_marked_for_strip ())
246 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
247 :
248 : // if nothing else happens, increment
249 7493 : ++it;
250 : }
251 4704 : }
252 :
253 : void
254 67551 : CfgStrip::maybe_strip_function_params (
255 : std::vector<std::unique_ptr<AST::Param>> ¶ms)
256 : {
257 151978 : for (auto it = params.begin (); it != params.end ();)
258 : {
259 84427 : if (!(*it)->is_self () && !(*it)->is_variadic ())
260 : {
261 43016 : auto param = static_cast<AST::FunctionParam *> (it->get ());
262 :
263 43016 : auto ¶m_attrs = param->get_outer_attrs ();
264 43016 : expand_cfg_attrs (param_attrs);
265 43016 : if (fails_cfg_with_expand (param_attrs))
266 : {
267 0 : it = params.erase (it);
268 0 : continue;
269 : }
270 :
271 : // TODO: should an unwanted strip lead to break out of loop?
272 43016 : auto &pattern = param->get_pattern ();
273 43016 : pattern.accept_vis (*this);
274 43016 : if (pattern.is_marked_for_strip ())
275 0 : rust_error_at (pattern.get_locus (),
276 : "cannot strip pattern in this position");
277 :
278 43016 : auto &type = param->get_type ();
279 43016 : type.accept_vis (*this);
280 :
281 43016 : if (type.is_marked_for_strip ())
282 0 : rust_error_at (type.get_locus (),
283 : "cannot strip type in this position");
284 : }
285 : // increment
286 84427 : ++it;
287 : }
288 67551 : }
289 :
290 : void
291 20635 : CfgStrip::maybe_strip_generic_args (AST::GenericArgs &args)
292 : {
293 : // lifetime args can't be expanded
294 : // FIXME: Can we have macro invocations for lifetimes?
295 :
296 : // expand type args - strip sub-types only
297 42008 : for (auto &arg : args.get_generic_args ())
298 : {
299 21373 : switch (arg.get_kind ())
300 : {
301 9435 : case AST::GenericArg::Kind::Type:
302 9435 : {
303 9435 : auto &type = arg.get_type ();
304 9435 : type.accept_vis (*this);
305 :
306 9435 : if (type.is_marked_for_strip ())
307 0 : rust_error_at (type.get_locus (),
308 : "cannot strip type in this position");
309 : break;
310 : }
311 392 : case AST::GenericArg::Kind::Const:
312 392 : {
313 392 : auto &expr = arg.get_expression ();
314 392 : expr.accept_vis (*this);
315 :
316 392 : if (expr.is_marked_for_strip ())
317 0 : rust_error_at (expr.get_locus (),
318 : "cannot strip expression in this position");
319 : break;
320 : }
321 : default:
322 : break;
323 : // FIXME: Figure out what to do here if there is ambiguity. Since the
324 : // resolver comes after the expansion, we need to figure out a way to
325 : // strip ambiguous values here
326 : // TODO: Arthur: Probably add a `mark_as_strip` method to `GenericArg`
327 : // or something. This would clean up this whole thing
328 : }
329 : }
330 :
331 : // FIXME: Can we have macro invocations in generic type bindings?
332 : // expand binding args - strip sub-types only
333 20967 : for (auto &binding : args.get_binding_args ())
334 : {
335 332 : auto &type = binding.get_type ();
336 332 : type.accept_vis (*this);
337 :
338 332 : if (type.is_marked_for_strip ())
339 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
340 : }
341 20635 : }
342 :
343 : void
344 1779 : CfgStrip::maybe_strip_qualified_path_type (AST::QualifiedPathType &path_type)
345 : {
346 1779 : auto &type = path_type.get_type ();
347 1779 : type.accept_vis (*this);
348 :
349 1779 : if (type.is_marked_for_strip ())
350 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
351 :
352 1779 : if (path_type.has_as_clause ())
353 : {
354 1589 : auto &type_path = path_type.get_as_type_path ();
355 1589 : visit (type_path);
356 1589 : if (type_path.is_marked_for_strip ())
357 0 : rust_error_at (type_path.get_locus (),
358 : "cannot strip type path in this position");
359 : }
360 1779 : }
361 :
362 : void
363 250 : CfgStrip::CfgStrip::maybe_strip_closure_params (
364 : std::vector<AST::ClosureParam> ¶ms)
365 : {
366 500 : for (auto it = params.begin (); it != params.end ();)
367 : {
368 250 : auto ¶m = *it;
369 :
370 250 : auto ¶m_attrs = param.get_outer_attrs ();
371 250 : expand_cfg_attrs (param_attrs);
372 250 : if (fails_cfg_with_expand (param_attrs))
373 : {
374 0 : it = params.erase (it);
375 0 : continue;
376 : }
377 :
378 250 : auto &pattern = param.get_pattern ();
379 250 : pattern.accept_vis (*this);
380 250 : if (pattern.is_marked_for_strip ())
381 0 : rust_error_at (pattern.get_locus (),
382 : "cannot strip pattern in this position");
383 :
384 250 : if (param.has_type_given ())
385 : {
386 232 : auto &type = param.get_type ();
387 232 : type.accept_vis (*this);
388 :
389 232 : if (type.is_marked_for_strip ())
390 0 : rust_error_at (type.get_locus (),
391 : "cannot strip type in this position");
392 : }
393 :
394 : // increment if found nothing else so far
395 250 : ++it;
396 : }
397 250 : }
398 :
399 : void
400 0 : CfgStrip::maybe_strip_where_clause (AST::WhereClause &where_clause)
401 : {
402 : // items cannot be stripped conceptually, so just accept visitor
403 0 : for (auto &item : where_clause.get_items ())
404 0 : item->accept_vis (*this);
405 0 : }
406 :
407 : void
408 207976 : CfgStrip::visit (AST::IdentifierExpr &ident_expr)
409 : {
410 : // strip test based on outer attrs
411 207976 : AST::DefaultASTVisitor::visit (ident_expr);
412 207976 : expand_cfg_attrs (ident_expr.get_outer_attrs ());
413 207976 : if (fails_cfg_with_expand (ident_expr.get_outer_attrs ()))
414 : {
415 0 : ident_expr.mark_for_strip ();
416 0 : return;
417 : }
418 : }
419 :
420 : void
421 4583 : CfgStrip::visit (AST::MacroInvocation ¯o_invoc)
422 : {
423 : // initial strip test based on outer attrs
424 4583 : expand_cfg_attrs (macro_invoc.get_outer_attrs ());
425 4583 : if (fails_cfg_with_expand (macro_invoc.get_outer_attrs ()))
426 : {
427 0 : macro_invoc.mark_for_strip ();
428 0 : return;
429 : }
430 :
431 : // can't strip simple path
432 :
433 : // I don't think any macro token trees can be stripped in any way
434 :
435 : // TODO: maybe have cfg! macro stripping behaviour here?
436 : }
437 :
438 : void
439 160455 : CfgStrip::visit (AST::PathInExpression &path)
440 : {
441 : // initial strip test based on outer attrs
442 160455 : expand_cfg_attrs (path.get_outer_attrs ());
443 160455 : if (fails_cfg_with_expand (path.get_outer_attrs ()))
444 : {
445 0 : path.mark_for_strip ();
446 0 : return;
447 : }
448 :
449 160455 : if (!path.is_lang_item ())
450 : {
451 382616 : for (auto &segment : path.get_segments ())
452 : {
453 445318 : if (segment.has_generic_args ())
454 7105 : maybe_strip_generic_args (segment.get_generic_args ());
455 : }
456 : }
457 : }
458 :
459 : void
460 13446 : CfgStrip::visit (AST::TypePathSegmentGeneric &segment)
461 : {
462 : // TODO: strip inside generic args
463 :
464 13446 : if (!segment.has_generic_args ())
465 : return;
466 :
467 13442 : maybe_strip_generic_args (segment.get_generic_args ());
468 : }
469 : void
470 78 : CfgStrip::visit (AST::TypePathSegmentFunction &segment)
471 : {
472 78 : AST::DefaultASTVisitor::visit (segment);
473 78 : auto &type_path_function = segment.get_type_path_function ();
474 :
475 160 : for (auto &type : type_path_function.get_params ())
476 : {
477 82 : if (type->is_marked_for_strip ())
478 0 : rust_error_at (type->get_locus (),
479 : "cannot strip type in this position");
480 : }
481 :
482 78 : if (type_path_function.has_return_type ())
483 : {
484 74 : auto &return_type = type_path_function.get_return_type ();
485 :
486 74 : if (return_type.is_marked_for_strip ())
487 0 : rust_error_at (return_type.get_locus (),
488 : "cannot strip type in this position");
489 : }
490 78 : }
491 :
492 : void
493 526 : CfgStrip::visit (AST::QualifiedPathInExpression &path)
494 : {
495 : // initial strip test based on outer attrs
496 526 : AST::DefaultASTVisitor::visit (path);
497 :
498 526 : expand_cfg_attrs (path.get_outer_attrs ());
499 526 : if (fails_cfg_with_expand (path.get_outer_attrs ()))
500 : {
501 0 : path.mark_for_strip ();
502 0 : return;
503 : }
504 :
505 526 : maybe_strip_qualified_path_type (path.get_qualified_path_type ());
506 :
507 1052 : for (auto &segment : path.get_segments ())
508 : {
509 1052 : if (segment.has_generic_args ())
510 0 : maybe_strip_generic_args (segment.get_generic_args ());
511 : }
512 : }
513 :
514 : void
515 1253 : CfgStrip::visit (AST::QualifiedPathInType &path)
516 : {
517 1253 : maybe_strip_qualified_path_type (path.get_qualified_path_type ());
518 :
519 : // this shouldn't strip any segments, but can strip inside them
520 1253 : AST::DefaultASTVisitor::visit (path);
521 1253 : }
522 :
523 : void
524 637076 : CfgStrip::visit (AST::LiteralExpr &expr)
525 : {
526 : // initial strip test based on outer attrs
527 637076 : expand_cfg_attrs (expr.get_outer_attrs ());
528 637076 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
529 : {
530 0 : expr.mark_for_strip ();
531 0 : return;
532 : }
533 : }
534 :
535 : void
536 17510 : CfgStrip::visit (AST::BorrowExpr &expr)
537 : {
538 17510 : AST::DefaultASTVisitor::visit (expr);
539 : // initial strip test based on outer attrs
540 17510 : expand_cfg_attrs (expr.get_outer_attrs ());
541 17510 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
542 : {
543 0 : expr.mark_for_strip ();
544 0 : return;
545 : }
546 :
547 : /* strip any internal sub-expressions - expression itself isn't
548 : * allowed to have external attributes in this position so can't be
549 : * stripped. */
550 17510 : auto &borrowed_expr = expr.get_borrowed_expr ();
551 17510 : if (borrowed_expr.is_marked_for_strip ())
552 0 : rust_error_at (borrowed_expr.get_locus (),
553 : "cannot strip expression in this position - outer "
554 : "attributes not allowed");
555 : }
556 : void
557 21384 : CfgStrip::visit (AST::DereferenceExpr &expr)
558 : {
559 : // initial strip test based on outer attrs
560 21384 : expand_cfg_attrs (expr.get_outer_attrs ());
561 21384 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
562 : {
563 0 : expr.mark_for_strip ();
564 0 : return;
565 : }
566 :
567 : /* strip any internal sub-expressions - expression itself isn't
568 : * allowed to have external attributes in this position so can't be
569 : * stripped. */
570 21384 : auto &dereferenced_expr = expr.get_dereferenced_expr ();
571 21384 : dereferenced_expr.accept_vis (*this);
572 21384 : if (dereferenced_expr.is_marked_for_strip ())
573 0 : rust_error_at (dereferenced_expr.get_locus (),
574 : "cannot strip expression in this position - outer "
575 : "attributes not allowed");
576 : }
577 : void
578 4 : CfgStrip::visit (AST::ErrorPropagationExpr &expr)
579 : {
580 4 : AST::DefaultASTVisitor::visit (expr);
581 :
582 : // initial strip test based on outer attrs
583 4 : expand_cfg_attrs (expr.get_outer_attrs ());
584 4 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
585 : {
586 0 : expr.mark_for_strip ();
587 0 : return;
588 : }
589 :
590 : /* strip any internal sub-expressions - expression itself isn't
591 : * allowed to have external attributes in this position so can't be
592 : * stripped. */
593 4 : auto &propagating_expr = expr.get_propagating_expr ();
594 4 : if (propagating_expr.is_marked_for_strip ())
595 0 : rust_error_at (propagating_expr.get_locus (),
596 : "cannot strip expression in this position - outer "
597 : "attributes not allowed");
598 : }
599 : void
600 2418 : CfgStrip::visit (AST::NegationExpr &expr)
601 : {
602 2418 : AST::DefaultASTVisitor::visit (expr);
603 : // initial strip test based on outer attrs
604 2418 : expand_cfg_attrs (expr.get_outer_attrs ());
605 2418 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
606 : {
607 0 : expr.mark_for_strip ();
608 0 : return;
609 : }
610 :
611 : /* strip any internal sub-expressions - expression itself isn't
612 : * allowed to have external attributes in this position so can't be
613 : * stripped. */
614 2418 : auto &negated_expr = expr.get_negated_expr ();
615 2418 : if (negated_expr.is_marked_for_strip ())
616 0 : rust_error_at (negated_expr.get_locus (),
617 : "cannot strip expression in this position - outer "
618 : "attributes not allowed");
619 : }
620 : void
621 540417 : CfgStrip::visit (AST::ArithmeticOrLogicalExpr &expr)
622 : {
623 540417 : AST::DefaultASTVisitor::visit (expr);
624 : /* outer attributes never allowed before these. while cannot strip
625 : * two direct descendant expressions, can strip ones below that */
626 :
627 : // ensure that they are not marked for strip
628 540417 : if (expr.get_left_expr ().is_marked_for_strip ())
629 0 : rust_error_at (expr.get_left_expr ().get_locus (),
630 : "cannot strip expression in this position - outer "
631 : "attributes are never allowed "
632 : "before binary op exprs");
633 540417 : if (expr.get_right_expr ().is_marked_for_strip ())
634 0 : rust_error_at (expr.get_right_expr ().get_locus (),
635 : "cannot strip expression in this position - outer "
636 : "attributes not allowed");
637 540417 : }
638 :
639 : void
640 13191 : CfgStrip::visit (AST::ComparisonExpr &expr)
641 : {
642 : /* outer attributes never allowed before these. while cannot strip
643 : * two direct descendant expressions, can strip ones below that */
644 13191 : AST::DefaultASTVisitor::visit (expr);
645 :
646 : // ensure that they are not marked for strip
647 13191 : if (expr.get_left_expr ().is_marked_for_strip ())
648 0 : rust_error_at (expr.get_left_expr ().get_locus (),
649 : "cannot strip expression in this position - outer "
650 : "attributes are never allowed "
651 : "before binary op exprs");
652 13191 : if (expr.get_right_expr ().is_marked_for_strip ())
653 0 : rust_error_at (expr.get_right_expr ().get_locus (),
654 : "cannot strip expression in this position - outer "
655 : "attributes not allowed");
656 13191 : }
657 :
658 : void
659 1580 : CfgStrip::visit (AST::LazyBooleanExpr &expr)
660 : {
661 : /* outer attributes never allowed before these. while cannot strip
662 : * two direct descendant expressions, can strip ones below that */
663 1580 : AST::DefaultASTVisitor::visit (expr);
664 :
665 : // ensure that they are not marked for strip
666 1580 : if (expr.get_left_expr ().is_marked_for_strip ())
667 0 : rust_error_at (expr.get_left_expr ().get_locus (),
668 : "cannot strip expression in this position - outer "
669 : "attributes are never allowed "
670 : "before binary op exprs");
671 1580 : if (expr.get_right_expr ().is_marked_for_strip ())
672 0 : rust_error_at (expr.get_right_expr ().get_locus (),
673 : "cannot strip expression in this position - outer "
674 : "attributes not allowed");
675 1580 : }
676 :
677 : void
678 52274 : CfgStrip::visit (AST::TypeCastExpr &expr)
679 : {
680 : /* outer attributes never allowed before these. while cannot strip
681 : * direct descendant expression, can strip ones below that */
682 52274 : AST::DefaultASTVisitor::visit (expr);
683 :
684 52274 : auto &casted_expr = expr.get_casted_expr ();
685 : // ensure that they are not marked for strip
686 52274 : if (casted_expr.is_marked_for_strip ())
687 0 : rust_error_at (casted_expr.get_locus (),
688 : "cannot strip expression in this position - outer "
689 : "attributes are never allowed before cast exprs");
690 :
691 : // TODO: strip sub-types of type
692 52274 : auto &type = expr.get_type_to_cast_to ();
693 52274 : if (type.is_marked_for_strip ())
694 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
695 52274 : }
696 : void
697 15840 : CfgStrip::visit (AST::AssignmentExpr &expr)
698 : {
699 15840 : expand_cfg_attrs (expr.get_outer_attrs ());
700 15840 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
701 : {
702 14 : expr.mark_for_strip ();
703 14 : return;
704 : }
705 15826 : AST::DefaultASTVisitor::visit (expr);
706 :
707 : // ensure that they are not marked for strip
708 15826 : if (expr.get_left_expr ().is_marked_for_strip ())
709 0 : rust_error_at (expr.get_left_expr ().get_locus (),
710 : "cannot strip expression in this position - outer "
711 : "attributes are never allowed "
712 : "before binary op exprs");
713 15826 : if (expr.get_right_expr ().is_marked_for_strip ())
714 0 : rust_error_at (expr.get_right_expr ().get_locus (),
715 : "cannot strip expression in this position - outer "
716 : "attributes not allowed");
717 : }
718 : void
719 6294 : CfgStrip::visit (AST::CompoundAssignmentExpr &expr)
720 : {
721 : /* outer attributes never allowed before these. while cannot strip
722 : * two direct descendant expressions, can strip ones below that */
723 6294 : AST::DefaultASTVisitor::visit (expr);
724 :
725 : // ensure that they are not marked for strip
726 6294 : if (expr.get_left_expr ().is_marked_for_strip ())
727 0 : rust_error_at (expr.get_left_expr ().get_locus (),
728 : "cannot strip expression in this position - outer "
729 : "attributes are never allowed "
730 : "before binary op exprs");
731 6294 : if (expr.get_right_expr ().is_marked_for_strip ())
732 0 : rust_error_at (expr.get_right_expr ().get_locus (),
733 : "cannot strip expression in this position - outer "
734 : "attributes not allowed");
735 6294 : }
736 : void
737 2135 : CfgStrip::visit (AST::GroupedExpr &expr)
738 : {
739 : // initial strip test based on outer attrs
740 2135 : expand_cfg_attrs (expr.get_outer_attrs ());
741 2135 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
742 : {
743 0 : expr.mark_for_strip ();
744 0 : return;
745 : }
746 :
747 : /* strip test based on inner attrs - spec says these are inner
748 : * attributes, not outer attributes of inner expr */
749 2135 : expand_cfg_attrs (expr.get_inner_attrs ());
750 2135 : if (fails_cfg_with_expand (expr.get_inner_attrs ()))
751 : {
752 0 : expr.mark_for_strip ();
753 0 : return;
754 : }
755 :
756 : /* strip any internal sub-expressions - expression itself isn't
757 : * allowed to have external attributes in this position so can't be
758 : * stripped. */
759 2135 : AST::DefaultASTVisitor::visit (expr);
760 :
761 2135 : auto &inner_expr = expr.get_expr_in_parens ();
762 2135 : if (inner_expr.is_marked_for_strip ())
763 0 : rust_error_at (inner_expr.get_locus (),
764 : "cannot strip expression in this position - outer "
765 : "attributes not allowed");
766 : }
767 : void
768 1148 : CfgStrip::visit (AST::ArrayElemsValues &elems)
769 : {
770 : /* apparently outer attributes are allowed in "elements of array
771 : * expressions" according to spec */
772 1148 : maybe_strip_pointer_allow_strip (elems.get_values ());
773 1148 : }
774 : void
775 466 : CfgStrip::visit (AST::ArrayElemsCopied &elems)
776 : {
777 : /* apparently outer attributes are allowed in "elements of array
778 : * expressions" according to spec. on the other hand, it would not
779 : * make conceptual sense to be able to remove either expression. As
780 : * such, not implementing. TODO clear up the ambiguity here */
781 466 : AST::DefaultASTVisitor::visit (elems);
782 :
783 : // only intend stripping for internal sub-expressions
784 466 : auto &copied_expr = elems.get_elem_to_copy ();
785 466 : if (copied_expr.is_marked_for_strip ())
786 0 : rust_error_at (copied_expr.get_locus (),
787 : "cannot strip expression in this position - outer "
788 : "attributes not allowed");
789 :
790 466 : auto ©_count = elems.get_num_copies ();
791 466 : copy_count.accept_vis (*this);
792 466 : if (copy_count.is_marked_for_strip ())
793 0 : rust_error_at (copy_count.get_locus (),
794 : "cannot strip expression in this position - outer "
795 : "attributes not allowed");
796 466 : }
797 : void
798 1614 : CfgStrip::visit (AST::ArrayExpr &expr)
799 : {
800 : // initial strip test based on outer attrs
801 1614 : expand_cfg_attrs (expr.get_outer_attrs ());
802 1614 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
803 : {
804 0 : expr.mark_for_strip ();
805 0 : return;
806 : }
807 :
808 : /* strip test based on inner attrs - spec says there are separate
809 : * inner attributes, not just outer attributes of inner exprs */
810 1614 : expand_cfg_attrs (expr.get_inner_attrs ());
811 1614 : if (fails_cfg_with_expand (expr.get_inner_attrs ()))
812 : {
813 0 : expr.mark_for_strip ();
814 0 : return;
815 : }
816 :
817 : /* assuming you can't strip away the ArrayElems type, but can strip
818 : * internal expressions and whatever */
819 1614 : AST::DefaultASTVisitor::visit (expr);
820 : }
821 :
822 : void
823 1220 : CfgStrip::visit (AST::ArrayIndexExpr &expr)
824 : {
825 : /* it is unclear whether outer attributes are supposed to be
826 : * allowed, but conceptually it wouldn't make much sense, but
827 : * having expansion code anyway. TODO */
828 : // initial strip test based on outer attrs
829 1220 : expand_cfg_attrs (expr.get_outer_attrs ());
830 1220 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
831 : {
832 0 : expr.mark_for_strip ();
833 0 : return;
834 : }
835 :
836 : /* strip any internal sub-expressions - expression itself isn't
837 : * allowed to have external attributes in this position so can't be
838 : * stripped. */
839 1220 : AST::DefaultASTVisitor::visit (expr);
840 :
841 1220 : const auto &array_expr = expr.get_array_expr ();
842 1220 : if (array_expr.is_marked_for_strip ())
843 0 : rust_error_at (array_expr.get_locus (),
844 : "cannot strip expression in this position - outer "
845 : "attributes not allowed");
846 :
847 1220 : const auto &index_expr = expr.get_index_expr ();
848 1220 : if (index_expr.is_marked_for_strip ())
849 0 : rust_error_at (index_expr.get_locus (),
850 : "cannot strip expression in this position - outer "
851 : "attributes not allowed");
852 : }
853 : void
854 2617 : CfgStrip::visit (AST::TupleExpr &expr)
855 : {
856 : /* according to spec, outer attributes are allowed on "elements of
857 : * tuple expressions" */
858 :
859 : // initial strip test based on outer attrs
860 2617 : expand_cfg_attrs (expr.get_outer_attrs ());
861 2617 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
862 : {
863 0 : expr.mark_for_strip ();
864 0 : return;
865 : }
866 :
867 : /* strip test based on inner attrs - spec says these are inner
868 : * attributes, not outer attributes of inner expr */
869 2617 : expand_cfg_attrs (expr.get_inner_attrs ());
870 2617 : if (fails_cfg_with_expand (expr.get_inner_attrs ()))
871 : {
872 0 : expr.mark_for_strip ();
873 0 : return;
874 : }
875 :
876 : /* apparently outer attributes are allowed in "elements of tuple
877 : * expressions" according to spec */
878 2617 : maybe_strip_pointer_allow_strip (expr.get_tuple_elems ());
879 : }
880 : void
881 5616 : CfgStrip::visit (AST::TupleIndexExpr &expr)
882 : {
883 : // initial strip test based on outer attrs
884 5616 : expand_cfg_attrs (expr.get_outer_attrs ());
885 5616 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
886 : {
887 0 : expr.mark_for_strip ();
888 0 : return;
889 : }
890 :
891 5616 : AST::DefaultASTVisitor::visit (expr);
892 : /* wouldn't strip this directly (as outer attrs should be
893 : * associated with this level), but any sub-expressions would be
894 : * stripped. Thus, no need to erase when strip check called. */
895 5616 : auto &tuple_expr = expr.get_tuple_expr ();
896 5616 : if (tuple_expr.is_marked_for_strip ())
897 0 : rust_error_at (tuple_expr.get_locus (),
898 : "cannot strip expression in this position - outer "
899 : "attributes not allowed");
900 : }
901 :
902 : void
903 328 : CfgStrip::visit (AST::StructExprStruct &expr)
904 : {
905 : // initial strip test based on outer attrs
906 328 : expand_cfg_attrs (expr.get_outer_attrs ());
907 328 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
908 : {
909 0 : expr.mark_for_strip ();
910 0 : return;
911 : }
912 :
913 : /* strip test based on inner attrs - spec says these are inner
914 : * attributes, not outer attributes of inner expr */
915 328 : expand_cfg_attrs (expr.get_inner_attrs ());
916 328 : if (fails_cfg_with_expand (expr.get_inner_attrs ()))
917 : {
918 0 : expr.mark_for_strip ();
919 0 : return;
920 : }
921 :
922 : // strip sub-exprs of path
923 328 : auto &struct_name = expr.get_struct_name ();
924 328 : visit (struct_name);
925 328 : if (struct_name.is_marked_for_strip ())
926 0 : rust_error_at (struct_name.get_locus (),
927 : "cannot strip path in this position");
928 : }
929 :
930 : void
931 9419 : CfgStrip::visit (AST::StructExprFieldIdentifierValue &field)
932 : {
933 : /* as no attrs possible (at moment, at least), only sub-expression
934 : * stripping is possible */
935 9419 : AST::DefaultASTVisitor::visit (field);
936 :
937 9419 : auto &value = field.get_value ();
938 9419 : if (value.is_marked_for_strip ())
939 0 : rust_error_at (value.get_locus (),
940 : "cannot strip expression in this position - outer "
941 : "attributes not allowed");
942 9419 : }
943 : void
944 176 : CfgStrip::visit (AST::StructExprFieldIndexValue &field)
945 : {
946 : /* as no attrs possible (at moment, at least), only sub-expression
947 : * stripping is possible */
948 176 : AST::DefaultASTVisitor::visit (field);
949 :
950 176 : auto &value = field.get_value ();
951 176 : if (value.is_marked_for_strip ())
952 0 : rust_error_at (value.get_locus (),
953 : "cannot strip expression in this position - outer "
954 : "attributes not allowed");
955 176 : }
956 : void
957 5732 : CfgStrip::visit (AST::StructExprStructFields &expr)
958 : {
959 : // initial strip test based on outer attrs
960 5732 : expand_cfg_attrs (expr.get_outer_attrs ());
961 5732 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
962 : {
963 0 : expr.mark_for_strip ();
964 0 : return;
965 : }
966 :
967 : /* strip test based on inner attrs - spec says these are inner
968 : * attributes, not outer attributes of inner expr */
969 5732 : expand_cfg_attrs (expr.get_inner_attrs ());
970 5732 : if (fails_cfg_with_expand (expr.get_inner_attrs ()))
971 : {
972 0 : expr.mark_for_strip ();
973 0 : return;
974 : }
975 :
976 : // strip sub-exprs of path
977 5732 : auto &struct_name = expr.get_struct_name ();
978 5732 : visit (struct_name);
979 5732 : if (struct_name.is_marked_for_strip ())
980 0 : rust_error_at (struct_name.get_locus (),
981 : "cannot strip path in this position");
982 :
983 : /* spec does not specify whether expressions are allowed to be
984 : * stripped at top level of struct fields, but I wouldn't think
985 : * that they would be, so operating under the assumption that only
986 : * sub-expressions can be stripped. */
987 5732 : AST::DefaultASTVisitor::visit (expr);
988 :
989 : /* struct base presumably can't be stripped, as the '..' is before
990 : * the expression. as such, can only strip sub-expressions. */
991 5732 : if (expr.has_struct_base ())
992 : {
993 252 : auto &base_struct_expr = expr.get_struct_base ().get_base_struct ();
994 252 : base_struct_expr.accept_vis (*this);
995 252 : if (base_struct_expr.is_marked_for_strip ())
996 0 : rust_error_at (base_struct_expr.get_locus (),
997 : "cannot strip expression in this position - outer "
998 : "attributes not allowed");
999 : }
1000 :
1001 5732 : maybe_strip_struct_expr_fields (expr.get_fields ());
1002 : }
1003 :
1004 : void
1005 0 : CfgStrip::visit (AST::StructExprStructBase &expr)
1006 : {
1007 : // initial strip test based on outer attrs
1008 0 : expand_cfg_attrs (expr.get_outer_attrs ());
1009 0 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1010 : {
1011 0 : expr.mark_for_strip ();
1012 0 : return;
1013 : }
1014 :
1015 : /* strip test based on inner attrs - spec says these are inner
1016 : * attributes, not outer attributes of inner expr */
1017 0 : expand_cfg_attrs (expr.get_inner_attrs ());
1018 0 : if (fails_cfg_with_expand (expr.get_inner_attrs ()))
1019 : {
1020 0 : expr.mark_for_strip ();
1021 0 : return;
1022 : }
1023 :
1024 : // strip sub-exprs of path
1025 0 : auto &struct_name = expr.get_struct_name ();
1026 0 : visit (struct_name);
1027 0 : if (struct_name.is_marked_for_strip ())
1028 0 : rust_error_at (struct_name.get_locus (),
1029 : "cannot strip path in this position");
1030 :
1031 : /* struct base presumably can't be stripped, as the '..' is before
1032 : * the expression. as such, can only strip sub-expressions. */
1033 0 : rust_assert (!expr.get_struct_base ().is_invalid ());
1034 0 : auto &base_struct_expr = expr.get_struct_base ().get_base_struct ();
1035 0 : base_struct_expr.accept_vis (*this);
1036 0 : if (base_struct_expr.is_marked_for_strip ())
1037 0 : rust_error_at (base_struct_expr.get_locus (),
1038 : "cannot strip expression in this position - outer "
1039 : "attributes not allowed");
1040 : }
1041 : void
1042 68083 : CfgStrip::visit (AST::CallExpr &expr)
1043 : {
1044 : // initial strip test based on outer attrs
1045 68083 : expand_cfg_attrs (expr.get_outer_attrs ());
1046 68083 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1047 : {
1048 0 : expr.mark_for_strip ();
1049 0 : return;
1050 : }
1051 :
1052 : /* should not be outer attrs on "function" expression - outer attrs
1053 : * should be associated with call expr as a whole. only sub-expr
1054 : * expansion is possible. */
1055 68083 : AST::DefaultASTVisitor::visit (expr);
1056 :
1057 68083 : auto &function = expr.get_function_expr ();
1058 68083 : if (function.is_marked_for_strip ())
1059 0 : rust_error_at (function.get_locus (),
1060 : "cannot strip expression in this position - outer "
1061 : "attributes not allowed");
1062 :
1063 : /* spec says outer attributes are specifically allowed for elements
1064 : * of call expressions, so full stripping possible */
1065 : // FIXME: Arthur: Figure out how to refactor this - This is similar to
1066 : // expanding items in the crate or stmts in blocks
1067 68083 : maybe_strip_pointer_allow_strip (expr.get_params ());
1068 : }
1069 : void
1070 20153 : CfgStrip::visit (AST::MethodCallExpr &expr)
1071 : {
1072 : // initial strip test based on outer attrs
1073 20153 : expand_cfg_attrs (expr.get_outer_attrs ());
1074 20153 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1075 : {
1076 0 : expr.mark_for_strip ();
1077 0 : return;
1078 : }
1079 :
1080 : /* should not be outer attrs on "receiver" expression - outer attrs
1081 : * should be associated with call expr as a whole. only sub-expr
1082 : * expansion is possible. */
1083 20153 : AST::DefaultASTVisitor::visit (expr);
1084 :
1085 20153 : auto &receiver = expr.get_receiver_expr ();
1086 20153 : if (receiver.is_marked_for_strip ())
1087 0 : rust_error_at (receiver.get_locus (),
1088 : "cannot strip expression in this position - outer "
1089 : "attributes not allowed");
1090 :
1091 20153 : auto &method_name = expr.get_method_name ();
1092 20153 : if (method_name.has_generic_args ())
1093 88 : maybe_strip_generic_args (method_name.get_generic_args ());
1094 :
1095 : /* spec says outer attributes are specifically allowed for elements
1096 : * of method call expressions, so full stripping possible */
1097 20153 : maybe_strip_pointer_allow_strip (expr.get_params ());
1098 : }
1099 : void
1100 39745 : CfgStrip::visit (AST::FieldAccessExpr &expr)
1101 : {
1102 : // initial strip test based on outer attrs
1103 39745 : expand_cfg_attrs (expr.get_outer_attrs ());
1104 39745 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1105 : {
1106 0 : expr.mark_for_strip ();
1107 0 : return;
1108 : }
1109 :
1110 : /* should not be outer attrs on "receiver" expression - outer attrs
1111 : * should be associated with field expr as a whole. only sub-expr
1112 : * expansion is possible. */
1113 39745 : AST::DefaultASTVisitor::visit (expr);
1114 :
1115 39745 : auto &receiver = expr.get_receiver_expr ();
1116 39745 : if (receiver.is_marked_for_strip ())
1117 0 : rust_error_at (receiver.get_locus (),
1118 : "cannot strip expression in this position - outer "
1119 : "attributes not allowed");
1120 : }
1121 : void
1122 130 : CfgStrip::visit (AST::ClosureExprInner &expr)
1123 : {
1124 : // initial strip test based on outer attrs
1125 130 : expand_cfg_attrs (expr.get_outer_attrs ());
1126 130 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1127 : {
1128 0 : expr.mark_for_strip ();
1129 0 : return;
1130 : }
1131 :
1132 : /* strip closure parameters if required - this is specifically
1133 : * allowed by spec */
1134 130 : maybe_strip_closure_params (expr.get_params ());
1135 :
1136 130 : AST::DefaultASTVisitor::visit (expr);
1137 :
1138 : // can't strip expression itself, but can strip sub-expressions
1139 130 : auto &definition_expr = expr.get_definition_expr ();
1140 130 : if (definition_expr.is_marked_for_strip ())
1141 0 : rust_error_at (definition_expr.get_locus (),
1142 : "cannot strip expression in this position - outer "
1143 : "attributes not allowed");
1144 : }
1145 :
1146 : void
1147 90169 : CfgStrip::visit (AST::BlockExpr &expr)
1148 : {
1149 : // initial strip test based on outer attrs
1150 90169 : expand_cfg_attrs (expr.get_outer_attrs ());
1151 90169 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1152 : {
1153 54 : expr.mark_for_strip ();
1154 54 : return;
1155 : }
1156 :
1157 : /* strip test based on inner attrs - spec says there are inner
1158 : * attributes, not just outer attributes of inner stmts */
1159 90115 : expand_cfg_attrs (expr.get_inner_attrs ());
1160 90115 : if (fails_cfg_with_expand (expr.get_inner_attrs ()))
1161 : {
1162 0 : expr.mark_for_strip ();
1163 0 : return;
1164 : }
1165 :
1166 90115 : maybe_strip_pointer_allow_strip (expr.get_statements ());
1167 :
1168 90115 : AST::DefaultASTVisitor::visit (expr);
1169 :
1170 : // strip tail expression if exists - can actually fully remove it
1171 90115 : if (expr.has_tail_expr ())
1172 : {
1173 70786 : auto &tail_expr = expr.get_tail_expr ();
1174 :
1175 70786 : if (tail_expr.is_marked_for_strip ())
1176 57 : expr.strip_tail_expr ();
1177 : }
1178 : }
1179 :
1180 : void
1181 120 : CfgStrip::visit (AST::ClosureExprInnerTyped &expr)
1182 : {
1183 : // initial strip test based on outer attrs
1184 120 : expand_cfg_attrs (expr.get_outer_attrs ());
1185 120 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1186 : {
1187 0 : expr.mark_for_strip ();
1188 0 : return;
1189 : }
1190 :
1191 : /* strip closure parameters if required - this is specifically
1192 : * allowed by spec */
1193 120 : maybe_strip_closure_params (expr.get_params ());
1194 :
1195 120 : AST::DefaultASTVisitor::visit (expr);
1196 :
1197 : // can't strip return type, but can strip sub-types
1198 120 : auto &type = expr.get_return_type ();
1199 :
1200 120 : if (type.is_marked_for_strip ())
1201 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
1202 :
1203 : // can't strip expression itself, but can strip sub-expressions
1204 120 : auto &definition_block = expr.get_definition_expr ();
1205 120 : definition_block.accept_vis (*this);
1206 120 : if (definition_block.is_marked_for_strip ())
1207 0 : rust_error_at (definition_block.get_locus (),
1208 : "cannot strip block expression in this position - outer "
1209 : "attributes not allowed");
1210 : }
1211 : void
1212 154 : CfgStrip::visit (AST::ContinueExpr &expr)
1213 : {
1214 : // initial strip test based on outer attrs
1215 154 : expand_cfg_attrs (expr.get_outer_attrs ());
1216 154 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1217 : {
1218 0 : expr.mark_for_strip ();
1219 0 : return;
1220 : }
1221 : }
1222 : void
1223 628 : CfgStrip::visit (AST::BreakExpr &expr)
1224 : {
1225 : // initial strip test based on outer attrs
1226 628 : expand_cfg_attrs (expr.get_outer_attrs ());
1227 628 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1228 : {
1229 0 : expr.mark_for_strip ();
1230 0 : return;
1231 : }
1232 628 : AST::DefaultASTVisitor::visit (expr);
1233 :
1234 : /* spec does not say that you can have outer attributes on
1235 : * expression, so assuming you can't. stripping for sub-expressions
1236 : * is the only thing that can be done */
1237 628 : if (expr.has_break_expr ())
1238 : {
1239 248 : auto &break_expr = expr.get_break_expr_unchecked ();
1240 :
1241 248 : if (break_expr.is_marked_for_strip ())
1242 0 : rust_error_at (break_expr.get_locus (),
1243 : "cannot strip expression in this position - outer "
1244 : "attributes not allowed");
1245 : }
1246 : }
1247 : void
1248 356 : CfgStrip::visit (AST::RangeFromToExpr &expr)
1249 : {
1250 : /* outer attributes never allowed before these. while cannot strip
1251 : * two direct descendant expressions, can strip ones below that */
1252 356 : AST::DefaultASTVisitor::visit (expr);
1253 :
1254 : // ensure that they are not marked for strip
1255 356 : if (expr.get_from_expr ().is_marked_for_strip ())
1256 0 : rust_error_at (expr.get_from_expr ().get_locus (),
1257 : "cannot strip expression in this position - outer "
1258 : "attributes are never allowed "
1259 : "before range exprs");
1260 356 : if (expr.get_to_expr ().is_marked_for_strip ())
1261 0 : rust_error_at (expr.get_to_expr ().get_locus (),
1262 : "cannot strip expression in this position - outer "
1263 : "attributes not allowed");
1264 356 : }
1265 : void
1266 28 : CfgStrip::visit (AST::RangeFromExpr &expr)
1267 : {
1268 : /* outer attributes never allowed before these. while cannot strip
1269 : * direct descendant expression, can strip ones below that */
1270 :
1271 28 : AST::DefaultASTVisitor::visit (expr);
1272 : /* should have no possibility for outer attrs as would be parsed
1273 : * with outer expr */
1274 28 : auto &from_expr = expr.get_from_expr ();
1275 28 : if (from_expr.is_marked_for_strip ())
1276 0 : rust_error_at (from_expr.get_locus (),
1277 : "cannot strip expression in this position - outer "
1278 : "attributes are never allowed before range exprs");
1279 28 : }
1280 : void
1281 28 : CfgStrip::visit (AST::RangeToExpr &expr)
1282 : {
1283 : /* outer attributes never allowed before these. while cannot strip
1284 : * direct descendant expression, can strip ones below that */
1285 :
1286 28 : AST::DefaultASTVisitor::visit (expr);
1287 : /* should syntactically not have outer attributes, though this may
1288 : * not have worked in practice */
1289 28 : auto &to_expr = expr.get_to_expr ();
1290 28 : if (to_expr.is_marked_for_strip ())
1291 0 : rust_error_at (to_expr.get_locus (),
1292 : "cannot strip expression in this position - outer "
1293 : "attributes not allowed");
1294 28 : }
1295 :
1296 : void
1297 28 : CfgStrip::visit (AST::RangeFromToInclExpr &expr)
1298 : {
1299 : /* outer attributes never allowed before these. while cannot strip
1300 : * two direct descendant expressions, can strip ones below that */
1301 :
1302 28 : AST::DefaultASTVisitor::visit (expr);
1303 :
1304 : // ensure that they are not marked for strip
1305 28 : if (expr.get_from_expr ().is_marked_for_strip ())
1306 0 : rust_error_at (expr.get_from_expr ().get_locus (),
1307 : "cannot strip expression in this position - outer "
1308 : "attributes are never allowed "
1309 : "before range exprs");
1310 28 : if (expr.get_to_expr ().is_marked_for_strip ())
1311 0 : rust_error_at (expr.get_to_expr ().get_locus (),
1312 : "cannot strip expression in this position - outer "
1313 : "attributes not allowed");
1314 28 : }
1315 : void
1316 0 : CfgStrip::visit (AST::RangeToInclExpr &expr)
1317 : {
1318 : /* outer attributes never allowed before these. while cannot strip
1319 : * direct descendant expression, can strip ones below that */
1320 :
1321 0 : AST::DefaultASTVisitor::visit (expr);
1322 : /* should syntactically not have outer attributes, though this may
1323 : * not have worked in practice */
1324 0 : auto &to_expr = expr.get_to_expr ();
1325 0 : if (to_expr.is_marked_for_strip ())
1326 0 : rust_error_at (to_expr.get_locus (),
1327 : "cannot strip expression in this position - outer "
1328 : "attributes not allowed");
1329 0 : }
1330 : void
1331 3108 : CfgStrip::visit (AST::ReturnExpr &expr)
1332 : {
1333 : // initial strip test based on outer attrs
1334 3108 : expand_cfg_attrs (expr.get_outer_attrs ());
1335 3108 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1336 : {
1337 0 : expr.mark_for_strip ();
1338 0 : return;
1339 : }
1340 :
1341 3108 : AST::DefaultASTVisitor::visit (expr);
1342 :
1343 : /* spec does not say that you can have outer attributes on
1344 : * expression, so assuming you can't. stripping for sub-expressions
1345 : * is the only thing that can be done */
1346 3108 : if (expr.has_returned_expr ())
1347 : {
1348 2750 : auto &returned_expr = expr.get_returned_expr ();
1349 2750 : if (returned_expr.is_marked_for_strip ())
1350 0 : rust_error_at (returned_expr.get_locus (),
1351 : "cannot strip expression in this position - outer "
1352 : "attributes not allowed");
1353 : }
1354 : /* TODO: conceptually, you would maybe be able to remove a returned
1355 : * expr - e.g. if you had conditional compilation returning void or
1356 : * returning a type. On the other hand, I think that function
1357 : * return type cannot be conditionally compiled, so I assumed you
1358 : * can't do this either. */
1359 : }
1360 : void
1361 16484 : CfgStrip::visit (AST::UnsafeBlockExpr &expr)
1362 : {
1363 : // initial strip test based on outer attrs
1364 16484 : expand_cfg_attrs (expr.get_outer_attrs ());
1365 16484 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1366 : {
1367 7 : expr.mark_for_strip ();
1368 7 : return;
1369 : }
1370 :
1371 16477 : AST::DefaultASTVisitor::visit (expr);
1372 :
1373 : // can't strip block itself, but can strip sub-expressions
1374 16477 : auto &block_expr = expr.get_block_expr ();
1375 16477 : if (block_expr.is_marked_for_strip ())
1376 0 : rust_error_at (block_expr.get_locus (),
1377 : "cannot strip block expression in this position - outer "
1378 : "attributes not allowed");
1379 : }
1380 : void
1381 330 : CfgStrip::visit (AST::LoopExpr &expr)
1382 : {
1383 : // initial strip test based on outer attrs
1384 330 : expand_cfg_attrs (expr.get_outer_attrs ());
1385 330 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1386 : {
1387 0 : expr.mark_for_strip ();
1388 0 : return;
1389 : }
1390 :
1391 330 : AST::DefaultASTVisitor::visit (expr);
1392 :
1393 : // can't strip block itself, but can strip sub-expressions
1394 330 : auto &loop_block = expr.get_loop_block ();
1395 330 : if (loop_block.is_marked_for_strip ())
1396 0 : rust_error_at (loop_block.get_locus (),
1397 : "cannot strip block expression in this position - outer "
1398 : "attributes not allowed");
1399 : }
1400 : void
1401 470 : CfgStrip::visit (AST::WhileLoopExpr &expr)
1402 : {
1403 : // initial strip test based on outer attrs
1404 470 : expand_cfg_attrs (expr.get_outer_attrs ());
1405 470 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1406 : {
1407 0 : expr.mark_for_strip ();
1408 0 : return;
1409 : }
1410 :
1411 470 : AST::DefaultASTVisitor::visit (expr);
1412 : // can't strip predicate expr itself, but can strip sub-expressions
1413 470 : auto &predicate_expr = expr.get_predicate_expr ();
1414 470 : if (predicate_expr.is_marked_for_strip ())
1415 0 : rust_error_at (predicate_expr.get_locus (),
1416 : "cannot strip expression in this position - outer "
1417 : "attributes not allowed");
1418 :
1419 : // can't strip block itself, but can strip sub-expressions
1420 470 : auto &loop_block = expr.get_loop_block ();
1421 470 : if (loop_block.is_marked_for_strip ())
1422 0 : rust_error_at (loop_block.get_locus (),
1423 : "cannot strip block expression in this position - outer "
1424 : "attributes not allowed");
1425 : }
1426 : void
1427 4 : CfgStrip::visit (AST::WhileLetLoopExpr &expr)
1428 : {
1429 : // initial strip test based on outer attrs
1430 4 : expand_cfg_attrs (expr.get_outer_attrs ());
1431 4 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1432 : {
1433 0 : expr.mark_for_strip ();
1434 0 : return;
1435 : }
1436 :
1437 4 : AST::DefaultASTVisitor::visit (expr);
1438 :
1439 4 : if (expr.get_pattern ()->is_marked_for_strip ())
1440 0 : rust_error_at (expr.get_pattern ()->get_locus (),
1441 : "cannot strip pattern in this position");
1442 :
1443 : // can't strip scrutinee expr itself, but can strip sub-expressions
1444 4 : auto &scrutinee_expr = expr.get_scrutinee_expr ();
1445 4 : if (scrutinee_expr.is_marked_for_strip ())
1446 0 : rust_error_at (scrutinee_expr.get_locus (),
1447 : "cannot strip expression in this position - outer "
1448 : "attributes not allowed");
1449 :
1450 : // can't strip block itself, but can strip sub-expressions
1451 4 : auto &loop_block = expr.get_loop_block ();
1452 4 : if (loop_block.is_marked_for_strip ())
1453 0 : rust_error_at (loop_block.get_locus (),
1454 : "cannot strip block expression in this position - outer "
1455 : "attributes not allowed");
1456 : }
1457 : void
1458 120 : CfgStrip::visit (AST::ForLoopExpr &expr)
1459 : {
1460 : // initial strip test based on outer attrs
1461 120 : expand_cfg_attrs (expr.get_outer_attrs ());
1462 120 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1463 : {
1464 0 : expr.mark_for_strip ();
1465 0 : return;
1466 : }
1467 :
1468 120 : AST::DefaultASTVisitor::visit (expr);
1469 : // strip sub-patterns of pattern
1470 120 : auto &pattern = expr.get_pattern ();
1471 120 : if (pattern.is_marked_for_strip ())
1472 0 : rust_error_at (pattern.get_locus (),
1473 : "cannot strip pattern in this position");
1474 :
1475 : // can't strip scrutinee expr itself, but can strip sub-expressions
1476 120 : auto &iterator_expr = expr.get_iterator_expr ();
1477 120 : if (iterator_expr.is_marked_for_strip ())
1478 0 : rust_error_at (iterator_expr.get_locus (),
1479 : "cannot strip expression in this position - outer "
1480 : "attributes not allowed");
1481 :
1482 : // can't strip block itself, but can strip sub-expressions
1483 120 : auto &loop_block = expr.get_loop_block ();
1484 120 : if (loop_block.is_marked_for_strip ())
1485 0 : rust_error_at (loop_block.get_locus (),
1486 : "cannot strip block expression in this position - outer "
1487 : "attributes not allowed");
1488 : }
1489 : void
1490 8103 : CfgStrip::visit (AST::IfExpr &expr)
1491 : {
1492 : // rust playground test shows that IfExpr does support outer attrs, at least
1493 : // when used as statement
1494 :
1495 : // initial strip test based on outer attrs
1496 8103 : expand_cfg_attrs (expr.get_outer_attrs ());
1497 8103 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1498 : {
1499 0 : expr.mark_for_strip ();
1500 0 : return;
1501 : }
1502 :
1503 8103 : AST::DefaultASTVisitor::visit (expr);
1504 :
1505 : // can't strip condition expr itself, but can strip sub-expressions
1506 8103 : auto &condition_expr = expr.get_condition_expr ();
1507 8103 : if (condition_expr.is_marked_for_strip ())
1508 0 : rust_error_at (condition_expr.get_locus (),
1509 : "cannot strip expression in this position - outer "
1510 : "attributes not allowed");
1511 :
1512 : // can't strip if block itself, but can strip sub-expressions
1513 8103 : auto &if_block = expr.get_if_block ();
1514 8103 : if (if_block.is_marked_for_strip ())
1515 0 : rust_error_at (if_block.get_locus (),
1516 : "cannot strip block expression in this position - outer "
1517 : "attributes not allowed");
1518 : }
1519 :
1520 : void
1521 5924 : CfgStrip::visit (AST::IfExprConseqElse &expr)
1522 : {
1523 : // initial strip test based on outer attrs
1524 5924 : expand_cfg_attrs (expr.get_outer_attrs ());
1525 5924 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1526 : {
1527 0 : expr.mark_for_strip ();
1528 0 : return;
1529 : }
1530 :
1531 5924 : AST::DefaultASTVisitor::visit (expr);
1532 :
1533 : // can't strip condition expr itself, but can strip sub-expressions
1534 5924 : auto &condition_expr = expr.get_condition_expr ();
1535 5924 : if (condition_expr.is_marked_for_strip ())
1536 0 : rust_error_at (condition_expr.get_locus (),
1537 : "cannot strip expression in this position - outer "
1538 : "attributes not allowed");
1539 :
1540 : // can't strip if block itself, but can strip sub-expressions
1541 5924 : auto &if_block = expr.get_if_block ();
1542 5924 : if (if_block.is_marked_for_strip ())
1543 0 : rust_error_at (if_block.get_locus (),
1544 : "cannot strip block expression in this position - outer "
1545 : "attributes not allowed");
1546 :
1547 : // can't strip else block itself, but can strip sub-expressions
1548 5924 : auto &else_block = expr.get_else_block ();
1549 5924 : if (else_block.is_marked_for_strip ())
1550 0 : rust_error_at (else_block.get_locus (),
1551 : "cannot strip block expression in this position - outer "
1552 : "attributes not allowed");
1553 : }
1554 :
1555 : void
1556 102 : CfgStrip::visit (AST::IfLetExpr &expr)
1557 : {
1558 : // initial strip test based on outer attrs
1559 102 : expand_cfg_attrs (expr.get_outer_attrs ());
1560 102 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1561 : {
1562 0 : expr.mark_for_strip ();
1563 0 : return;
1564 : }
1565 :
1566 102 : AST::DefaultASTVisitor::visit (expr);
1567 :
1568 102 : if (expr.get_pattern ()->is_marked_for_strip ())
1569 0 : rust_error_at (expr.get_pattern ()->get_locus (),
1570 : "cannot strip pattern in this position");
1571 :
1572 : // can't strip value expr itself, but can strip sub-expressions
1573 102 : auto &value_expr = expr.get_value_expr ();
1574 102 : if (value_expr.is_marked_for_strip ())
1575 0 : rust_error_at (value_expr.get_locus (),
1576 : "cannot strip expression in this position - outer "
1577 : "attributes not allowed");
1578 :
1579 : // can't strip if block itself, but can strip sub-expressions
1580 102 : auto &if_block = expr.get_if_block ();
1581 102 : if (if_block.is_marked_for_strip ())
1582 0 : rust_error_at (if_block.get_locus (),
1583 : "cannot strip block expression in this position - outer "
1584 : "attributes not allowed");
1585 : }
1586 : void
1587 30 : CfgStrip::visit (AST::IfLetExprConseqElse &expr)
1588 : {
1589 : // initial strip test based on outer attrs
1590 30 : expand_cfg_attrs (expr.get_outer_attrs ());
1591 30 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1592 : {
1593 0 : expr.mark_for_strip ();
1594 0 : return;
1595 : }
1596 :
1597 30 : AST::DefaultASTVisitor::visit (expr);
1598 :
1599 30 : if (expr.get_pattern ()->is_marked_for_strip ())
1600 0 : rust_error_at (expr.get_pattern ()->get_locus (),
1601 : "cannot strip pattern in this position");
1602 :
1603 : // can't strip value expr itself, but can strip sub-expressions
1604 30 : auto &value_expr = expr.get_value_expr ();
1605 30 : if (value_expr.is_marked_for_strip ())
1606 0 : rust_error_at (value_expr.get_locus (),
1607 : "cannot strip expression in this position - outer "
1608 : "attributes not allowed");
1609 :
1610 : // can't strip if block itself, but can strip sub-expressions
1611 30 : auto &if_block = expr.get_if_block ();
1612 30 : if (if_block.is_marked_for_strip ())
1613 0 : rust_error_at (if_block.get_locus (),
1614 : "cannot strip block expression in this position - outer "
1615 : "attributes not allowed");
1616 :
1617 : // can't strip else block itself, but can strip sub-expressions
1618 30 : auto &else_block = expr.get_else_block ();
1619 30 : if (else_block.is_marked_for_strip ())
1620 0 : rust_error_at (else_block.get_locus (),
1621 : "cannot strip block expression in this position - outer "
1622 : "attributes not allowed");
1623 : }
1624 : void
1625 4419 : CfgStrip::visit (AST::MatchExpr &expr)
1626 : {
1627 : // initial strip test based on outer attrs
1628 4419 : expand_cfg_attrs (expr.get_outer_attrs ());
1629 4419 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1630 : {
1631 0 : expr.mark_for_strip ();
1632 0 : return;
1633 : }
1634 :
1635 : // inner attr strip test
1636 4419 : expand_cfg_attrs (expr.get_inner_attrs ());
1637 4419 : if (fails_cfg_with_expand (expr.get_inner_attrs ()))
1638 : {
1639 0 : expr.mark_for_strip ();
1640 0 : return;
1641 : }
1642 :
1643 4419 : AST::DefaultASTVisitor::visit (expr);
1644 :
1645 : // can't strip scrutinee expr itself, but can strip sub-expressions
1646 4419 : auto &scrutinee_expr = expr.get_scrutinee_expr ();
1647 4419 : if (scrutinee_expr.is_marked_for_strip ())
1648 0 : rust_error_at (scrutinee_expr.get_locus (),
1649 : "cannot strip expression in this position - outer "
1650 : "attributes not allowed");
1651 :
1652 : // strip match cases
1653 4419 : auto &match_cases = expr.get_match_cases ();
1654 14601 : for (auto it = match_cases.begin (); it != match_cases.end ();)
1655 : {
1656 10182 : auto &match_case = *it;
1657 :
1658 : // strip match case based on outer attributes in match arm
1659 10182 : auto &match_arm = match_case.get_arm ();
1660 10182 : expand_cfg_attrs (match_arm.get_outer_attrs ());
1661 10182 : if (fails_cfg_with_expand (match_arm.get_outer_attrs ()))
1662 : {
1663 : // strip match case
1664 0 : it = match_cases.erase (it);
1665 0 : continue;
1666 : }
1667 :
1668 10182 : if (match_arm.get_pattern ()->is_marked_for_strip ())
1669 0 : rust_error_at (match_arm.get_pattern ()->get_locus (),
1670 : "cannot strip pattern in this position");
1671 :
1672 : /* assuming that guard expression cannot be stripped as
1673 : * strictly speaking you would have to strip the whole guard to
1674 : * make syntactical sense, which you can't do. as such, only
1675 : * strip sub-expressions */
1676 10182 : if (match_arm.has_match_arm_guard ())
1677 : {
1678 2 : auto &guard_expr = match_arm.get_guard_expr ();
1679 2 : if (guard_expr.is_marked_for_strip ())
1680 0 : rust_error_at (guard_expr.get_locus (),
1681 : "cannot strip expression in this position - outer "
1682 : "attributes not allowed");
1683 : }
1684 :
1685 : // strip sub-expressions from match cases
1686 10182 : auto &case_expr = match_case.get_expr ();
1687 10182 : if (case_expr.is_marked_for_strip ())
1688 0 : rust_error_at (case_expr.get_locus (),
1689 : "cannot strip expression in this position - outer "
1690 : "attributes not allowed");
1691 :
1692 : // increment to next case if haven't continued
1693 10182 : ++it;
1694 : }
1695 : }
1696 :
1697 : void
1698 0 : CfgStrip::visit (AST::AwaitExpr &expr)
1699 : {
1700 : // initial strip test based on outer attrs
1701 0 : expand_cfg_attrs (expr.get_outer_attrs ());
1702 0 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1703 : {
1704 0 : expr.mark_for_strip ();
1705 0 : return;
1706 : }
1707 :
1708 : /* can't strip awaited expr itself, but can strip sub-expressions
1709 : * - this is because you can't have no expr to await */
1710 0 : auto &awaited_expr = expr.get_awaited_expr ();
1711 0 : awaited_expr->accept_vis (*this);
1712 0 : if (awaited_expr->is_marked_for_strip ())
1713 0 : rust_error_at (awaited_expr->get_locus (),
1714 : "cannot strip expression in this position - outer "
1715 : "attributes not allowed");
1716 : }
1717 :
1718 : void
1719 0 : CfgStrip::visit (AST::AsyncBlockExpr &expr)
1720 : {
1721 : // initial strip test based on outer attrs
1722 0 : expand_cfg_attrs (expr.get_outer_attrs ());
1723 0 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1724 : {
1725 0 : expr.mark_for_strip ();
1726 0 : return;
1727 : }
1728 :
1729 0 : AST::DefaultASTVisitor::visit (expr);
1730 :
1731 : // can't strip block itself, but can strip sub-expressions
1732 0 : auto &block_expr = expr.get_block_expr ();
1733 0 : if (block_expr->is_marked_for_strip ())
1734 0 : rust_error_at (block_expr->get_locus (),
1735 : "cannot strip block expression in this position - outer "
1736 : "attributes not allowed");
1737 : }
1738 :
1739 : void
1740 20007 : CfgStrip::visit (AST::TypeParam ¶m)
1741 : {
1742 : // outer attributes don't actually do anything, so ignore them
1743 :
1744 20007 : AST::DefaultASTVisitor::visit (param);
1745 :
1746 20007 : if (param.has_type () && param.get_type ().is_marked_for_strip ())
1747 0 : rust_error_at (param.get_type ().get_locus (),
1748 : "cannot strip type in this position");
1749 20007 : }
1750 :
1751 : void
1752 1259 : CfgStrip::visit (AST::TypeBoundWhereClauseItem &item)
1753 : {
1754 : // for lifetimes shouldn't require
1755 1259 : AST::DefaultASTVisitor::visit (item);
1756 :
1757 1259 : auto &type = item.get_type ();
1758 1259 : if (type.is_marked_for_strip ())
1759 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
1760 1259 : }
1761 :
1762 : void
1763 3261 : CfgStrip::visit (AST::Module &module)
1764 : {
1765 : // strip test based on outer attrs
1766 3261 : expand_cfg_attrs (module.get_outer_attrs ());
1767 3261 : if (fails_cfg_with_expand (module.get_outer_attrs ()))
1768 : {
1769 0 : module.mark_for_strip ();
1770 0 : return;
1771 : }
1772 :
1773 3261 : if (module.get_kind () == AST::Module::UNLOADED)
1774 : {
1775 82 : module.load_items ();
1776 : }
1777 :
1778 : // strip test based on inner attrs
1779 3261 : expand_cfg_attrs (module.get_inner_attrs ());
1780 3261 : if (fails_cfg_with_expand (module.get_inner_attrs ()))
1781 : {
1782 0 : module.mark_for_strip ();
1783 0 : return;
1784 : }
1785 :
1786 : // strip items if required
1787 3261 : maybe_strip_pointer_allow_strip (module.get_items ());
1788 : }
1789 :
1790 : void
1791 51 : CfgStrip::visit (AST::ExternCrate &extern_crate)
1792 : {
1793 : // strip test based on outer attrs
1794 51 : expand_cfg_attrs (extern_crate.get_outer_attrs ());
1795 51 : if (fails_cfg_with_expand (extern_crate.get_outer_attrs ()))
1796 : {
1797 0 : extern_crate.mark_for_strip ();
1798 0 : return;
1799 : }
1800 :
1801 51 : if (!extern_crate.references_self ())
1802 : {
1803 51 : Session &session = Session::get_instance ();
1804 51 : session.load_extern_crate (extern_crate.get_referenced_crate (),
1805 : extern_crate.get_locus ());
1806 : }
1807 : }
1808 :
1809 : void
1810 1848 : CfgStrip::visit (AST::UseDeclaration &use_decl)
1811 : {
1812 : // strip test based on outer attrs
1813 1848 : expand_cfg_attrs (use_decl.get_outer_attrs ());
1814 1848 : if (fails_cfg_with_expand (use_decl.get_outer_attrs ()))
1815 : {
1816 0 : use_decl.mark_for_strip ();
1817 0 : return;
1818 : }
1819 : }
1820 :
1821 : void
1822 67582 : CfgStrip::visit (AST::Function &function)
1823 : {
1824 : // initial test based on outer attrs
1825 67582 : expand_cfg_attrs (function.get_outer_attrs ());
1826 67582 : if (fails_cfg_with_expand (function.get_outer_attrs ()))
1827 : {
1828 31 : function.mark_for_strip ();
1829 31 : return;
1830 : }
1831 :
1832 67551 : AST::DefaultASTVisitor::visit (function);
1833 :
1834 : /* strip function parameters if required - this is specifically
1835 : * allowed by spec */
1836 67551 : maybe_strip_function_params (function.get_function_params ());
1837 :
1838 67551 : if (function.has_return_type ())
1839 : {
1840 53601 : auto &return_type = function.get_return_type ();
1841 53601 : if (return_type.is_marked_for_strip ())
1842 0 : rust_error_at (return_type.get_locus (),
1843 : "cannot strip type in this position");
1844 : }
1845 :
1846 : /* body should always exist - if error state, should have returned
1847 : * before now */
1848 : // can't strip block itself, but can strip sub-expressions
1849 67551 : if (function.has_body ())
1850 : {
1851 53476 : auto &block_expr = function.get_definition ();
1852 53476 : if (block_expr.value ()->is_marked_for_strip ())
1853 0 : rust_error_at (block_expr.value ()->get_locus (),
1854 : "cannot strip block expression in this position - outer "
1855 : "attributes not allowed");
1856 : }
1857 : }
1858 :
1859 : void
1860 6244 : CfgStrip::visit (AST::TypeAlias &type_alias)
1861 : {
1862 : // initial test based on outer attrs
1863 6244 : expand_cfg_attrs (type_alias.get_outer_attrs ());
1864 6244 : if (fails_cfg_with_expand (type_alias.get_outer_attrs ()))
1865 : {
1866 0 : type_alias.mark_for_strip ();
1867 0 : return;
1868 : }
1869 :
1870 6244 : AST::DefaultASTVisitor::visit (type_alias);
1871 :
1872 6244 : auto &type = type_alias.get_type_aliased ();
1873 6244 : if (type.is_marked_for_strip ())
1874 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
1875 : }
1876 :
1877 : void
1878 4074 : CfgStrip::visit (AST::StructStruct &struct_item)
1879 : {
1880 : // initial test based on outer attrs
1881 4074 : expand_cfg_attrs (struct_item.get_outer_attrs ());
1882 4074 : if (fails_cfg_with_expand (struct_item.get_outer_attrs ()))
1883 : {
1884 2 : struct_item.mark_for_strip ();
1885 2 : return;
1886 : }
1887 :
1888 4072 : AST::DefaultASTVisitor::visit (struct_item);
1889 :
1890 : /* strip struct fields if required - this is presumably
1891 : * allowed by spec */
1892 4072 : maybe_strip_struct_fields (struct_item.get_fields ());
1893 : }
1894 : void
1895 2454 : CfgStrip::visit (AST::TupleStruct &tuple_struct)
1896 : {
1897 : // initial test based on outer attrs
1898 2454 : expand_cfg_attrs (tuple_struct.get_outer_attrs ());
1899 2454 : if (fails_cfg_with_expand (tuple_struct.get_outer_attrs ()))
1900 : {
1901 0 : tuple_struct.mark_for_strip ();
1902 0 : return;
1903 : }
1904 :
1905 2454 : AST::DefaultASTVisitor::visit (tuple_struct);
1906 :
1907 : /* strip struct fields if required - this is presumably
1908 : * allowed by spec */
1909 2454 : maybe_strip_tuple_fields (tuple_struct.get_fields ());
1910 : }
1911 : void
1912 2112 : CfgStrip::visit (AST::EnumItem &item)
1913 : {
1914 : // initial test based on outer attrs
1915 2112 : expand_cfg_attrs (item.get_outer_attrs ());
1916 2112 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
1917 : {
1918 0 : item.mark_for_strip ();
1919 0 : return;
1920 : }
1921 : }
1922 :
1923 : void
1924 2250 : CfgStrip::visit (AST::EnumItemTuple &item)
1925 : {
1926 : // initial test based on outer attrs
1927 2250 : expand_cfg_attrs (item.get_outer_attrs ());
1928 2250 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
1929 : {
1930 0 : item.mark_for_strip ();
1931 0 : return;
1932 : }
1933 :
1934 : /* strip item fields if required - this is presumably
1935 : * allowed by spec */
1936 2250 : maybe_strip_tuple_fields (item.get_tuple_fields ());
1937 : }
1938 :
1939 : void
1940 440 : CfgStrip::visit (AST::EnumItemStruct &item)
1941 : {
1942 : // initial test based on outer attrs
1943 440 : expand_cfg_attrs (item.get_outer_attrs ());
1944 440 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
1945 : {
1946 0 : item.mark_for_strip ();
1947 0 : return;
1948 : }
1949 :
1950 : /* strip item fields if required - this is presumably
1951 : * allowed by spec */
1952 440 : maybe_strip_struct_fields (item.get_struct_fields ());
1953 : }
1954 :
1955 : void
1956 1378 : CfgStrip::visit (AST::EnumItemDiscriminant &item)
1957 : {
1958 : // initial test based on outer attrs
1959 1378 : expand_cfg_attrs (item.get_outer_attrs ());
1960 1378 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
1961 : {
1962 0 : item.mark_for_strip ();
1963 0 : return;
1964 : }
1965 :
1966 1378 : AST::DefaultASTVisitor::visit (item);
1967 : /* strip any internal sub-expressions - expression itself isn't
1968 : * allowed to have external attributes in this position so can't be
1969 : * stripped. */
1970 1378 : auto &expr = item.get_expr ();
1971 1378 : if (expr.is_marked_for_strip ())
1972 0 : rust_error_at (expr.get_locus (),
1973 : "cannot strip expression in this position - outer "
1974 : "attributes not allowed");
1975 : }
1976 : void
1977 1328 : CfgStrip::visit (AST::Enum &enum_item)
1978 : {
1979 : // initial test based on outer attrs
1980 1328 : expand_cfg_attrs (enum_item.get_outer_attrs ());
1981 1328 : if (fails_cfg_with_expand (enum_item.get_outer_attrs ()))
1982 : {
1983 0 : enum_item.mark_for_strip ();
1984 0 : return;
1985 : }
1986 :
1987 1328 : AST::DefaultASTVisitor::visit (enum_item);
1988 :
1989 : /* strip enum fields if required - this is presumably
1990 : * allowed by spec */
1991 1328 : maybe_strip_pointer_allow_strip (enum_item.get_variants ());
1992 : }
1993 : void
1994 222 : CfgStrip::visit (AST::Union &union_item)
1995 : {
1996 : // initial test based on outer attrs
1997 222 : expand_cfg_attrs (union_item.get_outer_attrs ());
1998 222 : if (fails_cfg_with_expand (union_item.get_outer_attrs ()))
1999 : {
2000 0 : union_item.mark_for_strip ();
2001 0 : return;
2002 : }
2003 :
2004 222 : AST::DefaultASTVisitor::visit (union_item);
2005 :
2006 : /* strip union fields if required - this is presumably
2007 : * allowed by spec */
2008 222 : maybe_strip_struct_fields (union_item.get_variants ());
2009 : }
2010 : void
2011 1503 : CfgStrip::visit (AST::ConstantItem &const_item)
2012 : {
2013 : // initial test based on outer attrs
2014 1503 : expand_cfg_attrs (const_item.get_outer_attrs ());
2015 1503 : if (fails_cfg_with_expand (const_item.get_outer_attrs ()))
2016 : {
2017 0 : const_item.mark_for_strip ();
2018 0 : return;
2019 : }
2020 :
2021 1503 : AST::DefaultASTVisitor::visit (const_item);
2022 :
2023 : // strip any sub-types
2024 1503 : auto &type = const_item.get_type ();
2025 1503 : if (type.is_marked_for_strip ())
2026 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2027 :
2028 : /* strip any internal sub-expressions - expression itself isn't
2029 : * allowed to have external attributes in this position so can't be
2030 : * stripped. */
2031 1503 : if (const_item.has_expr ())
2032 : {
2033 1361 : auto &expr = const_item.get_expr ();
2034 1361 : if (expr.is_marked_for_strip ())
2035 0 : rust_error_at (expr.get_locus (),
2036 : "cannot strip expression in this position - outer "
2037 : "attributes not allowed");
2038 : }
2039 : }
2040 : void
2041 121 : CfgStrip::visit (AST::StaticItem &static_item)
2042 : {
2043 : // initial test based on outer attrs
2044 121 : expand_cfg_attrs (static_item.get_outer_attrs ());
2045 121 : if (fails_cfg_with_expand (static_item.get_outer_attrs ()))
2046 : {
2047 0 : static_item.mark_for_strip ();
2048 0 : return;
2049 : }
2050 :
2051 121 : AST::DefaultASTVisitor::visit (static_item);
2052 :
2053 : // strip any sub-types
2054 121 : auto &type = static_item.get_type ();
2055 :
2056 121 : if (type.is_marked_for_strip ())
2057 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2058 :
2059 : /* strip any internal sub-expressions - expression itself isn't
2060 : * allowed to have external attributes in this position so can't be
2061 : * stripped. */
2062 121 : auto &expr = static_item.get_expr ();
2063 121 : if (expr.is_marked_for_strip ())
2064 0 : rust_error_at (expr.get_locus (),
2065 : "cannot strip expression in this position - outer "
2066 : "attributes not allowed");
2067 : }
2068 :
2069 : void
2070 3686 : CfgStrip::visit (AST::TraitItemType &item)
2071 : {
2072 : // initial test based on outer attrs
2073 3686 : expand_cfg_attrs (item.get_outer_attrs ());
2074 3686 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
2075 : {
2076 0 : item.mark_for_strip ();
2077 0 : return;
2078 : }
2079 :
2080 3686 : AST::DefaultASTVisitor::visit (item);
2081 : }
2082 :
2083 : void
2084 8674 : CfgStrip::visit (AST::Trait &trait)
2085 : {
2086 : // initial strip test based on outer attrs
2087 8674 : expand_cfg_attrs (trait.get_outer_attrs ());
2088 8674 : if (fails_cfg_with_expand (trait.get_outer_attrs ()))
2089 : {
2090 1 : trait.mark_for_strip ();
2091 1 : return;
2092 : }
2093 :
2094 : // strip test based on inner attrs
2095 8673 : expand_cfg_attrs (trait.get_inner_attrs ());
2096 8673 : if (fails_cfg_with_expand (trait.get_inner_attrs ()))
2097 : {
2098 0 : trait.mark_for_strip ();
2099 0 : return;
2100 : }
2101 :
2102 8673 : AST::DefaultASTVisitor::visit (trait);
2103 :
2104 8673 : maybe_strip_pointer_allow_strip (trait.get_trait_items ());
2105 : }
2106 :
2107 : void
2108 2201 : CfgStrip::visit (AST::InherentImpl &impl)
2109 : {
2110 : // initial strip test based on outer attrs
2111 2201 : expand_cfg_attrs (impl.get_outer_attrs ());
2112 2201 : if (fails_cfg_with_expand (impl.get_outer_attrs ()))
2113 : {
2114 1 : impl.mark_for_strip ();
2115 1 : return;
2116 : }
2117 :
2118 : // strip test based on inner attrs
2119 2200 : expand_cfg_attrs (impl.get_inner_attrs ());
2120 2200 : if (fails_cfg_with_expand (impl.get_inner_attrs ()))
2121 : {
2122 0 : impl.mark_for_strip ();
2123 0 : return;
2124 : }
2125 :
2126 2200 : AST::DefaultASTVisitor::visit (impl);
2127 :
2128 2200 : auto &type = impl.get_type ();
2129 :
2130 2200 : if (type.is_marked_for_strip ())
2131 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2132 :
2133 2200 : maybe_strip_pointer_allow_strip (impl.get_impl_items ());
2134 : }
2135 :
2136 : void
2137 11160 : CfgStrip::visit (AST::TraitImpl &impl)
2138 : {
2139 : // initial strip test based on outer attrs
2140 11160 : expand_cfg_attrs (impl.get_outer_attrs ());
2141 11160 : if (fails_cfg_with_expand (impl.get_outer_attrs ()))
2142 : {
2143 0 : impl.mark_for_strip ();
2144 0 : return;
2145 : }
2146 :
2147 : // strip test based on inner attrs
2148 11160 : expand_cfg_attrs (impl.get_inner_attrs ());
2149 11160 : if (fails_cfg_with_expand (impl.get_inner_attrs ()))
2150 : {
2151 0 : impl.mark_for_strip ();
2152 0 : return;
2153 : }
2154 :
2155 11160 : AST::DefaultASTVisitor::visit (impl);
2156 :
2157 11160 : auto &type = impl.get_type ();
2158 11160 : if (type.is_marked_for_strip ())
2159 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2160 :
2161 11160 : auto &trait_path = impl.get_trait_path ();
2162 11160 : visit (trait_path);
2163 11160 : if (trait_path.is_marked_for_strip ())
2164 0 : rust_error_at (trait_path.get_locus (),
2165 : "cannot strip typepath in this position");
2166 :
2167 11160 : maybe_strip_pointer_allow_strip (impl.get_impl_items ());
2168 : }
2169 :
2170 : void
2171 2 : CfgStrip::visit (AST::ExternalTypeItem &item)
2172 : {
2173 2 : expand_cfg_attrs (item.get_outer_attrs ());
2174 :
2175 2 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
2176 0 : item.mark_for_strip ();
2177 :
2178 : // TODO: Can we do anything like expand a macro here?
2179 : // extern "C" { type ffi_ty!(); }
2180 : // ?
2181 2 : }
2182 :
2183 : void
2184 2 : CfgStrip::visit (AST::ExternalStaticItem &item)
2185 : {
2186 : // strip test based on outer attrs
2187 2 : expand_cfg_attrs (item.get_outer_attrs ());
2188 2 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
2189 : {
2190 0 : item.mark_for_strip ();
2191 0 : return;
2192 : }
2193 :
2194 2 : AST::DefaultASTVisitor::visit (item);
2195 :
2196 2 : auto &type = item.get_type ();
2197 2 : if (type.is_marked_for_strip ())
2198 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2199 : }
2200 :
2201 : void
2202 3351 : CfgStrip::visit (AST::ExternBlock &block)
2203 : {
2204 : // initial strip test based on outer attrs
2205 3351 : expand_cfg_attrs (block.get_outer_attrs ());
2206 3351 : if (fails_cfg_with_expand (block.get_outer_attrs ()))
2207 : {
2208 0 : block.mark_for_strip ();
2209 0 : return;
2210 : }
2211 :
2212 : // strip test based on inner attrs
2213 3351 : expand_cfg_attrs (block.get_inner_attrs ());
2214 3351 : if (fails_cfg_with_expand (block.get_inner_attrs ()))
2215 : {
2216 0 : block.mark_for_strip ();
2217 0 : return;
2218 : }
2219 :
2220 3351 : maybe_strip_pointer_allow_strip (block.get_extern_items ());
2221 : }
2222 :
2223 : void
2224 3815 : CfgStrip::visit (AST::MacroRulesDefinition &rules_def)
2225 : {
2226 : // initial strip test based on outer attrs
2227 3815 : expand_cfg_attrs (rules_def.get_outer_attrs ());
2228 3815 : if (fails_cfg_with_expand (rules_def.get_outer_attrs ()))
2229 : {
2230 0 : rules_def.mark_for_strip ();
2231 0 : return;
2232 : }
2233 : }
2234 :
2235 : void
2236 164034 : CfgStrip::visit (AST::IdentifierPattern &pattern)
2237 : {
2238 : // can only strip sub-patterns of the inner pattern to bind
2239 164034 : if (!pattern.has_subpattern ())
2240 : return;
2241 :
2242 70 : AST::DefaultASTVisitor::visit (pattern);
2243 :
2244 70 : auto &sub_pattern = pattern.get_subpattern ();
2245 70 : if (sub_pattern.is_marked_for_strip ())
2246 0 : rust_error_at (sub_pattern.get_locus (),
2247 : "cannot strip pattern in this position");
2248 : }
2249 :
2250 : void
2251 42 : CfgStrip::visit (AST::RangePatternBoundPath &bound)
2252 : {
2253 : // can expand path, but not strip it directly
2254 42 : auto &path = bound.get_path ();
2255 42 : visit (path);
2256 42 : if (path.is_marked_for_strip ())
2257 0 : rust_error_at (path.get_locus (), "cannot strip path in this position");
2258 42 : }
2259 :
2260 : void
2261 0 : CfgStrip::visit (AST::RangePatternBoundQualPath &bound)
2262 : {
2263 : // can expand path, but not strip it directly
2264 0 : auto &path = bound.get_qualified_path ();
2265 0 : visit (path);
2266 0 : if (path.is_marked_for_strip ())
2267 0 : rust_error_at (path.get_locus (), "cannot strip path in this position");
2268 0 : }
2269 :
2270 : void
2271 820 : CfgStrip::visit (AST::ReferencePattern &pattern)
2272 : {
2273 820 : AST::DefaultASTVisitor::visit (pattern);
2274 :
2275 820 : auto &sub_pattern = pattern.get_referenced_pattern ();
2276 820 : if (sub_pattern.is_marked_for_strip ())
2277 0 : rust_error_at (sub_pattern.get_locus (),
2278 : "cannot strip pattern in this position");
2279 820 : }
2280 : void
2281 78 : CfgStrip::visit (AST::StructPatternFieldTuplePat &field)
2282 : {
2283 : // initial strip test based on outer attrs
2284 78 : expand_cfg_attrs (field.get_outer_attrs ());
2285 78 : if (fails_cfg_with_expand (field.get_outer_attrs ()))
2286 : {
2287 0 : field.mark_for_strip ();
2288 0 : return;
2289 : }
2290 :
2291 78 : AST::DefaultASTVisitor::visit (field);
2292 :
2293 : // strip sub-patterns (can't strip top-level pattern)
2294 78 : auto &sub_pattern = field.get_index_pattern ();
2295 78 : if (sub_pattern.is_marked_for_strip ())
2296 0 : rust_error_at (sub_pattern.get_locus (),
2297 : "cannot strip pattern in this position");
2298 : }
2299 :
2300 : void
2301 516 : CfgStrip::visit (AST::StructPatternFieldIdentPat &field)
2302 : {
2303 : // initial strip test based on outer attrs
2304 516 : expand_cfg_attrs (field.get_outer_attrs ());
2305 516 : if (fails_cfg_with_expand (field.get_outer_attrs ()))
2306 : {
2307 0 : field.mark_for_strip ();
2308 0 : return;
2309 : }
2310 :
2311 516 : AST::DefaultASTVisitor::visit (field);
2312 : // strip sub-patterns (can't strip top-level pattern)
2313 516 : auto &sub_pattern = field.get_ident_pattern ();
2314 516 : if (sub_pattern.is_marked_for_strip ())
2315 0 : rust_error_at (sub_pattern.get_locus (),
2316 : "cannot strip pattern in this position");
2317 : }
2318 : void
2319 252 : CfgStrip::visit (AST::StructPatternFieldIdent &field)
2320 : {
2321 : // initial strip test based on outer attrs
2322 252 : expand_cfg_attrs (field.get_outer_attrs ());
2323 252 : if (fails_cfg_with_expand (field.get_outer_attrs ()))
2324 : {
2325 0 : field.mark_for_strip ();
2326 0 : return;
2327 : }
2328 : }
2329 :
2330 : void
2331 502 : CfgStrip::visit (AST::StructPattern &pattern)
2332 : {
2333 : // expand (but don't strip) path
2334 502 : auto &path = pattern.get_path ();
2335 502 : visit (path);
2336 502 : if (path.is_marked_for_strip ())
2337 0 : rust_error_at (path.get_locus (), "cannot strip path in this position");
2338 :
2339 : /* TODO: apparently struct pattern fields can have outer attrs. so can they
2340 : * be stripped? */
2341 502 : if (!pattern.has_struct_pattern_elems ())
2342 : return;
2343 :
2344 500 : auto &elems = pattern.get_struct_pattern_elems ();
2345 :
2346 : // assuming you can strip struct pattern fields
2347 500 : maybe_strip_pointer_allow_strip (elems.get_struct_pattern_fields ());
2348 :
2349 : // assuming you can strip the ".." part
2350 500 : if (elems.has_rest ())
2351 : {
2352 10 : expand_cfg_attrs (elems.get_etc_outer_attrs ());
2353 10 : if (fails_cfg_with_expand (elems.get_etc_outer_attrs ()))
2354 0 : elems.strip_etc ();
2355 : }
2356 : }
2357 :
2358 : void
2359 4788 : CfgStrip::visit (AST::TupleStructItemsNoRest &tuple_items)
2360 : {
2361 4788 : AST::DefaultASTVisitor::visit (tuple_items);
2362 : // can't strip individual patterns, only sub-patterns
2363 10114 : for (auto &pattern : tuple_items.get_patterns ())
2364 : {
2365 5326 : if (pattern->is_marked_for_strip ())
2366 0 : rust_error_at (pattern->get_locus (),
2367 : "cannot strip pattern in this position");
2368 : // TODO: quit stripping now? or keep going?
2369 : }
2370 4788 : }
2371 : void
2372 148 : CfgStrip::visit (AST::TupleStructItemsHasRest &tuple_items)
2373 : {
2374 148 : AST::DefaultASTVisitor::visit (tuple_items);
2375 : // can't strip individual patterns, only sub-patterns
2376 266 : for (auto &lower_pattern : tuple_items.get_lower_patterns ())
2377 : {
2378 118 : if (lower_pattern->is_marked_for_strip ())
2379 0 : rust_error_at (lower_pattern->get_locus (),
2380 : "cannot strip pattern in this position");
2381 : // TODO: quit stripping now? or keep going?
2382 : }
2383 214 : for (auto &upper_pattern : tuple_items.get_upper_patterns ())
2384 : {
2385 66 : if (upper_pattern->is_marked_for_strip ())
2386 0 : rust_error_at (upper_pattern->get_locus (),
2387 : "cannot strip pattern in this position");
2388 : // TODO: quit stripping now? or keep going?
2389 : }
2390 148 : }
2391 :
2392 : void
2393 4936 : CfgStrip::visit (AST::TupleStructPattern &pattern)
2394 : {
2395 : // expand (but don't strip) path
2396 4936 : auto &path = pattern.get_path ();
2397 4936 : visit (path);
2398 4936 : if (path.is_marked_for_strip ())
2399 0 : rust_error_at (path.get_locus (), "cannot strip path in this position");
2400 :
2401 4936 : AST::DefaultASTVisitor::visit (pattern);
2402 4936 : }
2403 :
2404 : void
2405 3934 : CfgStrip::visit (AST::TuplePatternItemsNoRest &tuple_items)
2406 : {
2407 3934 : AST::DefaultASTVisitor::visit (tuple_items);
2408 :
2409 : // can't strip individual patterns, only sub-patterns
2410 11814 : for (auto &pattern : tuple_items.get_patterns ())
2411 : {
2412 7880 : if (pattern->is_marked_for_strip ())
2413 0 : rust_error_at (pattern->get_locus (),
2414 : "cannot strip pattern in this position");
2415 : // TODO: quit stripping now? or keep going?
2416 : }
2417 3934 : }
2418 :
2419 : void
2420 102 : CfgStrip::visit (AST::TuplePatternItemsHasRest &tuple_items)
2421 : {
2422 102 : AST::DefaultASTVisitor::visit (tuple_items);
2423 :
2424 : // can't strip individual patterns, only sub-patterns
2425 206 : for (auto &lower_pattern : tuple_items.get_lower_patterns ())
2426 : {
2427 104 : if (lower_pattern->is_marked_for_strip ())
2428 0 : rust_error_at (lower_pattern->get_locus (),
2429 : "cannot strip pattern in this position");
2430 : // TODO: quit stripping now? or keep going?
2431 : }
2432 214 : for (auto &upper_pattern : tuple_items.get_upper_patterns ())
2433 : {
2434 112 : if (upper_pattern->is_marked_for_strip ())
2435 0 : rust_error_at (upper_pattern->get_locus (),
2436 : "cannot strip pattern in this position");
2437 : // TODO: quit stripping now? or keep going?
2438 : }
2439 102 : }
2440 :
2441 : void
2442 176 : CfgStrip::visit (AST::GroupedPattern &pattern)
2443 : {
2444 176 : AST::DefaultASTVisitor::visit (pattern);
2445 : // can't strip inner pattern, only sub-patterns
2446 176 : auto &pattern_in_parens = pattern.get_pattern_in_parens ();
2447 :
2448 176 : if (pattern_in_parens.is_marked_for_strip ())
2449 0 : rust_error_at (pattern_in_parens.get_locus (),
2450 : "cannot strip pattern in this position");
2451 176 : }
2452 :
2453 : void
2454 120 : CfgStrip::visit (AST::SlicePatternItemsNoRest &items)
2455 : {
2456 120 : AST::DefaultASTVisitor::visit (items);
2457 : // can't strip individual patterns, only sub-patterns
2458 360 : for (auto &pattern : items.get_patterns ())
2459 : {
2460 240 : if (pattern->is_marked_for_strip ())
2461 0 : rust_error_at (pattern->get_locus (),
2462 : "cannot strip pattern in this position");
2463 : }
2464 120 : }
2465 :
2466 : void
2467 172 : CfgStrip::visit (AST::SlicePatternItemsHasRest &items)
2468 : {
2469 172 : AST::DefaultASTVisitor::visit (items);
2470 : // can't strip individual patterns, only sub-patterns
2471 342 : for (auto &pattern : items.get_lower_patterns ())
2472 : {
2473 170 : if (pattern->is_marked_for_strip ())
2474 0 : rust_error_at (pattern->get_locus (),
2475 : "cannot strip pattern in this position");
2476 : }
2477 342 : for (auto &pattern : items.get_upper_patterns ())
2478 : {
2479 170 : if (pattern->is_marked_for_strip ())
2480 0 : rust_error_at (pattern->get_locus (),
2481 : "cannot strip pattern in this position");
2482 : }
2483 172 : }
2484 :
2485 : void
2486 292 : CfgStrip::visit (AST::SlicePattern &pattern)
2487 : {
2488 292 : AST::DefaultASTVisitor::visit (pattern);
2489 292 : }
2490 :
2491 : void
2492 970 : CfgStrip::visit (AST::AltPattern &pattern)
2493 : {
2494 970 : AST::DefaultASTVisitor::visit (pattern);
2495 : // can't strip individual patterns, only sub-patterns
2496 3040 : for (auto &alt : pattern.get_alts ())
2497 : {
2498 2070 : if (alt->is_marked_for_strip ())
2499 0 : rust_error_at (alt->get_locus (),
2500 : "cannot strip pattern in this position");
2501 : // TODO: quit stripping now? or keep going?
2502 : }
2503 970 : }
2504 :
2505 : void
2506 73880 : CfgStrip::visit (AST::LetStmt &stmt)
2507 : {
2508 : // initial strip test based on outer attrs
2509 73880 : expand_cfg_attrs (stmt.get_outer_attrs ());
2510 73880 : if (fails_cfg_with_expand (stmt.get_outer_attrs ()))
2511 : {
2512 0 : stmt.mark_for_strip ();
2513 0 : return;
2514 : }
2515 :
2516 73880 : AST::DefaultASTVisitor::visit (stmt);
2517 : // can't strip pattern, but call for sub-patterns
2518 73880 : auto &pattern = stmt.get_pattern ();
2519 73880 : if (pattern.is_marked_for_strip ())
2520 0 : rust_error_at (pattern.get_locus (),
2521 : "cannot strip pattern in this position");
2522 :
2523 : // similar for type
2524 73880 : if (stmt.has_type ())
2525 : {
2526 10010 : auto &type = stmt.get_type ();
2527 :
2528 10010 : if (type.is_marked_for_strip ())
2529 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2530 : }
2531 :
2532 : /* strip any internal sub-expressions - expression itself isn't
2533 : * allowed to have external attributes in this position so can't be
2534 : * stripped */
2535 73880 : if (stmt.has_init_expr ())
2536 : {
2537 68756 : auto &init_expr = stmt.get_init_expr ();
2538 :
2539 68756 : if (init_expr.is_marked_for_strip ())
2540 0 : rust_error_at (init_expr.get_locus (),
2541 : "cannot strip expression in this position - outer "
2542 : "attributes not allowed");
2543 : }
2544 : }
2545 :
2546 : void
2547 61852 : CfgStrip::visit (AST::ExprStmt &stmt)
2548 : {
2549 : // outer attributes associated with expr, so rely on expr
2550 :
2551 : // guard - should prevent null pointer expr
2552 61852 : if (stmt.is_marked_for_strip ())
2553 : return;
2554 :
2555 61852 : AST::DefaultASTVisitor::visit (stmt);
2556 : // strip if expr is to be stripped
2557 61852 : auto &expr = stmt.get_expr ();
2558 61852 : if (expr.is_marked_for_strip ())
2559 : {
2560 18 : stmt.mark_for_strip ();
2561 18 : return;
2562 : }
2563 : }
2564 :
2565 : void
2566 6873 : CfgStrip::visit (AST::TraitBound &bound)
2567 : {
2568 : // nothing in for lifetimes to strip
2569 :
2570 : // expand but don't strip type path
2571 6873 : auto &path = bound.get_type_path ();
2572 6873 : visit (path);
2573 6873 : if (path.is_marked_for_strip ())
2574 0 : rust_error_at (path.get_locus (),
2575 : "cannot strip type path in this position");
2576 6873 : }
2577 :
2578 : void
2579 22 : CfgStrip::visit (AST::ParenthesisedType &type)
2580 : {
2581 22 : AST::DefaultASTVisitor::visit (type);
2582 : // expand but don't strip inner type
2583 22 : auto &inner_type = type.get_type_in_parens ();
2584 22 : if (inner_type->is_marked_for_strip ())
2585 0 : rust_error_at (inner_type->get_locus (),
2586 : "cannot strip type in this position");
2587 22 : }
2588 :
2589 : void
2590 1799 : CfgStrip::visit (AST::TupleType &type)
2591 : {
2592 1799 : AST::DefaultASTVisitor::visit (type);
2593 : // TODO: assuming that types can't be stripped as types don't have outer
2594 : // attributes
2595 4681 : for (auto &elem_type : type.get_elems ())
2596 : {
2597 2882 : if (elem_type->is_marked_for_strip ())
2598 0 : rust_error_at (elem_type->get_locus (),
2599 : "cannot strip type in this position");
2600 : }
2601 1799 : }
2602 :
2603 : void
2604 48521 : CfgStrip::visit (AST::RawPointerType &type)
2605 : {
2606 48521 : AST::DefaultASTVisitor::visit (type);
2607 : // expand but don't strip type pointed to
2608 48521 : auto &pointed_type = type.get_type_pointed_to ();
2609 48521 : if (pointed_type.is_marked_for_strip ())
2610 0 : rust_error_at (pointed_type.get_locus (),
2611 : "cannot strip type in this position");
2612 48521 : }
2613 :
2614 : void
2615 32958 : CfgStrip::visit (AST::ReferenceType &type)
2616 : {
2617 32958 : AST::DefaultASTVisitor::visit (type);
2618 : // expand but don't strip type referenced
2619 32958 : auto &referenced_type = type.get_type_referenced ();
2620 32958 : if (referenced_type.is_marked_for_strip ())
2621 0 : rust_error_at (referenced_type.get_locus (),
2622 : "cannot strip type in this position");
2623 32958 : }
2624 :
2625 : void
2626 4876 : CfgStrip::visit (AST::ArrayType &type)
2627 : {
2628 4876 : AST::DefaultASTVisitor::visit (type);
2629 : // expand but don't strip type referenced
2630 4876 : auto &base_type = type.get_elem_type ();
2631 4876 : if (base_type.is_marked_for_strip ())
2632 0 : rust_error_at (base_type.get_locus (),
2633 : "cannot strip type in this position");
2634 :
2635 : // same for expression
2636 4876 : auto &size_expr = type.get_size_expr ();
2637 4876 : if (size_expr.is_marked_for_strip ())
2638 0 : rust_error_at (size_expr.get_locus (),
2639 : "cannot strip expression in this position");
2640 4876 : }
2641 : void
2642 4023 : CfgStrip::visit (AST::SliceType &type)
2643 : {
2644 4023 : AST::DefaultASTVisitor::visit (type);
2645 : // expand but don't strip elem type
2646 4023 : auto &elem_type = type.get_elem_type ();
2647 4023 : if (elem_type.is_marked_for_strip ())
2648 0 : rust_error_at (elem_type.get_locus (),
2649 : "cannot strip type in this position");
2650 4023 : }
2651 :
2652 : void
2653 254 : CfgStrip::visit (AST::BareFunctionType &type)
2654 : {
2655 : // seem to be no generics
2656 254 : AST::DefaultASTVisitor::visit (type);
2657 :
2658 : // presumably function params can be stripped
2659 254 : auto ¶ms = type.get_function_params ();
2660 474 : for (auto it = params.begin (); it != params.end ();)
2661 : {
2662 220 : auto ¶m = *it;
2663 :
2664 220 : auto ¶m_attrs = param.get_outer_attrs ();
2665 220 : expand_cfg_attrs (param_attrs);
2666 220 : if (fails_cfg_with_expand (param_attrs))
2667 : {
2668 0 : it = params.erase (it);
2669 0 : continue;
2670 : }
2671 :
2672 220 : auto &type = param.get_type ();
2673 220 : if (type.is_marked_for_strip ())
2674 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2675 :
2676 : // increment if nothing else happens
2677 220 : ++it;
2678 : }
2679 :
2680 : /* TODO: assuming that variadic nature cannot be stripped. If this
2681 : * is not true, then have code here to do so. */
2682 :
2683 254 : if (type.has_return_type ())
2684 : {
2685 : // FIXME: Can we have type expansion in this position?
2686 : // In that case, we need to handle AST::TypeNoBounds on top of just
2687 : // AST::Types
2688 182 : auto &return_type = type.get_return_type ();
2689 182 : if (return_type.is_marked_for_strip ())
2690 0 : rust_error_at (return_type.get_locus (),
2691 : "cannot strip type in this position");
2692 : }
2693 :
2694 : // no where clause, apparently
2695 254 : }
2696 :
2697 : void
2698 39642 : CfgStrip::visit (AST::SelfParam ¶m)
2699 : {
2700 39642 : AST::DefaultASTVisitor::visit (param);
2701 :
2702 39642 : if (param.has_type ())
2703 : {
2704 4 : auto &type = param.get_type ();
2705 4 : if (type.is_marked_for_strip ())
2706 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2707 : }
2708 : /* TODO: maybe check for invariants being violated - e.g. both type and
2709 : * lifetime? */
2710 39642 : }
2711 :
2712 : } // namespace Rust
|