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