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