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 67881961 : CfgStrip::fails_cfg_with_expand (AST::AttrVec &attrs) const
35 : {
36 67881961 : auto &session = Session::get_instance ();
37 :
38 : // TODO: maybe have something that strips cfg attributes that evaluate true?
39 71780969 : for (auto &attr : attrs)
40 : {
41 3899387 : if (attr.get_path () == Values::Attributes::CFG)
42 : {
43 8061 : if (!attr.is_parsed_to_meta_item ())
44 945 : attr.parse_attr_to_meta_item ();
45 :
46 : // DEBUG
47 8061 : 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 8060 : rust_debug ("attr has been successfully parsed to meta item, "
52 : "right before cfg predicate check");
53 :
54 8061 : if (!attr.check_cfg_predicate (session))
55 : {
56 : // DEBUG
57 378 : rust_debug (
58 : "cfg predicate failed for attribute: \033[0;31m'%s'\033[0m",
59 : attr.as_string ().c_str ());
60 :
61 : return true;
62 : }
63 : else
64 : {
65 : // DEBUG
66 7683 : rust_debug ("cfg predicate succeeded for attribute: "
67 : "\033[0;31m'%s'\033[0m",
68 : attr.as_string ().c_str ());
69 : }
70 : }
71 3891326 : else if (!expansion_cfg.should_test
72 7782652 : && 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 67886937 : expand_cfg_attrs (AST::AttrVec &attrs)
83 : {
84 67886937 : auto &session = Session::get_instance ();
85 :
86 139687827 : for (std::size_t i = 0; i < attrs.size (); i++)
87 : {
88 3913953 : auto &attr = attrs[i];
89 3913953 : if (attr.get_path () == Values::Attributes::CFG_ATTR)
90 : {
91 1708 : if (!attr.is_parsed_to_meta_item ())
92 1683 : attr.parse_attr_to_meta_item ();
93 :
94 1708 : 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 61 : AST::AttrVec new_attrs = attr.separate_cfg_attrs ();
101 :
102 : // remove attr from vector
103 61 : attrs.erase (attrs.begin () + i);
104 :
105 : // add new attrs to vector
106 61 : 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 61 : i--;
115 61 : }
116 : else
117 : {
118 : // Key has not been found, remove the whole attribute
119 1647 : attrs.erase (attrs.begin () + i);
120 1647 : 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 67886937 : attrs.shrink_to_fit ();
132 67886937 : }
133 :
134 : void
135 11447 : CfgStrip::go (AST::Crate &crate)
136 : {
137 11447 : visit (crate);
138 11447 : }
139 :
140 : void
141 11447 : CfgStrip::visit (AST::Crate &crate)
142 : {
143 : // expand crate cfg_attr attributes
144 11447 : expand_cfg_attrs (crate.inner_attrs);
145 :
146 11447 : 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 11447 : auto &items = crate.items;
154 :
155 11447 : AST::DefaultASTVisitor::visit (crate);
156 64908 : for (auto it = items.begin (); it != items.end ();)
157 : {
158 53461 : auto &item = *it;
159 53461 : if (item->is_marked_for_strip ())
160 24 : it = items.erase (it);
161 : else
162 53437 : it++;
163 : }
164 : // expand module attributes?
165 11447 : }
166 :
167 : // Visitor used to expand attributes.
168 : void
169 114456 : CfgStrip::maybe_strip_struct_fields (std::vector<AST::StructField> &fields)
170 : {
171 142049 : for (auto it = fields.begin (); it != fields.end ();)
172 : {
173 27593 : auto &field = *it;
174 :
175 27593 : auto &field_attrs = field.get_outer_attrs ();
176 27593 : expand_cfg_attrs (field_attrs);
177 27593 : 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 27591 : auto &type = field.get_field_type ();
185 27591 : type.accept_vis (*this);
186 :
187 27591 : 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 27591 : ++it;
192 : }
193 114456 : }
194 :
195 : void
196 57009 : CfgStrip::maybe_strip_struct_expr_fields (
197 : std::vector<std::unique_ptr<AST::StructExprField>> &fields)
198 : {
199 164016 : for (auto it = fields.begin (); it != fields.end ();)
200 : {
201 107007 : auto &field = *it;
202 :
203 107007 : auto &field_attrs = field->get_outer_attrs ();
204 107007 : expand_cfg_attrs (field_attrs);
205 107007 : if (fails_cfg_with_expand (field_attrs))
206 : {
207 1 : it = fields.erase (it);
208 1 : continue;
209 : }
210 :
211 107006 : ++it;
212 : }
213 57009 : }
214 :
215 : void
216 11106 : CfgStrip::maybe_strip_tuple_fields (std::vector<AST::TupleField> &fields)
217 : {
218 38145 : for (auto it = fields.begin (); it != fields.end ();)
219 : {
220 27039 : auto &field = *it;
221 :
222 27039 : auto &field_attrs = field.get_outer_attrs ();
223 27039 : expand_cfg_attrs (field_attrs);
224 27039 : 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 27039 : auto &type = field.get_field_type ();
232 27039 : type.accept_vis (*this);
233 27039 : 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 27039 : ++it;
238 : }
239 11106 : }
240 :
241 : void
242 824920 : CfgStrip::maybe_strip_function_params (
243 : std::vector<std::unique_ptr<AST::Param>> ¶ms)
244 : {
245 2263198 : for (auto it = params.begin (); it != params.end ();)
246 : {
247 1438278 : if (!(*it)->is_self () && !(*it)->is_variadic ())
248 : {
249 833407 : auto param = static_cast<AST::FunctionParam *> (it->get ());
250 :
251 833407 : auto ¶m_attrs = param->get_outer_attrs ();
252 833407 : expand_cfg_attrs (param_attrs);
253 833407 : 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 833407 : auto &pattern = param->get_pattern ();
261 833407 : pattern.accept_vis (*this);
262 833407 : if (pattern.is_marked_for_strip ())
263 0 : rust_error_at (pattern.get_locus (),
264 : "cannot strip pattern in this position");
265 :
266 833407 : auto &type = param->get_type ();
267 833407 : type.accept_vis (*this);
268 :
269 833407 : 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 1438278 : ++it;
275 : }
276 824920 : }
277 :
278 : void
279 1337521 : 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 2617349 : for (auto &arg : args.get_generic_args ())
286 : {
287 1279828 : switch (arg.get_kind ())
288 : {
289 362696 : case AST::GenericArg::Kind::Type:
290 362696 : {
291 362696 : auto &type = arg.get_type ();
292 362696 : type.accept_vis (*this);
293 :
294 362696 : 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 1357579 : for (auto &binding : args.get_binding_args ())
322 : {
323 20058 : auto &type = binding.get_type ();
324 20058 : type.accept_vis (*this);
325 :
326 20058 : if (type.is_marked_for_strip ())
327 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
328 : }
329 1337521 : }
330 :
331 : void
332 218392 : CfgStrip::maybe_strip_qualified_path_type (AST::QualifiedPathType &path_type)
333 : {
334 218392 : auto &type = path_type.get_type ();
335 218392 : type.accept_vis (*this);
336 :
337 218392 : if (type.is_marked_for_strip ())
338 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
339 :
340 218392 : if (path_type.has_as_clause ())
341 : {
342 208604 : auto &type_path = path_type.get_as_type_path ();
343 208604 : visit (type_path);
344 208604 : 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 218392 : }
349 :
350 : void
351 48676 : CfgStrip::CfgStrip::maybe_strip_closure_params (
352 : std::vector<AST::ClosureParam> ¶ms)
353 : {
354 104724 : for (auto it = params.begin (); it != params.end ();)
355 : {
356 56048 : auto ¶m = *it;
357 :
358 56048 : auto ¶m_attrs = param.get_outer_attrs ();
359 56048 : expand_cfg_attrs (param_attrs);
360 56048 : if (fails_cfg_with_expand (param_attrs))
361 : {
362 0 : it = params.erase (it);
363 0 : continue;
364 : }
365 :
366 56048 : auto &pattern = param.get_pattern ();
367 56048 : pattern.accept_vis (*this);
368 56048 : if (pattern.is_marked_for_strip ())
369 0 : rust_error_at (pattern.get_locus (),
370 : "cannot strip pattern in this position");
371 :
372 56048 : if (param.has_type_given ())
373 : {
374 2720 : auto &type = param.get_type ();
375 2720 : type.accept_vis (*this);
376 :
377 2720 : 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 56048 : ++it;
384 : }
385 48676 : }
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 14425649 : CfgStrip::visit (AST::IdentifierExpr &ident_expr)
397 : {
398 : // strip test based on outer attrs
399 14425649 : AST::DefaultASTVisitor::visit (ident_expr);
400 14425649 : expand_cfg_attrs (ident_expr.get_outer_attrs ());
401 14425649 : 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 99310 : CfgStrip::visit (AST::MacroInvocation ¯o_invoc)
410 : {
411 : // initial strip test based on outer attrs
412 99310 : expand_cfg_attrs (macro_invoc.get_outer_attrs ());
413 99310 : 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 6266114 : CfgStrip::visit (AST::PathInExpression &path)
428 : {
429 : // initial strip test based on outer attrs
430 6266114 : expand_cfg_attrs (path.get_outer_attrs ());
431 6266114 : if (fails_cfg_with_expand (path.get_outer_attrs ()))
432 : {
433 0 : path.mark_for_strip ();
434 0 : return;
435 : }
436 :
437 6266114 : if (!path.is_lang_item ())
438 : {
439 14226863 : for (auto &segment : path.get_segments ())
440 : {
441 15948362 : if (segment.has_generic_args ())
442 42640 : maybe_strip_generic_args (segment.get_generic_args ());
443 : }
444 : }
445 : }
446 :
447 : void
448 1292053 : CfgStrip::visit (AST::TypePathSegmentGeneric &segment)
449 : {
450 : // TODO: strip inside generic args
451 :
452 1292053 : if (!segment.has_generic_args ())
453 : return;
454 :
455 1292049 : maybe_strip_generic_args (segment.get_generic_args ());
456 : }
457 : void
458 42217 : CfgStrip::visit (AST::TypePathSegmentFunction &segment)
459 : {
460 42217 : AST::DefaultASTVisitor::visit (segment);
461 42217 : auto &type_path_function = segment.get_type_path_function ();
462 :
463 104569 : for (auto &type : type_path_function.get_params ())
464 : {
465 62352 : if (type->is_marked_for_strip ())
466 0 : rust_error_at (type->get_locus (),
467 : "cannot strip type in this position");
468 : }
469 :
470 42217 : if (type_path_function.has_return_type ())
471 : {
472 40828 : auto &return_type = type_path_function.get_return_type ();
473 :
474 40828 : 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 42217 : }
479 :
480 : void
481 12226 : CfgStrip::visit (AST::QualifiedPathInExpression &path)
482 : {
483 : // initial strip test based on outer attrs
484 12226 : AST::DefaultASTVisitor::visit (path);
485 :
486 12226 : expand_cfg_attrs (path.get_outer_attrs ());
487 12226 : if (fails_cfg_with_expand (path.get_outer_attrs ()))
488 : {
489 0 : path.mark_for_strip ();
490 0 : return;
491 : }
492 :
493 12226 : maybe_strip_qualified_path_type (path.get_qualified_path_type ());
494 :
495 24468 : for (auto &segment : path.get_segments ())
496 : {
497 24484 : if (segment.has_generic_args ())
498 0 : maybe_strip_generic_args (segment.get_generic_args ());
499 : }
500 : }
501 :
502 : void
503 206166 : CfgStrip::visit (AST::QualifiedPathInType &path)
504 : {
505 206166 : maybe_strip_qualified_path_type (path.get_qualified_path_type ());
506 :
507 : // this shouldn't strip any segments, but can strip inside them
508 206166 : AST::DefaultASTVisitor::visit (path);
509 206166 : }
510 :
511 : void
512 21853145 : CfgStrip::visit (AST::LiteralExpr &expr)
513 : {
514 : // initial strip test based on outer attrs
515 21853145 : expand_cfg_attrs (expr.get_outer_attrs ());
516 21853145 : 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 887182 : CfgStrip::visit (AST::BorrowExpr &expr)
525 : {
526 887182 : AST::DefaultASTVisitor::visit (expr);
527 : // initial strip test based on outer attrs
528 887182 : expand_cfg_attrs (expr.get_outer_attrs ());
529 887182 : 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 887182 : auto &borrowed_expr = expr.get_borrowed_expr ();
539 887182 : 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 816874 : CfgStrip::visit (AST::DereferenceExpr &expr)
546 : {
547 : // initial strip test based on outer attrs
548 816874 : expand_cfg_attrs (expr.get_outer_attrs ());
549 816874 : 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 816874 : auto &dereferenced_expr = expr.get_dereferenced_expr ();
559 816874 : dereferenced_expr.accept_vis (*this);
560 816874 : 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 64394 : CfgStrip::visit (AST::ErrorPropagationExpr &expr)
567 : {
568 64394 : AST::DefaultASTVisitor::visit (expr);
569 :
570 : // initial strip test based on outer attrs
571 64394 : expand_cfg_attrs (expr.get_outer_attrs ());
572 64394 : 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 64394 : auto &propagating_expr = expr.get_propagating_expr ();
582 64394 : 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 86343 : CfgStrip::visit (AST::NegationExpr &expr)
589 : {
590 86343 : AST::DefaultASTVisitor::visit (expr);
591 : // initial strip test based on outer attrs
592 86343 : expand_cfg_attrs (expr.get_outer_attrs ());
593 86343 : 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 86343 : auto &negated_expr = expr.get_negated_expr ();
603 86343 : 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 2572116 : CfgStrip::visit (AST::ArithmeticOrLogicalExpr &expr)
610 : {
611 2572116 : 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 2572116 : 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 2572116 : 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 2572116 : }
626 :
627 : void
628 263017 : 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 263017 : AST::DefaultASTVisitor::visit (expr);
633 :
634 : // ensure that they are not marked for strip
635 263017 : 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 263017 : 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 263017 : }
645 :
646 : void
647 62376 : 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 62376 : AST::DefaultASTVisitor::visit (expr);
652 :
653 : // ensure that they are not marked for strip
654 62376 : 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 62376 : 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 62376 : }
664 :
665 : void
666 528373 : 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 528373 : AST::DefaultASTVisitor::visit (expr);
671 :
672 528373 : auto &casted_expr = expr.get_casted_expr ();
673 : // ensure that they are not marked for strip
674 528373 : 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 528373 : auto &type = expr.get_type_to_cast_to ();
681 528373 : if (type.is_marked_for_strip ())
682 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
683 528373 : }
684 : void
685 260217 : CfgStrip::visit (AST::AssignmentExpr &expr)
686 : {
687 260217 : expand_cfg_attrs (expr.get_outer_attrs ());
688 260217 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
689 : {
690 14 : expr.mark_for_strip ();
691 14 : return;
692 : }
693 260203 : AST::DefaultASTVisitor::visit (expr);
694 :
695 : // ensure that they are not marked for strip
696 260203 : 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 260203 : 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 143254 : 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 143254 : AST::DefaultASTVisitor::visit (expr);
712 :
713 : // ensure that they are not marked for strip
714 143254 : 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 143254 : 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 143254 : }
724 : void
725 472554 : CfgStrip::visit (AST::GroupedExpr &expr)
726 : {
727 : // initial strip test based on outer attrs
728 472554 : expand_cfg_attrs (expr.get_outer_attrs ());
729 472554 : 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 472554 : expand_cfg_attrs (expr.get_inner_attrs ());
738 472554 : 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 472554 : AST::DefaultASTVisitor::visit (expr);
748 :
749 472554 : auto &inner_expr = expr.get_expr_in_parens ();
750 472554 : 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 1205784 : CfgStrip::visit (AST::ArrayElemsValues &elems)
757 : {
758 : /* apparently outer attributes are allowed in "elements of array
759 : * expressions" according to spec */
760 1205784 : maybe_strip_pointer_allow_strip (elems.get_values ());
761 1205784 : }
762 : void
763 5628 : 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 5628 : AST::DefaultASTVisitor::visit (elems);
770 :
771 : // only intend stripping for internal sub-expressions
772 5628 : auto &copied_expr = elems.get_elem_to_copy ();
773 5628 : 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 5628 : auto ©_count = elems.get_num_copies ();
779 5628 : copy_count.accept_vis (*this);
780 5628 : 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 5628 : }
785 : void
786 1211412 : CfgStrip::visit (AST::ArrayExpr &expr)
787 : {
788 : // initial strip test based on outer attrs
789 1211412 : expand_cfg_attrs (expr.get_outer_attrs ());
790 1211412 : 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 1211412 : expand_cfg_attrs (expr.get_inner_attrs ());
799 1211412 : 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 1211412 : AST::DefaultASTVisitor::visit (expr);
808 : }
809 :
810 : void
811 116483 : 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 116483 : expand_cfg_attrs (expr.get_outer_attrs ());
818 116483 : 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 116483 : AST::DefaultASTVisitor::visit (expr);
828 :
829 116483 : const auto &array_expr = expr.get_array_expr ();
830 116483 : 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 116482 : const auto &index_expr = expr.get_index_expr ();
840 116482 : 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 231707 : 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 231707 : expand_cfg_attrs (expr.get_outer_attrs ());
853 231707 : 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 231707 : expand_cfg_attrs (expr.get_inner_attrs ());
862 231707 : 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 231707 : maybe_strip_pointer_allow_strip (expr.get_tuple_elems ());
871 : }
872 : void
873 417711 : CfgStrip::visit (AST::TupleIndexExpr &expr)
874 : {
875 : // initial strip test based on outer attrs
876 417711 : expand_cfg_attrs (expr.get_outer_attrs ());
877 417711 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
878 : {
879 0 : expr.mark_for_strip ();
880 0 : return;
881 : }
882 :
883 417711 : 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 417711 : auto &tuple_expr = expr.get_tuple_expr ();
888 417711 : 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 2050 : CfgStrip::visit (AST::StructExprStruct &expr)
896 : {
897 : // initial strip test based on outer attrs
898 2050 : expand_cfg_attrs (expr.get_outer_attrs ());
899 2050 : 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 2050 : expand_cfg_attrs (expr.get_inner_attrs ());
908 2050 : 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 2050 : auto &struct_name = expr.get_struct_name ();
916 2050 : visit (struct_name);
917 2050 : 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 92134 : CfgStrip::visit (AST::StructExprFieldIdentifierValue &field)
924 : {
925 : /* as no attrs possible (at moment, at least), only sub-expression
926 : * stripping is possible */
927 92134 : AST::DefaultASTVisitor::visit (field);
928 :
929 92134 : auto &value = field.get_value ();
930 92134 : 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 92134 : }
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 57009 : CfgStrip::visit (AST::StructExprStructFields &expr)
950 : {
951 : // initial strip test based on outer attrs
952 57009 : expand_cfg_attrs (expr.get_outer_attrs ());
953 57009 : 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 57009 : expand_cfg_attrs (expr.get_inner_attrs ());
962 57009 : 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 57009 : auto &struct_name = expr.get_struct_name ();
970 57009 : visit (struct_name);
971 57009 : 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 57009 : 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 57009 : if (expr.has_struct_base ())
984 : {
985 600 : auto &base_struct_expr = expr.get_struct_base ().get_base_struct ();
986 600 : base_struct_expr.accept_vis (*this);
987 600 : 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 57009 : 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 4175282 : CfgStrip::visit (AST::CallExpr &expr)
1035 : {
1036 : // initial strip test based on outer attrs
1037 4175282 : expand_cfg_attrs (expr.get_outer_attrs ());
1038 4175282 : 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 4175281 : AST::DefaultASTVisitor::visit (expr);
1048 :
1049 4175281 : auto &function = expr.get_function_expr ();
1050 4175281 : 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 4175280 : maybe_strip_pointer_allow_strip (expr.get_params ());
1064 : }
1065 : void
1066 3508971 : CfgStrip::visit (AST::MethodCallExpr &expr)
1067 : {
1068 : // initial strip test based on outer attrs
1069 3508971 : expand_cfg_attrs (expr.get_outer_attrs ());
1070 3508971 : 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 3508971 : AST::DefaultASTVisitor::visit (expr);
1080 :
1081 3508971 : auto &receiver = expr.get_receiver_expr ();
1082 3508971 : 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 3508971 : auto &method_name = expr.get_method_name ();
1088 3508971 : if (method_name.has_generic_args ())
1089 2832 : 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 3508971 : maybe_strip_pointer_allow_strip (expr.get_params ());
1094 : }
1095 : void
1096 681758 : CfgStrip::visit (AST::FieldAccessExpr &expr)
1097 : {
1098 : // initial strip test based on outer attrs
1099 681758 : expand_cfg_attrs (expr.get_outer_attrs ());
1100 681758 : 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 681758 : AST::DefaultASTVisitor::visit (expr);
1110 :
1111 681758 : auto &receiver = expr.get_receiver_expr ();
1112 681758 : 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 48486 : CfgStrip::visit (AST::ClosureExprInner &expr)
1119 : {
1120 : // initial strip test based on outer attrs
1121 48486 : expand_cfg_attrs (expr.get_outer_attrs ());
1122 48486 : 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 48486 : maybe_strip_closure_params (expr.get_params ());
1131 :
1132 48486 : AST::DefaultASTVisitor::visit (expr);
1133 :
1134 : // can't strip expression itself, but can strip sub-expressions
1135 48486 : auto &definition_expr = expr.get_definition_expr ();
1136 48486 : 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 1389893 : CfgStrip::visit (AST::BlockExpr &expr)
1144 : {
1145 : // initial strip test based on outer attrs
1146 1389893 : expand_cfg_attrs (expr.get_outer_attrs ());
1147 1389893 : 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 1389786 : expand_cfg_attrs (expr.get_inner_attrs ());
1156 1389786 : if (fails_cfg_with_expand (expr.get_inner_attrs ()))
1157 : {
1158 0 : expr.mark_for_strip ();
1159 0 : return;
1160 : }
1161 :
1162 1389786 : maybe_strip_pointer_allow_strip (expr.get_statements ());
1163 :
1164 1389786 : AST::DefaultASTVisitor::visit (expr);
1165 :
1166 : // strip tail expression if exists - can actually fully remove it
1167 1389786 : if (expr.has_tail_expr ())
1168 : {
1169 1146775 : auto &tail_expr = expr.get_tail_expr ();
1170 :
1171 1146775 : 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 4764 : CfgStrip::visit (AST::ContinueExpr &expr)
1209 : {
1210 : // initial strip test based on outer attrs
1211 4764 : expand_cfg_attrs (expr.get_outer_attrs ());
1212 4764 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1213 : {
1214 0 : expr.mark_for_strip ();
1215 0 : return;
1216 : }
1217 : }
1218 : void
1219 9938 : CfgStrip::visit (AST::BreakExpr &expr)
1220 : {
1221 : // initial strip test based on outer attrs
1222 9938 : expand_cfg_attrs (expr.get_outer_attrs ());
1223 9938 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1224 : {
1225 0 : expr.mark_for_strip ();
1226 0 : return;
1227 : }
1228 9938 : 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 9938 : if (expr.has_break_expr ())
1234 : {
1235 304 : auto &break_expr = expr.get_break_expr_unchecked ();
1236 :
1237 304 : 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 40681 : 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 40681 : AST::DefaultASTVisitor::visit (expr);
1249 :
1250 : // ensure that they are not marked for strip
1251 40681 : 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 40681 : 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 40681 : }
1261 : void
1262 15918 : 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 15918 : AST::DefaultASTVisitor::visit (expr);
1268 : /* should have no possibility for outer attrs as would be parsed
1269 : * with outer expr */
1270 15918 : auto &from_expr = expr.get_from_expr ();
1271 15918 : 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 15918 : }
1276 : void
1277 21944 : 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 21944 : AST::DefaultASTVisitor::visit (expr);
1283 : /* should syntactically not have outer attributes, though this may
1284 : * not have worked in practice */
1285 21944 : auto &to_expr = expr.get_to_expr ();
1286 21944 : 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 21944 : }
1291 :
1292 : void
1293 640 : 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 640 : AST::DefaultASTVisitor::visit (expr);
1299 :
1300 : // ensure that they are not marked for strip
1301 640 : 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 640 : 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 640 : }
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 95546 : CfgStrip::visit (AST::ReturnExpr &expr)
1328 : {
1329 : // initial strip test based on outer attrs
1330 95546 : expand_cfg_attrs (expr.get_outer_attrs ());
1331 95546 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1332 : {
1333 0 : expr.mark_for_strip ();
1334 0 : return;
1335 : }
1336 :
1337 95546 : 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 95546 : if (expr.has_returned_expr ())
1343 : {
1344 92618 : auto &returned_expr = expr.get_returned_expr ();
1345 92618 : 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 132365 : CfgStrip::visit (AST::UnsafeBlockExpr &expr)
1358 : {
1359 : // initial strip test based on outer attrs
1360 132365 : expand_cfg_attrs (expr.get_outer_attrs ());
1361 132365 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1362 : {
1363 7 : expr.mark_for_strip ();
1364 7 : return;
1365 : }
1366 :
1367 132358 : AST::DefaultASTVisitor::visit (expr);
1368 :
1369 : // can't strip block itself, but can strip sub-expressions
1370 132358 : auto &block_expr = expr.get_block_expr ();
1371 132358 : 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 5222 : CfgStrip::visit (AST::LoopExpr &expr)
1378 : {
1379 : // initial strip test based on outer attrs
1380 5222 : expand_cfg_attrs (expr.get_outer_attrs ());
1381 5222 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1382 : {
1383 0 : expr.mark_for_strip ();
1384 0 : return;
1385 : }
1386 :
1387 5222 : AST::DefaultASTVisitor::visit (expr);
1388 :
1389 : // can't strip block itself, but can strip sub-expressions
1390 5222 : auto &loop_block = expr.get_loop_block ();
1391 5222 : 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 14828 : CfgStrip::visit (AST::WhileLoopExpr &expr)
1398 : {
1399 : // initial strip test based on outer attrs
1400 14828 : expand_cfg_attrs (expr.get_outer_attrs ());
1401 14828 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1402 : {
1403 0 : expr.mark_for_strip ();
1404 0 : return;
1405 : }
1406 :
1407 14828 : AST::DefaultASTVisitor::visit (expr);
1408 : // can't strip predicate expr itself, but can strip sub-expressions
1409 14828 : auto &predicate_expr = expr.get_predicate_expr ();
1410 14828 : 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 14828 : auto &loop_block = expr.get_loop_block ();
1417 14828 : 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 3332 : CfgStrip::visit (AST::WhileLetLoopExpr &expr)
1424 : {
1425 : // initial strip test based on outer attrs
1426 3332 : expand_cfg_attrs (expr.get_outer_attrs ());
1427 3332 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1428 : {
1429 0 : expr.mark_for_strip ();
1430 0 : return;
1431 : }
1432 :
1433 3332 : AST::DefaultASTVisitor::visit (expr);
1434 :
1435 3332 : 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 3332 : auto &scrutinee_expr = expr.get_scrutinee_expr ();
1441 3332 : 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 3332 : auto &loop_block = expr.get_loop_block ();
1448 3332 : 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 16613 : CfgStrip::visit (AST::ForLoopExpr &expr)
1455 : {
1456 : // initial strip test based on outer attrs
1457 16613 : expand_cfg_attrs (expr.get_outer_attrs ());
1458 16613 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1459 : {
1460 0 : expr.mark_for_strip ();
1461 0 : return;
1462 : }
1463 :
1464 16613 : AST::DefaultASTVisitor::visit (expr);
1465 : // strip sub-patterns of pattern
1466 16613 : auto &pattern = expr.get_pattern ();
1467 16613 : 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 16613 : auto &iterator_expr = expr.get_iterator_expr ();
1473 16613 : 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 16613 : auto &loop_block = expr.get_loop_block ();
1480 16613 : 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 209160 : 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 209160 : expand_cfg_attrs (expr.get_outer_attrs ());
1493 209160 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1494 : {
1495 0 : expr.mark_for_strip ();
1496 0 : return;
1497 : }
1498 :
1499 209160 : AST::DefaultASTVisitor::visit (expr);
1500 :
1501 : // can't strip condition expr itself, but can strip sub-expressions
1502 209160 : auto &condition_expr = expr.get_condition_expr ();
1503 209160 : 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 209160 : auto &if_block = expr.get_if_block ();
1510 209160 : 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 96718 : CfgStrip::visit (AST::IfExprConseqElse &expr)
1518 : {
1519 : // initial strip test based on outer attrs
1520 96718 : expand_cfg_attrs (expr.get_outer_attrs ());
1521 96718 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1522 : {
1523 0 : expr.mark_for_strip ();
1524 0 : return;
1525 : }
1526 :
1527 96718 : AST::DefaultASTVisitor::visit (expr);
1528 :
1529 : // can't strip condition expr itself, but can strip sub-expressions
1530 96718 : auto &condition_expr = expr.get_condition_expr ();
1531 96718 : 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 96718 : auto &if_block = expr.get_if_block ();
1538 96718 : 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 96718 : auto &else_block = expr.get_else_block ();
1545 96718 : 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 11176 : CfgStrip::visit (AST::IfLetExpr &expr)
1553 : {
1554 : // initial strip test based on outer attrs
1555 11176 : expand_cfg_attrs (expr.get_outer_attrs ());
1556 11176 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1557 : {
1558 0 : expr.mark_for_strip ();
1559 0 : return;
1560 : }
1561 :
1562 11176 : AST::DefaultASTVisitor::visit (expr);
1563 :
1564 11176 : 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 11176 : auto &value_expr = expr.get_value_expr ();
1570 11176 : 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 11176 : auto &if_block = expr.get_if_block ();
1577 11176 : 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 2950 : CfgStrip::visit (AST::IfLetExprConseqElse &expr)
1584 : {
1585 : // initial strip test based on outer attrs
1586 2950 : expand_cfg_attrs (expr.get_outer_attrs ());
1587 2950 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1588 : {
1589 0 : expr.mark_for_strip ();
1590 0 : return;
1591 : }
1592 :
1593 2950 : AST::DefaultASTVisitor::visit (expr);
1594 :
1595 2950 : 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 2950 : auto &value_expr = expr.get_value_expr ();
1601 2950 : 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 2950 : auto &if_block = expr.get_if_block ();
1608 2950 : 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 2950 : auto &else_block = expr.get_else_block ();
1615 2950 : 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 287733 : CfgStrip::visit (AST::MatchExpr &expr)
1622 : {
1623 : // initial strip test based on outer attrs
1624 287733 : expand_cfg_attrs (expr.get_outer_attrs ());
1625 287733 : 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 287733 : expand_cfg_attrs (expr.get_inner_attrs ());
1633 287733 : if (fails_cfg_with_expand (expr.get_inner_attrs ()))
1634 : {
1635 0 : expr.mark_for_strip ();
1636 0 : return;
1637 : }
1638 :
1639 287733 : AST::DefaultASTVisitor::visit (expr);
1640 :
1641 : // can't strip scrutinee expr itself, but can strip sub-expressions
1642 287733 : auto &scrutinee_expr = expr.get_scrutinee_expr ();
1643 287733 : 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 287733 : auto &match_cases = expr.get_match_cases ();
1650 2996299 : for (auto it = match_cases.begin (); it != match_cases.end ();)
1651 : {
1652 2708566 : auto &match_case = *it;
1653 :
1654 : // strip match case based on outer attributes in match arm
1655 2708566 : auto &match_arm = match_case.get_arm ();
1656 2708566 : expand_cfg_attrs (match_arm.get_outer_attrs ());
1657 2708566 : 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 2708566 : 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 2708566 : if (match_arm.has_match_arm_guard ())
1673 : {
1674 2595 : auto &guard_expr = match_arm.get_guard_expr ();
1675 2595 : 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 2708566 : auto &case_expr = match_case.get_expr ();
1683 2708566 : 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 2708566 : ++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 332860 : CfgStrip::visit (AST::TypeParam ¶m)
1737 : {
1738 : // outer attributes don't actually do anything, so ignore them
1739 :
1740 332860 : AST::DefaultASTVisitor::visit (param);
1741 :
1742 332860 : 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 332860 : }
1746 :
1747 : void
1748 61636 : CfgStrip::visit (AST::TypeBoundWhereClauseItem &item)
1749 : {
1750 : // for lifetimes shouldn't require
1751 61636 : AST::DefaultASTVisitor::visit (item);
1752 :
1753 61636 : auto &type = item.get_type ();
1754 61636 : if (type.is_marked_for_strip ())
1755 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
1756 61636 : }
1757 :
1758 : void
1759 12292 : CfgStrip::visit (AST::Module &module)
1760 : {
1761 : // strip test based on outer attrs
1762 12292 : expand_cfg_attrs (module.get_outer_attrs ());
1763 12292 : if (fails_cfg_with_expand (module.get_outer_attrs ()))
1764 : {
1765 79 : module.mark_for_strip ();
1766 79 : return;
1767 : }
1768 :
1769 12213 : if (module.get_kind () == AST::Module::UNLOADED)
1770 : {
1771 318 : module.load_items ();
1772 : }
1773 :
1774 : // strip test based on inner attrs
1775 12213 : expand_cfg_attrs (module.get_inner_attrs ());
1776 12213 : 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 12213 : maybe_strip_pointer_allow_strip (module.get_items ());
1784 : }
1785 :
1786 : void
1787 137 : CfgStrip::visit (AST::ExternCrate &extern_crate)
1788 : {
1789 : // strip test based on outer attrs
1790 137 : expand_cfg_attrs (extern_crate.get_outer_attrs ());
1791 137 : if (fails_cfg_with_expand (extern_crate.get_outer_attrs ()))
1792 : {
1793 2 : extern_crate.mark_for_strip ();
1794 2 : return;
1795 : }
1796 : }
1797 :
1798 : void
1799 31344 : CfgStrip::visit (AST::UseDeclaration &use_decl)
1800 : {
1801 : // strip test based on outer attrs
1802 31344 : expand_cfg_attrs (use_decl.get_outer_attrs ());
1803 31344 : if (fails_cfg_with_expand (use_decl.get_outer_attrs ()))
1804 : {
1805 51 : use_decl.mark_for_strip ();
1806 51 : return;
1807 : }
1808 : }
1809 :
1810 : void
1811 824982 : CfgStrip::visit (AST::Function &function)
1812 : {
1813 : // initial test based on outer attrs
1814 824982 : expand_cfg_attrs (function.get_outer_attrs ());
1815 824982 : if (fails_cfg_with_expand (function.get_outer_attrs ()))
1816 : {
1817 62 : function.mark_for_strip ();
1818 62 : return;
1819 : }
1820 :
1821 824920 : AST::DefaultASTVisitor::visit (function);
1822 :
1823 : /* strip function parameters if required - this is specifically
1824 : * allowed by spec */
1825 824920 : maybe_strip_function_params (function.get_function_params ());
1826 :
1827 824920 : if (function.has_return_type ())
1828 : {
1829 707239 : auto &return_type = function.get_return_type ();
1830 707239 : 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 824920 : if (function.has_body ())
1839 : {
1840 767305 : auto &block_expr = function.get_definition ();
1841 767305 : 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 180851 : CfgStrip::visit (AST::TypeAlias &type_alias)
1850 : {
1851 : // initial test based on outer attrs
1852 180851 : expand_cfg_attrs (type_alias.get_outer_attrs ());
1853 180851 : if (fails_cfg_with_expand (type_alias.get_outer_attrs ()))
1854 : {
1855 0 : type_alias.mark_for_strip ();
1856 0 : return;
1857 : }
1858 :
1859 180851 : AST::DefaultASTVisitor::visit (type_alias);
1860 :
1861 180851 : auto &type = type_alias.get_type_aliased ();
1862 180851 : 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 113674 : CfgStrip::visit (AST::StructStruct &struct_item)
1868 : {
1869 : // initial test based on outer attrs
1870 113674 : expand_cfg_attrs (struct_item.get_outer_attrs ());
1871 113674 : if (fails_cfg_with_expand (struct_item.get_outer_attrs ()))
1872 : {
1873 8 : struct_item.mark_for_strip ();
1874 8 : return;
1875 : }
1876 :
1877 113666 : AST::DefaultASTVisitor::visit (struct_item);
1878 :
1879 : /* strip struct fields if required - this is presumably
1880 : * allowed by spec */
1881 113666 : maybe_strip_struct_fields (struct_item.get_fields ());
1882 : }
1883 : void
1884 6464 : CfgStrip::visit (AST::TupleStruct &tuple_struct)
1885 : {
1886 : // initial test based on outer attrs
1887 6464 : expand_cfg_attrs (tuple_struct.get_outer_attrs ());
1888 6464 : if (fails_cfg_with_expand (tuple_struct.get_outer_attrs ()))
1889 : {
1890 0 : tuple_struct.mark_for_strip ();
1891 0 : return;
1892 : }
1893 :
1894 6464 : AST::DefaultASTVisitor::visit (tuple_struct);
1895 :
1896 : /* strip struct fields if required - this is presumably
1897 : * allowed by spec */
1898 6464 : maybe_strip_tuple_fields (tuple_struct.get_fields ());
1899 : }
1900 : void
1901 6624 : CfgStrip::visit (AST::EnumItem &item)
1902 : {
1903 : // initial test based on outer attrs
1904 6624 : expand_cfg_attrs (item.get_outer_attrs ());
1905 6624 : 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 4642 : CfgStrip::visit (AST::EnumItemTuple &item)
1914 : {
1915 : // initial test based on outer attrs
1916 4642 : expand_cfg_attrs (item.get_outer_attrs ());
1917 4642 : 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 4642 : maybe_strip_tuple_fields (item.get_tuple_fields ());
1926 : }
1927 :
1928 : void
1929 480 : CfgStrip::visit (AST::EnumItemStruct &item)
1930 : {
1931 : // initial test based on outer attrs
1932 480 : expand_cfg_attrs (item.get_outer_attrs ());
1933 480 : 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 480 : maybe_strip_struct_fields (item.get_struct_fields ());
1942 : }
1943 :
1944 : void
1945 1678 : CfgStrip::visit (AST::EnumItemDiscriminant &item)
1946 : {
1947 : // initial test based on outer attrs
1948 1678 : expand_cfg_attrs (item.get_outer_attrs ());
1949 1678 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
1950 : {
1951 0 : item.mark_for_strip ();
1952 0 : return;
1953 : }
1954 :
1955 1678 : 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 1678 : auto &expr = item.get_expr ();
1960 1678 : 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 2646 : CfgStrip::visit (AST::Enum &enum_item)
1967 : {
1968 : // initial test based on outer attrs
1969 2646 : expand_cfg_attrs (enum_item.get_outer_attrs ());
1970 2646 : if (fails_cfg_with_expand (enum_item.get_outer_attrs ()))
1971 : {
1972 0 : enum_item.mark_for_strip ();
1973 0 : return;
1974 : }
1975 :
1976 2646 : AST::DefaultASTVisitor::visit (enum_item);
1977 :
1978 : /* strip enum fields if required - this is presumably
1979 : * allowed by spec */
1980 2646 : maybe_strip_pointer_allow_strip (enum_item.get_variants ());
1981 : }
1982 : void
1983 310 : CfgStrip::visit (AST::Union &union_item)
1984 : {
1985 : // initial test based on outer attrs
1986 310 : expand_cfg_attrs (union_item.get_outer_attrs ());
1987 310 : if (fails_cfg_with_expand (union_item.get_outer_attrs ()))
1988 : {
1989 0 : union_item.mark_for_strip ();
1990 0 : return;
1991 : }
1992 :
1993 310 : AST::DefaultASTVisitor::visit (union_item);
1994 :
1995 : /* strip union fields if required - this is presumably
1996 : * allowed by spec */
1997 310 : maybe_strip_struct_fields (union_item.get_variants ());
1998 : }
1999 : void
2000 33778 : CfgStrip::visit (AST::ConstantItem &const_item)
2001 : {
2002 : // initial test based on outer attrs
2003 33778 : expand_cfg_attrs (const_item.get_outer_attrs ());
2004 33778 : if (fails_cfg_with_expand (const_item.get_outer_attrs ()))
2005 : {
2006 1 : const_item.mark_for_strip ();
2007 1 : return;
2008 : }
2009 :
2010 33777 : AST::DefaultASTVisitor::visit (const_item);
2011 :
2012 : // strip any sub-types
2013 33777 : auto &type = const_item.get_type ();
2014 33777 : 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 33777 : if (const_item.has_expr ())
2021 : {
2022 32297 : auto &expr = const_item.get_expr ();
2023 32297 : 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 1365 : CfgStrip::visit (AST::StaticItem &static_item)
2031 : {
2032 : // initial test based on outer attrs
2033 1365 : expand_cfg_attrs (static_item.get_outer_attrs ());
2034 1365 : if (fails_cfg_with_expand (static_item.get_outer_attrs ()))
2035 : {
2036 0 : static_item.mark_for_strip ();
2037 0 : return;
2038 : }
2039 :
2040 1365 : AST::DefaultASTVisitor::visit (static_item);
2041 :
2042 : // strip any sub-types
2043 1365 : auto &type = static_item.get_type ();
2044 :
2045 1365 : 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 1365 : auto &expr = static_item.get_expr ();
2052 1365 : 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 7010 : CfgStrip::visit (AST::TraitItemType &item)
2060 : {
2061 : // initial test based on outer attrs
2062 7010 : expand_cfg_attrs (item.get_outer_attrs ());
2063 7010 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
2064 : {
2065 0 : item.mark_for_strip ();
2066 0 : return;
2067 : }
2068 :
2069 7010 : AST::DefaultASTVisitor::visit (item);
2070 : }
2071 :
2072 : void
2073 14896 : CfgStrip::visit (AST::Trait &trait)
2074 : {
2075 : // initial strip test based on outer attrs
2076 14896 : expand_cfg_attrs (trait.get_outer_attrs ());
2077 14896 : 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 14895 : expand_cfg_attrs (trait.get_inner_attrs ());
2085 14895 : if (fails_cfg_with_expand (trait.get_inner_attrs ()))
2086 : {
2087 0 : trait.mark_for_strip ();
2088 0 : return;
2089 : }
2090 :
2091 14895 : AST::DefaultASTVisitor::visit (trait);
2092 :
2093 14895 : maybe_strip_pointer_allow_strip (trait.get_trait_items ());
2094 : }
2095 :
2096 : void
2097 13253 : CfgStrip::visit (AST::InherentImpl &impl)
2098 : {
2099 : // initial strip test based on outer attrs
2100 13253 : expand_cfg_attrs (impl.get_outer_attrs ());
2101 13253 : if (fails_cfg_with_expand (impl.get_outer_attrs ()))
2102 : {
2103 9 : impl.mark_for_strip ();
2104 9 : return;
2105 : }
2106 :
2107 : // strip test based on inner attrs
2108 13244 : expand_cfg_attrs (impl.get_inner_attrs ());
2109 13244 : if (fails_cfg_with_expand (impl.get_inner_attrs ()))
2110 : {
2111 0 : impl.mark_for_strip ();
2112 0 : return;
2113 : }
2114 :
2115 13244 : AST::DefaultASTVisitor::visit (impl);
2116 :
2117 13244 : auto &type = impl.get_type ();
2118 :
2119 13244 : if (type.is_marked_for_strip ())
2120 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2121 :
2122 13244 : maybe_strip_pointer_allow_strip (impl.get_impl_items ());
2123 : }
2124 :
2125 : void
2126 239290 : CfgStrip::visit (AST::TraitImpl &impl)
2127 : {
2128 : // initial strip test based on outer attrs
2129 239290 : expand_cfg_attrs (impl.get_outer_attrs ());
2130 239290 : 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 239279 : expand_cfg_attrs (impl.get_inner_attrs ());
2138 239279 : if (fails_cfg_with_expand (impl.get_inner_attrs ()))
2139 : {
2140 0 : impl.mark_for_strip ();
2141 0 : return;
2142 : }
2143 :
2144 239279 : AST::DefaultASTVisitor::visit (impl);
2145 :
2146 239279 : auto &type = impl.get_type ();
2147 239279 : if (type.is_marked_for_strip ())
2148 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2149 :
2150 239279 : auto &trait_path = impl.get_trait_path ();
2151 239279 : visit (trait_path);
2152 239279 : 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 239279 : maybe_strip_pointer_allow_strip (impl.get_impl_items ());
2157 : }
2158 :
2159 : void
2160 43 : CfgStrip::visit (AST::ExternalTypeItem &item)
2161 : {
2162 43 : expand_cfg_attrs (item.get_outer_attrs ());
2163 :
2164 43 : 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 43 : }
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 5597 : CfgStrip::visit (AST::ExternBlock &block)
2192 : {
2193 : // initial strip test based on outer attrs
2194 5597 : expand_cfg_attrs (block.get_outer_attrs ());
2195 5597 : 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 5597 : expand_cfg_attrs (block.get_inner_attrs ());
2203 5597 : if (fails_cfg_with_expand (block.get_inner_attrs ()))
2204 : {
2205 0 : block.mark_for_strip ();
2206 0 : return;
2207 : }
2208 :
2209 5597 : maybe_strip_pointer_allow_strip (block.get_extern_items ());
2210 : }
2211 :
2212 : void
2213 48006 : CfgStrip::visit (AST::MacroRulesDefinition &rules_def)
2214 : {
2215 : // initial strip test based on outer attrs
2216 48006 : expand_cfg_attrs (rules_def.get_outer_attrs ());
2217 48006 : if (fails_cfg_with_expand (rules_def.get_outer_attrs ()))
2218 : {
2219 4 : rules_def.mark_for_strip ();
2220 4 : return;
2221 : }
2222 : }
2223 :
2224 : void
2225 2455922 : CfgStrip::visit (AST::IdentifierPattern &pattern)
2226 : {
2227 : // can only strip sub-patterns of the inner pattern to bind
2228 2455922 : if (!pattern.has_subpattern ())
2229 : return;
2230 :
2231 1302 : AST::DefaultASTVisitor::visit (pattern);
2232 :
2233 1302 : auto &sub_pattern = pattern.get_subpattern ();
2234 1302 : 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 46 : CfgStrip::visit (AST::RangePatternBoundPath &bound)
2241 : {
2242 : // can expand path, but not strip it directly
2243 46 : auto &path = bound.get_path ();
2244 46 : visit (path);
2245 46 : if (path.is_marked_for_strip ())
2246 0 : rust_error_at (path.get_locus (), "cannot strip path in this position");
2247 46 : }
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 22598 : CfgStrip::visit (AST::ReferencePattern &pattern)
2261 : {
2262 22598 : AST::DefaultASTVisitor::visit (pattern);
2263 :
2264 22598 : auto &sub_pattern = pattern.get_referenced_pattern ();
2265 22598 : if (sub_pattern.is_marked_for_strip ())
2266 0 : rust_error_at (sub_pattern.get_locus (),
2267 : "cannot strip pattern in this position");
2268 22598 : }
2269 : void
2270 110 : CfgStrip::visit (AST::StructPatternFieldTuplePat &field)
2271 : {
2272 : // initial strip test based on outer attrs
2273 110 : expand_cfg_attrs (field.get_outer_attrs ());
2274 110 : if (fails_cfg_with_expand (field.get_outer_attrs ()))
2275 : {
2276 0 : field.mark_for_strip ();
2277 0 : return;
2278 : }
2279 :
2280 110 : AST::DefaultASTVisitor::visit (field);
2281 :
2282 : // strip sub-patterns (can't strip top-level pattern)
2283 110 : auto &sub_pattern = field.get_index_pattern ();
2284 110 : 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 3596 : CfgStrip::visit (AST::StructPatternFieldIdentPat &field)
2291 : {
2292 : // initial strip test based on outer attrs
2293 3596 : expand_cfg_attrs (field.get_outer_attrs ());
2294 3596 : if (fails_cfg_with_expand (field.get_outer_attrs ()))
2295 : {
2296 0 : field.mark_for_strip ();
2297 0 : return;
2298 : }
2299 :
2300 3596 : AST::DefaultASTVisitor::visit (field);
2301 : // strip sub-patterns (can't strip top-level pattern)
2302 3596 : auto &sub_pattern = field.get_ident_pattern ();
2303 3596 : 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 2276 : CfgStrip::visit (AST::StructPatternFieldIdent &field)
2309 : {
2310 : // initial strip test based on outer attrs
2311 2276 : expand_cfg_attrs (field.get_outer_attrs ());
2312 2276 : 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 4142 : CfgStrip::visit (AST::StructPattern &pattern)
2321 : {
2322 : // expand (but don't strip) path
2323 4142 : auto &path = pattern.get_path ();
2324 4142 : visit (path);
2325 4142 : 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 4142 : if (!pattern.has_struct_pattern_elems ())
2331 : return;
2332 :
2333 4140 : auto &elems = pattern.get_struct_pattern_elems ();
2334 :
2335 : // assuming you can strip struct pattern fields
2336 4140 : maybe_strip_pointer_allow_strip (elems.get_struct_pattern_fields ());
2337 :
2338 : // assuming you can strip the ".." part
2339 4140 : if (elems.has_rest ())
2340 : {
2341 148 : expand_cfg_attrs (elems.get_etc_outer_attrs ());
2342 148 : if (fails_cfg_with_expand (elems.get_etc_outer_attrs ()))
2343 0 : elems.strip_etc ();
2344 : }
2345 : }
2346 :
2347 : void
2348 85432 : CfgStrip::visit (AST::TupleStructItemsNoRest &tuple_items)
2349 : {
2350 85432 : AST::DefaultASTVisitor::visit (tuple_items);
2351 : // can't strip individual patterns, only sub-patterns
2352 173374 : for (auto &pattern : tuple_items.get_patterns ())
2353 : {
2354 87942 : 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 85432 : }
2360 : void
2361 818 : CfgStrip::visit (AST::TupleStructItemsHasRest &tuple_items)
2362 : {
2363 818 : AST::DefaultASTVisitor::visit (tuple_items);
2364 : // can't strip individual patterns, only sub-patterns
2365 960 : 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 900 : 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 818 : }
2380 :
2381 : void
2382 86250 : CfgStrip::visit (AST::TupleStructPattern &pattern)
2383 : {
2384 : // expand (but don't strip) path
2385 86250 : auto &path = pattern.get_path ();
2386 86250 : visit (path);
2387 86250 : if (path.is_marked_for_strip ())
2388 0 : rust_error_at (path.get_locus (), "cannot strip path in this position");
2389 :
2390 86250 : AST::DefaultASTVisitor::visit (pattern);
2391 86250 : }
2392 :
2393 : void
2394 222243 : CfgStrip::visit (AST::TuplePatternItemsNoRest &tuple_items)
2395 : {
2396 222243 : AST::DefaultASTVisitor::visit (tuple_items);
2397 :
2398 : // can't strip individual patterns, only sub-patterns
2399 720279 : for (auto &pattern : tuple_items.get_patterns ())
2400 : {
2401 498036 : 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 222243 : }
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 1544 : CfgStrip::visit (AST::SlicePattern &pattern)
2444 : {
2445 1544 : AST::DefaultASTVisitor::visit (pattern);
2446 : // can't strip individual patterns, only sub-patterns
2447 4840 : for (auto &sub_pat : pattern.get_patterns ())
2448 : {
2449 3296 : 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 1544 : }
2454 :
2455 : void
2456 4004 : CfgStrip::visit (AST::AltPattern &pattern)
2457 : {
2458 4004 : AST::DefaultASTVisitor::visit (pattern);
2459 : // can't strip individual patterns, only sub-patterns
2460 14459 : for (auto &alt : pattern.get_alts ())
2461 : {
2462 10455 : 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 4004 : }
2468 :
2469 : void
2470 532560 : CfgStrip::visit (AST::LetStmt &stmt)
2471 : {
2472 : // initial strip test based on outer attrs
2473 532560 : expand_cfg_attrs (stmt.get_outer_attrs ());
2474 532560 : if (fails_cfg_with_expand (stmt.get_outer_attrs ()))
2475 : {
2476 0 : stmt.mark_for_strip ();
2477 0 : return;
2478 : }
2479 :
2480 532560 : AST::DefaultASTVisitor::visit (stmt);
2481 : // can't strip pattern, but call for sub-patterns
2482 532560 : auto &pattern = stmt.get_pattern ();
2483 532560 : 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 532560 : if (stmt.has_type ())
2489 : {
2490 56862 : auto &type = stmt.get_type ();
2491 :
2492 56862 : 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 532560 : if (stmt.has_init_expr ())
2500 : {
2501 513944 : auto &init_expr = stmt.get_init_expr ();
2502 :
2503 513944 : 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 891540 : 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 891540 : if (stmt.is_marked_for_strip ())
2517 : return;
2518 :
2519 891540 : AST::DefaultASTVisitor::visit (stmt);
2520 : // strip if expr is to be stripped
2521 891540 : auto &expr = stmt.get_expr ();
2522 891540 : if (expr.is_marked_for_strip ())
2523 : {
2524 46 : stmt.mark_for_strip ();
2525 46 : return;
2526 : }
2527 : }
2528 :
2529 : void
2530 208064 : CfgStrip::visit (AST::TraitBound &bound)
2531 : {
2532 : // nothing in for lifetimes to strip
2533 :
2534 : // expand but don't strip type path
2535 208064 : auto &path = bound.get_type_path ();
2536 208064 : visit (path);
2537 208064 : if (path.is_marked_for_strip ())
2538 0 : rust_error_at (path.get_locus (),
2539 : "cannot strip type path in this position");
2540 208064 : }
2541 :
2542 : void
2543 746 : CfgStrip::visit (AST::ParenthesisedType &type)
2544 : {
2545 746 : AST::DefaultASTVisitor::visit (type);
2546 : // expand but don't strip inner type
2547 746 : auto &inner_type = type.get_type_in_parens ();
2548 746 : if (inner_type->is_marked_for_strip ())
2549 0 : rust_error_at (inner_type->get_locus (),
2550 : "cannot strip type in this position");
2551 746 : }
2552 :
2553 : void
2554 83657 : CfgStrip::visit (AST::TupleType &type)
2555 : {
2556 83657 : AST::DefaultASTVisitor::visit (type);
2557 : // TODO: assuming that types can't be stripped as types don't have outer
2558 : // attributes
2559 262639 : for (auto &elem_type : type.get_elems ())
2560 : {
2561 178982 : 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 83657 : }
2566 :
2567 : void
2568 179594 : CfgStrip::visit (AST::RawPointerType &type)
2569 : {
2570 179594 : AST::DefaultASTVisitor::visit (type);
2571 : // expand but don't strip type pointed to
2572 179594 : auto &pointed_type = type.get_type_pointed_to ();
2573 179594 : if (pointed_type.is_marked_for_strip ())
2574 0 : rust_error_at (pointed_type.get_locus (),
2575 : "cannot strip type in this position");
2576 179594 : }
2577 :
2578 : void
2579 757359 : CfgStrip::visit (AST::ReferenceType &type)
2580 : {
2581 757359 : AST::DefaultASTVisitor::visit (type);
2582 : // expand but don't strip type referenced
2583 757359 : auto &referenced_type = type.get_type_referenced ();
2584 757359 : if (referenced_type.is_marked_for_strip ())
2585 0 : rust_error_at (referenced_type.get_locus (),
2586 : "cannot strip type in this position");
2587 757359 : }
2588 :
2589 : void
2590 28677 : CfgStrip::visit (AST::ArrayType &type)
2591 : {
2592 28677 : AST::DefaultASTVisitor::visit (type);
2593 : // expand but don't strip type referenced
2594 28677 : auto &base_type = type.get_elem_type ();
2595 28677 : 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 28677 : auto &size_expr = type.get_size_expr ();
2601 28677 : if (size_expr.is_marked_for_strip ())
2602 0 : rust_error_at (size_expr.get_locus (),
2603 : "cannot strip expression in this position");
2604 28677 : }
2605 : void
2606 57771 : CfgStrip::visit (AST::SliceType &type)
2607 : {
2608 57771 : AST::DefaultASTVisitor::visit (type);
2609 : // expand but don't strip elem type
2610 57771 : auto &elem_type = type.get_elem_type ();
2611 57771 : if (elem_type.is_marked_for_strip ())
2612 0 : rust_error_at (elem_type.get_locus (),
2613 : "cannot strip type in this position");
2614 57771 : }
2615 :
2616 : void
2617 19206 : CfgStrip::visit (AST::BareFunctionType &type)
2618 : {
2619 : // seem to be no generics
2620 19206 : AST::DefaultASTVisitor::visit (type);
2621 :
2622 : // presumably function params can be stripped
2623 19206 : auto ¶ms = type.get_function_params ();
2624 129222 : for (auto it = params.begin (); it != params.end ();)
2625 : {
2626 110016 : auto ¶m = *it;
2627 :
2628 110016 : auto ¶m_attrs = param.get_outer_attrs ();
2629 110016 : expand_cfg_attrs (param_attrs);
2630 110016 : if (fails_cfg_with_expand (param_attrs))
2631 : {
2632 0 : it = params.erase (it);
2633 0 : continue;
2634 : }
2635 :
2636 110016 : auto &type = param.get_type ();
2637 110016 : 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 110016 : ++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 19206 : 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 18322 : auto &return_type = type.get_return_type ();
2653 18322 : 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 19206 : }
2660 :
2661 : void
2662 602952 : CfgStrip::visit (AST::SelfParam ¶m)
2663 : {
2664 602952 : AST::DefaultASTVisitor::visit (param);
2665 :
2666 602952 : if (param.has_type ())
2667 : {
2668 1088 : auto &type = param.get_type ();
2669 1088 : 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 602952 : }
2675 :
2676 : } // namespace Rust
|