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.0 % 543 418
Test Date: 2025-06-21 16:26:05 Functions: 76.7 % 103 79
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

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