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 1877865 : CfgStrip::fails_cfg_with_expand (AST::AttrVec &attrs) const
35 : {
36 1877865 : auto &session = Session::get_instance ();
37 :
38 : // TODO: maybe have something that strips cfg attributes that evaluate true?
39 1979849 : for (auto &attr : attrs)
40 : {
41 102098 : if (attr.get_path () == Values::Attributes::CFG)
42 : {
43 2117 : if (!attr.is_parsed_to_meta_item ())
44 480 : attr.parse_attr_to_meta_item ();
45 :
46 : // DEBUG
47 2117 : 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 2116 : rust_debug ("attr has been successfully parsed to meta item, "
52 : "right before cfg predicate check");
53 :
54 2117 : if (!attr.check_cfg_predicate (session))
55 : {
56 : // DEBUG
57 113 : rust_debug (
58 : "cfg predicate failed for attribute: \033[0;31m'%s'\033[0m",
59 : attr.as_string ().c_str ());
60 :
61 113 : return true;
62 : }
63 : else
64 : {
65 : // DEBUG
66 2004 : rust_debug ("cfg predicate succeeded for attribute: "
67 : "\033[0;31m'%s'\033[0m",
68 : attr.as_string ().c_str ());
69 : }
70 : }
71 99981 : else if (!expansion_cfg.should_test
72 199962 : && 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 1882561 : expand_cfg_attrs (AST::AttrVec &attrs)
83 : {
84 1882561 : auto &session = Session::get_instance ();
85 :
86 1996587 : for (std::size_t i = 0; i < attrs.size (); i++)
87 : {
88 114026 : auto &attr = attrs[i];
89 114026 : if (attr.get_path () == Values::Attributes::CFG_ATTR)
90 : {
91 17 : if (!attr.is_parsed_to_meta_item ())
92 3 : attr.parse_attr_to_meta_item ();
93 :
94 17 : 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 9 : AST::AttrVec new_attrs = attr.separate_cfg_attrs ();
101 :
102 : // remove attr from vector
103 9 : attrs.erase (attrs.begin () + i);
104 :
105 : // add new attrs to vector
106 9 : 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 9 : i--;
115 9 : }
116 : else
117 : {
118 : // Key has not been found, remove the whole attribute
119 8 : attrs.erase (attrs.begin () + i);
120 8 : 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 1882561 : attrs.shrink_to_fit ();
132 1882561 : }
133 :
134 : void
135 10802 : CfgStrip::go (AST::Crate &crate)
136 : {
137 10802 : visit (crate);
138 10802 : }
139 :
140 : void
141 10802 : CfgStrip::visit (AST::Crate &crate)
142 : {
143 : // expand crate cfg_attr attributes
144 10802 : expand_cfg_attrs (crate.inner_attrs);
145 :
146 10802 : 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 10802 : auto &items = crate.items;
154 :
155 10802 : AST::DefaultASTVisitor::visit (crate);
156 57080 : for (auto it = items.begin (); it != items.end ();)
157 : {
158 46278 : auto &item = *it;
159 46278 : if (item->is_marked_for_strip ())
160 19 : it = items.erase (it);
161 : else
162 46259 : it++;
163 : }
164 : // expand module attributes?
165 10802 : }
166 :
167 : // Visitor used to expand attributes.
168 : void
169 4785 : CfgStrip::maybe_strip_struct_fields (std::vector<AST::StructField> &fields)
170 : {
171 10587 : for (auto it = fields.begin (); it != fields.end ();)
172 : {
173 5802 : auto &field = *it;
174 :
175 5802 : auto &field_attrs = field.get_outer_attrs ();
176 5802 : expand_cfg_attrs (field_attrs);
177 5802 : if (fails_cfg_with_expand (field_attrs))
178 : {
179 1 : it = fields.erase (it);
180 1 : continue;
181 : }
182 :
183 : // expand sub-types of type, but can't strip type itself
184 5801 : auto &type = field.get_field_type ();
185 5801 : type.accept_vis (*this);
186 :
187 5801 : 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 5801 : ++it;
192 : }
193 4785 : }
194 :
195 : void
196 5764 : CfgStrip::maybe_strip_struct_expr_fields (
197 : std::vector<std::unique_ptr<AST::StructExprField>> &fields)
198 : {
199 16057 : for (auto it = fields.begin (); it != fields.end ();)
200 : {
201 10293 : auto &field = *it;
202 :
203 10293 : auto &field_attrs = field->get_outer_attrs ();
204 10293 : expand_cfg_attrs (field_attrs);
205 10293 : if (fails_cfg_with_expand (field_attrs))
206 : {
207 1 : it = fields.erase (it);
208 1 : continue;
209 : }
210 :
211 10292 : ++it;
212 : }
213 5764 : }
214 :
215 : void
216 4730 : CfgStrip::maybe_strip_tuple_fields (std::vector<AST::TupleField> &fields)
217 : {
218 12255 : for (auto it = fields.begin (); it != fields.end ();)
219 : {
220 7525 : auto &field = *it;
221 :
222 7525 : auto &field_attrs = field.get_outer_attrs ();
223 7525 : expand_cfg_attrs (field_attrs);
224 7525 : 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 7525 : auto &type = field.get_field_type ();
232 7525 : type.accept_vis (*this);
233 7525 : 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 7525 : ++it;
238 : }
239 4730 : }
240 :
241 : void
242 68564 : CfgStrip::maybe_strip_function_params (
243 : std::vector<std::unique_ptr<AST::Param>> ¶ms)
244 : {
245 153317 : for (auto it = params.begin (); it != params.end ();)
246 : {
247 84753 : if (!(*it)->is_self () && !(*it)->is_variadic ())
248 : {
249 43332 : auto param = static_cast<AST::FunctionParam *> (it->get ());
250 :
251 43332 : auto ¶m_attrs = param->get_outer_attrs ();
252 43332 : expand_cfg_attrs (param_attrs);
253 43332 : 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 43332 : auto &pattern = param->get_pattern ();
261 43332 : pattern.accept_vis (*this);
262 43332 : if (pattern.is_marked_for_strip ())
263 0 : rust_error_at (pattern.get_locus (),
264 : "cannot strip pattern in this position");
265 :
266 43332 : auto &type = param->get_type ();
267 43332 : type.accept_vis (*this);
268 :
269 43332 : 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 84753 : ++it;
275 : }
276 68564 : }
277 :
278 : void
279 20645 : 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 42028 : for (auto &arg : args.get_generic_args ())
286 : {
287 21383 : switch (arg.get_kind ())
288 : {
289 9435 : case AST::GenericArg::Kind::Type:
290 9435 : {
291 9435 : auto &type = arg.get_type ();
292 9435 : type.accept_vis (*this);
293 :
294 9435 : 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 400 : case AST::GenericArg::Kind::Const:
300 400 : {
301 400 : auto &expr = arg.get_expression ();
302 400 : expr.accept_vis (*this);
303 :
304 400 : 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 20977 : for (auto &binding : args.get_binding_args ())
322 : {
323 332 : auto &type = binding.get_type ();
324 332 : type.accept_vis (*this);
325 :
326 332 : if (type.is_marked_for_strip ())
327 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
328 : }
329 20645 : }
330 :
331 : void
332 1785 : CfgStrip::maybe_strip_qualified_path_type (AST::QualifiedPathType &path_type)
333 : {
334 1785 : auto &type = path_type.get_type ();
335 1785 : type.accept_vis (*this);
336 :
337 1785 : if (type.is_marked_for_strip ())
338 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
339 :
340 1785 : if (path_type.has_as_clause ())
341 : {
342 1595 : auto &type_path = path_type.get_as_type_path ();
343 1595 : visit (type_path);
344 1595 : 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 1785 : }
349 :
350 : void
351 250 : CfgStrip::CfgStrip::maybe_strip_closure_params (
352 : std::vector<AST::ClosureParam> ¶ms)
353 : {
354 500 : for (auto it = params.begin (); it != params.end ();)
355 : {
356 250 : auto ¶m = *it;
357 :
358 250 : auto ¶m_attrs = param.get_outer_attrs ();
359 250 : expand_cfg_attrs (param_attrs);
360 250 : if (fails_cfg_with_expand (param_attrs))
361 : {
362 0 : it = params.erase (it);
363 0 : continue;
364 : }
365 :
366 250 : auto &pattern = param.get_pattern ();
367 250 : pattern.accept_vis (*this);
368 250 : if (pattern.is_marked_for_strip ())
369 0 : rust_error_at (pattern.get_locus (),
370 : "cannot strip pattern in this position");
371 :
372 250 : if (param.has_type_given ())
373 : {
374 232 : auto &type = param.get_type ();
375 232 : type.accept_vis (*this);
376 :
377 232 : 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 250 : ++it;
384 : }
385 250 : }
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 208436 : CfgStrip::visit (AST::IdentifierExpr &ident_expr)
397 : {
398 : // strip test based on outer attrs
399 208436 : AST::DefaultASTVisitor::visit (ident_expr);
400 208436 : expand_cfg_attrs (ident_expr.get_outer_attrs ());
401 208436 : 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 4603 : CfgStrip::visit (AST::MacroInvocation ¯o_invoc)
410 : {
411 : // initial strip test based on outer attrs
412 4603 : expand_cfg_attrs (macro_invoc.get_outer_attrs ());
413 4603 : if (fails_cfg_with_expand (macro_invoc.get_outer_attrs ()))
414 : {
415 0 : macro_invoc.mark_for_strip ();
416 0 : 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 172057 : CfgStrip::visit (AST::PathInExpression &path)
428 : {
429 : // initial strip test based on outer attrs
430 172057 : expand_cfg_attrs (path.get_outer_attrs ());
431 172057 : if (fails_cfg_with_expand (path.get_outer_attrs ()))
432 : {
433 0 : path.mark_for_strip ();
434 0 : return;
435 : }
436 :
437 172057 : if (!path.is_lang_item ())
438 : {
439 405850 : for (auto &segment : path.get_segments ())
440 : {
441 468582 : if (segment.has_generic_args ())
442 7105 : maybe_strip_generic_args (segment.get_generic_args ());
443 : }
444 : }
445 : }
446 :
447 : void
448 13456 : CfgStrip::visit (AST::TypePathSegmentGeneric &segment)
449 : {
450 : // TODO: strip inside generic args
451 :
452 13456 : if (!segment.has_generic_args ())
453 : return;
454 :
455 13452 : maybe_strip_generic_args (segment.get_generic_args ());
456 : }
457 : void
458 78 : CfgStrip::visit (AST::TypePathSegmentFunction &segment)
459 : {
460 78 : AST::DefaultASTVisitor::visit (segment);
461 78 : auto &type_path_function = segment.get_type_path_function ();
462 :
463 160 : for (auto &type : type_path_function.get_params ())
464 : {
465 82 : if (type->is_marked_for_strip ())
466 0 : rust_error_at (type->get_locus (),
467 : "cannot strip type in this position");
468 : }
469 :
470 78 : if (type_path_function.has_return_type ())
471 : {
472 74 : auto &return_type = type_path_function.get_return_type ();
473 :
474 74 : 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 78 : }
479 :
480 : void
481 532 : CfgStrip::visit (AST::QualifiedPathInExpression &path)
482 : {
483 : // initial strip test based on outer attrs
484 532 : AST::DefaultASTVisitor::visit (path);
485 :
486 532 : expand_cfg_attrs (path.get_outer_attrs ());
487 532 : if (fails_cfg_with_expand (path.get_outer_attrs ()))
488 : {
489 0 : path.mark_for_strip ();
490 0 : return;
491 : }
492 :
493 532 : maybe_strip_qualified_path_type (path.get_qualified_path_type ());
494 :
495 1064 : for (auto &segment : path.get_segments ())
496 : {
497 1064 : if (segment.has_generic_args ())
498 0 : maybe_strip_generic_args (segment.get_generic_args ());
499 : }
500 : }
501 :
502 : void
503 1253 : CfgStrip::visit (AST::QualifiedPathInType &path)
504 : {
505 1253 : maybe_strip_qualified_path_type (path.get_qualified_path_type ());
506 :
507 : // this shouldn't strip any segments, but can strip inside them
508 1253 : AST::DefaultASTVisitor::visit (path);
509 1253 : }
510 :
511 : void
512 701148 : CfgStrip::visit (AST::LiteralExpr &expr)
513 : {
514 : // initial strip test based on outer attrs
515 701148 : expand_cfg_attrs (expr.get_outer_attrs ());
516 701148 : 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 17526 : CfgStrip::visit (AST::BorrowExpr &expr)
525 : {
526 17526 : AST::DefaultASTVisitor::visit (expr);
527 : // initial strip test based on outer attrs
528 17526 : expand_cfg_attrs (expr.get_outer_attrs ());
529 17526 : 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 17526 : auto &borrowed_expr = expr.get_borrowed_expr ();
539 17526 : 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 21384 : CfgStrip::visit (AST::DereferenceExpr &expr)
546 : {
547 : // initial strip test based on outer attrs
548 21384 : expand_cfg_attrs (expr.get_outer_attrs ());
549 21384 : 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 21384 : auto &dereferenced_expr = expr.get_dereferenced_expr ();
559 21384 : dereferenced_expr.accept_vis (*this);
560 21384 : 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 4 : CfgStrip::visit (AST::ErrorPropagationExpr &expr)
567 : {
568 4 : AST::DefaultASTVisitor::visit (expr);
569 :
570 : // initial strip test based on outer attrs
571 4 : expand_cfg_attrs (expr.get_outer_attrs ());
572 4 : 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 4 : auto &propagating_expr = expr.get_propagating_expr ();
582 4 : 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 3891 : CfgStrip::visit (AST::NegationExpr &expr)
589 : {
590 3891 : AST::DefaultASTVisitor::visit (expr);
591 : // initial strip test based on outer attrs
592 3891 : expand_cfg_attrs (expr.get_outer_attrs ());
593 3891 : 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 3891 : auto &negated_expr = expr.get_negated_expr ();
603 3891 : 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 540431 : CfgStrip::visit (AST::ArithmeticOrLogicalExpr &expr)
610 : {
611 540431 : 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 540431 : 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 540431 : 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 540431 : }
626 :
627 : void
628 17047 : 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 17047 : AST::DefaultASTVisitor::visit (expr);
633 :
634 : // ensure that they are not marked for strip
635 17047 : 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 17047 : 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 17047 : }
645 :
646 : void
647 1580 : 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 1580 : AST::DefaultASTVisitor::visit (expr);
652 :
653 : // ensure that they are not marked for strip
654 1580 : 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 1580 : 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 1580 : }
664 :
665 : void
666 52302 : 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 52302 : AST::DefaultASTVisitor::visit (expr);
671 :
672 52302 : auto &casted_expr = expr.get_casted_expr ();
673 : // ensure that they are not marked for strip
674 52302 : 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 52302 : auto &type = expr.get_type_to_cast_to ();
681 52302 : if (type.is_marked_for_strip ())
682 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
683 52302 : }
684 : void
685 15868 : CfgStrip::visit (AST::AssignmentExpr &expr)
686 : {
687 15868 : expand_cfg_attrs (expr.get_outer_attrs ());
688 15868 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
689 : {
690 14 : expr.mark_for_strip ();
691 14 : return;
692 : }
693 15854 : AST::DefaultASTVisitor::visit (expr);
694 :
695 : // ensure that they are not marked for strip
696 15854 : 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 15854 : 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 6342 : 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 6342 : AST::DefaultASTVisitor::visit (expr);
712 :
713 : // ensure that they are not marked for strip
714 6342 : 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 6342 : 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 6342 : }
724 : void
725 2147 : CfgStrip::visit (AST::GroupedExpr &expr)
726 : {
727 : // initial strip test based on outer attrs
728 2147 : expand_cfg_attrs (expr.get_outer_attrs ());
729 2147 : 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 2147 : expand_cfg_attrs (expr.get_inner_attrs ());
738 2147 : 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 2147 : AST::DefaultASTVisitor::visit (expr);
748 :
749 2147 : auto &inner_expr = expr.get_expr_in_parens ();
750 2147 : 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 1165 : CfgStrip::visit (AST::ArrayElemsValues &elems)
757 : {
758 : /* apparently outer attributes are allowed in "elements of array
759 : * expressions" according to spec */
760 1165 : maybe_strip_pointer_allow_strip (elems.get_values ());
761 1165 : }
762 : void
763 466 : 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 466 : AST::DefaultASTVisitor::visit (elems);
770 :
771 : // only intend stripping for internal sub-expressions
772 466 : auto &copied_expr = elems.get_elem_to_copy ();
773 466 : 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 466 : auto ©_count = elems.get_num_copies ();
779 466 : copy_count.accept_vis (*this);
780 466 : 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 466 : }
785 : void
786 1631 : CfgStrip::visit (AST::ArrayExpr &expr)
787 : {
788 : // initial strip test based on outer attrs
789 1631 : expand_cfg_attrs (expr.get_outer_attrs ());
790 1631 : 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 1631 : expand_cfg_attrs (expr.get_inner_attrs ());
799 1631 : 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 1631 : AST::DefaultASTVisitor::visit (expr);
808 : }
809 :
810 : void
811 1405 : 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 1405 : expand_cfg_attrs (expr.get_outer_attrs ());
818 1405 : 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 1405 : AST::DefaultASTVisitor::visit (expr);
828 :
829 1405 : const auto &array_expr = expr.get_array_expr ();
830 1405 : 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 1404 : const auto &index_expr = expr.get_index_expr ();
840 1404 : 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 2641 : 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 2641 : expand_cfg_attrs (expr.get_outer_attrs ());
853 2641 : 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 2641 : expand_cfg_attrs (expr.get_inner_attrs ());
862 2641 : 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 2641 : maybe_strip_pointer_allow_strip (expr.get_tuple_elems ());
871 : }
872 : void
873 5628 : CfgStrip::visit (AST::TupleIndexExpr &expr)
874 : {
875 : // initial strip test based on outer attrs
876 5628 : expand_cfg_attrs (expr.get_outer_attrs ());
877 5628 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
878 : {
879 0 : expr.mark_for_strip ();
880 0 : return;
881 : }
882 :
883 5628 : 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 5628 : auto &tuple_expr = expr.get_tuple_expr ();
888 5628 : 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 328 : CfgStrip::visit (AST::StructExprStruct &expr)
896 : {
897 : // initial strip test based on outer attrs
898 328 : expand_cfg_attrs (expr.get_outer_attrs ());
899 328 : 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 328 : expand_cfg_attrs (expr.get_inner_attrs ());
908 328 : 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 328 : auto &struct_name = expr.get_struct_name ();
916 328 : visit (struct_name);
917 328 : 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 9451 : CfgStrip::visit (AST::StructExprFieldIdentifierValue &field)
924 : {
925 : /* as no attrs possible (at moment, at least), only sub-expression
926 : * stripping is possible */
927 9451 : AST::DefaultASTVisitor::visit (field);
928 :
929 9451 : auto &value = field.get_value ();
930 9451 : 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 9451 : }
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 5764 : CfgStrip::visit (AST::StructExprStructFields &expr)
950 : {
951 : // initial strip test based on outer attrs
952 5764 : expand_cfg_attrs (expr.get_outer_attrs ());
953 5764 : 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 5764 : expand_cfg_attrs (expr.get_inner_attrs ());
962 5764 : 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 5764 : auto &struct_name = expr.get_struct_name ();
970 5764 : visit (struct_name);
971 5764 : 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 5764 : 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 5764 : if (expr.has_struct_base ())
984 : {
985 252 : auto &base_struct_expr = expr.get_struct_base ().get_base_struct ();
986 252 : base_struct_expr.accept_vis (*this);
987 252 : 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 5764 : 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 79536 : CfgStrip::visit (AST::CallExpr &expr)
1035 : {
1036 : // initial strip test based on outer attrs
1037 79536 : expand_cfg_attrs (expr.get_outer_attrs ());
1038 79536 : 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 79535 : AST::DefaultASTVisitor::visit (expr);
1048 :
1049 79535 : auto &function = expr.get_function_expr ();
1050 79535 : 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 79534 : maybe_strip_pointer_allow_strip (expr.get_params ());
1064 : }
1065 : void
1066 20153 : CfgStrip::visit (AST::MethodCallExpr &expr)
1067 : {
1068 : // initial strip test based on outer attrs
1069 20153 : expand_cfg_attrs (expr.get_outer_attrs ());
1070 20153 : 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 20153 : AST::DefaultASTVisitor::visit (expr);
1080 :
1081 20153 : auto &receiver = expr.get_receiver_expr ();
1082 20153 : 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 20153 : auto &method_name = expr.get_method_name ();
1088 20153 : if (method_name.has_generic_args ())
1089 88 : 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 20153 : maybe_strip_pointer_allow_strip (expr.get_params ());
1094 : }
1095 : void
1096 39961 : CfgStrip::visit (AST::FieldAccessExpr &expr)
1097 : {
1098 : // initial strip test based on outer attrs
1099 39961 : expand_cfg_attrs (expr.get_outer_attrs ());
1100 39961 : 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 39961 : AST::DefaultASTVisitor::visit (expr);
1110 :
1111 39961 : auto &receiver = expr.get_receiver_expr ();
1112 39961 : 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 130 : CfgStrip::visit (AST::ClosureExprInner &expr)
1119 : {
1120 : // initial strip test based on outer attrs
1121 130 : expand_cfg_attrs (expr.get_outer_attrs ());
1122 130 : 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 130 : maybe_strip_closure_params (expr.get_params ());
1131 :
1132 130 : AST::DefaultASTVisitor::visit (expr);
1133 :
1134 : // can't strip expression itself, but can strip sub-expressions
1135 130 : auto &definition_expr = expr.get_definition_expr ();
1136 130 : 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 94781 : CfgStrip::visit (AST::BlockExpr &expr)
1144 : {
1145 : // initial strip test based on outer attrs
1146 94781 : expand_cfg_attrs (expr.get_outer_attrs ());
1147 94781 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1148 : {
1149 54 : expr.mark_for_strip ();
1150 54 : 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 94727 : expand_cfg_attrs (expr.get_inner_attrs ());
1156 94727 : if (fails_cfg_with_expand (expr.get_inner_attrs ()))
1157 : {
1158 0 : expr.mark_for_strip ();
1159 0 : return;
1160 : }
1161 :
1162 94727 : maybe_strip_pointer_allow_strip (expr.get_statements ());
1163 :
1164 94727 : AST::DefaultASTVisitor::visit (expr);
1165 :
1166 : // strip tail expression if exists - can actually fully remove it
1167 94727 : if (expr.has_tail_expr ())
1168 : {
1169 71435 : auto &tail_expr = expr.get_tail_expr ();
1170 :
1171 71435 : if (tail_expr.is_marked_for_strip ())
1172 57 : expr.strip_tail_expr ();
1173 : }
1174 : }
1175 :
1176 : void
1177 120 : CfgStrip::visit (AST::ClosureExprInnerTyped &expr)
1178 : {
1179 : // initial strip test based on outer attrs
1180 120 : expand_cfg_attrs (expr.get_outer_attrs ());
1181 120 : 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 120 : maybe_strip_closure_params (expr.get_params ());
1190 :
1191 120 : AST::DefaultASTVisitor::visit (expr);
1192 :
1193 : // can't strip return type, but can strip sub-types
1194 120 : auto &type = expr.get_return_type ();
1195 :
1196 120 : 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 120 : auto &definition_block = expr.get_definition_expr ();
1201 120 : definition_block.accept_vis (*this);
1202 120 : 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 154 : CfgStrip::visit (AST::ContinueExpr &expr)
1209 : {
1210 : // initial strip test based on outer attrs
1211 154 : expand_cfg_attrs (expr.get_outer_attrs ());
1212 154 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1213 : {
1214 0 : expr.mark_for_strip ();
1215 0 : return;
1216 : }
1217 : }
1218 : void
1219 660 : CfgStrip::visit (AST::BreakExpr &expr)
1220 : {
1221 : // initial strip test based on outer attrs
1222 660 : expand_cfg_attrs (expr.get_outer_attrs ());
1223 660 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1224 : {
1225 0 : expr.mark_for_strip ();
1226 0 : return;
1227 : }
1228 660 : 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 660 : if (expr.has_break_expr ())
1234 : {
1235 280 : auto &break_expr = expr.get_break_expr_unchecked ();
1236 :
1237 280 : 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 356 : 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 356 : AST::DefaultASTVisitor::visit (expr);
1249 :
1250 : // ensure that they are not marked for strip
1251 356 : 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 356 : 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 356 : }
1261 : void
1262 28 : 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 28 : AST::DefaultASTVisitor::visit (expr);
1268 : /* should have no possibility for outer attrs as would be parsed
1269 : * with outer expr */
1270 28 : auto &from_expr = expr.get_from_expr ();
1271 28 : 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 28 : }
1276 : void
1277 28 : 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 28 : AST::DefaultASTVisitor::visit (expr);
1283 : /* should syntactically not have outer attributes, though this may
1284 : * not have worked in practice */
1285 28 : auto &to_expr = expr.get_to_expr ();
1286 28 : 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 28 : }
1291 :
1292 : void
1293 28 : 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 28 : AST::DefaultASTVisitor::visit (expr);
1299 :
1300 : // ensure that they are not marked for strip
1301 28 : 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 28 : 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 28 : }
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 3132 : CfgStrip::visit (AST::ReturnExpr &expr)
1328 : {
1329 : // initial strip test based on outer attrs
1330 3132 : expand_cfg_attrs (expr.get_outer_attrs ());
1331 3132 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1332 : {
1333 0 : expr.mark_for_strip ();
1334 0 : return;
1335 : }
1336 :
1337 3132 : 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 3132 : if (expr.has_returned_expr ())
1343 : {
1344 2774 : auto &returned_expr = expr.get_returned_expr ();
1345 2774 : 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 16780 : CfgStrip::visit (AST::UnsafeBlockExpr &expr)
1358 : {
1359 : // initial strip test based on outer attrs
1360 16780 : expand_cfg_attrs (expr.get_outer_attrs ());
1361 16780 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1362 : {
1363 7 : expr.mark_for_strip ();
1364 7 : return;
1365 : }
1366 :
1367 16773 : AST::DefaultASTVisitor::visit (expr);
1368 :
1369 : // can't strip block itself, but can strip sub-expressions
1370 16773 : auto &block_expr = expr.get_block_expr ();
1371 16773 : 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 330 : CfgStrip::visit (AST::LoopExpr &expr)
1378 : {
1379 : // initial strip test based on outer attrs
1380 330 : expand_cfg_attrs (expr.get_outer_attrs ());
1381 330 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1382 : {
1383 0 : expr.mark_for_strip ();
1384 0 : return;
1385 : }
1386 :
1387 330 : AST::DefaultASTVisitor::visit (expr);
1388 :
1389 : // can't strip block itself, but can strip sub-expressions
1390 330 : auto &loop_block = expr.get_loop_block ();
1391 330 : 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 474 : CfgStrip::visit (AST::WhileLoopExpr &expr)
1398 : {
1399 : // initial strip test based on outer attrs
1400 474 : expand_cfg_attrs (expr.get_outer_attrs ());
1401 474 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1402 : {
1403 0 : expr.mark_for_strip ();
1404 0 : return;
1405 : }
1406 :
1407 474 : AST::DefaultASTVisitor::visit (expr);
1408 : // can't strip predicate expr itself, but can strip sub-expressions
1409 474 : auto &predicate_expr = expr.get_predicate_expr ();
1410 474 : 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 474 : auto &loop_block = expr.get_loop_block ();
1417 474 : 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 6 : CfgStrip::visit (AST::WhileLetLoopExpr &expr)
1424 : {
1425 : // initial strip test based on outer attrs
1426 6 : expand_cfg_attrs (expr.get_outer_attrs ());
1427 6 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1428 : {
1429 0 : expr.mark_for_strip ();
1430 0 : return;
1431 : }
1432 :
1433 6 : AST::DefaultASTVisitor::visit (expr);
1434 :
1435 6 : 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 6 : auto &scrutinee_expr = expr.get_scrutinee_expr ();
1441 6 : 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 6 : auto &loop_block = expr.get_loop_block ();
1448 6 : 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 122 : CfgStrip::visit (AST::ForLoopExpr &expr)
1455 : {
1456 : // initial strip test based on outer attrs
1457 122 : expand_cfg_attrs (expr.get_outer_attrs ());
1458 122 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1459 : {
1460 0 : expr.mark_for_strip ();
1461 0 : return;
1462 : }
1463 :
1464 122 : AST::DefaultASTVisitor::visit (expr);
1465 : // strip sub-patterns of pattern
1466 122 : auto &pattern = expr.get_pattern ();
1467 122 : 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 122 : auto &iterator_expr = expr.get_iterator_expr ();
1473 122 : 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 122 : auto &loop_block = expr.get_loop_block ();
1480 122 : 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 11974 : 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 11974 : expand_cfg_attrs (expr.get_outer_attrs ());
1493 11974 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1494 : {
1495 0 : expr.mark_for_strip ();
1496 0 : return;
1497 : }
1498 :
1499 11974 : AST::DefaultASTVisitor::visit (expr);
1500 :
1501 : // can't strip condition expr itself, but can strip sub-expressions
1502 11974 : auto &condition_expr = expr.get_condition_expr ();
1503 11974 : 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 11974 : auto &if_block = expr.get_if_block ();
1510 11974 : 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 5924 : CfgStrip::visit (AST::IfExprConseqElse &expr)
1518 : {
1519 : // initial strip test based on outer attrs
1520 5924 : expand_cfg_attrs (expr.get_outer_attrs ());
1521 5924 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1522 : {
1523 0 : expr.mark_for_strip ();
1524 0 : return;
1525 : }
1526 :
1527 5924 : AST::DefaultASTVisitor::visit (expr);
1528 :
1529 : // can't strip condition expr itself, but can strip sub-expressions
1530 5924 : auto &condition_expr = expr.get_condition_expr ();
1531 5924 : 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 5924 : auto &if_block = expr.get_if_block ();
1538 5924 : 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 5924 : auto &else_block = expr.get_else_block ();
1545 5924 : 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 102 : CfgStrip::visit (AST::IfLetExpr &expr)
1553 : {
1554 : // initial strip test based on outer attrs
1555 102 : expand_cfg_attrs (expr.get_outer_attrs ());
1556 102 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1557 : {
1558 0 : expr.mark_for_strip ();
1559 0 : return;
1560 : }
1561 :
1562 102 : AST::DefaultASTVisitor::visit (expr);
1563 :
1564 102 : 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 102 : auto &value_expr = expr.get_value_expr ();
1570 102 : 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 102 : auto &if_block = expr.get_if_block ();
1577 102 : 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 30 : CfgStrip::visit (AST::IfLetExprConseqElse &expr)
1584 : {
1585 : // initial strip test based on outer attrs
1586 30 : expand_cfg_attrs (expr.get_outer_attrs ());
1587 30 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1588 : {
1589 0 : expr.mark_for_strip ();
1590 0 : return;
1591 : }
1592 :
1593 30 : AST::DefaultASTVisitor::visit (expr);
1594 :
1595 30 : 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 30 : auto &value_expr = expr.get_value_expr ();
1601 30 : 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 30 : auto &if_block = expr.get_if_block ();
1608 30 : 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 30 : auto &else_block = expr.get_else_block ();
1615 30 : 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 4446 : CfgStrip::visit (AST::MatchExpr &expr)
1622 : {
1623 : // initial strip test based on outer attrs
1624 4446 : expand_cfg_attrs (expr.get_outer_attrs ());
1625 4446 : 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 4446 : expand_cfg_attrs (expr.get_inner_attrs ());
1633 4446 : if (fails_cfg_with_expand (expr.get_inner_attrs ()))
1634 : {
1635 0 : expr.mark_for_strip ();
1636 0 : return;
1637 : }
1638 :
1639 4446 : AST::DefaultASTVisitor::visit (expr);
1640 :
1641 : // can't strip scrutinee expr itself, but can strip sub-expressions
1642 4446 : auto &scrutinee_expr = expr.get_scrutinee_expr ();
1643 4446 : 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 4446 : auto &match_cases = expr.get_match_cases ();
1650 14678 : for (auto it = match_cases.begin (); it != match_cases.end ();)
1651 : {
1652 10232 : auto &match_case = *it;
1653 :
1654 : // strip match case based on outer attributes in match arm
1655 10232 : auto &match_arm = match_case.get_arm ();
1656 10232 : expand_cfg_attrs (match_arm.get_outer_attrs ());
1657 10232 : 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 10232 : 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 10232 : if (match_arm.has_match_arm_guard ())
1673 : {
1674 2 : auto &guard_expr = match_arm.get_guard_expr ();
1675 2 : 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 10232 : auto &case_expr = match_case.get_expr ();
1683 10232 : 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 10232 : ++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 20639 : CfgStrip::visit (AST::TypeParam ¶m)
1737 : {
1738 : // outer attributes don't actually do anything, so ignore them
1739 :
1740 20639 : AST::DefaultASTVisitor::visit (param);
1741 :
1742 20639 : 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 20639 : }
1746 :
1747 : void
1748 1259 : CfgStrip::visit (AST::TypeBoundWhereClauseItem &item)
1749 : {
1750 : // for lifetimes shouldn't require
1751 1259 : AST::DefaultASTVisitor::visit (item);
1752 :
1753 1259 : auto &type = item.get_type ();
1754 1259 : if (type.is_marked_for_strip ())
1755 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
1756 1259 : }
1757 :
1758 : void
1759 3267 : CfgStrip::visit (AST::Module &module)
1760 : {
1761 : // strip test based on outer attrs
1762 3267 : expand_cfg_attrs (module.get_outer_attrs ());
1763 3267 : if (fails_cfg_with_expand (module.get_outer_attrs ()))
1764 : {
1765 0 : module.mark_for_strip ();
1766 0 : return;
1767 : }
1768 :
1769 3267 : if (module.get_kind () == AST::Module::UNLOADED)
1770 : {
1771 82 : module.load_items ();
1772 : }
1773 :
1774 : // strip test based on inner attrs
1775 3267 : expand_cfg_attrs (module.get_inner_attrs ());
1776 3267 : 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 3267 : maybe_strip_pointer_allow_strip (module.get_items ());
1784 : }
1785 :
1786 : void
1787 51 : CfgStrip::visit (AST::ExternCrate &extern_crate)
1788 : {
1789 : // strip test based on outer attrs
1790 51 : expand_cfg_attrs (extern_crate.get_outer_attrs ());
1791 51 : if (fails_cfg_with_expand (extern_crate.get_outer_attrs ()))
1792 : {
1793 0 : extern_crate.mark_for_strip ();
1794 0 : return;
1795 : }
1796 :
1797 51 : if (!extern_crate.references_self ())
1798 : {
1799 51 : Session &session = Session::get_instance ();
1800 51 : session.load_extern_crate (extern_crate.get_referenced_crate (),
1801 : extern_crate.get_locus ());
1802 : }
1803 : }
1804 :
1805 : void
1806 1860 : CfgStrip::visit (AST::UseDeclaration &use_decl)
1807 : {
1808 : // strip test based on outer attrs
1809 1860 : expand_cfg_attrs (use_decl.get_outer_attrs ());
1810 1860 : if (fails_cfg_with_expand (use_decl.get_outer_attrs ()))
1811 : {
1812 0 : use_decl.mark_for_strip ();
1813 0 : return;
1814 : }
1815 : }
1816 :
1817 : void
1818 68595 : CfgStrip::visit (AST::Function &function)
1819 : {
1820 : // initial test based on outer attrs
1821 68595 : expand_cfg_attrs (function.get_outer_attrs ());
1822 68595 : if (fails_cfg_with_expand (function.get_outer_attrs ()))
1823 : {
1824 31 : function.mark_for_strip ();
1825 31 : return;
1826 : }
1827 :
1828 68564 : AST::DefaultASTVisitor::visit (function);
1829 :
1830 : /* strip function parameters if required - this is specifically
1831 : * allowed by spec */
1832 68564 : maybe_strip_function_params (function.get_function_params ());
1833 :
1834 68564 : if (function.has_return_type ())
1835 : {
1836 54479 : auto &return_type = function.get_return_type ();
1837 54479 : if (return_type.is_marked_for_strip ())
1838 0 : rust_error_at (return_type.get_locus (),
1839 : "cannot strip type in this position");
1840 : }
1841 :
1842 : /* body should always exist - if error state, should have returned
1843 : * before now */
1844 : // can't strip block itself, but can strip sub-expressions
1845 68564 : if (function.has_body ())
1846 : {
1847 53863 : auto &block_expr = function.get_definition ();
1848 53863 : if (block_expr.value ()->is_marked_for_strip ())
1849 0 : rust_error_at (block_expr.value ()->get_locus (),
1850 : "cannot strip block expression in this position - outer "
1851 : "attributes not allowed");
1852 : }
1853 : }
1854 :
1855 : void
1856 6244 : CfgStrip::visit (AST::TypeAlias &type_alias)
1857 : {
1858 : // initial test based on outer attrs
1859 6244 : expand_cfg_attrs (type_alias.get_outer_attrs ());
1860 6244 : if (fails_cfg_with_expand (type_alias.get_outer_attrs ()))
1861 : {
1862 0 : type_alias.mark_for_strip ();
1863 0 : return;
1864 : }
1865 :
1866 6244 : AST::DefaultASTVisitor::visit (type_alias);
1867 :
1868 6244 : auto &type = type_alias.get_type_aliased ();
1869 6244 : if (type.is_marked_for_strip ())
1870 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
1871 : }
1872 :
1873 : void
1874 4117 : CfgStrip::visit (AST::StructStruct &struct_item)
1875 : {
1876 : // initial test based on outer attrs
1877 4117 : expand_cfg_attrs (struct_item.get_outer_attrs ());
1878 4117 : if (fails_cfg_with_expand (struct_item.get_outer_attrs ()))
1879 : {
1880 2 : struct_item.mark_for_strip ();
1881 2 : return;
1882 : }
1883 :
1884 4115 : AST::DefaultASTVisitor::visit (struct_item);
1885 :
1886 : /* strip struct fields if required - this is presumably
1887 : * allowed by spec */
1888 4115 : maybe_strip_struct_fields (struct_item.get_fields ());
1889 : }
1890 : void
1891 2464 : CfgStrip::visit (AST::TupleStruct &tuple_struct)
1892 : {
1893 : // initial test based on outer attrs
1894 2464 : expand_cfg_attrs (tuple_struct.get_outer_attrs ());
1895 2464 : if (fails_cfg_with_expand (tuple_struct.get_outer_attrs ()))
1896 : {
1897 0 : tuple_struct.mark_for_strip ();
1898 0 : return;
1899 : }
1900 :
1901 2464 : AST::DefaultASTVisitor::visit (tuple_struct);
1902 :
1903 : /* strip struct fields if required - this is presumably
1904 : * allowed by spec */
1905 2464 : maybe_strip_tuple_fields (tuple_struct.get_fields ());
1906 : }
1907 : void
1908 2152 : CfgStrip::visit (AST::EnumItem &item)
1909 : {
1910 : // initial test based on outer attrs
1911 2152 : expand_cfg_attrs (item.get_outer_attrs ());
1912 2152 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
1913 : {
1914 0 : item.mark_for_strip ();
1915 0 : return;
1916 : }
1917 : }
1918 :
1919 : void
1920 2266 : CfgStrip::visit (AST::EnumItemTuple &item)
1921 : {
1922 : // initial test based on outer attrs
1923 2266 : expand_cfg_attrs (item.get_outer_attrs ());
1924 2266 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
1925 : {
1926 0 : item.mark_for_strip ();
1927 0 : return;
1928 : }
1929 :
1930 : /* strip item fields if required - this is presumably
1931 : * allowed by spec */
1932 2266 : maybe_strip_tuple_fields (item.get_tuple_fields ());
1933 : }
1934 :
1935 : void
1936 440 : CfgStrip::visit (AST::EnumItemStruct &item)
1937 : {
1938 : // initial test based on outer attrs
1939 440 : expand_cfg_attrs (item.get_outer_attrs ());
1940 440 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
1941 : {
1942 0 : item.mark_for_strip ();
1943 0 : return;
1944 : }
1945 :
1946 : /* strip item fields if required - this is presumably
1947 : * allowed by spec */
1948 440 : maybe_strip_struct_fields (item.get_struct_fields ());
1949 : }
1950 :
1951 : void
1952 1410 : CfgStrip::visit (AST::EnumItemDiscriminant &item)
1953 : {
1954 : // initial test based on outer attrs
1955 1410 : expand_cfg_attrs (item.get_outer_attrs ());
1956 1410 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
1957 : {
1958 0 : item.mark_for_strip ();
1959 0 : return;
1960 : }
1961 :
1962 1410 : AST::DefaultASTVisitor::visit (item);
1963 : /* strip any internal sub-expressions - expression itself isn't
1964 : * allowed to have external attributes in this position so can't be
1965 : * stripped. */
1966 1410 : auto &expr = item.get_expr ();
1967 1410 : if (expr.is_marked_for_strip ())
1968 0 : rust_error_at (expr.get_locus (),
1969 : "cannot strip expression in this position - outer "
1970 : "attributes not allowed");
1971 : }
1972 : void
1973 1364 : CfgStrip::visit (AST::Enum &enum_item)
1974 : {
1975 : // initial test based on outer attrs
1976 1364 : expand_cfg_attrs (enum_item.get_outer_attrs ());
1977 1364 : if (fails_cfg_with_expand (enum_item.get_outer_attrs ()))
1978 : {
1979 0 : enum_item.mark_for_strip ();
1980 0 : return;
1981 : }
1982 :
1983 1364 : AST::DefaultASTVisitor::visit (enum_item);
1984 :
1985 : /* strip enum fields if required - this is presumably
1986 : * allowed by spec */
1987 1364 : maybe_strip_pointer_allow_strip (enum_item.get_variants ());
1988 : }
1989 : void
1990 230 : CfgStrip::visit (AST::Union &union_item)
1991 : {
1992 : // initial test based on outer attrs
1993 230 : expand_cfg_attrs (union_item.get_outer_attrs ());
1994 230 : if (fails_cfg_with_expand (union_item.get_outer_attrs ()))
1995 : {
1996 0 : union_item.mark_for_strip ();
1997 0 : return;
1998 : }
1999 :
2000 230 : AST::DefaultASTVisitor::visit (union_item);
2001 :
2002 : /* strip union fields if required - this is presumably
2003 : * allowed by spec */
2004 230 : maybe_strip_struct_fields (union_item.get_variants ());
2005 : }
2006 : void
2007 1531 : CfgStrip::visit (AST::ConstantItem &const_item)
2008 : {
2009 : // initial test based on outer attrs
2010 1531 : expand_cfg_attrs (const_item.get_outer_attrs ());
2011 1531 : if (fails_cfg_with_expand (const_item.get_outer_attrs ()))
2012 : {
2013 0 : const_item.mark_for_strip ();
2014 0 : return;
2015 : }
2016 :
2017 1531 : AST::DefaultASTVisitor::visit (const_item);
2018 :
2019 : // strip any sub-types
2020 1531 : auto &type = const_item.get_type ();
2021 1531 : if (type.is_marked_for_strip ())
2022 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2023 :
2024 : /* strip any internal sub-expressions - expression itself isn't
2025 : * allowed to have external attributes in this position so can't be
2026 : * stripped. */
2027 1531 : if (const_item.has_expr ())
2028 : {
2029 1389 : auto &expr = const_item.get_expr ();
2030 1389 : if (expr.is_marked_for_strip ())
2031 0 : rust_error_at (expr.get_locus (),
2032 : "cannot strip expression in this position - outer "
2033 : "attributes not allowed");
2034 : }
2035 : }
2036 : void
2037 126 : CfgStrip::visit (AST::StaticItem &static_item)
2038 : {
2039 : // initial test based on outer attrs
2040 126 : expand_cfg_attrs (static_item.get_outer_attrs ());
2041 126 : if (fails_cfg_with_expand (static_item.get_outer_attrs ()))
2042 : {
2043 0 : static_item.mark_for_strip ();
2044 0 : return;
2045 : }
2046 :
2047 126 : AST::DefaultASTVisitor::visit (static_item);
2048 :
2049 : // strip any sub-types
2050 126 : auto &type = static_item.get_type ();
2051 :
2052 126 : if (type.is_marked_for_strip ())
2053 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2054 :
2055 : /* strip any internal sub-expressions - expression itself isn't
2056 : * allowed to have external attributes in this position so can't be
2057 : * stripped. */
2058 126 : auto &expr = static_item.get_expr ();
2059 126 : if (expr.is_marked_for_strip ())
2060 0 : rust_error_at (expr.get_locus (),
2061 : "cannot strip expression in this position - outer "
2062 : "attributes not allowed");
2063 : }
2064 :
2065 : void
2066 3686 : CfgStrip::visit (AST::TraitItemType &item)
2067 : {
2068 : // initial test based on outer attrs
2069 3686 : expand_cfg_attrs (item.get_outer_attrs ());
2070 3686 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
2071 : {
2072 0 : item.mark_for_strip ();
2073 0 : return;
2074 : }
2075 :
2076 3686 : AST::DefaultASTVisitor::visit (item);
2077 : }
2078 :
2079 : void
2080 9012 : CfgStrip::visit (AST::Trait &trait)
2081 : {
2082 : // initial strip test based on outer attrs
2083 9012 : expand_cfg_attrs (trait.get_outer_attrs ());
2084 9012 : if (fails_cfg_with_expand (trait.get_outer_attrs ()))
2085 : {
2086 1 : trait.mark_for_strip ();
2087 1 : return;
2088 : }
2089 :
2090 : // strip test based on inner attrs
2091 9011 : expand_cfg_attrs (trait.get_inner_attrs ());
2092 9011 : if (fails_cfg_with_expand (trait.get_inner_attrs ()))
2093 : {
2094 0 : trait.mark_for_strip ();
2095 0 : return;
2096 : }
2097 :
2098 9011 : AST::DefaultASTVisitor::visit (trait);
2099 :
2100 9011 : maybe_strip_pointer_allow_strip (trait.get_trait_items ());
2101 : }
2102 :
2103 : void
2104 2205 : CfgStrip::visit (AST::InherentImpl &impl)
2105 : {
2106 : // initial strip test based on outer attrs
2107 2205 : expand_cfg_attrs (impl.get_outer_attrs ());
2108 2205 : if (fails_cfg_with_expand (impl.get_outer_attrs ()))
2109 : {
2110 1 : impl.mark_for_strip ();
2111 1 : return;
2112 : }
2113 :
2114 : // strip test based on inner attrs
2115 2204 : expand_cfg_attrs (impl.get_inner_attrs ());
2116 2204 : if (fails_cfg_with_expand (impl.get_inner_attrs ()))
2117 : {
2118 0 : impl.mark_for_strip ();
2119 0 : return;
2120 : }
2121 :
2122 2204 : AST::DefaultASTVisitor::visit (impl);
2123 :
2124 2204 : auto &type = impl.get_type ();
2125 :
2126 2204 : if (type.is_marked_for_strip ())
2127 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2128 :
2129 2204 : maybe_strip_pointer_allow_strip (impl.get_impl_items ());
2130 : }
2131 :
2132 : void
2133 11162 : CfgStrip::visit (AST::TraitImpl &impl)
2134 : {
2135 : // initial strip test based on outer attrs
2136 11162 : expand_cfg_attrs (impl.get_outer_attrs ());
2137 11162 : if (fails_cfg_with_expand (impl.get_outer_attrs ()))
2138 : {
2139 0 : impl.mark_for_strip ();
2140 0 : return;
2141 : }
2142 :
2143 : // strip test based on inner attrs
2144 11162 : expand_cfg_attrs (impl.get_inner_attrs ());
2145 11162 : if (fails_cfg_with_expand (impl.get_inner_attrs ()))
2146 : {
2147 0 : impl.mark_for_strip ();
2148 0 : return;
2149 : }
2150 :
2151 11162 : AST::DefaultASTVisitor::visit (impl);
2152 :
2153 11162 : auto &type = impl.get_type ();
2154 11162 : if (type.is_marked_for_strip ())
2155 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2156 :
2157 11162 : auto &trait_path = impl.get_trait_path ();
2158 11162 : visit (trait_path);
2159 11162 : if (trait_path.is_marked_for_strip ())
2160 0 : rust_error_at (trait_path.get_locus (),
2161 : "cannot strip typepath in this position");
2162 :
2163 11162 : maybe_strip_pointer_allow_strip (impl.get_impl_items ());
2164 : }
2165 :
2166 : void
2167 2 : CfgStrip::visit (AST::ExternalTypeItem &item)
2168 : {
2169 2 : expand_cfg_attrs (item.get_outer_attrs ());
2170 :
2171 2 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
2172 0 : item.mark_for_strip ();
2173 :
2174 : // TODO: Can we do anything like expand a macro here?
2175 : // extern "C" { type ffi_ty!(); }
2176 : // ?
2177 2 : }
2178 :
2179 : void
2180 2 : CfgStrip::visit (AST::ExternalStaticItem &item)
2181 : {
2182 : // strip test based on outer attrs
2183 2 : expand_cfg_attrs (item.get_outer_attrs ());
2184 2 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
2185 : {
2186 0 : item.mark_for_strip ();
2187 0 : return;
2188 : }
2189 :
2190 2 : AST::DefaultASTVisitor::visit (item);
2191 :
2192 2 : auto &type = item.get_type ();
2193 2 : if (type.is_marked_for_strip ())
2194 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2195 : }
2196 :
2197 : void
2198 3649 : CfgStrip::visit (AST::ExternBlock &block)
2199 : {
2200 : // initial strip test based on outer attrs
2201 3649 : expand_cfg_attrs (block.get_outer_attrs ());
2202 3649 : if (fails_cfg_with_expand (block.get_outer_attrs ()))
2203 : {
2204 0 : block.mark_for_strip ();
2205 0 : return;
2206 : }
2207 :
2208 : // strip test based on inner attrs
2209 3649 : expand_cfg_attrs (block.get_inner_attrs ());
2210 3649 : if (fails_cfg_with_expand (block.get_inner_attrs ()))
2211 : {
2212 0 : block.mark_for_strip ();
2213 0 : return;
2214 : }
2215 :
2216 3649 : maybe_strip_pointer_allow_strip (block.get_extern_items ());
2217 : }
2218 :
2219 : void
2220 3845 : CfgStrip::visit (AST::MacroRulesDefinition &rules_def)
2221 : {
2222 : // initial strip test based on outer attrs
2223 3845 : expand_cfg_attrs (rules_def.get_outer_attrs ());
2224 3845 : if (fails_cfg_with_expand (rules_def.get_outer_attrs ()))
2225 : {
2226 0 : rules_def.mark_for_strip ();
2227 0 : return;
2228 : }
2229 : }
2230 :
2231 : void
2232 164814 : CfgStrip::visit (AST::IdentifierPattern &pattern)
2233 : {
2234 : // can only strip sub-patterns of the inner pattern to bind
2235 164814 : if (!pattern.has_subpattern ())
2236 : return;
2237 :
2238 70 : AST::DefaultASTVisitor::visit (pattern);
2239 :
2240 70 : auto &sub_pattern = pattern.get_subpattern ();
2241 70 : if (sub_pattern.is_marked_for_strip ())
2242 0 : rust_error_at (sub_pattern.get_locus (),
2243 : "cannot strip pattern in this position");
2244 : }
2245 :
2246 : void
2247 42 : CfgStrip::visit (AST::RangePatternBoundPath &bound)
2248 : {
2249 : // can expand path, but not strip it directly
2250 42 : auto &path = bound.get_path ();
2251 42 : visit (path);
2252 42 : if (path.is_marked_for_strip ())
2253 0 : rust_error_at (path.get_locus (), "cannot strip path in this position");
2254 42 : }
2255 :
2256 : void
2257 0 : CfgStrip::visit (AST::RangePatternBoundQualPath &bound)
2258 : {
2259 : // can expand path, but not strip it directly
2260 0 : auto &path = bound.get_qualified_path ();
2261 0 : visit (path);
2262 0 : if (path.is_marked_for_strip ())
2263 0 : rust_error_at (path.get_locus (), "cannot strip path in this position");
2264 0 : }
2265 :
2266 : void
2267 820 : CfgStrip::visit (AST::ReferencePattern &pattern)
2268 : {
2269 820 : AST::DefaultASTVisitor::visit (pattern);
2270 :
2271 820 : auto &sub_pattern = pattern.get_referenced_pattern ();
2272 820 : if (sub_pattern.is_marked_for_strip ())
2273 0 : rust_error_at (sub_pattern.get_locus (),
2274 : "cannot strip pattern in this position");
2275 820 : }
2276 : void
2277 78 : CfgStrip::visit (AST::StructPatternFieldTuplePat &field)
2278 : {
2279 : // initial strip test based on outer attrs
2280 78 : expand_cfg_attrs (field.get_outer_attrs ());
2281 78 : if (fails_cfg_with_expand (field.get_outer_attrs ()))
2282 : {
2283 0 : field.mark_for_strip ();
2284 0 : return;
2285 : }
2286 :
2287 78 : AST::DefaultASTVisitor::visit (field);
2288 :
2289 : // strip sub-patterns (can't strip top-level pattern)
2290 78 : auto &sub_pattern = field.get_index_pattern ();
2291 78 : if (sub_pattern.is_marked_for_strip ())
2292 0 : rust_error_at (sub_pattern.get_locus (),
2293 : "cannot strip pattern in this position");
2294 : }
2295 :
2296 : void
2297 516 : CfgStrip::visit (AST::StructPatternFieldIdentPat &field)
2298 : {
2299 : // initial strip test based on outer attrs
2300 516 : expand_cfg_attrs (field.get_outer_attrs ());
2301 516 : if (fails_cfg_with_expand (field.get_outer_attrs ()))
2302 : {
2303 0 : field.mark_for_strip ();
2304 0 : return;
2305 : }
2306 :
2307 516 : AST::DefaultASTVisitor::visit (field);
2308 : // strip sub-patterns (can't strip top-level pattern)
2309 516 : auto &sub_pattern = field.get_ident_pattern ();
2310 516 : if (sub_pattern.is_marked_for_strip ())
2311 0 : rust_error_at (sub_pattern.get_locus (),
2312 : "cannot strip pattern in this position");
2313 : }
2314 : void
2315 252 : CfgStrip::visit (AST::StructPatternFieldIdent &field)
2316 : {
2317 : // initial strip test based on outer attrs
2318 252 : expand_cfg_attrs (field.get_outer_attrs ());
2319 252 : if (fails_cfg_with_expand (field.get_outer_attrs ()))
2320 : {
2321 0 : field.mark_for_strip ();
2322 0 : return;
2323 : }
2324 : }
2325 :
2326 : void
2327 502 : CfgStrip::visit (AST::StructPattern &pattern)
2328 : {
2329 : // expand (but don't strip) path
2330 502 : auto &path = pattern.get_path ();
2331 502 : visit (path);
2332 502 : if (path.is_marked_for_strip ())
2333 0 : rust_error_at (path.get_locus (), "cannot strip path in this position");
2334 :
2335 : /* TODO: apparently struct pattern fields can have outer attrs. so can they
2336 : * be stripped? */
2337 502 : if (!pattern.has_struct_pattern_elems ())
2338 : return;
2339 :
2340 500 : auto &elems = pattern.get_struct_pattern_elems ();
2341 :
2342 : // assuming you can strip struct pattern fields
2343 500 : maybe_strip_pointer_allow_strip (elems.get_struct_pattern_fields ());
2344 :
2345 : // assuming you can strip the ".." part
2346 500 : if (elems.has_rest ())
2347 : {
2348 10 : expand_cfg_attrs (elems.get_etc_outer_attrs ());
2349 10 : if (fails_cfg_with_expand (elems.get_etc_outer_attrs ()))
2350 0 : elems.strip_etc ();
2351 : }
2352 : }
2353 :
2354 : void
2355 4798 : CfgStrip::visit (AST::TupleStructItemsNoRest &tuple_items)
2356 : {
2357 4798 : AST::DefaultASTVisitor::visit (tuple_items);
2358 : // can't strip individual patterns, only sub-patterns
2359 10138 : for (auto &pattern : tuple_items.get_patterns ())
2360 : {
2361 5340 : if (pattern->is_marked_for_strip ())
2362 0 : rust_error_at (pattern->get_locus (),
2363 : "cannot strip pattern in this position");
2364 : // TODO: quit stripping now? or keep going?
2365 : }
2366 4798 : }
2367 : void
2368 148 : CfgStrip::visit (AST::TupleStructItemsHasRest &tuple_items)
2369 : {
2370 148 : AST::DefaultASTVisitor::visit (tuple_items);
2371 : // can't strip individual patterns, only sub-patterns
2372 266 : for (auto &lower_pattern : tuple_items.get_lower_patterns ())
2373 : {
2374 118 : if (lower_pattern->is_marked_for_strip ())
2375 0 : rust_error_at (lower_pattern->get_locus (),
2376 : "cannot strip pattern in this position");
2377 : // TODO: quit stripping now? or keep going?
2378 : }
2379 214 : for (auto &upper_pattern : tuple_items.get_upper_patterns ())
2380 : {
2381 66 : if (upper_pattern->is_marked_for_strip ())
2382 0 : rust_error_at (upper_pattern->get_locus (),
2383 : "cannot strip pattern in this position");
2384 : // TODO: quit stripping now? or keep going?
2385 : }
2386 148 : }
2387 :
2388 : void
2389 4946 : CfgStrip::visit (AST::TupleStructPattern &pattern)
2390 : {
2391 : // expand (but don't strip) path
2392 4946 : auto &path = pattern.get_path ();
2393 4946 : visit (path);
2394 4946 : if (path.is_marked_for_strip ())
2395 0 : rust_error_at (path.get_locus (), "cannot strip path in this position");
2396 :
2397 4946 : AST::DefaultASTVisitor::visit (pattern);
2398 4946 : }
2399 :
2400 : void
2401 3934 : CfgStrip::visit (AST::TuplePatternItemsNoRest &tuple_items)
2402 : {
2403 3934 : AST::DefaultASTVisitor::visit (tuple_items);
2404 :
2405 : // can't strip individual patterns, only sub-patterns
2406 11814 : for (auto &pattern : tuple_items.get_patterns ())
2407 : {
2408 7880 : if (pattern->is_marked_for_strip ())
2409 0 : rust_error_at (pattern->get_locus (),
2410 : "cannot strip pattern in this position");
2411 : // TODO: quit stripping now? or keep going?
2412 : }
2413 3934 : }
2414 :
2415 : void
2416 104 : CfgStrip::visit (AST::TuplePatternItemsHasRest &tuple_items)
2417 : {
2418 104 : AST::DefaultASTVisitor::visit (tuple_items);
2419 :
2420 : // can't strip individual patterns, only sub-patterns
2421 210 : for (auto &lower_pattern : tuple_items.get_lower_patterns ())
2422 : {
2423 106 : if (lower_pattern->is_marked_for_strip ())
2424 0 : rust_error_at (lower_pattern->get_locus (),
2425 : "cannot strip pattern in this position");
2426 : // TODO: quit stripping now? or keep going?
2427 : }
2428 216 : for (auto &upper_pattern : tuple_items.get_upper_patterns ())
2429 : {
2430 112 : if (upper_pattern->is_marked_for_strip ())
2431 0 : rust_error_at (upper_pattern->get_locus (),
2432 : "cannot strip pattern in this position");
2433 : // TODO: quit stripping now? or keep going?
2434 : }
2435 104 : }
2436 :
2437 : void
2438 176 : CfgStrip::visit (AST::GroupedPattern &pattern)
2439 : {
2440 176 : AST::DefaultASTVisitor::visit (pattern);
2441 : // can't strip inner pattern, only sub-patterns
2442 176 : auto &pattern_in_parens = pattern.get_pattern_in_parens ();
2443 :
2444 176 : if (pattern_in_parens.is_marked_for_strip ())
2445 0 : rust_error_at (pattern_in_parens.get_locus (),
2446 : "cannot strip pattern in this position");
2447 176 : }
2448 :
2449 : void
2450 122 : CfgStrip::visit (AST::SlicePatternItemsNoRest &items)
2451 : {
2452 122 : AST::DefaultASTVisitor::visit (items);
2453 : // can't strip individual patterns, only sub-patterns
2454 364 : for (auto &pattern : items.get_patterns ())
2455 : {
2456 242 : if (pattern->is_marked_for_strip ())
2457 0 : rust_error_at (pattern->get_locus (),
2458 : "cannot strip pattern in this position");
2459 : }
2460 122 : }
2461 :
2462 : void
2463 172 : CfgStrip::visit (AST::SlicePatternItemsHasRest &items)
2464 : {
2465 172 : AST::DefaultASTVisitor::visit (items);
2466 : // can't strip individual patterns, only sub-patterns
2467 342 : for (auto &pattern : items.get_lower_patterns ())
2468 : {
2469 170 : if (pattern->is_marked_for_strip ())
2470 0 : rust_error_at (pattern->get_locus (),
2471 : "cannot strip pattern in this position");
2472 : }
2473 342 : for (auto &pattern : items.get_upper_patterns ())
2474 : {
2475 170 : if (pattern->is_marked_for_strip ())
2476 0 : rust_error_at (pattern->get_locus (),
2477 : "cannot strip pattern in this position");
2478 : }
2479 172 : }
2480 :
2481 : void
2482 294 : CfgStrip::visit (AST::SlicePattern &pattern)
2483 : {
2484 294 : AST::DefaultASTVisitor::visit (pattern);
2485 294 : }
2486 :
2487 : void
2488 970 : CfgStrip::visit (AST::AltPattern &pattern)
2489 : {
2490 970 : AST::DefaultASTVisitor::visit (pattern);
2491 : // can't strip individual patterns, only sub-patterns
2492 3040 : for (auto &alt : pattern.get_alts ())
2493 : {
2494 2070 : if (alt->is_marked_for_strip ())
2495 0 : rust_error_at (alt->get_locus (),
2496 : "cannot strip pattern in this position");
2497 : // TODO: quit stripping now? or keep going?
2498 : }
2499 970 : }
2500 :
2501 : void
2502 74088 : CfgStrip::visit (AST::LetStmt &stmt)
2503 : {
2504 : // initial strip test based on outer attrs
2505 74088 : expand_cfg_attrs (stmt.get_outer_attrs ());
2506 74088 : if (fails_cfg_with_expand (stmt.get_outer_attrs ()))
2507 : {
2508 0 : stmt.mark_for_strip ();
2509 0 : return;
2510 : }
2511 :
2512 74088 : AST::DefaultASTVisitor::visit (stmt);
2513 : // can't strip pattern, but call for sub-patterns
2514 74088 : auto &pattern = stmt.get_pattern ();
2515 74088 : if (pattern.is_marked_for_strip ())
2516 0 : rust_error_at (pattern.get_locus (),
2517 : "cannot strip pattern in this position");
2518 :
2519 : // similar for type
2520 74088 : if (stmt.has_type ())
2521 : {
2522 10046 : auto &type = stmt.get_type ();
2523 :
2524 10046 : if (type.is_marked_for_strip ())
2525 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2526 : }
2527 :
2528 : /* strip any internal sub-expressions - expression itself isn't
2529 : * allowed to have external attributes in this position so can't be
2530 : * stripped */
2531 74088 : if (stmt.has_init_expr ())
2532 : {
2533 68964 : auto &init_expr = stmt.get_init_expr ();
2534 :
2535 68964 : if (init_expr.is_marked_for_strip ())
2536 0 : rust_error_at (init_expr.get_locus (),
2537 : "cannot strip expression in this position - outer "
2538 : "attributes not allowed");
2539 : }
2540 : }
2541 :
2542 : void
2543 73575 : CfgStrip::visit (AST::ExprStmt &stmt)
2544 : {
2545 : // outer attributes associated with expr, so rely on expr
2546 :
2547 : // guard - should prevent null pointer expr
2548 73575 : if (stmt.is_marked_for_strip ())
2549 : return;
2550 :
2551 73575 : AST::DefaultASTVisitor::visit (stmt);
2552 : // strip if expr is to be stripped
2553 73575 : auto &expr = stmt.get_expr ();
2554 73575 : if (expr.is_marked_for_strip ())
2555 : {
2556 19 : stmt.mark_for_strip ();
2557 19 : return;
2558 : }
2559 : }
2560 :
2561 : void
2562 6875 : CfgStrip::visit (AST::TraitBound &bound)
2563 : {
2564 : // nothing in for lifetimes to strip
2565 :
2566 : // expand but don't strip type path
2567 6875 : auto &path = bound.get_type_path ();
2568 6875 : visit (path);
2569 6875 : if (path.is_marked_for_strip ())
2570 0 : rust_error_at (path.get_locus (),
2571 : "cannot strip type path in this position");
2572 6875 : }
2573 :
2574 : void
2575 22 : CfgStrip::visit (AST::ParenthesisedType &type)
2576 : {
2577 22 : AST::DefaultASTVisitor::visit (type);
2578 : // expand but don't strip inner type
2579 22 : auto &inner_type = type.get_type_in_parens ();
2580 22 : if (inner_type->is_marked_for_strip ())
2581 0 : rust_error_at (inner_type->get_locus (),
2582 : "cannot strip type in this position");
2583 22 : }
2584 :
2585 : void
2586 1831 : CfgStrip::visit (AST::TupleType &type)
2587 : {
2588 1831 : AST::DefaultASTVisitor::visit (type);
2589 : // TODO: assuming that types can't be stripped as types don't have outer
2590 : // attributes
2591 4713 : for (auto &elem_type : type.get_elems ())
2592 : {
2593 2882 : if (elem_type->is_marked_for_strip ())
2594 0 : rust_error_at (elem_type->get_locus (),
2595 : "cannot strip type in this position");
2596 : }
2597 1831 : }
2598 :
2599 : void
2600 48545 : CfgStrip::visit (AST::RawPointerType &type)
2601 : {
2602 48545 : AST::DefaultASTVisitor::visit (type);
2603 : // expand but don't strip type pointed to
2604 48545 : auto &pointed_type = type.get_type_pointed_to ();
2605 48545 : if (pointed_type.is_marked_for_strip ())
2606 0 : rust_error_at (pointed_type.get_locus (),
2607 : "cannot strip type in this position");
2608 48545 : }
2609 :
2610 : void
2611 32958 : CfgStrip::visit (AST::ReferenceType &type)
2612 : {
2613 32958 : AST::DefaultASTVisitor::visit (type);
2614 : // expand but don't strip type referenced
2615 32958 : auto &referenced_type = type.get_type_referenced ();
2616 32958 : if (referenced_type.is_marked_for_strip ())
2617 0 : rust_error_at (referenced_type.get_locus (),
2618 : "cannot strip type in this position");
2619 32958 : }
2620 :
2621 : void
2622 4906 : CfgStrip::visit (AST::ArrayType &type)
2623 : {
2624 4906 : AST::DefaultASTVisitor::visit (type);
2625 : // expand but don't strip type referenced
2626 4906 : auto &base_type = type.get_elem_type ();
2627 4906 : if (base_type.is_marked_for_strip ())
2628 0 : rust_error_at (base_type.get_locus (),
2629 : "cannot strip type in this position");
2630 :
2631 : // same for expression
2632 4906 : auto &size_expr = type.get_size_expr ();
2633 4906 : if (size_expr.is_marked_for_strip ())
2634 0 : rust_error_at (size_expr.get_locus (),
2635 : "cannot strip expression in this position");
2636 4906 : }
2637 : void
2638 4023 : CfgStrip::visit (AST::SliceType &type)
2639 : {
2640 4023 : AST::DefaultASTVisitor::visit (type);
2641 : // expand but don't strip elem type
2642 4023 : auto &elem_type = type.get_elem_type ();
2643 4023 : if (elem_type.is_marked_for_strip ())
2644 0 : rust_error_at (elem_type.get_locus (),
2645 : "cannot strip type in this position");
2646 4023 : }
2647 :
2648 : void
2649 254 : CfgStrip::visit (AST::BareFunctionType &type)
2650 : {
2651 : // seem to be no generics
2652 254 : AST::DefaultASTVisitor::visit (type);
2653 :
2654 : // presumably function params can be stripped
2655 254 : auto ¶ms = type.get_function_params ();
2656 474 : for (auto it = params.begin (); it != params.end ();)
2657 : {
2658 220 : auto ¶m = *it;
2659 :
2660 220 : auto ¶m_attrs = param.get_outer_attrs ();
2661 220 : expand_cfg_attrs (param_attrs);
2662 220 : if (fails_cfg_with_expand (param_attrs))
2663 : {
2664 0 : it = params.erase (it);
2665 0 : continue;
2666 : }
2667 :
2668 220 : auto &type = param.get_type ();
2669 220 : if (type.is_marked_for_strip ())
2670 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2671 :
2672 : // increment if nothing else happens
2673 220 : ++it;
2674 : }
2675 :
2676 : /* TODO: assuming that variadic nature cannot be stripped. If this
2677 : * is not true, then have code here to do so. */
2678 :
2679 254 : if (type.has_return_type ())
2680 : {
2681 : // FIXME: Can we have type expansion in this position?
2682 : // In that case, we need to handle AST::TypeNoBounds on top of just
2683 : // AST::Types
2684 182 : auto &return_type = type.get_return_type ();
2685 182 : if (return_type.is_marked_for_strip ())
2686 0 : rust_error_at (return_type.get_locus (),
2687 : "cannot strip type in this position");
2688 : }
2689 :
2690 : // no where clause, apparently
2691 254 : }
2692 :
2693 : void
2694 39648 : CfgStrip::visit (AST::SelfParam ¶m)
2695 : {
2696 39648 : AST::DefaultASTVisitor::visit (param);
2697 :
2698 39648 : if (param.has_type ())
2699 : {
2700 4 : auto &type = param.get_type ();
2701 4 : if (type.is_marked_for_strip ())
2702 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2703 : }
2704 : /* TODO: maybe check for invariants being violated - e.g. both type and
2705 : * lifetime? */
2706 39648 : }
2707 :
2708 : } // namespace Rust
|