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