LCOV - code coverage report
Current view: top level - gcc/rust/expand - rust-expand-visitor.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 77.7 % 548 426
Test Date: 2024-04-27 14:03:13 Functions: 74.8 % 103 77
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // Copyright (C) 2020-2024 Free Software Foundation, Inc.
       2                 :             : 
       3                 :             : // This file is part of GCC.
       4                 :             : 
       5                 :             : // GCC is free software; you can redistribute it and/or modify it under
       6                 :             : // the terms of the GNU General Public License as published by the Free
       7                 :             : // Software Foundation; either version 3, or (at your option) any later
       8                 :             : // version.
       9                 :             : 
      10                 :             : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11                 :             : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12                 :             : // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13                 :             : // for more details.
      14                 :             : 
      15                 :             : // You should have received a copy of the GNU General Public License
      16                 :             : // along with GCC; see the file COPYING3.  If not see
      17                 :             : // <http://www.gnu.org/licenses/>.
      18                 :             : 
      19                 :             : #include "rust-expand-visitor.h"
      20                 :             : #include "rust-proc-macro.h"
      21                 :             : #include "rust-attributes.h"
      22                 :             : #include "rust-ast.h"
      23                 :             : #include "rust-type.h"
      24                 :             : #include "rust-derive.h"
      25                 :             : 
      26                 :             : namespace Rust {
      27                 :             : 
      28                 :             : bool
      29                 :        2762 : is_builtin (AST::Attribute &attr)
      30                 :             : {
      31                 :        2762 :   auto &segments = attr.get_path ().get_segments ();
      32                 :        2762 :   return !segments.empty ()
      33                 :        2762 :          && !Analysis::BuiltinAttributeMappings::get ()
      34                 :        2762 :                ->lookup_builtin (segments[0].get_segment_name ())
      35                 :        2762 :                .is_error ();
      36                 :             : }
      37                 :             : 
      38                 :             : /* Expand all of the macro invocations currently contained in a crate */
      39                 :             : void
      40                 :        5257 : ExpandVisitor::go (AST::Crate &crate)
      41                 :             : {
      42                 :        5257 :   visit (crate);
      43                 :        5257 : }
      44                 :             : 
      45                 :             : static std::unique_ptr<AST::Item>
      46                 :          24 : builtin_derive_item (AST::Item &item, const AST::Attribute &derive,
      47                 :             :                      BuiltinMacro to_derive)
      48                 :             : {
      49                 :           0 :   return AST::DeriveVisitor::derive (item, derive, to_derive);
      50                 :             : }
      51                 :             : 
      52                 :             : static std::vector<std::unique_ptr<AST::Item>>
      53                 :           0 : derive_item (AST::Item &item, AST::SimplePath &to_derive,
      54                 :             :              MacroExpander &expander)
      55                 :             : {
      56                 :           0 :   std::vector<std::unique_ptr<AST::Item>> result;
      57                 :           0 :   auto frag = expander.expand_derive_proc_macro (item, to_derive);
      58                 :           0 :   if (!frag.is_error ())
      59                 :             :     {
      60                 :           0 :       for (auto &node : frag.get_nodes ())
      61                 :             :         {
      62                 :           0 :           switch (node.get_kind ())
      63                 :             :             {
      64                 :           0 :             case AST::SingleASTNode::ITEM:
      65                 :           0 :               result.push_back (node.take_item ());
      66                 :           0 :               break;
      67                 :           0 :             default:
      68                 :           0 :               rust_unreachable ();
      69                 :             :             }
      70                 :             :         }
      71                 :             :     }
      72                 :           0 :   return result;
      73                 :           0 : }
      74                 :             : 
      75                 :             : static std::vector<std::unique_ptr<AST::Item>>
      76                 :           1 : expand_item_attribute (AST::Item &item, AST::SimplePath &name,
      77                 :             :                        MacroExpander &expander)
      78                 :             : {
      79                 :           1 :   std::vector<std::unique_ptr<AST::Item>> result;
      80                 :           1 :   auto frag = expander.expand_attribute_proc_macro (item, name);
      81                 :           1 :   if (!frag.is_error ())
      82                 :             :     {
      83                 :           0 :       for (auto &node : frag.get_nodes ())
      84                 :             :         {
      85                 :           0 :           switch (node.get_kind ())
      86                 :             :             {
      87                 :           0 :             case AST::SingleASTNode::ITEM:
      88                 :           0 :               result.push_back (node.take_item ());
      89                 :           0 :               break;
      90                 :           0 :             default:
      91                 :           0 :               rust_unreachable ();
      92                 :             :             }
      93                 :             :         }
      94                 :             :     }
      95                 :           1 :   return result;
      96                 :           1 : }
      97                 :             : 
      98                 :             : /* Helper function to expand a given attribute on a statement and collect back
      99                 :             :  * statements.
     100                 :             :  * T should be anything that can be used as a statement accepting outer
     101                 :             :  * attributes.
     102                 :             :  */
     103                 :             : template <typename T>
     104                 :             : static std::vector<std::unique_ptr<AST::Stmt>>
     105                 :           0 : expand_stmt_attribute (T &statement, AST::SimplePath &attribute,
     106                 :             :                        MacroExpander &expander)
     107                 :             : {
     108                 :           0 :   std::vector<std::unique_ptr<AST::Stmt>> result;
     109                 :           0 :   auto frag = expander.expand_attribute_proc_macro (statement, attribute);
     110                 :           0 :   if (!frag.is_error ())
     111                 :             :     {
     112                 :           0 :       for (auto &node : frag.get_nodes ())
     113                 :             :         {
     114                 :           0 :           switch (node.get_kind ())
     115                 :             :             {
     116                 :           0 :             case AST::SingleASTNode::STMT:
     117                 :           0 :               result.push_back (node.take_stmt ());
     118                 :             :               break;
     119                 :           0 :             default:
     120                 :           0 :               rust_unreachable ();
     121                 :             :             }
     122                 :             :         }
     123                 :             :     }
     124                 :           0 :   return result;
     125                 :           0 : }
     126                 :             : 
     127                 :             : void
     128                 :       16901 : expand_tail_expr (AST::BlockExpr &block_expr, MacroExpander &expander)
     129                 :             : {
     130                 :       16901 :   if (block_expr.has_tail_expr ())
     131                 :             :     {
     132                 :       11917 :       auto tail = block_expr.take_tail_expr ();
     133                 :       11917 :       auto attrs = tail->get_outer_attrs ();
     134                 :       11917 :       bool changed = false;
     135                 :       12129 :       for (auto it = attrs.begin (); it != attrs.end ();)
     136                 :             :         {
     137                 :         212 :           auto current = *it;
     138                 :         212 :           if (is_builtin (current))
     139                 :             :             {
     140                 :         212 :               it++;
     141                 :             :             }
     142                 :             :           else
     143                 :             :             {
     144                 :           0 :               it = attrs.erase (it);
     145                 :           0 :               changed = true;
     146                 :           0 :               auto new_stmts
     147                 :             :                 = expand_stmt_attribute (block_expr, current.get_path (),
     148                 :           0 :                                          expander);
     149                 :           0 :               auto &stmts = block_expr.get_statements ();
     150                 :           0 :               std::move (new_stmts.begin (), new_stmts.end (),
     151                 :             :                          std::inserter (stmts, stmts.end ()));
     152                 :           0 :             }
     153                 :         212 :         }
     154                 :       11917 :       if (changed)
     155                 :           0 :         block_expr.normalize_tail_expr ();
     156                 :             :       else
     157                 :       11917 :         block_expr.set_tail_expr (std::move (tail));
     158                 :       11917 :     }
     159                 :       16901 : }
     160                 :             : 
     161                 :             : void
     162                 :        5257 : ExpandVisitor::expand_inner_items (
     163                 :             :   std::vector<std::unique_ptr<AST::Item>> &items)
     164                 :             : {
     165                 :        5257 :   expander.push_context (MacroExpander::ContextType::ITEM);
     166                 :             : 
     167                 :       24633 :   for (auto it = items.begin (); it != items.end (); it++)
     168                 :             :     {
     169                 :       19376 :       auto &item = *it;
     170                 :       19376 :       if (item->has_outer_attrs ())
     171                 :             :         {
     172                 :        2480 :           auto &attrs = item->get_outer_attrs ();
     173                 :             : 
     174                 :        5050 :           for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
     175                 :             :                /* erase => No increment*/)
     176                 :             :             {
     177                 :        2571 :               auto current = *attr_it;
     178                 :             : 
     179                 :        2571 :               if (current.is_derive ())
     180                 :             :                 {
     181                 :          25 :                   current.parse_attr_to_meta_item ();
     182                 :          25 :                   attr_it = attrs.erase (attr_it);
     183                 :             :                   // Get traits to derive in the current attribute
     184                 :          25 :                   auto traits_to_derive = current.get_traits_to_derive ();
     185                 :          49 :                   for (auto &to_derive : traits_to_derive)
     186                 :             :                     {
     187                 :          48 :                       auto maybe_builtin = MacroBuiltin::builtins.lookup (
     188                 :          24 :                         to_derive.get ().as_string ());
     189                 :          24 :                       if (MacroBuiltin::builtins.is_iter_ok (maybe_builtin))
     190                 :             :                         {
     191                 :          24 :                           auto new_item
     192                 :          24 :                             = builtin_derive_item (*item, current,
     193                 :          24 :                                                    maybe_builtin->second);
     194                 :             :                           // this inserts the derive *before* the item - is it a
     195                 :             :                           // problem?
     196                 :          24 :                           it = items.insert (it, std::move (new_item));
     197                 :          24 :                         }
     198                 :             :                       else
     199                 :             :                         {
     200                 :           0 :                           auto new_items
     201                 :           0 :                             = derive_item (*item, to_derive, expander);
     202                 :           0 :                           std::move (new_items.begin (), new_items.end (),
     203                 :             :                                      std::inserter (items, it));
     204                 :           0 :                         }
     205                 :             :                     }
     206                 :          25 :                 }
     207                 :             :               else /* Attribute */
     208                 :             :                 {
     209                 :        2546 :                   if (is_builtin (current))
     210                 :             :                     {
     211                 :        2545 :                       attr_it++;
     212                 :             :                     }
     213                 :             :                   else
     214                 :             :                     {
     215                 :           1 :                       attr_it = attrs.erase (attr_it);
     216                 :           1 :                       auto new_items
     217                 :           1 :                         = expand_item_attribute (*item, current.get_path (),
     218                 :           1 :                                                  expander);
     219                 :           1 :                       it = items.erase (it);
     220                 :           1 :                       std::move (new_items.begin (), new_items.end (),
     221                 :             :                                  std::inserter (items, it));
     222                 :             :                       // TODO: Improve this ?
     223                 :             :                       // item is invalid since it refers to now deleted,
     224                 :             :                       // cancel the loop increment and break.
     225                 :           1 :                       it--;
     226                 :           1 :                       break;
     227                 :           1 :                     }
     228                 :             :                 }
     229                 :        2571 :             }
     230                 :             :         }
     231                 :             :     }
     232                 :             : 
     233                 :        5257 :   std::function<std::unique_ptr<AST::Item> (AST::SingleASTNode)> extractor
     234                 :        1633 :     = [] (AST::SingleASTNode node) { return node.take_item (); };
     235                 :             : 
     236                 :        5257 :   expand_macro_children (items, extractor);
     237                 :             : 
     238                 :        5257 :   expander.pop_context ();
     239                 :        5257 : }
     240                 :             : 
     241                 :             : void
     242                 :       16901 : ExpandVisitor::expand_inner_stmts (AST::BlockExpr &expr)
     243                 :             : {
     244                 :       16901 :   auto &stmts = expr.get_statements ();
     245                 :       16901 :   expander.push_context (MacroExpander::ContextType::STMT);
     246                 :             : 
     247                 :       35863 :   for (auto it = stmts.begin (); it != stmts.end (); it++)
     248                 :             :     {
     249                 :       18962 :       auto &stmt = *it;
     250                 :             : 
     251                 :             :       // skip all non-item statements
     252                 :       18962 :       if (stmt->get_stmt_kind () != AST::Stmt::Kind::Item)
     253                 :       18183 :         continue;
     254                 :             : 
     255                 :         779 :       auto &item = static_cast<AST::Item &> (*stmt.get ());
     256                 :             : 
     257                 :         779 :       if (item.has_outer_attrs ())
     258                 :             :         {
     259                 :           4 :           auto &attrs = item.get_outer_attrs ();
     260                 :             : 
     261                 :           8 :           for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
     262                 :             :                /* erase => No increment*/)
     263                 :             :             {
     264                 :           4 :               auto current = *attr_it;
     265                 :             : 
     266                 :           4 :               if (current.is_derive ())
     267                 :             :                 {
     268                 :           0 :                   attr_it = attrs.erase (attr_it);
     269                 :             :                   // Get traits to derive in the current attribute
     270                 :           0 :                   auto traits_to_derive = current.get_traits_to_derive ();
     271                 :           0 :                   for (auto &to_derive : traits_to_derive)
     272                 :             :                     {
     273                 :           0 :                       auto maybe_builtin = MacroBuiltin::builtins.lookup (
     274                 :           0 :                         to_derive.get ().as_string ());
     275                 :           0 :                       if (MacroBuiltin::builtins.is_iter_ok (maybe_builtin))
     276                 :             :                         {
     277                 :           0 :                           auto new_item
     278                 :             :                             = builtin_derive_item (item, current,
     279                 :           0 :                                                    maybe_builtin->second);
     280                 :             :                           // this inserts the derive *before* the item - is it a
     281                 :             :                           // problem?
     282                 :           0 :                           it = stmts.insert (it, std::move (new_item));
     283                 :           0 :                         }
     284                 :             :                       else
     285                 :             :                         {
     286                 :           0 :                           auto new_items
     287                 :           0 :                             = derive_item (item, to_derive, expander);
     288                 :           0 :                           std::move (new_items.begin (), new_items.end (),
     289                 :             :                                      std::inserter (stmts, it));
     290                 :           0 :                         }
     291                 :             :                     }
     292                 :           0 :                 }
     293                 :             :               else /* Attribute */
     294                 :             :                 {
     295                 :           4 :                   if (is_builtin (current))
     296                 :             :                     {
     297                 :           4 :                       attr_it++;
     298                 :             :                     }
     299                 :             :                   else
     300                 :             :                     {
     301                 :           0 :                       attr_it = attrs.erase (attr_it);
     302                 :           0 :                       auto new_items
     303                 :             :                         = expand_stmt_attribute (item, current.get_path (),
     304                 :           0 :                                                  expander);
     305                 :           0 :                       it = stmts.erase (it);
     306                 :           0 :                       std::move (new_items.begin (), new_items.end (),
     307                 :             :                                  std::inserter (stmts, it));
     308                 :             :                       // TODO: Improve this ?
     309                 :             :                       // item is invalid since it refers to now deleted,
     310                 :             :                       // cancel the loop increment and break.
     311                 :           0 :                       it--;
     312                 :           0 :                       break;
     313                 :           0 :                     }
     314                 :             :                 }
     315                 :           4 :             }
     316                 :             :         }
     317                 :             :     }
     318                 :             : 
     319                 :       16901 :   if (!expr.has_tail_expr ())
     320                 :        5001 :     expr.normalize_tail_expr ();
     321                 :             : 
     322                 :       16901 :   std::function<std::unique_ptr<AST::Stmt> (AST::SingleASTNode)> extractor
     323                 :         373 :     = [] (AST::SingleASTNode node) { return node.take_stmt (); };
     324                 :             : 
     325                 :       16901 :   expand_macro_children (stmts, extractor);
     326                 :             : 
     327                 :       16901 :   expander.pop_context ();
     328                 :       16901 : }
     329                 :             : 
     330                 :             : void
     331                 :     1103402 : ExpandVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
     332                 :             : {
     333                 :     1103402 :   expander.push_context (MacroExpander::ContextType::EXPR);
     334                 :     1103402 :   expr->accept_vis (*this);
     335                 :     1103402 :   expander.pop_context ();
     336                 :             : 
     337                 :     1103402 :   auto final_fragment = expander.take_expanded_fragment ();
     338                 :     1103402 :   if (final_fragment.should_expand ()
     339                 :     1103402 :       && final_fragment.is_expression_fragment ())
     340                 :        1664 :     expr = final_fragment.take_expression_fragment ();
     341                 :     1103402 : }
     342                 :             : 
     343                 :             : void
     344                 :       27955 : ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::Type> &type)
     345                 :             : {
     346                 :       27955 :   expander.push_context (MacroExpander::ContextType::TYPE);
     347                 :             : 
     348                 :       27955 :   type->accept_vis (*this);
     349                 :       27955 :   auto final_fragment = expander.take_expanded_fragment ();
     350                 :       27955 :   if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
     351                 :          19 :     type = final_fragment.take_type_fragment ();
     352                 :             : 
     353                 :       27955 :   expander.pop_context ();
     354                 :       27955 : }
     355                 :             : 
     356                 :             : // FIXME: Can this be refactored into a `scoped` method? Which takes a
     357                 :             : // ContextType as parameter and a lambda? And maybe just an std::vector<T>&?
     358                 :             : void
     359                 :        1213 : ExpandVisitor::expand_struct_fields (std::vector<AST::StructField> &fields)
     360                 :             : {
     361                 :        2950 :   for (auto &field : fields)
     362                 :             :     {
     363                 :        1737 :       maybe_expand_type (field.get_field_type ());
     364                 :             :     }
     365                 :        1213 : }
     366                 :             : 
     367                 :             : void
     368                 :        1057 : ExpandVisitor::expand_tuple_fields (std::vector<AST::TupleField> &fields)
     369                 :             : {
     370                 :        2751 :   for (auto &field : fields)
     371                 :        1694 :     maybe_expand_type (field.get_field_type ());
     372                 :        1057 : }
     373                 :             : 
     374                 :             : // FIXME: This can definitely be refactored with the method above
     375                 :             : void
     376                 :       12838 : ExpandVisitor::expand_function_params (
     377                 :             :   std::vector<std::unique_ptr<AST::Param>> &params)
     378                 :             : {
     379                 :       22082 :   for (auto &p : params)
     380                 :        9244 :     visit (p);
     381                 :       12838 : }
     382                 :             : 
     383                 :             : void
     384                 :         650 : ExpandVisitor::expand_generic_args (AST::GenericArgs &args)
     385                 :             : {
     386                 :        1340 :   for (auto &arg : args.get_generic_args ())
     387                 :             :     {
     388                 :         690 :       switch (arg.get_kind ())
     389                 :             :         {
     390                 :         305 :         case AST::GenericArg::Kind::Type:
     391                 :         305 :           maybe_expand_type (arg.get_type ());
     392                 :         305 :           break;
     393                 :           0 :         case AST::GenericArg::Kind::Const:
     394                 :           0 :           maybe_expand_expr (arg.get_expression ());
     395                 :           0 :           break;
     396                 :             :         default:
     397                 :             :           break;
     398                 :             :           // FIXME: Figure out what to do here if there is ambiguity. Since the
     399                 :             :           // resolver comes after the expansion, we need to figure out a way to
     400                 :             :           // strip ambiguous values here
     401                 :             :           // TODO: ARTHUR: Probably add a `mark_as_strip` method to `GenericArg`
     402                 :             :           // or something. This would clean up this whole thing
     403                 :             :         }
     404                 :             :     }
     405                 :             : 
     406                 :             :   // FIXME: Can we have macro invocations in generic type bindings?
     407                 :             :   // expand binding args - strip sub-types only
     408                 :             :   // FIXME: ARTHUR: This needs a test! Foo<Item = macro!()>
     409                 :         652 :   for (auto &binding : args.get_binding_args ())
     410                 :           2 :     maybe_expand_type (binding.get_type ());
     411                 :         650 : }
     412                 :             : 
     413                 :             : void
     414                 :         326 : ExpandVisitor::expand_qualified_path_type (AST::QualifiedPathType &path_type)
     415                 :             : {
     416                 :         326 :   maybe_expand_type (path_type.get_type ());
     417                 :             : 
     418                 :             :   // FIXME: ARTHUR: Can we do macro expansion in there? Needs a test!
     419                 :         326 :   if (path_type.has_as_clause ())
     420                 :         301 :     path_type.get_as_type_path ().accept_vis (*this);
     421                 :         326 : }
     422                 :             : 
     423                 :             : void
     424                 :          55 : ExpandVisitor::expand_closure_params (std::vector<AST::ClosureParam> &params)
     425                 :             : {
     426                 :         110 :   for (auto &param : params)
     427                 :             :     {
     428                 :          55 :       if (param.has_type_given ())
     429                 :          51 :         maybe_expand_type (param.get_type ());
     430                 :             :     }
     431                 :          55 : }
     432                 :             : 
     433                 :             : void
     434                 :         106 : ExpandVisitor::expand_where_clause (AST::WhereClause &where_clause)
     435                 :             : {
     436                 :         215 :   for (auto &item : where_clause.get_items ())
     437                 :         109 :     visit (item);
     438                 :         106 : }
     439                 :             : 
     440                 :             : void
     441                 :        5257 : ExpandVisitor::visit (AST::Crate &crate)
     442                 :             : {
     443                 :        5257 :   expand_inner_items (crate.items);
     444                 :        5257 : }
     445                 :             : 
     446                 :             : void
     447                 :           0 : ExpandVisitor::visit (AST::DelimTokenTree &)
     448                 :           0 : {}
     449                 :             : 
     450                 :             : void
     451                 :           0 : ExpandVisitor::visit (AST::AttrInputMetaItemContainer &)
     452                 :           0 : {}
     453                 :             : 
     454                 :             : void
     455                 :       17241 : ExpandVisitor::visit (AST::IdentifierExpr &ident_expr)
     456                 :       17241 : {}
     457                 :             : 
     458                 :             : void
     459                 :         201 : ExpandVisitor::visit (AST::LifetimeParam &)
     460                 :         201 : {}
     461                 :             : 
     462                 :             : void
     463                 :          28 : ExpandVisitor::visit (AST::ConstGenericParam &)
     464                 :          28 : {}
     465                 :             : 
     466                 :             : void
     467                 :        2271 : ExpandVisitor::visit (AST::MacroInvocation &macro_invoc)
     468                 :             : {
     469                 :             :   // TODO: Can we do the AST fragment replacing here? Probably not, right?
     470                 :        2271 :   expander.expand_invoc (macro_invoc, macro_invoc.has_semicolon ());
     471                 :        2271 : }
     472                 :             : 
     473                 :             : void
     474                 :       13052 : ExpandVisitor::visit (AST::PathInExpression &path)
     475                 :             : {
     476                 :       29520 :   for (auto &segment : path.get_segments ())
     477                 :       32936 :     if (segment.has_generic_args ())
     478                 :         650 :       expand_generic_args (segment.get_generic_args ());
     479                 :       13052 : }
     480                 :             : 
     481                 :             : void
     482                 :        1752 : ExpandVisitor::visit (AST::TypePathSegmentGeneric &segment)
     483                 :        1752 : {}
     484                 :             : 
     485                 :             : void
     486                 :          19 : ExpandVisitor::visit (AST::TypePathSegmentFunction &segment)
     487                 :             : {
     488                 :          19 :   auto &type_path_function = segment.get_type_path_function ();
     489                 :             : 
     490                 :          38 :   for (auto &type : type_path_function.get_params ())
     491                 :          19 :     visit (type);
     492                 :             : 
     493                 :          19 :   if (type_path_function.has_return_type ())
     494                 :          17 :     maybe_expand_type (type_path_function.get_return_type ());
     495                 :          19 : }
     496                 :             : 
     497                 :             : void
     498                 :          88 : ExpandVisitor::visit (AST::QualifiedPathInExpression &path)
     499                 :             : {
     500                 :          88 :   expand_qualified_path_type (path.get_qualified_path_type ());
     501                 :             : 
     502                 :         176 :   for (auto &segment : path.get_segments ())
     503                 :         176 :     if (segment.has_generic_args ())
     504                 :           0 :       expand_generic_args (segment.get_generic_args ());
     505                 :          88 : }
     506                 :             : 
     507                 :             : void
     508                 :         238 : ExpandVisitor::visit (AST::QualifiedPathInType &path)
     509                 :             : {
     510                 :         238 :   expand_qualified_path_type (path.get_qualified_path_type ());
     511                 :             : 
     512                 :             :   // this shouldn't strip any segments, but can strip inside them
     513                 :         238 :   for (auto &segment : path.get_segments ())
     514                 :           0 :     visit (segment);
     515                 :         238 : }
     516                 :             : 
     517                 :             : void
     518                 :      538761 : ExpandVisitor::visit (AST::LiteralExpr &expr)
     519                 :      538761 : {}
     520                 :             : 
     521                 :             : void
     522                 :           0 : ExpandVisitor::visit (AST::AttrInputLiteral &)
     523                 :           0 : {}
     524                 :             : 
     525                 :             : void
     526                 :           0 : ExpandVisitor::visit (AST::AttrInputMacro &macro)
     527                 :             : {
     528                 :           0 :   rust_sorry_at (UNDEF_LOCATION, "macros in attributes not supported");
     529                 :           0 : }
     530                 :             : 
     531                 :             : void
     532                 :           0 : ExpandVisitor::visit (AST::MetaItemLitExpr &)
     533                 :           0 : {}
     534                 :             : 
     535                 :             : void
     536                 :           0 : ExpandVisitor::visit (AST::MetaItemPathLit &)
     537                 :           0 : {}
     538                 :             : 
     539                 :             : void
     540                 :           0 : ExpandVisitor::visit (AST::ErrorPropagationExpr &expr)
     541                 :             : {
     542                 :           0 :   visit (expr.get_propagating_expr ());
     543                 :           0 : }
     544                 :             : 
     545                 :             : void
     546                 :      527327 : ExpandVisitor::visit (AST::ArithmeticOrLogicalExpr &expr)
     547                 :             : {
     548                 :      527327 :   maybe_expand_expr (expr.get_left_expr ());
     549                 :      527327 :   maybe_expand_expr (expr.get_right_expr ());
     550                 :      527327 : }
     551                 :             : 
     552                 :             : void
     553                 :        1135 : ExpandVisitor::visit (AST::ComparisonExpr &expr)
     554                 :             : {
     555                 :        1135 :   maybe_expand_expr (expr.get_left_expr ());
     556                 :        1135 :   maybe_expand_expr (expr.get_right_expr ());
     557                 :        1135 : }
     558                 :             : 
     559                 :             : void
     560                 :         497 : ExpandVisitor::visit (AST::LazyBooleanExpr &expr)
     561                 :             : {
     562                 :         497 :   maybe_expand_expr (expr.get_left_expr ());
     563                 :         497 :   maybe_expand_expr (expr.get_right_expr ());
     564                 :         497 : }
     565                 :             : 
     566                 :             : void
     567                 :        1794 : ExpandVisitor::visit (AST::AssignmentExpr &expr)
     568                 :             : {
     569                 :        1794 :   maybe_expand_expr (expr.get_left_expr ());
     570                 :        1794 :   maybe_expand_expr (expr.get_right_expr ());
     571                 :        1794 : }
     572                 :             : 
     573                 :             : void
     574                 :         198 : ExpandVisitor::visit (AST::CompoundAssignmentExpr &expr)
     575                 :             : {
     576                 :         198 :   maybe_expand_expr (expr.get_left_expr ());
     577                 :         198 :   maybe_expand_expr (expr.get_right_expr ());
     578                 :         198 : }
     579                 :             : 
     580                 :             : void
     581                 :         198 : ExpandVisitor::visit (AST::GroupedExpr &expr)
     582                 :             : {
     583                 :         198 :   maybe_expand_expr (expr.get_expr_in_parens ());
     584                 :         198 : }
     585                 :             : 
     586                 :             : void
     587                 :          51 : ExpandVisitor::visit (AST::StructExprStruct &expr)
     588                 :          51 : {}
     589                 :             : 
     590                 :             : void
     591                 :        8374 : ExpandVisitor::visit (AST::CallExpr &expr)
     592                 :             : {
     593                 :        8374 :   visit (expr.get_function_expr ());
     594                 :             : 
     595                 :       18271 :   for (auto &param : expr.get_params ())
     596                 :        9897 :     maybe_expand_expr (param);
     597                 :        8374 : }
     598                 :             : 
     599                 :             : void
     600                 :        1267 : ExpandVisitor::visit (AST::MethodCallExpr &expr)
     601                 :             : {
     602                 :        1267 :   visit (expr.get_receiver_expr ());
     603                 :             : 
     604                 :        1865 :   for (auto &param : expr.get_params ())
     605                 :         598 :     maybe_expand_expr (param);
     606                 :        1267 : }
     607                 :             : 
     608                 :             : void
     609                 :          25 : ExpandVisitor::visit (AST::ClosureExprInner &expr)
     610                 :             : {
     611                 :          25 :   expand_closure_params (expr.get_params ());
     612                 :             : 
     613                 :          25 :   visit (expr.get_definition_expr ());
     614                 :          25 : }
     615                 :             : 
     616                 :             : void
     617                 :       16901 : ExpandVisitor::visit (AST::BlockExpr &expr)
     618                 :             : {
     619                 :       16901 :   expand_inner_stmts (expr);
     620                 :             : 
     621                 :       16901 :   expand_tail_expr (expr, expander);
     622                 :       16901 :   if (expr.has_tail_expr ())
     623                 :       11917 :     maybe_expand_expr (expr.get_tail_expr ());
     624                 :       16901 : }
     625                 :             : 
     626                 :             : void
     627                 :          30 : ExpandVisitor::visit (AST::ClosureExprInnerTyped &expr)
     628                 :             : {
     629                 :          30 :   expand_closure_params (expr.get_params ());
     630                 :             : 
     631                 :          30 :   maybe_expand_type (expr.get_return_type ());
     632                 :             : 
     633                 :          30 :   visit (expr.get_definition_block ());
     634                 :          30 : }
     635                 :             : 
     636                 :             : void
     637                 :          10 : ExpandVisitor::visit (AST::ContinueExpr &expr)
     638                 :          10 : {}
     639                 :             : 
     640                 :             : void
     641                 :         375 : ExpandVisitor::visit (AST::IfExpr &expr)
     642                 :             : {
     643                 :         375 :   maybe_expand_expr (expr.get_condition_expr ());
     644                 :             : 
     645                 :         375 :   visit (expr.get_if_block ());
     646                 :         375 : }
     647                 :             : 
     648                 :             : void
     649                 :         465 : ExpandVisitor::visit (AST::IfExprConseqElse &expr)
     650                 :             : {
     651                 :         465 :   maybe_expand_expr (expr.get_condition_expr ());
     652                 :             : 
     653                 :         465 :   visit (expr.get_if_block ());
     654                 :         465 :   visit (expr.get_else_block ());
     655                 :         465 : }
     656                 :             : 
     657                 :             : void
     658                 :           1 : ExpandVisitor::visit (AST::IfLetExpr &expr)
     659                 :             : {
     660                 :           1 :   maybe_expand_expr (expr.get_value_expr ());
     661                 :             : 
     662                 :           1 :   visit (expr.get_if_block ());
     663                 :           1 : }
     664                 :             : 
     665                 :             : void
     666                 :           2 : ExpandVisitor::visit (AST::IfLetExprConseqElse &expr)
     667                 :             : {
     668                 :           2 :   maybe_expand_expr (expr.get_value_expr ());
     669                 :             : 
     670                 :           2 :   visit (expr.get_if_block ());
     671                 :           2 :   visit (expr.get_else_block ());
     672                 :           2 : }
     673                 :             : 
     674                 :             : void
     675                 :         238 : ExpandVisitor::visit (AST::MatchExpr &expr)
     676                 :             : {
     677                 :         238 :   visit (expr.get_scrutinee_expr ());
     678                 :             : 
     679                 :         815 :   for (auto &match_case : expr.get_match_cases ())
     680                 :             :     {
     681                 :         577 :       auto &arm = match_case.get_arm ();
     682                 :             : 
     683                 :        1154 :       for (auto &pattern : arm.get_patterns ())
     684                 :         577 :         visit (pattern);
     685                 :             : 
     686                 :         577 :       if (arm.has_match_arm_guard ())
     687                 :           2 :         maybe_expand_expr (arm.get_guard_expr ());
     688                 :             : 
     689                 :         577 :       maybe_expand_expr (match_case.get_expr ());
     690                 :             :     }
     691                 :         238 : }
     692                 :             : 
     693                 :             : void
     694                 :        3509 : ExpandVisitor::visit (AST::TypeParam &param)
     695                 :             : {
     696                 :        3886 :   for (auto &bound : param.get_type_param_bounds ())
     697                 :         377 :     visit (bound);
     698                 :             : 
     699                 :        3509 :   if (param.has_type ())
     700                 :         145 :     maybe_expand_type (param.get_type ());
     701                 :        3509 : }
     702                 :             : 
     703                 :             : void
     704                 :           0 : ExpandVisitor::visit (AST::LifetimeWhereClauseItem &)
     705                 :           0 : {}
     706                 :             : 
     707                 :             : void
     708                 :         109 : ExpandVisitor::visit (AST::TypeBoundWhereClauseItem &item)
     709                 :             : {
     710                 :         109 :   maybe_expand_type (item.get_type ());
     711                 :             : 
     712                 :         218 :   for (auto &bound : item.get_type_param_bounds ())
     713                 :         109 :     visit (bound);
     714                 :         109 : }
     715                 :             : 
     716                 :             : void
     717                 :           8 : ExpandVisitor::visit (AST::ExternCrate &crate)
     718                 :           8 : {}
     719                 :             : 
     720                 :             : void
     721                 :           0 : ExpandVisitor::visit (AST::UseTreeGlob &)
     722                 :           0 : {}
     723                 :             : 
     724                 :             : void
     725                 :           0 : ExpandVisitor::visit (AST::UseTreeList &)
     726                 :           0 : {}
     727                 :             : 
     728                 :             : void
     729                 :           0 : ExpandVisitor::visit (AST::UseTreeRebind &)
     730                 :           0 : {}
     731                 :             : 
     732                 :             : void
     733                 :         159 : ExpandVisitor::visit (AST::UseDeclaration &use_decl)
     734                 :         159 : {}
     735                 :             : 
     736                 :             : void
     737                 :       12838 : ExpandVisitor::visit (AST::Function &function)
     738                 :             : {
     739                 :       12838 :   if (function.has_body ())
     740                 :       11705 :     visit_inner_using_attrs (
     741                 :       11705 :       function, function.get_definition ().value ()->get_inner_attrs ());
     742                 :       13464 :   for (auto &param : function.get_generic_params ())
     743                 :         626 :     visit (param);
     744                 :             : 
     745                 :       12838 :   expand_function_params (function.get_function_params ());
     746                 :             : 
     747                 :       12838 :   if (function.has_return_type ())
     748                 :        9126 :     maybe_expand_type (function.get_return_type ());
     749                 :             : 
     750                 :       12838 :   if (function.has_where_clause ())
     751                 :          14 :     expand_where_clause (function.get_where_clause ());
     752                 :             : 
     753                 :       12838 :   if (function.has_body ())
     754                 :       11705 :     visit (*function.get_definition ());
     755                 :       12838 : }
     756                 :             : 
     757                 :             : void
     758                 :        1068 : ExpandVisitor::visit (AST::StructStruct &struct_item)
     759                 :             : {
     760                 :        1344 :   for (auto &generic : struct_item.get_generic_params ())
     761                 :         276 :     visit (generic);
     762                 :             : 
     763                 :        1068 :   if (struct_item.has_where_clause ())
     764                 :           2 :     expand_where_clause (struct_item.get_where_clause ());
     765                 :             : 
     766                 :        1068 :   expand_struct_fields (struct_item.get_fields ());
     767                 :        1068 : }
     768                 :             : 
     769                 :             : void
     770                 :         812 : ExpandVisitor::visit (AST::TupleStruct &tuple_struct)
     771                 :             : {
     772                 :        1166 :   for (auto &generic : tuple_struct.get_generic_params ())
     773                 :         354 :     visit (generic);
     774                 :             : 
     775                 :         812 :   if (tuple_struct.has_where_clause ())
     776                 :           0 :     expand_where_clause (tuple_struct.get_where_clause ());
     777                 :             : 
     778                 :         812 :   expand_tuple_fields (tuple_struct.get_fields ());
     779                 :         812 : }
     780                 :             : 
     781                 :             : void
     782                 :         224 : ExpandVisitor::visit (AST::EnumItem &item)
     783                 :         224 : {}
     784                 :             : 
     785                 :             : void
     786                 :         245 : ExpandVisitor::visit (AST::EnumItemTuple &item)
     787                 :             : {
     788                 :         245 :   expand_tuple_fields (item.get_tuple_fields ());
     789                 :         245 : }
     790                 :             : 
     791                 :             : void
     792                 :          51 : ExpandVisitor::visit (AST::EnumItemStruct &item)
     793                 :             : {
     794                 :          51 :   expand_struct_fields (item.get_struct_fields ());
     795                 :          51 : }
     796                 :             : 
     797                 :             : void
     798                 :          11 : ExpandVisitor::visit (AST::EnumItemDiscriminant &item)
     799                 :             : {
     800                 :          11 :   maybe_expand_expr (item.get_expr ());
     801                 :          11 : }
     802                 :             : 
     803                 :             : void
     804                 :          94 : ExpandVisitor::visit (AST::Union &union_item)
     805                 :             : {
     806                 :         160 :   for (auto &generic : union_item.get_generic_params ())
     807                 :          66 :     visit (generic);
     808                 :             : 
     809                 :          94 :   expand_struct_fields (union_item.get_variants ());
     810                 :          94 : }
     811                 :             : 
     812                 :             : void
     813                 :         473 : ExpandVisitor::visit (AST::ConstantItem &const_item)
     814                 :             : {
     815                 :         473 :   maybe_expand_type (const_item.get_type ());
     816                 :             : 
     817                 :         473 :   if (const_item.has_expr ())
     818                 :         472 :     maybe_expand_expr (const_item.get_expr ());
     819                 :         473 : }
     820                 :             : 
     821                 :             : void
     822                 :          42 : ExpandVisitor::visit (AST::StaticItem &static_item)
     823                 :             : {
     824                 :          42 :   maybe_expand_type (static_item.get_type ());
     825                 :             : 
     826                 :          42 :   maybe_expand_expr (static_item.get_expr ());
     827                 :          42 : }
     828                 :             : 
     829                 :             : void
     830                 :          44 : ExpandVisitor::visit (AST::TraitItemConst &const_item)
     831                 :             : {
     832                 :          44 :   maybe_expand_type (const_item.get_type ());
     833                 :             : 
     834                 :          44 :   if (const_item.has_expr ())
     835                 :          10 :     maybe_expand_expr (const_item.get_expr ());
     836                 :          44 : }
     837                 :             : 
     838                 :             : void
     839                 :        2427 : ExpandVisitor::visit (AST::Trait &trait)
     840                 :             : {
     841                 :        2813 :   for (auto &generic : trait.get_generic_params ())
     842                 :         386 :     visit (generic);
     843                 :             : 
     844                 :        2711 :   for (auto &bound : trait.get_type_param_bounds ())
     845                 :         284 :     visit (bound);
     846                 :             : 
     847                 :        2427 :   if (trait.has_where_clause ())
     848                 :          14 :     expand_where_clause (trait.get_where_clause ());
     849                 :             : 
     850                 :        2427 :   expander.push_context (MacroExpander::ContextType::TRAIT);
     851                 :             : 
     852                 :        2427 :   std::function<std::unique_ptr<AST::AssociatedItem> (AST::SingleASTNode)>
     853                 :             :     extractor
     854                 :           2 :     = [] (AST::SingleASTNode node) { return node.take_trait_item (); };
     855                 :             : 
     856                 :        2427 :   expand_macro_children (MacroExpander::ContextType::TRAIT,
     857                 :             :                          trait.get_trait_items (), extractor);
     858                 :             : 
     859                 :        2427 :   expander.pop_context ();
     860                 :        2427 : }
     861                 :             : 
     862                 :             : void
     863                 :         786 : ExpandVisitor::visit (AST::InherentImpl &impl)
     864                 :             : {
     865                 :        1572 :   visit_inner_attrs (impl);
     866                 :             :   // just expand sub-stuff - can't actually strip generic params themselves
     867                 :        1053 :   for (auto &generic : impl.get_generic_params ())
     868                 :         267 :     visit (generic);
     869                 :             : 
     870                 :             :   // FIXME: Is that correct? How do we test that?
     871                 :         786 :   expander.push_context (MacroExpander::ContextType::ITEM);
     872                 :             : 
     873                 :         786 :   maybe_expand_type (impl.get_type ());
     874                 :             : 
     875                 :         786 :   expander.pop_context ();
     876                 :             : 
     877                 :         786 :   if (impl.has_where_clause ())
     878                 :           1 :     expand_where_clause (impl.get_where_clause ());
     879                 :             : 
     880                 :         786 :   std::function<std::unique_ptr<AST::AssociatedItem> (AST::SingleASTNode)>
     881                 :           2 :     extractor = [] (AST::SingleASTNode node) { return node.take_impl_item (); };
     882                 :             : 
     883                 :         786 :   expand_macro_children (MacroExpander::ContextType::IMPL,
     884                 :             :                          impl.get_impl_items (), extractor);
     885                 :         786 : }
     886                 :             : 
     887                 :             : void
     888                 :        2873 : ExpandVisitor::visit (AST::TraitImpl &impl)
     889                 :             : {
     890                 :        5746 :   visit_inner_attrs (impl);
     891                 :             :   // just expand sub-stuff - can't actually strip generic params themselves
     892                 :        3555 :   for (auto &param : impl.get_generic_params ())
     893                 :         682 :     visit (param);
     894                 :             : 
     895                 :             :   // FIXME: Is that correct? How do we test that?
     896                 :        2873 :   expander.push_context (MacroExpander::ContextType::ITEM);
     897                 :             : 
     898                 :        2873 :   maybe_expand_type (impl.get_type ());
     899                 :             : 
     900                 :        2873 :   expander.pop_context ();
     901                 :             : 
     902                 :        2873 :   visit (impl.get_trait_path ());
     903                 :             : 
     904                 :        2873 :   if (impl.has_where_clause ())
     905                 :          75 :     expand_where_clause (impl.get_where_clause ());
     906                 :             : 
     907                 :        2873 :   std::function<std::unique_ptr<AST::AssociatedItem> (AST::SingleASTNode)>
     908                 :             :     extractor
     909                 :          39 :     = [] (AST::SingleASTNode node) { return node.take_trait_impl_item (); };
     910                 :             : 
     911                 :        2873 :   expand_macro_children (MacroExpander::ContextType::TRAIT_IMPL,
     912                 :             :                          impl.get_impl_items (), extractor);
     913                 :        2873 : }
     914                 :             : 
     915                 :             : void
     916                 :           1 : ExpandVisitor::visit (AST::ExternalTypeItem &item)
     917                 :           1 : {}
     918                 :             : 
     919                 :             : void
     920                 :           1 : ExpandVisitor::visit (AST::ExternalStaticItem &static_item)
     921                 :             : {
     922                 :           1 :   maybe_expand_type (static_item.get_type ());
     923                 :           1 : }
     924                 :             : 
     925                 :             : void
     926                 :        2092 : ExpandVisitor::visit (AST::ExternalFunctionItem &item)
     927                 :             : {
     928                 :        3000 :   for (auto &param : item.get_generic_params ())
     929                 :         908 :     visit (param);
     930                 :             : 
     931                 :        5615 :   for (auto &param : item.get_function_params ())
     932                 :        3523 :     if (!param.is_variadic ())
     933                 :        2641 :       maybe_expand_type (param.get_type ());
     934                 :             : 
     935                 :        2092 :   if (item.has_return_type ())
     936                 :         971 :     maybe_expand_type (item.get_return_type ());
     937                 :             : 
     938                 :        2092 :   if (item.has_where_clause ())
     939                 :           0 :     expand_where_clause (item.get_where_clause ());
     940                 :        2092 : }
     941                 :             : 
     942                 :             : void
     943                 :        1279 : ExpandVisitor::visit (AST::ExternBlock &block)
     944                 :             : {
     945                 :        2558 :   visit_inner_attrs (block);
     946                 :        1279 :   std::function<std::unique_ptr<AST::ExternalItem> (AST::SingleASTNode)>
     947                 :             :     extractor
     948                 :           3 :     = [] (AST::SingleASTNode node) { return node.take_external_item (); };
     949                 :             : 
     950                 :        1279 :   expand_macro_children (MacroExpander::ContextType::EXTERN,
     951                 :             :                          block.get_extern_items (), extractor);
     952                 :        1279 : }
     953                 :             : 
     954                 :             : void
     955                 :           0 : ExpandVisitor::visit (AST::MacroMatchRepetition &)
     956                 :           0 : {}
     957                 :             : 
     958                 :             : void
     959                 :           0 : ExpandVisitor::visit (AST::MacroMatcher &)
     960                 :           0 : {}
     961                 :             : 
     962                 :             : void
     963                 :        2597 : ExpandVisitor::visit (AST::MacroRulesDefinition &rules_def)
     964                 :        2597 : {}
     965                 :             : 
     966                 :             : void
     967                 :           0 : ExpandVisitor::visit (AST::MetaItemPath &)
     968                 :           0 : {}
     969                 :             : 
     970                 :             : void
     971                 :           0 : ExpandVisitor::visit (AST::MetaItemSeq &)
     972                 :           0 : {}
     973                 :             : 
     974                 :             : void
     975                 :           0 : ExpandVisitor::visit (AST::MetaListPaths &)
     976                 :           0 : {}
     977                 :             : 
     978                 :             : void
     979                 :           0 : ExpandVisitor::visit (AST::MetaListNameValueStr &)
     980                 :           0 : {}
     981                 :             : 
     982                 :             : void
     983                 :          63 : ExpandVisitor::visit (AST::StructPatternFieldIdent &field)
     984                 :          63 : {}
     985                 :             : 
     986                 :             : void
     987                 :           0 : ExpandVisitor::visit (AST::GroupedPattern &pattern)
     988                 :             : {
     989                 :           0 :   visit (pattern.get_pattern_in_parens ());
     990                 :           0 : }
     991                 :             : 
     992                 :             : void
     993                 :       11211 : ExpandVisitor::visit (AST::LetStmt &stmt)
     994                 :             : {
     995                 :       11211 :   visit (stmt.get_pattern ());
     996                 :             : 
     997                 :       11211 :   if (stmt.has_type ())
     998                 :        1769 :     maybe_expand_type (stmt.get_type ());
     999                 :             : 
    1000                 :       11211 :   if (stmt.has_init_expr ())
    1001                 :       10093 :     maybe_expand_expr (stmt.get_init_expr ());
    1002                 :       11211 : }
    1003                 :             : 
    1004                 :             : void
    1005                 :        6840 : ExpandVisitor::visit (AST::ExprStmt &stmt)
    1006                 :             : {
    1007                 :        6840 :   maybe_expand_expr (stmt.get_expr ());
    1008                 :        6840 : }
    1009                 :             : 
    1010                 :             : void
    1011                 :          37 : ExpandVisitor::visit (AST::BareFunctionType &type)
    1012                 :             : {
    1013                 :          72 :   for (auto &param : type.get_function_params ())
    1014                 :             :     {
    1015                 :          35 :       maybe_expand_type (param.get_type ());
    1016                 :             :     }
    1017                 :             : 
    1018                 :          37 :   if (type.has_return_type ())
    1019                 :          33 :     visit (type.get_return_type ());
    1020                 :          37 : }
    1021                 :             : 
    1022                 :             : void
    1023                 :        4777 : ExpandVisitor::visit (AST::FunctionParam &param)
    1024                 :             : {
    1025                 :        4777 :   maybe_expand_type (param.get_type ());
    1026                 :        4777 : }
    1027                 :             : 
    1028                 :             : void
    1029                 :        4463 : ExpandVisitor::visit (AST::SelfParam &param)
    1030                 :             : {
    1031                 :             :   /* TODO: maybe check for invariants being violated - e.g. both type and
    1032                 :             :    * lifetime? */
    1033                 :        4463 :   if (param.has_type ())
    1034                 :           1 :     maybe_expand_type (param.get_type ());
    1035                 :        4463 : }
    1036                 :             : 
    1037                 :             : template <typename T>
    1038                 :             : void
    1039                 :           0 : ExpandVisitor::expand_inner_attribute (T &item, AST::SimplePath &path)
    1040                 :             : {
    1041                 :             :   // FIXME: Retrieve path from segments + local use statements instead of string
    1042                 :           0 :   expander.expand_attribute_proc_macro (item, path);
    1043                 :           0 : }
    1044                 :             : 
    1045                 :             : template <typename T>
    1046                 :             : void
    1047                 :       16643 : ExpandVisitor::visit_inner_using_attrs (T &item,
    1048                 :             :                                         std::vector<AST::Attribute> &attrs)
    1049                 :             : {
    1050                 :       16643 :   for (auto it = attrs.begin (); it != attrs.end (); /* erase => No increment*/)
    1051                 :             :     {
    1052                 :           0 :       auto current = *it;
    1053                 :             : 
    1054                 :           0 :       if (!is_builtin (current) && !current.is_derive ())
    1055                 :             :         {
    1056                 :           0 :           it = attrs.erase (it);
    1057                 :           0 :           expand_inner_attribute (item, current.get_path ());
    1058                 :             :         }
    1059                 :             :       else
    1060                 :             :         {
    1061                 :           0 :           it++;
    1062                 :             :         }
    1063                 :             :     }
    1064                 :       16643 : }
    1065                 :             : 
    1066                 :             : template <typename T>
    1067                 :             : void
    1068                 :        1279 : ExpandVisitor::visit_inner_attrs (T &item)
    1069                 :             : {
    1070                 :        4938 :   visit_inner_using_attrs (item, item.get_inner_attrs ());
    1071                 :             : }
    1072                 :             : 
    1073                 :             : } // namespace Rust
        

Generated by: LCOV version 2.1-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.