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 1825945 : CfgStrip::fails_cfg_with_expand (AST::AttrVec &attrs) const
35 : {
36 1825945 : auto &session = Session::get_instance ();
37 :
38 : // TODO: maybe have something that strips cfg attributes that evaluate true?
39 1926166 : for (auto &attr : attrs)
40 : {
41 100334 : if (attr.get_path () == Values::Attributes::CFG)
42 : {
43 2116 : if (!attr.is_parsed_to_meta_item ())
44 479 : attr.parse_attr_to_meta_item ();
45 :
46 : // DEBUG
47 2116 : 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 2115 : rust_debug ("attr has been successfully parsed to meta item, "
52 : "right before cfg predicate check");
53 :
54 2116 : if (!attr.check_cfg_predicate (session))
55 : {
56 : // DEBUG
57 112 : rust_debug (
58 : "cfg predicate failed for attribute: \033[0;31m'%s'\033[0m",
59 : attr.as_string ().c_str ());
60 :
61 112 : 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 98218 : else if (!expansion_cfg.should_test
72 196436 : && 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 1830467 : expand_cfg_attrs (AST::AttrVec &attrs)
83 : {
84 1830467 : auto &session = Session::get_instance ();
85 :
86 1942073 : for (std::size_t i = 0; i < attrs.size (); i++)
87 : {
88 111606 : auto &attr = attrs[i];
89 111606 : if (attr.get_path () == Values::Attributes::CFG_ATTR)
90 : {
91 16 : if (!attr.is_parsed_to_meta_item ())
92 5 : attr.parse_attr_to_meta_item ();
93 :
94 16 : 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 8 : AST::AttrVec new_attrs = attr.separate_cfg_attrs ();
101 :
102 : // remove attr from vector
103 8 : attrs.erase (attrs.begin () + i);
104 :
105 : // add new attrs to vector
106 8 : 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 8 : i--;
115 8 : }
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 1830467 : attrs.shrink_to_fit ();
132 1830467 : }
133 :
134 : void
135 10431 : CfgStrip::go (AST::Crate &crate)
136 : {
137 10431 : visit (crate);
138 10431 : }
139 :
140 : void
141 10431 : CfgStrip::visit (AST::Crate &crate)
142 : {
143 : // expand crate cfg_attr attributes
144 10431 : expand_cfg_attrs (crate.inner_attrs);
145 :
146 10431 : 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 10431 : auto &items = crate.items;
154 :
155 10431 : AST::DefaultASTVisitor::visit (crate);
156 55656 : for (auto it = items.begin (); it != items.end ();)
157 : {
158 45225 : auto &item = *it;
159 45225 : if (item->is_marked_for_strip ())
160 19 : it = items.erase (it);
161 : else
162 45206 : it++;
163 : }
164 : // expand module attributes?
165 10431 : }
166 :
167 : // Visitor used to expand attributes.
168 : void
169 4749 : CfgStrip::maybe_strip_struct_fields (std::vector<AST::StructField> &fields)
170 : {
171 10551 : 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 4749 : }
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 4704 : CfgStrip::maybe_strip_tuple_fields (std::vector<AST::TupleField> &fields)
217 : {
218 12197 : for (auto it = fields.begin (); it != fields.end ();)
219 : {
220 7493 : auto &field = *it;
221 :
222 7493 : auto &field_attrs = field.get_outer_attrs ();
223 7493 : expand_cfg_attrs (field_attrs);
224 7493 : 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 7493 : auto &type = field.get_field_type ();
232 7493 : type.accept_vis (*this);
233 7493 : 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 7493 : ++it;
238 : }
239 4704 : }
240 :
241 : void
242 67581 : CfgStrip::maybe_strip_function_params (
243 : std::vector<std::unique_ptr<AST::Param>> ¶ms)
244 : {
245 152012 : for (auto it = params.begin (); it != params.end ();)
246 : {
247 84431 : if (!(*it)->is_self () && !(*it)->is_variadic ())
248 : {
249 43020 : auto param = static_cast<AST::FunctionParam *> (it->get ());
250 :
251 43020 : auto ¶m_attrs = param->get_outer_attrs ();
252 43020 : expand_cfg_attrs (param_attrs);
253 43020 : 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 43020 : auto &pattern = param->get_pattern ();
261 43020 : pattern.accept_vis (*this);
262 43020 : if (pattern.is_marked_for_strip ())
263 0 : rust_error_at (pattern.get_locus (),
264 : "cannot strip pattern in this position");
265 :
266 43020 : auto &type = param->get_type ();
267 43020 : type.accept_vis (*this);
268 :
269 43020 : 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 84431 : ++it;
275 : }
276 67581 : }
277 :
278 : void
279 20635 : 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 42008 : for (auto &arg : args.get_generic_args ())
286 : {
287 21373 : 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 392 : case AST::GenericArg::Kind::Const:
300 392 : {
301 392 : auto &expr = arg.get_expression ();
302 392 : expr.accept_vis (*this);
303 :
304 392 : 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 20967 : 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 20635 : }
330 :
331 : void
332 1779 : CfgStrip::maybe_strip_qualified_path_type (AST::QualifiedPathType &path_type)
333 : {
334 1779 : auto &type = path_type.get_type ();
335 1779 : type.accept_vis (*this);
336 :
337 1779 : if (type.is_marked_for_strip ())
338 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
339 :
340 1779 : if (path_type.has_as_clause ())
341 : {
342 1589 : auto &type_path = path_type.get_as_type_path ();
343 1589 : visit (type_path);
344 1589 : 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 1779 : }
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 208278 : CfgStrip::visit (AST::IdentifierExpr &ident_expr)
397 : {
398 : // strip test based on outer attrs
399 208278 : AST::DefaultASTVisitor::visit (ident_expr);
400 208278 : expand_cfg_attrs (ident_expr.get_outer_attrs ());
401 208278 : 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 4597 : CfgStrip::visit (AST::MacroInvocation ¯o_invoc)
410 : {
411 : // initial strip test based on outer attrs
412 4597 : expand_cfg_attrs (macro_invoc.get_outer_attrs ());
413 4597 : 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 160969 : CfgStrip::visit (AST::PathInExpression &path)
428 : {
429 : // initial strip test based on outer attrs
430 160969 : expand_cfg_attrs (path.get_outer_attrs ());
431 160969 : if (fails_cfg_with_expand (path.get_outer_attrs ()))
432 : {
433 0 : path.mark_for_strip ();
434 0 : return;
435 : }
436 :
437 160969 : if (!path.is_lang_item ())
438 : {
439 383644 : for (auto &segment : path.get_segments ())
440 : {
441 446346 : if (segment.has_generic_args ())
442 7105 : maybe_strip_generic_args (segment.get_generic_args ());
443 : }
444 : }
445 : }
446 :
447 : void
448 13446 : CfgStrip::visit (AST::TypePathSegmentGeneric &segment)
449 : {
450 : // TODO: strip inside generic args
451 :
452 13446 : if (!segment.has_generic_args ())
453 : return;
454 :
455 13442 : 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 526 : CfgStrip::visit (AST::QualifiedPathInExpression &path)
482 : {
483 : // initial strip test based on outer attrs
484 526 : AST::DefaultASTVisitor::visit (path);
485 :
486 526 : expand_cfg_attrs (path.get_outer_attrs ());
487 526 : if (fails_cfg_with_expand (path.get_outer_attrs ()))
488 : {
489 0 : path.mark_for_strip ();
490 0 : return;
491 : }
492 :
493 526 : maybe_strip_qualified_path_type (path.get_qualified_path_type ());
494 :
495 1052 : for (auto &segment : path.get_segments ())
496 : {
497 1052 : 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 689246 : CfgStrip::visit (AST::LiteralExpr &expr)
513 : {
514 : // initial strip test based on outer attrs
515 689246 : expand_cfg_attrs (expr.get_outer_attrs ());
516 689246 : 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 17510 : CfgStrip::visit (AST::BorrowExpr &expr)
525 : {
526 17510 : AST::DefaultASTVisitor::visit (expr);
527 : // initial strip test based on outer attrs
528 17510 : expand_cfg_attrs (expr.get_outer_attrs ());
529 17510 : 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 17510 : auto &borrowed_expr = expr.get_borrowed_expr ();
539 17510 : 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 2418 : CfgStrip::visit (AST::NegationExpr &expr)
589 : {
590 2418 : AST::DefaultASTVisitor::visit (expr);
591 : // initial strip test based on outer attrs
592 2418 : expand_cfg_attrs (expr.get_outer_attrs ());
593 2418 : 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 2418 : auto &negated_expr = expr.get_negated_expr ();
603 2418 : 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 540417 : CfgStrip::visit (AST::ArithmeticOrLogicalExpr &expr)
610 : {
611 540417 : 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 540417 : 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 540417 : 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 540417 : }
626 :
627 : void
628 13389 : 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 13389 : AST::DefaultASTVisitor::visit (expr);
633 :
634 : // ensure that they are not marked for strip
635 13389 : 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 13389 : 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 13389 : }
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 52274 : 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 52274 : AST::DefaultASTVisitor::visit (expr);
671 :
672 52274 : auto &casted_expr = expr.get_casted_expr ();
673 : // ensure that they are not marked for strip
674 52274 : 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 52274 : auto &type = expr.get_type_to_cast_to ();
681 52274 : if (type.is_marked_for_strip ())
682 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
683 52274 : }
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 6322 : 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 6322 : AST::DefaultASTVisitor::visit (expr);
712 :
713 : // ensure that they are not marked for strip
714 6322 : 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 6322 : 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 6322 : }
724 : void
725 2135 : CfgStrip::visit (AST::GroupedExpr &expr)
726 : {
727 : // initial strip test based on outer attrs
728 2135 : expand_cfg_attrs (expr.get_outer_attrs ());
729 2135 : 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 2135 : expand_cfg_attrs (expr.get_inner_attrs ());
738 2135 : 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 2135 : AST::DefaultASTVisitor::visit (expr);
748 :
749 2135 : auto &inner_expr = expr.get_expr_in_parens ();
750 2135 : 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 1164 : CfgStrip::visit (AST::ArrayElemsValues &elems)
757 : {
758 : /* apparently outer attributes are allowed in "elements of array
759 : * expressions" according to spec */
760 1164 : maybe_strip_pointer_allow_strip (elems.get_values ());
761 1164 : }
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 1630 : CfgStrip::visit (AST::ArrayExpr &expr)
787 : {
788 : // initial strip test based on outer attrs
789 1630 : expand_cfg_attrs (expr.get_outer_attrs ());
790 1630 : 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 1630 : expand_cfg_attrs (expr.get_inner_attrs ());
799 1630 : 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 1630 : AST::DefaultASTVisitor::visit (expr);
808 : }
809 :
810 : void
811 1404 : 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 1404 : expand_cfg_attrs (expr.get_outer_attrs ());
818 1404 : 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 1404 : AST::DefaultASTVisitor::visit (expr);
828 :
829 1404 : const auto &array_expr = expr.get_array_expr ();
830 1404 : if (array_expr.is_marked_for_strip ())
831 0 : rust_error_at (array_expr.get_locus (),
832 : "cannot strip expression in this position - outer "
833 : "attributes not allowed");
834 :
835 1404 : const auto &index_expr = expr.get_index_expr ();
836 1404 : if (index_expr.is_marked_for_strip ())
837 0 : rust_error_at (index_expr.get_locus (),
838 : "cannot strip expression in this position - outer "
839 : "attributes not allowed");
840 : }
841 : void
842 2617 : CfgStrip::visit (AST::TupleExpr &expr)
843 : {
844 : /* according to spec, outer attributes are allowed on "elements of
845 : * tuple expressions" */
846 :
847 : // initial strip test based on outer attrs
848 2617 : expand_cfg_attrs (expr.get_outer_attrs ());
849 2617 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
850 : {
851 0 : expr.mark_for_strip ();
852 0 : return;
853 : }
854 :
855 : /* strip test based on inner attrs - spec says these are inner
856 : * attributes, not outer attributes of inner expr */
857 2617 : expand_cfg_attrs (expr.get_inner_attrs ());
858 2617 : if (fails_cfg_with_expand (expr.get_inner_attrs ()))
859 : {
860 0 : expr.mark_for_strip ();
861 0 : return;
862 : }
863 :
864 : /* apparently outer attributes are allowed in "elements of tuple
865 : * expressions" according to spec */
866 2617 : maybe_strip_pointer_allow_strip (expr.get_tuple_elems ());
867 : }
868 : void
869 5616 : CfgStrip::visit (AST::TupleIndexExpr &expr)
870 : {
871 : // initial strip test based on outer attrs
872 5616 : expand_cfg_attrs (expr.get_outer_attrs ());
873 5616 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
874 : {
875 0 : expr.mark_for_strip ();
876 0 : return;
877 : }
878 :
879 5616 : AST::DefaultASTVisitor::visit (expr);
880 : /* wouldn't strip this directly (as outer attrs should be
881 : * associated with this level), but any sub-expressions would be
882 : * stripped. Thus, no need to erase when strip check called. */
883 5616 : auto &tuple_expr = expr.get_tuple_expr ();
884 5616 : if (tuple_expr.is_marked_for_strip ())
885 0 : rust_error_at (tuple_expr.get_locus (),
886 : "cannot strip expression in this position - outer "
887 : "attributes not allowed");
888 : }
889 :
890 : void
891 328 : CfgStrip::visit (AST::StructExprStruct &expr)
892 : {
893 : // initial strip test based on outer attrs
894 328 : expand_cfg_attrs (expr.get_outer_attrs ());
895 328 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
896 : {
897 0 : expr.mark_for_strip ();
898 0 : return;
899 : }
900 :
901 : /* strip test based on inner attrs - spec says these are inner
902 : * attributes, not outer attributes of inner expr */
903 328 : expand_cfg_attrs (expr.get_inner_attrs ());
904 328 : if (fails_cfg_with_expand (expr.get_inner_attrs ()))
905 : {
906 0 : expr.mark_for_strip ();
907 0 : return;
908 : }
909 :
910 : // strip sub-exprs of path
911 328 : auto &struct_name = expr.get_struct_name ();
912 328 : visit (struct_name);
913 328 : if (struct_name.is_marked_for_strip ())
914 0 : rust_error_at (struct_name.get_locus (),
915 : "cannot strip path in this position");
916 : }
917 :
918 : void
919 9451 : CfgStrip::visit (AST::StructExprFieldIdentifierValue &field)
920 : {
921 : /* as no attrs possible (at moment, at least), only sub-expression
922 : * stripping is possible */
923 9451 : AST::DefaultASTVisitor::visit (field);
924 :
925 9451 : auto &value = field.get_value ();
926 9451 : if (value.is_marked_for_strip ())
927 0 : rust_error_at (value.get_locus (),
928 : "cannot strip expression in this position - outer "
929 : "attributes not allowed");
930 9451 : }
931 : void
932 176 : CfgStrip::visit (AST::StructExprFieldIndexValue &field)
933 : {
934 : /* as no attrs possible (at moment, at least), only sub-expression
935 : * stripping is possible */
936 176 : AST::DefaultASTVisitor::visit (field);
937 :
938 176 : auto &value = field.get_value ();
939 176 : if (value.is_marked_for_strip ())
940 0 : rust_error_at (value.get_locus (),
941 : "cannot strip expression in this position - outer "
942 : "attributes not allowed");
943 176 : }
944 : void
945 5764 : CfgStrip::visit (AST::StructExprStructFields &expr)
946 : {
947 : // initial strip test based on outer attrs
948 5764 : expand_cfg_attrs (expr.get_outer_attrs ());
949 5764 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
950 : {
951 0 : expr.mark_for_strip ();
952 0 : return;
953 : }
954 :
955 : /* strip test based on inner attrs - spec says these are inner
956 : * attributes, not outer attributes of inner expr */
957 5764 : expand_cfg_attrs (expr.get_inner_attrs ());
958 5764 : if (fails_cfg_with_expand (expr.get_inner_attrs ()))
959 : {
960 0 : expr.mark_for_strip ();
961 0 : return;
962 : }
963 :
964 : // strip sub-exprs of path
965 5764 : auto &struct_name = expr.get_struct_name ();
966 5764 : visit (struct_name);
967 5764 : if (struct_name.is_marked_for_strip ())
968 0 : rust_error_at (struct_name.get_locus (),
969 : "cannot strip path in this position");
970 :
971 : /* spec does not specify whether expressions are allowed to be
972 : * stripped at top level of struct fields, but I wouldn't think
973 : * that they would be, so operating under the assumption that only
974 : * sub-expressions can be stripped. */
975 5764 : AST::DefaultASTVisitor::visit (expr);
976 :
977 : /* struct base presumably can't be stripped, as the '..' is before
978 : * the expression. as such, can only strip sub-expressions. */
979 5764 : if (expr.has_struct_base ())
980 : {
981 252 : auto &base_struct_expr = expr.get_struct_base ().get_base_struct ();
982 252 : base_struct_expr.accept_vis (*this);
983 252 : if (base_struct_expr.is_marked_for_strip ())
984 0 : rust_error_at (base_struct_expr.get_locus (),
985 : "cannot strip expression in this position - outer "
986 : "attributes not allowed");
987 : }
988 :
989 5764 : maybe_strip_struct_expr_fields (expr.get_fields ());
990 : }
991 :
992 : void
993 0 : CfgStrip::visit (AST::StructExprStructBase &expr)
994 : {
995 : // initial strip test based on outer attrs
996 0 : expand_cfg_attrs (expr.get_outer_attrs ());
997 0 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
998 : {
999 0 : expr.mark_for_strip ();
1000 0 : return;
1001 : }
1002 :
1003 : /* strip test based on inner attrs - spec says these are inner
1004 : * attributes, not outer attributes of inner expr */
1005 0 : expand_cfg_attrs (expr.get_inner_attrs ());
1006 0 : if (fails_cfg_with_expand (expr.get_inner_attrs ()))
1007 : {
1008 0 : expr.mark_for_strip ();
1009 0 : return;
1010 : }
1011 :
1012 : // strip sub-exprs of path
1013 0 : auto &struct_name = expr.get_struct_name ();
1014 0 : visit (struct_name);
1015 0 : if (struct_name.is_marked_for_strip ())
1016 0 : rust_error_at (struct_name.get_locus (),
1017 : "cannot strip path in this position");
1018 :
1019 : /* struct base presumably can't be stripped, as the '..' is before
1020 : * the expression. as such, can only strip sub-expressions. */
1021 0 : rust_assert (!expr.get_struct_base ().is_invalid ());
1022 0 : auto &base_struct_expr = expr.get_struct_base ().get_base_struct ();
1023 0 : base_struct_expr.accept_vis (*this);
1024 0 : if (base_struct_expr.is_marked_for_strip ())
1025 0 : rust_error_at (base_struct_expr.get_locus (),
1026 : "cannot strip expression in this position - outer "
1027 : "attributes not allowed");
1028 : }
1029 : void
1030 68533 : CfgStrip::visit (AST::CallExpr &expr)
1031 : {
1032 : // initial strip test based on outer attrs
1033 68533 : expand_cfg_attrs (expr.get_outer_attrs ());
1034 68533 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1035 : {
1036 0 : expr.mark_for_strip ();
1037 0 : return;
1038 : }
1039 :
1040 : /* should not be outer attrs on "function" expression - outer attrs
1041 : * should be associated with call expr as a whole. only sub-expr
1042 : * expansion is possible. */
1043 68533 : AST::DefaultASTVisitor::visit (expr);
1044 :
1045 68533 : auto &function = expr.get_function_expr ();
1046 68533 : if (function.is_marked_for_strip ())
1047 0 : rust_error_at (function.get_locus (),
1048 : "cannot strip expression in this position - outer "
1049 : "attributes not allowed");
1050 :
1051 : /* spec says outer attributes are specifically allowed for elements
1052 : * of call expressions, so full stripping possible */
1053 : // FIXME: Arthur: Figure out how to refactor this - This is similar to
1054 : // expanding items in the crate or stmts in blocks
1055 68533 : maybe_strip_pointer_allow_strip (expr.get_params ());
1056 : }
1057 : void
1058 20153 : CfgStrip::visit (AST::MethodCallExpr &expr)
1059 : {
1060 : // initial strip test based on outer attrs
1061 20153 : expand_cfg_attrs (expr.get_outer_attrs ());
1062 20153 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1063 : {
1064 0 : expr.mark_for_strip ();
1065 0 : return;
1066 : }
1067 :
1068 : /* should not be outer attrs on "receiver" expression - outer attrs
1069 : * should be associated with call expr as a whole. only sub-expr
1070 : * expansion is possible. */
1071 20153 : AST::DefaultASTVisitor::visit (expr);
1072 :
1073 20153 : auto &receiver = expr.get_receiver_expr ();
1074 20153 : if (receiver.is_marked_for_strip ())
1075 0 : rust_error_at (receiver.get_locus (),
1076 : "cannot strip expression in this position - outer "
1077 : "attributes not allowed");
1078 :
1079 20153 : auto &method_name = expr.get_method_name ();
1080 20153 : if (method_name.has_generic_args ())
1081 88 : maybe_strip_generic_args (method_name.get_generic_args ());
1082 :
1083 : /* spec says outer attributes are specifically allowed for elements
1084 : * of method call expressions, so full stripping possible */
1085 20153 : maybe_strip_pointer_allow_strip (expr.get_params ());
1086 : }
1087 : void
1088 39961 : CfgStrip::visit (AST::FieldAccessExpr &expr)
1089 : {
1090 : // initial strip test based on outer attrs
1091 39961 : expand_cfg_attrs (expr.get_outer_attrs ());
1092 39961 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1093 : {
1094 0 : expr.mark_for_strip ();
1095 0 : return;
1096 : }
1097 :
1098 : /* should not be outer attrs on "receiver" expression - outer attrs
1099 : * should be associated with field expr as a whole. only sub-expr
1100 : * expansion is possible. */
1101 39961 : AST::DefaultASTVisitor::visit (expr);
1102 :
1103 39961 : auto &receiver = expr.get_receiver_expr ();
1104 39961 : if (receiver.is_marked_for_strip ())
1105 0 : rust_error_at (receiver.get_locus (),
1106 : "cannot strip expression in this position - outer "
1107 : "attributes not allowed");
1108 : }
1109 : void
1110 130 : CfgStrip::visit (AST::ClosureExprInner &expr)
1111 : {
1112 : // initial strip test based on outer attrs
1113 130 : expand_cfg_attrs (expr.get_outer_attrs ());
1114 130 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1115 : {
1116 0 : expr.mark_for_strip ();
1117 0 : return;
1118 : }
1119 :
1120 : /* strip closure parameters if required - this is specifically
1121 : * allowed by spec */
1122 130 : maybe_strip_closure_params (expr.get_params ());
1123 :
1124 130 : AST::DefaultASTVisitor::visit (expr);
1125 :
1126 : // can't strip expression itself, but can strip sub-expressions
1127 130 : auto &definition_expr = expr.get_definition_expr ();
1128 130 : if (definition_expr.is_marked_for_strip ())
1129 0 : rust_error_at (definition_expr.get_locus (),
1130 : "cannot strip expression in this position - outer "
1131 : "attributes not allowed");
1132 : }
1133 :
1134 : void
1135 90409 : CfgStrip::visit (AST::BlockExpr &expr)
1136 : {
1137 : // initial strip test based on outer attrs
1138 90409 : expand_cfg_attrs (expr.get_outer_attrs ());
1139 90409 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1140 : {
1141 54 : expr.mark_for_strip ();
1142 54 : return;
1143 : }
1144 :
1145 : /* strip test based on inner attrs - spec says there are inner
1146 : * attributes, not just outer attributes of inner stmts */
1147 90355 : expand_cfg_attrs (expr.get_inner_attrs ());
1148 90355 : if (fails_cfg_with_expand (expr.get_inner_attrs ()))
1149 : {
1150 0 : expr.mark_for_strip ();
1151 0 : return;
1152 : }
1153 :
1154 90355 : maybe_strip_pointer_allow_strip (expr.get_statements ());
1155 :
1156 90355 : AST::DefaultASTVisitor::visit (expr);
1157 :
1158 : // strip tail expression if exists - can actually fully remove it
1159 90355 : if (expr.has_tail_expr ())
1160 : {
1161 70808 : auto &tail_expr = expr.get_tail_expr ();
1162 :
1163 70808 : if (tail_expr.is_marked_for_strip ())
1164 57 : expr.strip_tail_expr ();
1165 : }
1166 : }
1167 :
1168 : void
1169 120 : CfgStrip::visit (AST::ClosureExprInnerTyped &expr)
1170 : {
1171 : // initial strip test based on outer attrs
1172 120 : expand_cfg_attrs (expr.get_outer_attrs ());
1173 120 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1174 : {
1175 0 : expr.mark_for_strip ();
1176 0 : return;
1177 : }
1178 :
1179 : /* strip closure parameters if required - this is specifically
1180 : * allowed by spec */
1181 120 : maybe_strip_closure_params (expr.get_params ());
1182 :
1183 120 : AST::DefaultASTVisitor::visit (expr);
1184 :
1185 : // can't strip return type, but can strip sub-types
1186 120 : auto &type = expr.get_return_type ();
1187 :
1188 120 : if (type.is_marked_for_strip ())
1189 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
1190 :
1191 : // can't strip expression itself, but can strip sub-expressions
1192 120 : auto &definition_block = expr.get_definition_expr ();
1193 120 : definition_block.accept_vis (*this);
1194 120 : if (definition_block.is_marked_for_strip ())
1195 0 : rust_error_at (definition_block.get_locus (),
1196 : "cannot strip block expression in this position - outer "
1197 : "attributes not allowed");
1198 : }
1199 : void
1200 154 : CfgStrip::visit (AST::ContinueExpr &expr)
1201 : {
1202 : // initial strip test based on outer attrs
1203 154 : expand_cfg_attrs (expr.get_outer_attrs ());
1204 154 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1205 : {
1206 0 : expr.mark_for_strip ();
1207 0 : return;
1208 : }
1209 : }
1210 : void
1211 628 : CfgStrip::visit (AST::BreakExpr &expr)
1212 : {
1213 : // initial strip test based on outer attrs
1214 628 : expand_cfg_attrs (expr.get_outer_attrs ());
1215 628 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1216 : {
1217 0 : expr.mark_for_strip ();
1218 0 : return;
1219 : }
1220 628 : AST::DefaultASTVisitor::visit (expr);
1221 :
1222 : /* spec does not say that you can have outer attributes on
1223 : * expression, so assuming you can't. stripping for sub-expressions
1224 : * is the only thing that can be done */
1225 628 : if (expr.has_break_expr ())
1226 : {
1227 248 : auto &break_expr = expr.get_break_expr_unchecked ();
1228 :
1229 248 : if (break_expr.is_marked_for_strip ())
1230 0 : rust_error_at (break_expr.get_locus (),
1231 : "cannot strip expression in this position - outer "
1232 : "attributes not allowed");
1233 : }
1234 : }
1235 : void
1236 356 : CfgStrip::visit (AST::RangeFromToExpr &expr)
1237 : {
1238 : /* outer attributes never allowed before these. while cannot strip
1239 : * two direct descendant expressions, can strip ones below that */
1240 356 : AST::DefaultASTVisitor::visit (expr);
1241 :
1242 : // ensure that they are not marked for strip
1243 356 : if (expr.get_from_expr ().is_marked_for_strip ())
1244 0 : rust_error_at (expr.get_from_expr ().get_locus (),
1245 : "cannot strip expression in this position - outer "
1246 : "attributes are never allowed "
1247 : "before range exprs");
1248 356 : if (expr.get_to_expr ().is_marked_for_strip ())
1249 0 : rust_error_at (expr.get_to_expr ().get_locus (),
1250 : "cannot strip expression in this position - outer "
1251 : "attributes not allowed");
1252 356 : }
1253 : void
1254 28 : CfgStrip::visit (AST::RangeFromExpr &expr)
1255 : {
1256 : /* outer attributes never allowed before these. while cannot strip
1257 : * direct descendant expression, can strip ones below that */
1258 :
1259 28 : AST::DefaultASTVisitor::visit (expr);
1260 : /* should have no possibility for outer attrs as would be parsed
1261 : * with outer expr */
1262 28 : auto &from_expr = expr.get_from_expr ();
1263 28 : if (from_expr.is_marked_for_strip ())
1264 0 : rust_error_at (from_expr.get_locus (),
1265 : "cannot strip expression in this position - outer "
1266 : "attributes are never allowed before range exprs");
1267 28 : }
1268 : void
1269 28 : CfgStrip::visit (AST::RangeToExpr &expr)
1270 : {
1271 : /* outer attributes never allowed before these. while cannot strip
1272 : * direct descendant expression, can strip ones below that */
1273 :
1274 28 : AST::DefaultASTVisitor::visit (expr);
1275 : /* should syntactically not have outer attributes, though this may
1276 : * not have worked in practice */
1277 28 : auto &to_expr = expr.get_to_expr ();
1278 28 : if (to_expr.is_marked_for_strip ())
1279 0 : rust_error_at (to_expr.get_locus (),
1280 : "cannot strip expression in this position - outer "
1281 : "attributes not allowed");
1282 28 : }
1283 :
1284 : void
1285 28 : CfgStrip::visit (AST::RangeFromToInclExpr &expr)
1286 : {
1287 : /* outer attributes never allowed before these. while cannot strip
1288 : * two direct descendant expressions, can strip ones below that */
1289 :
1290 28 : AST::DefaultASTVisitor::visit (expr);
1291 :
1292 : // ensure that they are not marked for strip
1293 28 : if (expr.get_from_expr ().is_marked_for_strip ())
1294 0 : rust_error_at (expr.get_from_expr ().get_locus (),
1295 : "cannot strip expression in this position - outer "
1296 : "attributes are never allowed "
1297 : "before range exprs");
1298 28 : if (expr.get_to_expr ().is_marked_for_strip ())
1299 0 : rust_error_at (expr.get_to_expr ().get_locus (),
1300 : "cannot strip expression in this position - outer "
1301 : "attributes not allowed");
1302 28 : }
1303 : void
1304 0 : CfgStrip::visit (AST::RangeToInclExpr &expr)
1305 : {
1306 : /* outer attributes never allowed before these. while cannot strip
1307 : * direct descendant expression, can strip ones below that */
1308 :
1309 0 : AST::DefaultASTVisitor::visit (expr);
1310 : /* should syntactically not have outer attributes, though this may
1311 : * not have worked in practice */
1312 0 : auto &to_expr = expr.get_to_expr ();
1313 0 : if (to_expr.is_marked_for_strip ())
1314 0 : rust_error_at (to_expr.get_locus (),
1315 : "cannot strip expression in this position - outer "
1316 : "attributes not allowed");
1317 0 : }
1318 : void
1319 3108 : CfgStrip::visit (AST::ReturnExpr &expr)
1320 : {
1321 : // initial strip test based on outer attrs
1322 3108 : expand_cfg_attrs (expr.get_outer_attrs ());
1323 3108 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1324 : {
1325 0 : expr.mark_for_strip ();
1326 0 : return;
1327 : }
1328 :
1329 3108 : AST::DefaultASTVisitor::visit (expr);
1330 :
1331 : /* spec does not say that you can have outer attributes on
1332 : * expression, so assuming you can't. stripping for sub-expressions
1333 : * is the only thing that can be done */
1334 3108 : if (expr.has_returned_expr ())
1335 : {
1336 2750 : auto &returned_expr = expr.get_returned_expr ();
1337 2750 : if (returned_expr.is_marked_for_strip ())
1338 0 : rust_error_at (returned_expr.get_locus (),
1339 : "cannot strip expression in this position - outer "
1340 : "attributes not allowed");
1341 : }
1342 : /* TODO: conceptually, you would maybe be able to remove a returned
1343 : * expr - e.g. if you had conditional compilation returning void or
1344 : * returning a type. On the other hand, I think that function
1345 : * return type cannot be conditionally compiled, so I assumed you
1346 : * can't do this either. */
1347 : }
1348 : void
1349 16492 : CfgStrip::visit (AST::UnsafeBlockExpr &expr)
1350 : {
1351 : // initial strip test based on outer attrs
1352 16492 : expand_cfg_attrs (expr.get_outer_attrs ());
1353 16492 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1354 : {
1355 7 : expr.mark_for_strip ();
1356 7 : return;
1357 : }
1358 :
1359 16485 : AST::DefaultASTVisitor::visit (expr);
1360 :
1361 : // can't strip block itself, but can strip sub-expressions
1362 16485 : auto &block_expr = expr.get_block_expr ();
1363 16485 : if (block_expr.is_marked_for_strip ())
1364 0 : rust_error_at (block_expr.get_locus (),
1365 : "cannot strip block expression in this position - outer "
1366 : "attributes not allowed");
1367 : }
1368 : void
1369 330 : CfgStrip::visit (AST::LoopExpr &expr)
1370 : {
1371 : // initial strip test based on outer attrs
1372 330 : expand_cfg_attrs (expr.get_outer_attrs ());
1373 330 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1374 : {
1375 0 : expr.mark_for_strip ();
1376 0 : return;
1377 : }
1378 :
1379 330 : AST::DefaultASTVisitor::visit (expr);
1380 :
1381 : // can't strip block itself, but can strip sub-expressions
1382 330 : auto &loop_block = expr.get_loop_block ();
1383 330 : if (loop_block.is_marked_for_strip ())
1384 0 : rust_error_at (loop_block.get_locus (),
1385 : "cannot strip block expression in this position - outer "
1386 : "attributes not allowed");
1387 : }
1388 : void
1389 470 : CfgStrip::visit (AST::WhileLoopExpr &expr)
1390 : {
1391 : // initial strip test based on outer attrs
1392 470 : expand_cfg_attrs (expr.get_outer_attrs ());
1393 470 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1394 : {
1395 0 : expr.mark_for_strip ();
1396 0 : return;
1397 : }
1398 :
1399 470 : AST::DefaultASTVisitor::visit (expr);
1400 : // can't strip predicate expr itself, but can strip sub-expressions
1401 470 : auto &predicate_expr = expr.get_predicate_expr ();
1402 470 : if (predicate_expr.is_marked_for_strip ())
1403 0 : rust_error_at (predicate_expr.get_locus (),
1404 : "cannot strip expression in this position - outer "
1405 : "attributes not allowed");
1406 :
1407 : // can't strip block itself, but can strip sub-expressions
1408 470 : auto &loop_block = expr.get_loop_block ();
1409 470 : if (loop_block.is_marked_for_strip ())
1410 0 : rust_error_at (loop_block.get_locus (),
1411 : "cannot strip block expression in this position - outer "
1412 : "attributes not allowed");
1413 : }
1414 : void
1415 4 : CfgStrip::visit (AST::WhileLetLoopExpr &expr)
1416 : {
1417 : // initial strip test based on outer attrs
1418 4 : expand_cfg_attrs (expr.get_outer_attrs ());
1419 4 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1420 : {
1421 0 : expr.mark_for_strip ();
1422 0 : return;
1423 : }
1424 :
1425 4 : AST::DefaultASTVisitor::visit (expr);
1426 :
1427 4 : if (expr.get_pattern ()->is_marked_for_strip ())
1428 0 : rust_error_at (expr.get_pattern ()->get_locus (),
1429 : "cannot strip pattern in this position");
1430 :
1431 : // can't strip scrutinee expr itself, but can strip sub-expressions
1432 4 : auto &scrutinee_expr = expr.get_scrutinee_expr ();
1433 4 : if (scrutinee_expr.is_marked_for_strip ())
1434 0 : rust_error_at (scrutinee_expr.get_locus (),
1435 : "cannot strip expression in this position - outer "
1436 : "attributes not allowed");
1437 :
1438 : // can't strip block itself, but can strip sub-expressions
1439 4 : auto &loop_block = expr.get_loop_block ();
1440 4 : if (loop_block.is_marked_for_strip ())
1441 0 : rust_error_at (loop_block.get_locus (),
1442 : "cannot strip block expression in this position - outer "
1443 : "attributes not allowed");
1444 : }
1445 : void
1446 120 : CfgStrip::visit (AST::ForLoopExpr &expr)
1447 : {
1448 : // initial strip test based on outer attrs
1449 120 : expand_cfg_attrs (expr.get_outer_attrs ());
1450 120 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1451 : {
1452 0 : expr.mark_for_strip ();
1453 0 : return;
1454 : }
1455 :
1456 120 : AST::DefaultASTVisitor::visit (expr);
1457 : // strip sub-patterns of pattern
1458 120 : auto &pattern = expr.get_pattern ();
1459 120 : if (pattern.is_marked_for_strip ())
1460 0 : rust_error_at (pattern.get_locus (),
1461 : "cannot strip pattern in this position");
1462 :
1463 : // can't strip scrutinee expr itself, but can strip sub-expressions
1464 120 : auto &iterator_expr = expr.get_iterator_expr ();
1465 120 : if (iterator_expr.is_marked_for_strip ())
1466 0 : rust_error_at (iterator_expr.get_locus (),
1467 : "cannot strip expression in this position - outer "
1468 : "attributes not allowed");
1469 :
1470 : // can't strip block itself, but can strip sub-expressions
1471 120 : auto &loop_block = expr.get_loop_block ();
1472 120 : if (loop_block.is_marked_for_strip ())
1473 0 : rust_error_at (loop_block.get_locus (),
1474 : "cannot strip block expression in this position - outer "
1475 : "attributes not allowed");
1476 : }
1477 : void
1478 8301 : CfgStrip::visit (AST::IfExpr &expr)
1479 : {
1480 : // rust playground test shows that IfExpr does support outer attrs, at least
1481 : // when used as statement
1482 :
1483 : // initial strip test based on outer attrs
1484 8301 : expand_cfg_attrs (expr.get_outer_attrs ());
1485 8301 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1486 : {
1487 0 : expr.mark_for_strip ();
1488 0 : return;
1489 : }
1490 :
1491 8301 : AST::DefaultASTVisitor::visit (expr);
1492 :
1493 : // can't strip condition expr itself, but can strip sub-expressions
1494 8301 : auto &condition_expr = expr.get_condition_expr ();
1495 8301 : if (condition_expr.is_marked_for_strip ())
1496 0 : rust_error_at (condition_expr.get_locus (),
1497 : "cannot strip expression in this position - outer "
1498 : "attributes not allowed");
1499 :
1500 : // can't strip if block itself, but can strip sub-expressions
1501 8301 : auto &if_block = expr.get_if_block ();
1502 8301 : if (if_block.is_marked_for_strip ())
1503 0 : rust_error_at (if_block.get_locus (),
1504 : "cannot strip block expression in this position - outer "
1505 : "attributes not allowed");
1506 : }
1507 :
1508 : void
1509 5924 : CfgStrip::visit (AST::IfExprConseqElse &expr)
1510 : {
1511 : // initial strip test based on outer attrs
1512 5924 : expand_cfg_attrs (expr.get_outer_attrs ());
1513 5924 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1514 : {
1515 0 : expr.mark_for_strip ();
1516 0 : return;
1517 : }
1518 :
1519 5924 : AST::DefaultASTVisitor::visit (expr);
1520 :
1521 : // can't strip condition expr itself, but can strip sub-expressions
1522 5924 : auto &condition_expr = expr.get_condition_expr ();
1523 5924 : if (condition_expr.is_marked_for_strip ())
1524 0 : rust_error_at (condition_expr.get_locus (),
1525 : "cannot strip expression in this position - outer "
1526 : "attributes not allowed");
1527 :
1528 : // can't strip if block itself, but can strip sub-expressions
1529 5924 : auto &if_block = expr.get_if_block ();
1530 5924 : if (if_block.is_marked_for_strip ())
1531 0 : rust_error_at (if_block.get_locus (),
1532 : "cannot strip block expression in this position - outer "
1533 : "attributes not allowed");
1534 :
1535 : // can't strip else block itself, but can strip sub-expressions
1536 5924 : auto &else_block = expr.get_else_block ();
1537 5924 : if (else_block.is_marked_for_strip ())
1538 0 : rust_error_at (else_block.get_locus (),
1539 : "cannot strip block expression in this position - outer "
1540 : "attributes not allowed");
1541 : }
1542 :
1543 : void
1544 102 : CfgStrip::visit (AST::IfLetExpr &expr)
1545 : {
1546 : // initial strip test based on outer attrs
1547 102 : expand_cfg_attrs (expr.get_outer_attrs ());
1548 102 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1549 : {
1550 0 : expr.mark_for_strip ();
1551 0 : return;
1552 : }
1553 :
1554 102 : AST::DefaultASTVisitor::visit (expr);
1555 :
1556 102 : if (expr.get_pattern ()->is_marked_for_strip ())
1557 0 : rust_error_at (expr.get_pattern ()->get_locus (),
1558 : "cannot strip pattern in this position");
1559 :
1560 : // can't strip value expr itself, but can strip sub-expressions
1561 102 : auto &value_expr = expr.get_value_expr ();
1562 102 : if (value_expr.is_marked_for_strip ())
1563 0 : rust_error_at (value_expr.get_locus (),
1564 : "cannot strip expression in this position - outer "
1565 : "attributes not allowed");
1566 :
1567 : // can't strip if block itself, but can strip sub-expressions
1568 102 : auto &if_block = expr.get_if_block ();
1569 102 : if (if_block.is_marked_for_strip ())
1570 0 : rust_error_at (if_block.get_locus (),
1571 : "cannot strip block expression in this position - outer "
1572 : "attributes not allowed");
1573 : }
1574 : void
1575 30 : CfgStrip::visit (AST::IfLetExprConseqElse &expr)
1576 : {
1577 : // initial strip test based on outer attrs
1578 30 : expand_cfg_attrs (expr.get_outer_attrs ());
1579 30 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1580 : {
1581 0 : expr.mark_for_strip ();
1582 0 : return;
1583 : }
1584 :
1585 30 : AST::DefaultASTVisitor::visit (expr);
1586 :
1587 30 : if (expr.get_pattern ()->is_marked_for_strip ())
1588 0 : rust_error_at (expr.get_pattern ()->get_locus (),
1589 : "cannot strip pattern in this position");
1590 :
1591 : // can't strip value expr itself, but can strip sub-expressions
1592 30 : auto &value_expr = expr.get_value_expr ();
1593 30 : if (value_expr.is_marked_for_strip ())
1594 0 : rust_error_at (value_expr.get_locus (),
1595 : "cannot strip expression in this position - outer "
1596 : "attributes not allowed");
1597 :
1598 : // can't strip if block itself, but can strip sub-expressions
1599 30 : auto &if_block = expr.get_if_block ();
1600 30 : if (if_block.is_marked_for_strip ())
1601 0 : rust_error_at (if_block.get_locus (),
1602 : "cannot strip block expression in this position - outer "
1603 : "attributes not allowed");
1604 :
1605 : // can't strip else block itself, but can strip sub-expressions
1606 30 : auto &else_block = expr.get_else_block ();
1607 30 : if (else_block.is_marked_for_strip ())
1608 0 : rust_error_at (else_block.get_locus (),
1609 : "cannot strip block expression in this position - outer "
1610 : "attributes not allowed");
1611 : }
1612 : void
1613 4423 : CfgStrip::visit (AST::MatchExpr &expr)
1614 : {
1615 : // initial strip test based on outer attrs
1616 4423 : expand_cfg_attrs (expr.get_outer_attrs ());
1617 4423 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1618 : {
1619 0 : expr.mark_for_strip ();
1620 0 : return;
1621 : }
1622 :
1623 : // inner attr strip test
1624 4423 : expand_cfg_attrs (expr.get_inner_attrs ());
1625 4423 : if (fails_cfg_with_expand (expr.get_inner_attrs ()))
1626 : {
1627 0 : expr.mark_for_strip ();
1628 0 : return;
1629 : }
1630 :
1631 4423 : AST::DefaultASTVisitor::visit (expr);
1632 :
1633 : // can't strip scrutinee expr itself, but can strip sub-expressions
1634 4423 : auto &scrutinee_expr = expr.get_scrutinee_expr ();
1635 4423 : if (scrutinee_expr.is_marked_for_strip ())
1636 0 : rust_error_at (scrutinee_expr.get_locus (),
1637 : "cannot strip expression in this position - outer "
1638 : "attributes not allowed");
1639 :
1640 : // strip match cases
1641 4423 : auto &match_cases = expr.get_match_cases ();
1642 14609 : for (auto it = match_cases.begin (); it != match_cases.end ();)
1643 : {
1644 10186 : auto &match_case = *it;
1645 :
1646 : // strip match case based on outer attributes in match arm
1647 10186 : auto &match_arm = match_case.get_arm ();
1648 10186 : expand_cfg_attrs (match_arm.get_outer_attrs ());
1649 10186 : if (fails_cfg_with_expand (match_arm.get_outer_attrs ()))
1650 : {
1651 : // strip match case
1652 0 : it = match_cases.erase (it);
1653 0 : continue;
1654 : }
1655 :
1656 10186 : if (match_arm.get_pattern ()->is_marked_for_strip ())
1657 0 : rust_error_at (match_arm.get_pattern ()->get_locus (),
1658 : "cannot strip pattern in this position");
1659 :
1660 : /* assuming that guard expression cannot be stripped as
1661 : * strictly speaking you would have to strip the whole guard to
1662 : * make syntactical sense, which you can't do. as such, only
1663 : * strip sub-expressions */
1664 10186 : if (match_arm.has_match_arm_guard ())
1665 : {
1666 2 : auto &guard_expr = match_arm.get_guard_expr ();
1667 2 : if (guard_expr.is_marked_for_strip ())
1668 0 : rust_error_at (guard_expr.get_locus (),
1669 : "cannot strip expression in this position - outer "
1670 : "attributes not allowed");
1671 : }
1672 :
1673 : // strip sub-expressions from match cases
1674 10186 : auto &case_expr = match_case.get_expr ();
1675 10186 : if (case_expr.is_marked_for_strip ())
1676 0 : rust_error_at (case_expr.get_locus (),
1677 : "cannot strip expression in this position - outer "
1678 : "attributes not allowed");
1679 :
1680 : // increment to next case if haven't continued
1681 10186 : ++it;
1682 : }
1683 : }
1684 :
1685 : void
1686 0 : CfgStrip::visit (AST::AwaitExpr &expr)
1687 : {
1688 : // initial strip test based on outer attrs
1689 0 : expand_cfg_attrs (expr.get_outer_attrs ());
1690 0 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1691 : {
1692 0 : expr.mark_for_strip ();
1693 0 : return;
1694 : }
1695 :
1696 : /* can't strip awaited expr itself, but can strip sub-expressions
1697 : * - this is because you can't have no expr to await */
1698 0 : auto &awaited_expr = expr.get_awaited_expr ();
1699 0 : awaited_expr->accept_vis (*this);
1700 0 : if (awaited_expr->is_marked_for_strip ())
1701 0 : rust_error_at (awaited_expr->get_locus (),
1702 : "cannot strip expression in this position - outer "
1703 : "attributes not allowed");
1704 : }
1705 :
1706 : void
1707 0 : CfgStrip::visit (AST::AsyncBlockExpr &expr)
1708 : {
1709 : // initial strip test based on outer attrs
1710 0 : expand_cfg_attrs (expr.get_outer_attrs ());
1711 0 : if (fails_cfg_with_expand (expr.get_outer_attrs ()))
1712 : {
1713 0 : expr.mark_for_strip ();
1714 0 : return;
1715 : }
1716 :
1717 0 : AST::DefaultASTVisitor::visit (expr);
1718 :
1719 : // can't strip block itself, but can strip sub-expressions
1720 0 : auto &block_expr = expr.get_block_expr ();
1721 0 : if (block_expr->is_marked_for_strip ())
1722 0 : rust_error_at (block_expr->get_locus (),
1723 : "cannot strip block expression in this position - outer "
1724 : "attributes not allowed");
1725 : }
1726 :
1727 : void
1728 20023 : CfgStrip::visit (AST::TypeParam ¶m)
1729 : {
1730 : // outer attributes don't actually do anything, so ignore them
1731 :
1732 20023 : AST::DefaultASTVisitor::visit (param);
1733 :
1734 20023 : if (param.has_type () && param.get_type ().is_marked_for_strip ())
1735 0 : rust_error_at (param.get_type ().get_locus (),
1736 : "cannot strip type in this position");
1737 20023 : }
1738 :
1739 : void
1740 1259 : CfgStrip::visit (AST::TypeBoundWhereClauseItem &item)
1741 : {
1742 : // for lifetimes shouldn't require
1743 1259 : AST::DefaultASTVisitor::visit (item);
1744 :
1745 1259 : auto &type = item.get_type ();
1746 1259 : if (type.is_marked_for_strip ())
1747 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
1748 1259 : }
1749 :
1750 : void
1751 3264 : CfgStrip::visit (AST::Module &module)
1752 : {
1753 : // strip test based on outer attrs
1754 3264 : expand_cfg_attrs (module.get_outer_attrs ());
1755 3264 : if (fails_cfg_with_expand (module.get_outer_attrs ()))
1756 : {
1757 0 : module.mark_for_strip ();
1758 0 : return;
1759 : }
1760 :
1761 3264 : if (module.get_kind () == AST::Module::UNLOADED)
1762 : {
1763 82 : module.load_items ();
1764 : }
1765 :
1766 : // strip test based on inner attrs
1767 3264 : expand_cfg_attrs (module.get_inner_attrs ());
1768 3264 : if (fails_cfg_with_expand (module.get_inner_attrs ()))
1769 : {
1770 0 : module.mark_for_strip ();
1771 0 : return;
1772 : }
1773 :
1774 : // strip items if required
1775 3264 : maybe_strip_pointer_allow_strip (module.get_items ());
1776 : }
1777 :
1778 : void
1779 51 : CfgStrip::visit (AST::ExternCrate &extern_crate)
1780 : {
1781 : // strip test based on outer attrs
1782 51 : expand_cfg_attrs (extern_crate.get_outer_attrs ());
1783 51 : if (fails_cfg_with_expand (extern_crate.get_outer_attrs ()))
1784 : {
1785 0 : extern_crate.mark_for_strip ();
1786 0 : return;
1787 : }
1788 :
1789 51 : if (!extern_crate.references_self ())
1790 : {
1791 51 : Session &session = Session::get_instance ();
1792 51 : session.load_extern_crate (extern_crate.get_referenced_crate (),
1793 : extern_crate.get_locus ());
1794 : }
1795 : }
1796 :
1797 : void
1798 1851 : CfgStrip::visit (AST::UseDeclaration &use_decl)
1799 : {
1800 : // strip test based on outer attrs
1801 1851 : expand_cfg_attrs (use_decl.get_outer_attrs ());
1802 1851 : if (fails_cfg_with_expand (use_decl.get_outer_attrs ()))
1803 : {
1804 0 : use_decl.mark_for_strip ();
1805 0 : return;
1806 : }
1807 : }
1808 :
1809 : void
1810 67612 : CfgStrip::visit (AST::Function &function)
1811 : {
1812 : // initial test based on outer attrs
1813 67612 : expand_cfg_attrs (function.get_outer_attrs ());
1814 67612 : if (fails_cfg_with_expand (function.get_outer_attrs ()))
1815 : {
1816 31 : function.mark_for_strip ();
1817 31 : return;
1818 : }
1819 :
1820 67581 : AST::DefaultASTVisitor::visit (function);
1821 :
1822 : /* strip function parameters if required - this is specifically
1823 : * allowed by spec */
1824 67581 : maybe_strip_function_params (function.get_function_params ());
1825 :
1826 67581 : if (function.has_return_type ())
1827 : {
1828 53611 : auto &return_type = function.get_return_type ();
1829 53611 : if (return_type.is_marked_for_strip ())
1830 0 : rust_error_at (return_type.get_locus (),
1831 : "cannot strip type in this position");
1832 : }
1833 :
1834 : /* body should always exist - if error state, should have returned
1835 : * before now */
1836 : // can't strip block itself, but can strip sub-expressions
1837 67581 : if (function.has_body ())
1838 : {
1839 53500 : auto &block_expr = function.get_definition ();
1840 53500 : if (block_expr.value ()->is_marked_for_strip ())
1841 0 : rust_error_at (block_expr.value ()->get_locus (),
1842 : "cannot strip block expression in this position - outer "
1843 : "attributes not allowed");
1844 : }
1845 : }
1846 :
1847 : void
1848 6244 : CfgStrip::visit (AST::TypeAlias &type_alias)
1849 : {
1850 : // initial test based on outer attrs
1851 6244 : expand_cfg_attrs (type_alias.get_outer_attrs ());
1852 6244 : if (fails_cfg_with_expand (type_alias.get_outer_attrs ()))
1853 : {
1854 0 : type_alias.mark_for_strip ();
1855 0 : return;
1856 : }
1857 :
1858 6244 : AST::DefaultASTVisitor::visit (type_alias);
1859 :
1860 6244 : auto &type = type_alias.get_type_aliased ();
1861 6244 : if (type.is_marked_for_strip ())
1862 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
1863 : }
1864 :
1865 : void
1866 4081 : CfgStrip::visit (AST::StructStruct &struct_item)
1867 : {
1868 : // initial test based on outer attrs
1869 4081 : expand_cfg_attrs (struct_item.get_outer_attrs ());
1870 4081 : if (fails_cfg_with_expand (struct_item.get_outer_attrs ()))
1871 : {
1872 2 : struct_item.mark_for_strip ();
1873 2 : return;
1874 : }
1875 :
1876 4079 : AST::DefaultASTVisitor::visit (struct_item);
1877 :
1878 : /* strip struct fields if required - this is presumably
1879 : * allowed by spec */
1880 4079 : maybe_strip_struct_fields (struct_item.get_fields ());
1881 : }
1882 : void
1883 2454 : CfgStrip::visit (AST::TupleStruct &tuple_struct)
1884 : {
1885 : // initial test based on outer attrs
1886 2454 : expand_cfg_attrs (tuple_struct.get_outer_attrs ());
1887 2454 : if (fails_cfg_with_expand (tuple_struct.get_outer_attrs ()))
1888 : {
1889 0 : tuple_struct.mark_for_strip ();
1890 0 : return;
1891 : }
1892 :
1893 2454 : AST::DefaultASTVisitor::visit (tuple_struct);
1894 :
1895 : /* strip struct fields if required - this is presumably
1896 : * allowed by spec */
1897 2454 : maybe_strip_tuple_fields (tuple_struct.get_fields ());
1898 : }
1899 : void
1900 2112 : CfgStrip::visit (AST::EnumItem &item)
1901 : {
1902 : // initial test based on outer attrs
1903 2112 : expand_cfg_attrs (item.get_outer_attrs ());
1904 2112 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
1905 : {
1906 0 : item.mark_for_strip ();
1907 0 : return;
1908 : }
1909 : }
1910 :
1911 : void
1912 2250 : CfgStrip::visit (AST::EnumItemTuple &item)
1913 : {
1914 : // initial test based on outer attrs
1915 2250 : expand_cfg_attrs (item.get_outer_attrs ());
1916 2250 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
1917 : {
1918 0 : item.mark_for_strip ();
1919 0 : return;
1920 : }
1921 :
1922 : /* strip item fields if required - this is presumably
1923 : * allowed by spec */
1924 2250 : maybe_strip_tuple_fields (item.get_tuple_fields ());
1925 : }
1926 :
1927 : void
1928 440 : CfgStrip::visit (AST::EnumItemStruct &item)
1929 : {
1930 : // initial test based on outer attrs
1931 440 : expand_cfg_attrs (item.get_outer_attrs ());
1932 440 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
1933 : {
1934 0 : item.mark_for_strip ();
1935 0 : return;
1936 : }
1937 :
1938 : /* strip item fields if required - this is presumably
1939 : * allowed by spec */
1940 440 : maybe_strip_struct_fields (item.get_struct_fields ());
1941 : }
1942 :
1943 : void
1944 1378 : CfgStrip::visit (AST::EnumItemDiscriminant &item)
1945 : {
1946 : // initial test based on outer attrs
1947 1378 : expand_cfg_attrs (item.get_outer_attrs ());
1948 1378 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
1949 : {
1950 0 : item.mark_for_strip ();
1951 0 : return;
1952 : }
1953 :
1954 1378 : AST::DefaultASTVisitor::visit (item);
1955 : /* strip any internal sub-expressions - expression itself isn't
1956 : * allowed to have external attributes in this position so can't be
1957 : * stripped. */
1958 1378 : auto &expr = item.get_expr ();
1959 1378 : if (expr.is_marked_for_strip ())
1960 0 : rust_error_at (expr.get_locus (),
1961 : "cannot strip expression in this position - outer "
1962 : "attributes not allowed");
1963 : }
1964 : void
1965 1328 : CfgStrip::visit (AST::Enum &enum_item)
1966 : {
1967 : // initial test based on outer attrs
1968 1328 : expand_cfg_attrs (enum_item.get_outer_attrs ());
1969 1328 : if (fails_cfg_with_expand (enum_item.get_outer_attrs ()))
1970 : {
1971 0 : enum_item.mark_for_strip ();
1972 0 : return;
1973 : }
1974 :
1975 1328 : AST::DefaultASTVisitor::visit (enum_item);
1976 :
1977 : /* strip enum fields if required - this is presumably
1978 : * allowed by spec */
1979 1328 : maybe_strip_pointer_allow_strip (enum_item.get_variants ());
1980 : }
1981 : void
1982 230 : CfgStrip::visit (AST::Union &union_item)
1983 : {
1984 : // initial test based on outer attrs
1985 230 : expand_cfg_attrs (union_item.get_outer_attrs ());
1986 230 : if (fails_cfg_with_expand (union_item.get_outer_attrs ()))
1987 : {
1988 0 : union_item.mark_for_strip ();
1989 0 : return;
1990 : }
1991 :
1992 230 : AST::DefaultASTVisitor::visit (union_item);
1993 :
1994 : /* strip union fields if required - this is presumably
1995 : * allowed by spec */
1996 230 : maybe_strip_struct_fields (union_item.get_variants ());
1997 : }
1998 : void
1999 1507 : CfgStrip::visit (AST::ConstantItem &const_item)
2000 : {
2001 : // initial test based on outer attrs
2002 1507 : expand_cfg_attrs (const_item.get_outer_attrs ());
2003 1507 : if (fails_cfg_with_expand (const_item.get_outer_attrs ()))
2004 : {
2005 0 : const_item.mark_for_strip ();
2006 0 : return;
2007 : }
2008 :
2009 1507 : AST::DefaultASTVisitor::visit (const_item);
2010 :
2011 : // strip any sub-types
2012 1507 : auto &type = const_item.get_type ();
2013 1507 : if (type.is_marked_for_strip ())
2014 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2015 :
2016 : /* strip any internal sub-expressions - expression itself isn't
2017 : * allowed to have external attributes in this position so can't be
2018 : * stripped. */
2019 1507 : if (const_item.has_expr ())
2020 : {
2021 1365 : auto &expr = const_item.get_expr ();
2022 1365 : if (expr.is_marked_for_strip ())
2023 0 : rust_error_at (expr.get_locus (),
2024 : "cannot strip expression in this position - outer "
2025 : "attributes not allowed");
2026 : }
2027 : }
2028 : void
2029 121 : CfgStrip::visit (AST::StaticItem &static_item)
2030 : {
2031 : // initial test based on outer attrs
2032 121 : expand_cfg_attrs (static_item.get_outer_attrs ());
2033 121 : if (fails_cfg_with_expand (static_item.get_outer_attrs ()))
2034 : {
2035 0 : static_item.mark_for_strip ();
2036 0 : return;
2037 : }
2038 :
2039 121 : AST::DefaultASTVisitor::visit (static_item);
2040 :
2041 : // strip any sub-types
2042 121 : auto &type = static_item.get_type ();
2043 :
2044 121 : if (type.is_marked_for_strip ())
2045 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2046 :
2047 : /* strip any internal sub-expressions - expression itself isn't
2048 : * allowed to have external attributes in this position so can't be
2049 : * stripped. */
2050 121 : auto &expr = static_item.get_expr ();
2051 121 : if (expr.is_marked_for_strip ())
2052 0 : rust_error_at (expr.get_locus (),
2053 : "cannot strip expression in this position - outer "
2054 : "attributes not allowed");
2055 : }
2056 :
2057 : void
2058 3686 : CfgStrip::visit (AST::TraitItemType &item)
2059 : {
2060 : // initial test based on outer attrs
2061 3686 : expand_cfg_attrs (item.get_outer_attrs ());
2062 3686 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
2063 : {
2064 0 : item.mark_for_strip ();
2065 0 : return;
2066 : }
2067 :
2068 3686 : AST::DefaultASTVisitor::visit (item);
2069 : }
2070 :
2071 : void
2072 8686 : CfgStrip::visit (AST::Trait &trait)
2073 : {
2074 : // initial strip test based on outer attrs
2075 8686 : expand_cfg_attrs (trait.get_outer_attrs ());
2076 8686 : if (fails_cfg_with_expand (trait.get_outer_attrs ()))
2077 : {
2078 1 : trait.mark_for_strip ();
2079 1 : return;
2080 : }
2081 :
2082 : // strip test based on inner attrs
2083 8685 : expand_cfg_attrs (trait.get_inner_attrs ());
2084 8685 : if (fails_cfg_with_expand (trait.get_inner_attrs ()))
2085 : {
2086 0 : trait.mark_for_strip ();
2087 0 : return;
2088 : }
2089 :
2090 8685 : AST::DefaultASTVisitor::visit (trait);
2091 :
2092 8685 : maybe_strip_pointer_allow_strip (trait.get_trait_items ());
2093 : }
2094 :
2095 : void
2096 2201 : CfgStrip::visit (AST::InherentImpl &impl)
2097 : {
2098 : // initial strip test based on outer attrs
2099 2201 : expand_cfg_attrs (impl.get_outer_attrs ());
2100 2201 : if (fails_cfg_with_expand (impl.get_outer_attrs ()))
2101 : {
2102 1 : impl.mark_for_strip ();
2103 1 : return;
2104 : }
2105 :
2106 : // strip test based on inner attrs
2107 2200 : expand_cfg_attrs (impl.get_inner_attrs ());
2108 2200 : if (fails_cfg_with_expand (impl.get_inner_attrs ()))
2109 : {
2110 0 : impl.mark_for_strip ();
2111 0 : return;
2112 : }
2113 :
2114 2200 : AST::DefaultASTVisitor::visit (impl);
2115 :
2116 2200 : auto &type = impl.get_type ();
2117 :
2118 2200 : if (type.is_marked_for_strip ())
2119 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2120 :
2121 2200 : maybe_strip_pointer_allow_strip (impl.get_impl_items ());
2122 : }
2123 :
2124 : void
2125 11160 : CfgStrip::visit (AST::TraitImpl &impl)
2126 : {
2127 : // initial strip test based on outer attrs
2128 11160 : expand_cfg_attrs (impl.get_outer_attrs ());
2129 11160 : if (fails_cfg_with_expand (impl.get_outer_attrs ()))
2130 : {
2131 0 : impl.mark_for_strip ();
2132 0 : return;
2133 : }
2134 :
2135 : // strip test based on inner attrs
2136 11160 : expand_cfg_attrs (impl.get_inner_attrs ());
2137 11160 : if (fails_cfg_with_expand (impl.get_inner_attrs ()))
2138 : {
2139 0 : impl.mark_for_strip ();
2140 0 : return;
2141 : }
2142 :
2143 11160 : AST::DefaultASTVisitor::visit (impl);
2144 :
2145 11160 : auto &type = impl.get_type ();
2146 11160 : if (type.is_marked_for_strip ())
2147 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2148 :
2149 11160 : auto &trait_path = impl.get_trait_path ();
2150 11160 : visit (trait_path);
2151 11160 : if (trait_path.is_marked_for_strip ())
2152 0 : rust_error_at (trait_path.get_locus (),
2153 : "cannot strip typepath in this position");
2154 :
2155 11160 : maybe_strip_pointer_allow_strip (impl.get_impl_items ());
2156 : }
2157 :
2158 : void
2159 2 : CfgStrip::visit (AST::ExternalTypeItem &item)
2160 : {
2161 2 : expand_cfg_attrs (item.get_outer_attrs ());
2162 :
2163 2 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
2164 0 : item.mark_for_strip ();
2165 :
2166 : // TODO: Can we do anything like expand a macro here?
2167 : // extern "C" { type ffi_ty!(); }
2168 : // ?
2169 2 : }
2170 :
2171 : void
2172 2 : CfgStrip::visit (AST::ExternalStaticItem &item)
2173 : {
2174 : // strip test based on outer attrs
2175 2 : expand_cfg_attrs (item.get_outer_attrs ());
2176 2 : if (fails_cfg_with_expand (item.get_outer_attrs ()))
2177 : {
2178 0 : item.mark_for_strip ();
2179 0 : return;
2180 : }
2181 :
2182 2 : AST::DefaultASTVisitor::visit (item);
2183 :
2184 2 : auto &type = item.get_type ();
2185 2 : if (type.is_marked_for_strip ())
2186 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2187 : }
2188 :
2189 : void
2190 3355 : CfgStrip::visit (AST::ExternBlock &block)
2191 : {
2192 : // initial strip test based on outer attrs
2193 3355 : expand_cfg_attrs (block.get_outer_attrs ());
2194 3355 : if (fails_cfg_with_expand (block.get_outer_attrs ()))
2195 : {
2196 0 : block.mark_for_strip ();
2197 0 : return;
2198 : }
2199 :
2200 : // strip test based on inner attrs
2201 3355 : expand_cfg_attrs (block.get_inner_attrs ());
2202 3355 : if (fails_cfg_with_expand (block.get_inner_attrs ()))
2203 : {
2204 0 : block.mark_for_strip ();
2205 0 : return;
2206 : }
2207 :
2208 3355 : maybe_strip_pointer_allow_strip (block.get_extern_items ());
2209 : }
2210 :
2211 : void
2212 3825 : CfgStrip::visit (AST::MacroRulesDefinition &rules_def)
2213 : {
2214 : // initial strip test based on outer attrs
2215 3825 : expand_cfg_attrs (rules_def.get_outer_attrs ());
2216 3825 : if (fails_cfg_with_expand (rules_def.get_outer_attrs ()))
2217 : {
2218 0 : rules_def.mark_for_strip ();
2219 0 : return;
2220 : }
2221 : }
2222 :
2223 : void
2224 164106 : CfgStrip::visit (AST::IdentifierPattern &pattern)
2225 : {
2226 : // can only strip sub-patterns of the inner pattern to bind
2227 164106 : if (!pattern.has_subpattern ())
2228 : return;
2229 :
2230 70 : AST::DefaultASTVisitor::visit (pattern);
2231 :
2232 70 : auto &sub_pattern = pattern.get_subpattern ();
2233 70 : if (sub_pattern.is_marked_for_strip ())
2234 0 : rust_error_at (sub_pattern.get_locus (),
2235 : "cannot strip pattern in this position");
2236 : }
2237 :
2238 : void
2239 42 : CfgStrip::visit (AST::RangePatternBoundPath &bound)
2240 : {
2241 : // can expand path, but not strip it directly
2242 42 : auto &path = bound.get_path ();
2243 42 : visit (path);
2244 42 : if (path.is_marked_for_strip ())
2245 0 : rust_error_at (path.get_locus (), "cannot strip path in this position");
2246 42 : }
2247 :
2248 : void
2249 0 : CfgStrip::visit (AST::RangePatternBoundQualPath &bound)
2250 : {
2251 : // can expand path, but not strip it directly
2252 0 : auto &path = bound.get_qualified_path ();
2253 0 : visit (path);
2254 0 : if (path.is_marked_for_strip ())
2255 0 : rust_error_at (path.get_locus (), "cannot strip path in this position");
2256 0 : }
2257 :
2258 : void
2259 820 : CfgStrip::visit (AST::ReferencePattern &pattern)
2260 : {
2261 820 : AST::DefaultASTVisitor::visit (pattern);
2262 :
2263 820 : auto &sub_pattern = pattern.get_referenced_pattern ();
2264 820 : if (sub_pattern.is_marked_for_strip ())
2265 0 : rust_error_at (sub_pattern.get_locus (),
2266 : "cannot strip pattern in this position");
2267 820 : }
2268 : void
2269 78 : CfgStrip::visit (AST::StructPatternFieldTuplePat &field)
2270 : {
2271 : // initial strip test based on outer attrs
2272 78 : expand_cfg_attrs (field.get_outer_attrs ());
2273 78 : if (fails_cfg_with_expand (field.get_outer_attrs ()))
2274 : {
2275 0 : field.mark_for_strip ();
2276 0 : return;
2277 : }
2278 :
2279 78 : AST::DefaultASTVisitor::visit (field);
2280 :
2281 : // strip sub-patterns (can't strip top-level pattern)
2282 78 : auto &sub_pattern = field.get_index_pattern ();
2283 78 : if (sub_pattern.is_marked_for_strip ())
2284 0 : rust_error_at (sub_pattern.get_locus (),
2285 : "cannot strip pattern in this position");
2286 : }
2287 :
2288 : void
2289 516 : CfgStrip::visit (AST::StructPatternFieldIdentPat &field)
2290 : {
2291 : // initial strip test based on outer attrs
2292 516 : expand_cfg_attrs (field.get_outer_attrs ());
2293 516 : if (fails_cfg_with_expand (field.get_outer_attrs ()))
2294 : {
2295 0 : field.mark_for_strip ();
2296 0 : return;
2297 : }
2298 :
2299 516 : AST::DefaultASTVisitor::visit (field);
2300 : // strip sub-patterns (can't strip top-level pattern)
2301 516 : auto &sub_pattern = field.get_ident_pattern ();
2302 516 : if (sub_pattern.is_marked_for_strip ())
2303 0 : rust_error_at (sub_pattern.get_locus (),
2304 : "cannot strip pattern in this position");
2305 : }
2306 : void
2307 252 : CfgStrip::visit (AST::StructPatternFieldIdent &field)
2308 : {
2309 : // initial strip test based on outer attrs
2310 252 : expand_cfg_attrs (field.get_outer_attrs ());
2311 252 : if (fails_cfg_with_expand (field.get_outer_attrs ()))
2312 : {
2313 0 : field.mark_for_strip ();
2314 0 : return;
2315 : }
2316 : }
2317 :
2318 : void
2319 502 : CfgStrip::visit (AST::StructPattern &pattern)
2320 : {
2321 : // expand (but don't strip) path
2322 502 : auto &path = pattern.get_path ();
2323 502 : visit (path);
2324 502 : if (path.is_marked_for_strip ())
2325 0 : rust_error_at (path.get_locus (), "cannot strip path in this position");
2326 :
2327 : /* TODO: apparently struct pattern fields can have outer attrs. so can they
2328 : * be stripped? */
2329 502 : if (!pattern.has_struct_pattern_elems ())
2330 : return;
2331 :
2332 500 : auto &elems = pattern.get_struct_pattern_elems ();
2333 :
2334 : // assuming you can strip struct pattern fields
2335 500 : maybe_strip_pointer_allow_strip (elems.get_struct_pattern_fields ());
2336 :
2337 : // assuming you can strip the ".." part
2338 500 : if (elems.has_rest ())
2339 : {
2340 10 : expand_cfg_attrs (elems.get_etc_outer_attrs ());
2341 10 : if (fails_cfg_with_expand (elems.get_etc_outer_attrs ()))
2342 0 : elems.strip_etc ();
2343 : }
2344 : }
2345 :
2346 : void
2347 4788 : CfgStrip::visit (AST::TupleStructItemsNoRest &tuple_items)
2348 : {
2349 4788 : AST::DefaultASTVisitor::visit (tuple_items);
2350 : // can't strip individual patterns, only sub-patterns
2351 10114 : for (auto &pattern : tuple_items.get_patterns ())
2352 : {
2353 5326 : if (pattern->is_marked_for_strip ())
2354 0 : rust_error_at (pattern->get_locus (),
2355 : "cannot strip pattern in this position");
2356 : // TODO: quit stripping now? or keep going?
2357 : }
2358 4788 : }
2359 : void
2360 148 : CfgStrip::visit (AST::TupleStructItemsHasRest &tuple_items)
2361 : {
2362 148 : AST::DefaultASTVisitor::visit (tuple_items);
2363 : // can't strip individual patterns, only sub-patterns
2364 266 : for (auto &lower_pattern : tuple_items.get_lower_patterns ())
2365 : {
2366 118 : if (lower_pattern->is_marked_for_strip ())
2367 0 : rust_error_at (lower_pattern->get_locus (),
2368 : "cannot strip pattern in this position");
2369 : // TODO: quit stripping now? or keep going?
2370 : }
2371 214 : for (auto &upper_pattern : tuple_items.get_upper_patterns ())
2372 : {
2373 66 : if (upper_pattern->is_marked_for_strip ())
2374 0 : rust_error_at (upper_pattern->get_locus (),
2375 : "cannot strip pattern in this position");
2376 : // TODO: quit stripping now? or keep going?
2377 : }
2378 148 : }
2379 :
2380 : void
2381 4936 : CfgStrip::visit (AST::TupleStructPattern &pattern)
2382 : {
2383 : // expand (but don't strip) path
2384 4936 : auto &path = pattern.get_path ();
2385 4936 : visit (path);
2386 4936 : if (path.is_marked_for_strip ())
2387 0 : rust_error_at (path.get_locus (), "cannot strip path in this position");
2388 :
2389 4936 : AST::DefaultASTVisitor::visit (pattern);
2390 4936 : }
2391 :
2392 : void
2393 3934 : CfgStrip::visit (AST::TuplePatternItemsNoRest &tuple_items)
2394 : {
2395 3934 : AST::DefaultASTVisitor::visit (tuple_items);
2396 :
2397 : // can't strip individual patterns, only sub-patterns
2398 11814 : for (auto &pattern : tuple_items.get_patterns ())
2399 : {
2400 7880 : if (pattern->is_marked_for_strip ())
2401 0 : rust_error_at (pattern->get_locus (),
2402 : "cannot strip pattern in this position");
2403 : // TODO: quit stripping now? or keep going?
2404 : }
2405 3934 : }
2406 :
2407 : void
2408 102 : CfgStrip::visit (AST::TuplePatternItemsHasRest &tuple_items)
2409 : {
2410 102 : AST::DefaultASTVisitor::visit (tuple_items);
2411 :
2412 : // can't strip individual patterns, only sub-patterns
2413 206 : for (auto &lower_pattern : tuple_items.get_lower_patterns ())
2414 : {
2415 104 : if (lower_pattern->is_marked_for_strip ())
2416 0 : rust_error_at (lower_pattern->get_locus (),
2417 : "cannot strip pattern in this position");
2418 : // TODO: quit stripping now? or keep going?
2419 : }
2420 214 : for (auto &upper_pattern : tuple_items.get_upper_patterns ())
2421 : {
2422 112 : if (upper_pattern->is_marked_for_strip ())
2423 0 : rust_error_at (upper_pattern->get_locus (),
2424 : "cannot strip pattern in this position");
2425 : // TODO: quit stripping now? or keep going?
2426 : }
2427 102 : }
2428 :
2429 : void
2430 176 : CfgStrip::visit (AST::GroupedPattern &pattern)
2431 : {
2432 176 : AST::DefaultASTVisitor::visit (pattern);
2433 : // can't strip inner pattern, only sub-patterns
2434 176 : auto &pattern_in_parens = pattern.get_pattern_in_parens ();
2435 :
2436 176 : if (pattern_in_parens.is_marked_for_strip ())
2437 0 : rust_error_at (pattern_in_parens.get_locus (),
2438 : "cannot strip pattern in this position");
2439 176 : }
2440 :
2441 : void
2442 120 : CfgStrip::visit (AST::SlicePatternItemsNoRest &items)
2443 : {
2444 120 : AST::DefaultASTVisitor::visit (items);
2445 : // can't strip individual patterns, only sub-patterns
2446 360 : for (auto &pattern : items.get_patterns ())
2447 : {
2448 240 : if (pattern->is_marked_for_strip ())
2449 0 : rust_error_at (pattern->get_locus (),
2450 : "cannot strip pattern in this position");
2451 : }
2452 120 : }
2453 :
2454 : void
2455 172 : CfgStrip::visit (AST::SlicePatternItemsHasRest &items)
2456 : {
2457 172 : AST::DefaultASTVisitor::visit (items);
2458 : // can't strip individual patterns, only sub-patterns
2459 342 : for (auto &pattern : items.get_lower_patterns ())
2460 : {
2461 170 : if (pattern->is_marked_for_strip ())
2462 0 : rust_error_at (pattern->get_locus (),
2463 : "cannot strip pattern in this position");
2464 : }
2465 342 : for (auto &pattern : items.get_upper_patterns ())
2466 : {
2467 170 : if (pattern->is_marked_for_strip ())
2468 0 : rust_error_at (pattern->get_locus (),
2469 : "cannot strip pattern in this position");
2470 : }
2471 172 : }
2472 :
2473 : void
2474 292 : CfgStrip::visit (AST::SlicePattern &pattern)
2475 : {
2476 292 : AST::DefaultASTVisitor::visit (pattern);
2477 292 : }
2478 :
2479 : void
2480 970 : CfgStrip::visit (AST::AltPattern &pattern)
2481 : {
2482 970 : AST::DefaultASTVisitor::visit (pattern);
2483 : // can't strip individual patterns, only sub-patterns
2484 3040 : for (auto &alt : pattern.get_alts ())
2485 : {
2486 2070 : if (alt->is_marked_for_strip ())
2487 0 : rust_error_at (alt->get_locus (),
2488 : "cannot strip pattern in this position");
2489 : // TODO: quit stripping now? or keep going?
2490 : }
2491 970 : }
2492 :
2493 : void
2494 73952 : CfgStrip::visit (AST::LetStmt &stmt)
2495 : {
2496 : // initial strip test based on outer attrs
2497 73952 : expand_cfg_attrs (stmt.get_outer_attrs ());
2498 73952 : if (fails_cfg_with_expand (stmt.get_outer_attrs ()))
2499 : {
2500 0 : stmt.mark_for_strip ();
2501 0 : return;
2502 : }
2503 :
2504 73952 : AST::DefaultASTVisitor::visit (stmt);
2505 : // can't strip pattern, but call for sub-patterns
2506 73952 : auto &pattern = stmt.get_pattern ();
2507 73952 : if (pattern.is_marked_for_strip ())
2508 0 : rust_error_at (pattern.get_locus (),
2509 : "cannot strip pattern in this position");
2510 :
2511 : // similar for type
2512 73952 : if (stmt.has_type ())
2513 : {
2514 10018 : auto &type = stmt.get_type ();
2515 :
2516 10018 : if (type.is_marked_for_strip ())
2517 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2518 : }
2519 :
2520 : /* strip any internal sub-expressions - expression itself isn't
2521 : * allowed to have external attributes in this position so can't be
2522 : * stripped */
2523 73952 : if (stmt.has_init_expr ())
2524 : {
2525 68828 : auto &init_expr = stmt.get_init_expr ();
2526 :
2527 68828 : if (init_expr.is_marked_for_strip ())
2528 0 : rust_error_at (init_expr.get_locus (),
2529 : "cannot strip expression in this position - outer "
2530 : "attributes not allowed");
2531 : }
2532 : }
2533 :
2534 : void
2535 62516 : CfgStrip::visit (AST::ExprStmt &stmt)
2536 : {
2537 : // outer attributes associated with expr, so rely on expr
2538 :
2539 : // guard - should prevent null pointer expr
2540 62516 : if (stmt.is_marked_for_strip ())
2541 : return;
2542 :
2543 62516 : AST::DefaultASTVisitor::visit (stmt);
2544 : // strip if expr is to be stripped
2545 62516 : auto &expr = stmt.get_expr ();
2546 62516 : if (expr.is_marked_for_strip ())
2547 : {
2548 18 : stmt.mark_for_strip ();
2549 18 : return;
2550 : }
2551 : }
2552 :
2553 : void
2554 6873 : CfgStrip::visit (AST::TraitBound &bound)
2555 : {
2556 : // nothing in for lifetimes to strip
2557 :
2558 : // expand but don't strip type path
2559 6873 : auto &path = bound.get_type_path ();
2560 6873 : visit (path);
2561 6873 : if (path.is_marked_for_strip ())
2562 0 : rust_error_at (path.get_locus (),
2563 : "cannot strip type path in this position");
2564 6873 : }
2565 :
2566 : void
2567 22 : CfgStrip::visit (AST::ParenthesisedType &type)
2568 : {
2569 22 : AST::DefaultASTVisitor::visit (type);
2570 : // expand but don't strip inner type
2571 22 : auto &inner_type = type.get_type_in_parens ();
2572 22 : if (inner_type->is_marked_for_strip ())
2573 0 : rust_error_at (inner_type->get_locus (),
2574 : "cannot strip type in this position");
2575 22 : }
2576 :
2577 : void
2578 1811 : CfgStrip::visit (AST::TupleType &type)
2579 : {
2580 1811 : AST::DefaultASTVisitor::visit (type);
2581 : // TODO: assuming that types can't be stripped as types don't have outer
2582 : // attributes
2583 4693 : for (auto &elem_type : type.get_elems ())
2584 : {
2585 2882 : if (elem_type->is_marked_for_strip ())
2586 0 : rust_error_at (elem_type->get_locus (),
2587 : "cannot strip type in this position");
2588 : }
2589 1811 : }
2590 :
2591 : void
2592 48521 : CfgStrip::visit (AST::RawPointerType &type)
2593 : {
2594 48521 : AST::DefaultASTVisitor::visit (type);
2595 : // expand but don't strip type pointed to
2596 48521 : auto &pointed_type = type.get_type_pointed_to ();
2597 48521 : if (pointed_type.is_marked_for_strip ())
2598 0 : rust_error_at (pointed_type.get_locus (),
2599 : "cannot strip type in this position");
2600 48521 : }
2601 :
2602 : void
2603 32958 : CfgStrip::visit (AST::ReferenceType &type)
2604 : {
2605 32958 : AST::DefaultASTVisitor::visit (type);
2606 : // expand but don't strip type referenced
2607 32958 : auto &referenced_type = type.get_type_referenced ();
2608 32958 : if (referenced_type.is_marked_for_strip ())
2609 0 : rust_error_at (referenced_type.get_locus (),
2610 : "cannot strip type in this position");
2611 32958 : }
2612 :
2613 : void
2614 4892 : CfgStrip::visit (AST::ArrayType &type)
2615 : {
2616 4892 : AST::DefaultASTVisitor::visit (type);
2617 : // expand but don't strip type referenced
2618 4892 : auto &base_type = type.get_elem_type ();
2619 4892 : if (base_type.is_marked_for_strip ())
2620 0 : rust_error_at (base_type.get_locus (),
2621 : "cannot strip type in this position");
2622 :
2623 : // same for expression
2624 4892 : auto &size_expr = type.get_size_expr ();
2625 4892 : if (size_expr.is_marked_for_strip ())
2626 0 : rust_error_at (size_expr.get_locus (),
2627 : "cannot strip expression in this position");
2628 4892 : }
2629 : void
2630 4023 : CfgStrip::visit (AST::SliceType &type)
2631 : {
2632 4023 : AST::DefaultASTVisitor::visit (type);
2633 : // expand but don't strip elem type
2634 4023 : auto &elem_type = type.get_elem_type ();
2635 4023 : if (elem_type.is_marked_for_strip ())
2636 0 : rust_error_at (elem_type.get_locus (),
2637 : "cannot strip type in this position");
2638 4023 : }
2639 :
2640 : void
2641 254 : CfgStrip::visit (AST::BareFunctionType &type)
2642 : {
2643 : // seem to be no generics
2644 254 : AST::DefaultASTVisitor::visit (type);
2645 :
2646 : // presumably function params can be stripped
2647 254 : auto ¶ms = type.get_function_params ();
2648 474 : for (auto it = params.begin (); it != params.end ();)
2649 : {
2650 220 : auto ¶m = *it;
2651 :
2652 220 : auto ¶m_attrs = param.get_outer_attrs ();
2653 220 : expand_cfg_attrs (param_attrs);
2654 220 : if (fails_cfg_with_expand (param_attrs))
2655 : {
2656 0 : it = params.erase (it);
2657 0 : continue;
2658 : }
2659 :
2660 220 : auto &type = param.get_type ();
2661 220 : if (type.is_marked_for_strip ())
2662 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2663 :
2664 : // increment if nothing else happens
2665 220 : ++it;
2666 : }
2667 :
2668 : /* TODO: assuming that variadic nature cannot be stripped. If this
2669 : * is not true, then have code here to do so. */
2670 :
2671 254 : if (type.has_return_type ())
2672 : {
2673 : // FIXME: Can we have type expansion in this position?
2674 : // In that case, we need to handle AST::TypeNoBounds on top of just
2675 : // AST::Types
2676 182 : auto &return_type = type.get_return_type ();
2677 182 : if (return_type.is_marked_for_strip ())
2678 0 : rust_error_at (return_type.get_locus (),
2679 : "cannot strip type in this position");
2680 : }
2681 :
2682 : // no where clause, apparently
2683 254 : }
2684 :
2685 : void
2686 39642 : CfgStrip::visit (AST::SelfParam ¶m)
2687 : {
2688 39642 : AST::DefaultASTVisitor::visit (param);
2689 :
2690 39642 : if (param.has_type ())
2691 : {
2692 4 : auto &type = param.get_type ();
2693 4 : if (type.is_marked_for_strip ())
2694 0 : rust_error_at (type.get_locus (), "cannot strip type in this position");
2695 : }
2696 : /* TODO: maybe check for invariants being violated - e.g. both type and
2697 : * lifetime? */
2698 39642 : }
2699 :
2700 : } // namespace Rust
|