LCOV - code coverage report
Current view: top level - gcc/rust/expand - rust-expand-visitor.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 79.1 % 531 420
Test Date: 2025-09-20 13:40:47 Functions: 77.7 % 103 80
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                 :       12499 : is_builtin (AST::Attribute &attr)
      31                 :             : {
      32                 :       12499 :   auto &segments = attr.get_path ().get_segments ();
      33                 :       12499 :   return !segments.empty ()
      34                 :       12499 :          && !Analysis::BuiltinAttributeMappings::get ()
      35                 :       12499 :                ->lookup_builtin (segments[0].get_segment_name ())
      36                 :       12499 :                .is_error ();
      37                 :             : }
      38                 :             : 
      39                 :             : /* Expand all of the macro invocations currently contained in a crate */
      40                 :             : void
      41                 :        9953 : ExpandVisitor::go (AST::Crate &crate)
      42                 :             : {
      43                 :        9953 :   visit (crate);
      44                 :        9953 : }
      45                 :             : 
      46                 :             : static std::vector<std::unique_ptr<AST::Item>>
      47                 :         286 : 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                 :           1 : expand_stmt_attribute (T &statement, AST::SimplePath &attribute,
     107                 :             :                        MacroExpander &expander)
     108                 :             : {
     109                 :           1 :   std::vector<std::unique_ptr<AST::Stmt>> result;
     110                 :           1 :   auto frag = expander.expand_attribute_proc_macro (statement, attribute);
     111                 :           1 :   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                 :           1 :   return result;
     126                 :           1 : }
     127                 :             : 
     128                 :             : void
     129                 :       51588 : expand_tail_expr (AST::BlockExpr &block_expr, MacroExpander &expander)
     130                 :             : {
     131                 :       51588 :   if (block_expr.has_tail_expr ())
     132                 :             :     {
     133                 :       39014 :       auto tail = block_expr.take_tail_expr ();
     134                 :       39014 :       auto attrs = tail->get_outer_attrs ();
     135                 :       39014 :       bool changed = false;
     136                 :       39892 :       for (auto it = attrs.begin (); it != attrs.end ();)
     137                 :             :         {
     138                 :         878 :           auto current = *it;
     139                 :         878 :           if (is_builtin (current))
     140                 :             :             {
     141                 :         878 :               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                 :         878 :         }
     155                 :       39014 :       if (changed)
     156                 :           0 :         block_expr.normalize_tail_expr ();
     157                 :             :       else
     158                 :       39014 :         block_expr.set_tail_expr (std::move (tail));
     159                 :       39014 :     }
     160                 :       51588 : }
     161                 :             : 
     162                 :             : void
     163                 :       13077 : ExpandVisitor::expand_inner_items (
     164                 :             :   std::vector<std::unique_ptr<AST::Item>> &items)
     165                 :             : {
     166                 :       13077 :   expander.push_context (MacroExpander::ContextType::ITEM);
     167                 :             : 
     168                 :       68764 :   for (auto it = items.begin (); it != items.end (); it++)
     169                 :             :     {
     170                 :       55687 :       Rust::AST::Item &item = **it;
     171                 :       55687 :       if (item.has_outer_attrs ())
     172                 :             :         {
     173                 :        8660 :           auto &attrs = item.get_outer_attrs ();
     174                 :             : 
     175                 :       20429 :           for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
     176                 :             :                /* erase => No increment*/)
     177                 :             :             {
     178                 :       11769 :               auto current = *attr_it;
     179                 :             : 
     180                 :       11769 :               if (current.is_derive ())
     181                 :             :                 {
     182                 :         157 :                   current.parse_attr_to_meta_item ();
     183                 :         157 :                   attr_it = attrs.erase (attr_it);
     184                 :             :                   // Get traits to derive in the current attribute
     185                 :         157 :                   auto traits_to_derive = current.get_traits_to_derive ();
     186                 :         443 :                   for (auto &to_derive : traits_to_derive)
     187                 :             :                     {
     188                 :         286 :                       auto maybe_builtin = MacroBuiltin::builtins.lookup (
     189                 :         286 :                         to_derive.get ().as_string ());
     190                 :         286 :                       if (maybe_builtin.has_value ())
     191                 :             :                         {
     192                 :         286 :                           auto new_items
     193                 :             :                             = builtin_derive_item (item, current,
     194                 :         286 :                                                    maybe_builtin.value ());
     195                 :             : 
     196                 :         709 :                           for (auto &&new_item : new_items)
     197                 :         423 :                             it = items.insert (it, std::move (new_item));
     198                 :         286 :                         }
     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                 :         157 :                 }
     210                 :             :               else /* Attribute */
     211                 :             :                 {
     212                 :       11612 :                   if (is_builtin (current))
     213                 :             :                     {
     214                 :       11612 :                       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                 :       11769 :             }
     233                 :             :         }
     234                 :             :     }
     235                 :             : 
     236                 :       13077 :   expand_macro_children (items, &AST::SingleASTNode::take_item);
     237                 :             : 
     238                 :       13077 :   expander.pop_context ();
     239                 :       13077 : }
     240                 :             : 
     241                 :             : void
     242                 :       51588 : ExpandVisitor::expand_inner_stmts (AST::BlockExpr &expr)
     243                 :             : {
     244                 :       51588 :   auto &stmts = expr.get_statements ();
     245                 :       51588 :   expander.push_context (MacroExpander::ContextType::STMT);
     246                 :             : 
     247                 :       99027 :   for (auto it = stmts.begin (); it != stmts.end (); it++)
     248                 :             :     {
     249                 :       47439 :       auto &stmt = *it;
     250                 :             : 
     251                 :             :       // skip all non-item statements
     252                 :       47439 :       if (stmt->get_stmt_kind () != AST::Stmt::Kind::Item)
     253                 :       45905 :         continue;
     254                 :             : 
     255                 :        1534 :       auto &item = static_cast<AST::Item &> (*stmt.get ());
     256                 :             : 
     257                 :        1534 :       if (item.has_outer_attrs ())
     258                 :             :         {
     259                 :           9 :           auto &attrs = item.get_outer_attrs ();
     260                 :             : 
     261                 :          17 :           for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
     262                 :             :                /* erase => No increment*/)
     263                 :             :             {
     264                 :           9 :               auto current = *attr_it;
     265                 :             : 
     266                 :           9 :               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 (maybe_builtin.has_value ())
     276                 :             :                         {
     277                 :           0 :                           auto new_items
     278                 :             :                             = builtin_derive_item (item, current,
     279                 :           0 :                                                    maybe_builtin.value ());
     280                 :             : 
     281                 :             :                           // this inserts the derive *before* the item - is it a
     282                 :             :                           // problem?
     283                 :           0 :                           for (auto &&new_item : new_items)
     284                 :           0 :                             it = stmts.insert (it, std::move (new_item));
     285                 :           0 :                         }
     286                 :             :                       else
     287                 :             :                         {
     288                 :           0 :                           auto new_items
     289                 :           0 :                             = derive_item (item, to_derive, expander);
     290                 :           0 :                           std::move (new_items.begin (), new_items.end (),
     291                 :             :                                      std::inserter (stmts, it));
     292                 :           0 :                         }
     293                 :             :                     }
     294                 :           0 :                 }
     295                 :             :               else /* Attribute */
     296                 :             :                 {
     297                 :           9 :                   if (is_builtin (current))
     298                 :             :                     {
     299                 :           8 :                       attr_it++;
     300                 :             :                     }
     301                 :             :                   else
     302                 :             :                     {
     303                 :           1 :                       attr_it = attrs.erase (attr_it);
     304                 :           1 :                       auto new_items
     305                 :             :                         = expand_stmt_attribute (item, current.get_path (),
     306                 :           1 :                                                  expander);
     307                 :           1 :                       it = stmts.erase (it);
     308                 :           1 :                       std::move (new_items.begin (), new_items.end (),
     309                 :             :                                  std::inserter (stmts, it));
     310                 :             :                       // TODO: Improve this ?
     311                 :             :                       // item is invalid since it refers to now deleted,
     312                 :             :                       // cancel the loop increment and break.
     313                 :           1 :                       it--;
     314                 :           1 :                       break;
     315                 :           1 :                     }
     316                 :             :                 }
     317                 :           9 :             }
     318                 :             :         }
     319                 :             :     }
     320                 :             : 
     321                 :       51588 :   if (!expr.has_tail_expr ())
     322                 :       12633 :     expr.normalize_tail_expr ();
     323                 :             : 
     324                 :       51588 :   expand_macro_children (stmts, &AST::SingleASTNode::take_stmt);
     325                 :             : 
     326                 :       51588 :   expander.pop_context ();
     327                 :       51588 : }
     328                 :             : 
     329                 :             : void
     330                 :     1220200 : ExpandVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
     331                 :             : {
     332                 :     1220200 :   expander.push_context (MacroExpander::ContextType::EXPR);
     333                 :     1220200 :   expr->accept_vis (*this);
     334                 :     1220200 :   expander.pop_context ();
     335                 :             : 
     336                 :     1220200 :   auto final_fragment = expander.take_expanded_fragment ();
     337                 :     1220200 :   if (final_fragment.should_expand ()
     338                 :     1220200 :       && final_fragment.is_expression_fragment ())
     339                 :        1863 :     expr = final_fragment.take_expression_fragment ();
     340                 :     1220200 : }
     341                 :             : 
     342                 :             : void
     343                 :       94935 : ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::Type> &type)
     344                 :             : {
     345                 :       94935 :   expander.push_context (MacroExpander::ContextType::TYPE);
     346                 :             : 
     347                 :       94935 :   type->accept_vis (*this);
     348                 :       94935 :   auto final_fragment = expander.take_expanded_fragment ();
     349                 :       94935 :   if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
     350                 :          28 :     type = final_fragment.take_type_fragment ();
     351                 :             : 
     352                 :       94935 :   expander.pop_context ();
     353                 :       94935 : }
     354                 :             : 
     355                 :             : // FIXME: Can this be refactored into a `scoped` method? Which takes a
     356                 :             : // ContextType as parameter and a lambda? And maybe just an std::vector<T>&?
     357                 :             : void
     358                 :        3791 : ExpandVisitor::expand_struct_fields (std::vector<AST::StructField> &fields)
     359                 :             : {
     360                 :        8808 :   for (auto &field : fields)
     361                 :             :     {
     362                 :        5017 :       maybe_expand_type (field.get_field_type_ptr ());
     363                 :             :     }
     364                 :        3791 : }
     365                 :             : 
     366                 :             : void
     367                 :        3111 : ExpandVisitor::expand_tuple_fields (std::vector<AST::TupleField> &fields)
     368                 :             : {
     369                 :        7858 :   for (auto &field : fields)
     370                 :        4747 :     maybe_expand_type (field.get_field_type_ptr ());
     371                 :        3111 : }
     372                 :             : 
     373                 :             : // FIXME: This can definitely be refactored with the method above
     374                 :             : void
     375                 :       43381 : ExpandVisitor::expand_function_params (
     376                 :             :   std::vector<std::unique_ptr<AST::Param>> &params)
     377                 :             : {
     378                 :       92228 :   for (auto &p : params)
     379                 :       48847 :     visit (p);
     380                 :       43381 : }
     381                 :             : 
     382                 :             : void
     383                 :        8932 : ExpandVisitor::expand_generic_args (AST::GenericArgs &args)
     384                 :             : {
     385                 :       18281 :   for (auto &arg : args.get_generic_args ())
     386                 :             :     {
     387                 :        9349 :       switch (arg.get_kind ())
     388                 :             :         {
     389                 :        3819 :         case AST::GenericArg::Kind::Type:
     390                 :        3819 :           maybe_expand_type (arg.get_type_ptr ());
     391                 :        3819 :           break;
     392                 :          92 :         case AST::GenericArg::Kind::Const:
     393                 :          92 :           maybe_expand_expr (arg.get_expression_ptr ());
     394                 :          92 :           break;
     395                 :             :         default:
     396                 :             :           break;
     397                 :             :           // FIXME: Figure out what to do here if there is ambiguity. Since the
     398                 :             :           // resolver comes after the expansion, we need to figure out a way to
     399                 :             :           // strip ambiguous values here
     400                 :             :           // TODO: ARTHUR: Probably add a `mark_as_strip` method to `GenericArg`
     401                 :             :           // or something. This would clean up this whole thing
     402                 :             :         }
     403                 :             :     }
     404                 :             : 
     405                 :             :   // FIXME: Can we have macro invocations in generic type bindings?
     406                 :             :   // expand binding args - strip sub-types only
     407                 :             :   // FIXME: ARTHUR: This needs a test! Foo<Item = macro!()>
     408                 :        9126 :   for (auto &binding : args.get_binding_args ())
     409                 :         194 :     maybe_expand_type (binding.get_type_ptr ());
     410                 :        8932 : }
     411                 :             : 
     412                 :             : void
     413                 :         964 : ExpandVisitor::expand_qualified_path_type (AST::QualifiedPathType &path_type)
     414                 :             : {
     415                 :         964 :   maybe_expand_type (path_type.get_type_ptr ());
     416                 :             : 
     417                 :             :   // FIXME: ARTHUR: Can we do macro expansion in there? Needs a test!
     418                 :         964 :   if (path_type.has_as_clause ())
     419                 :         870 :     path_type.get_as_type_path ().accept_vis (*this);
     420                 :         964 : }
     421                 :             : 
     422                 :             : void
     423                 :         129 : ExpandVisitor::expand_closure_params (std::vector<AST::ClosureParam> &params)
     424                 :             : {
     425                 :         253 :   for (auto &param : params)
     426                 :             :     {
     427                 :         124 :       if (param.has_type_given ())
     428                 :         116 :         maybe_expand_type (param.get_type_ptr ());
     429                 :             :     }
     430                 :         129 : }
     431                 :             : 
     432                 :             : void
     433                 :         761 : ExpandVisitor::expand_where_clause (AST::WhereClause &where_clause)
     434                 :             : {
     435                 :        1542 :   for (auto &item : where_clause.get_items ())
     436                 :         781 :     visit (item);
     437                 :         761 : }
     438                 :             : 
     439                 :             : void
     440                 :        9953 : ExpandVisitor::visit (AST::Crate &crate)
     441                 :             : {
     442                 :        9953 :   expand_inner_items (crate.items);
     443                 :        9953 : }
     444                 :             : 
     445                 :             : void
     446                 :           0 : ExpandVisitor::visit (AST::DelimTokenTree &)
     447                 :           0 : {}
     448                 :             : 
     449                 :             : void
     450                 :           0 : ExpandVisitor::visit (AST::AttrInputMetaItemContainer &)
     451                 :           0 : {}
     452                 :             : 
     453                 :             : void
     454                 :       54130 : ExpandVisitor::visit (AST::IdentifierExpr &ident_expr)
     455                 :       54130 : {}
     456                 :             : 
     457                 :             : void
     458                 :         519 : ExpandVisitor::visit (AST::LifetimeParam &)
     459                 :         519 : {}
     460                 :             : 
     461                 :             : void
     462                 :          92 : ExpandVisitor::visit (AST::ConstGenericParam &)
     463                 :          92 : {}
     464                 :             : 
     465                 :             : void
     466                 :        2743 : ExpandVisitor::visit (AST::MacroInvocation &macro_invoc)
     467                 :             : {
     468                 :             :   // TODO: Can we do the AST fragment replacing here? Probably not, right?
     469                 :        4651 :   expander.expand_invoc (macro_invoc, macro_invoc.has_semicolon ()
     470                 :             :                                         ? AST::InvocKind::Semicoloned
     471                 :             :                                         : AST::InvocKind::Expr);
     472                 :        2743 : }
     473                 :             : 
     474                 :             : void
     475                 :       58030 : ExpandVisitor::visit (AST::PathInExpression &path)
     476                 :             : {
     477                 :       58030 :   if (!path.is_lang_item ())
     478                 :      140401 :     for (auto &segment : path.get_segments ())
     479                 :      165136 :       if (segment.has_generic_args ())
     480                 :        2032 :         expand_generic_args (segment.get_generic_args ());
     481                 :       58030 : }
     482                 :             : 
     483                 :             : void
     484                 :        6902 : ExpandVisitor::visit (AST::TypePathSegmentGeneric &segment)
     485                 :             : {
     486                 :        6902 :   if (segment.has_generic_args ())
     487                 :        6900 :     expand_generic_args (segment.get_generic_args ());
     488                 :        6902 : }
     489                 :             : 
     490                 :             : void
     491                 :          60 : ExpandVisitor::visit (AST::TypePathSegmentFunction &segment)
     492                 :             : {
     493                 :          60 :   auto &type_path_function = segment.get_type_path_function ();
     494                 :             : 
     495                 :         124 :   for (auto &type : type_path_function.get_params ())
     496                 :          64 :     visit (type);
     497                 :             : 
     498                 :          60 :   if (type_path_function.has_return_type ())
     499                 :          56 :     maybe_expand_type (type_path_function.get_return_type_ptr ());
     500                 :          60 : }
     501                 :             : 
     502                 :             : void
     503                 :         269 : ExpandVisitor::visit (AST::QualifiedPathInExpression &path)
     504                 :             : {
     505                 :         269 :   expand_qualified_path_type (path.get_qualified_path_type ());
     506                 :             : 
     507                 :         538 :   for (auto &segment : path.get_segments ())
     508                 :         538 :     if (segment.has_generic_args ())
     509                 :           0 :       expand_generic_args (segment.get_generic_args ());
     510                 :         269 : }
     511                 :             : 
     512                 :             : void
     513                 :         695 : ExpandVisitor::visit (AST::QualifiedPathInType &path)
     514                 :             : {
     515                 :         695 :   expand_qualified_path_type (path.get_qualified_path_type ());
     516                 :             : 
     517                 :             :   // this shouldn't strip any segments, but can strip inside them
     518                 :         695 :   for (auto &segment : path.get_segments ())
     519                 :           0 :     visit (segment);
     520                 :         695 : }
     521                 :             : 
     522                 :             : void
     523                 :      560884 : ExpandVisitor::visit (AST::LiteralExpr &expr)
     524                 :      560884 : {}
     525                 :             : 
     526                 :             : void
     527                 :           0 : ExpandVisitor::visit (AST::AttrInputLiteral &)
     528                 :           0 : {}
     529                 :             : 
     530                 :             : void
     531                 :           0 : ExpandVisitor::visit (AST::AttrInputMacro &macro)
     532                 :             : {
     533                 :           0 :   rust_sorry_at (UNDEF_LOCATION, "macros in attributes not supported");
     534                 :           0 : }
     535                 :             : 
     536                 :             : void
     537                 :           0 : ExpandVisitor::visit (AST::MetaItemLitExpr &)
     538                 :           0 : {}
     539                 :             : 
     540                 :             : void
     541                 :           0 : ExpandVisitor::visit (AST::MetaItemPathExpr &)
     542                 :           0 : {}
     543                 :             : 
     544                 :             : void
     545                 :           2 : ExpandVisitor::visit (AST::ErrorPropagationExpr &expr)
     546                 :             : {
     547                 :           2 :   visit (expr.get_propagating_expr ());
     548                 :           2 : }
     549                 :             : 
     550                 :             : void
     551                 :      531536 : ExpandVisitor::visit (AST::ArithmeticOrLogicalExpr &expr)
     552                 :             : {
     553                 :      531536 :   maybe_expand_expr (expr.get_left_expr_ptr ());
     554                 :      531536 :   maybe_expand_expr (expr.get_right_expr_ptr ());
     555                 :      531536 : }
     556                 :             : 
     557                 :             : void
     558                 :        6784 : ExpandVisitor::visit (AST::ComparisonExpr &expr)
     559                 :             : {
     560                 :        6784 :   maybe_expand_expr (expr.get_left_expr_ptr ());
     561                 :        6784 :   maybe_expand_expr (expr.get_right_expr_ptr ());
     562                 :        6784 : }
     563                 :             : 
     564                 :             : void
     565                 :         844 : ExpandVisitor::visit (AST::LazyBooleanExpr &expr)
     566                 :             : {
     567                 :         844 :   maybe_expand_expr (expr.get_left_expr_ptr ());
     568                 :         844 :   maybe_expand_expr (expr.get_right_expr_ptr ());
     569                 :         844 : }
     570                 :             : 
     571                 :             : void
     572                 :        4495 : ExpandVisitor::visit (AST::AssignmentExpr &expr)
     573                 :             : {
     574                 :        4495 :   maybe_expand_expr (expr.get_left_expr_ptr ());
     575                 :        4495 :   maybe_expand_expr (expr.get_right_expr_ptr ());
     576                 :        4495 : }
     577                 :             : 
     578                 :             : void
     579                 :        1187 : ExpandVisitor::visit (AST::CompoundAssignmentExpr &expr)
     580                 :             : {
     581                 :        1187 :   maybe_expand_expr (expr.get_left_expr_ptr ());
     582                 :        1187 :   maybe_expand_expr (expr.get_right_expr_ptr ());
     583                 :        1187 : }
     584                 :             : 
     585                 :             : void
     586                 :         713 : ExpandVisitor::visit (AST::GroupedExpr &expr)
     587                 :             : {
     588                 :         713 :   maybe_expand_expr (expr.get_expr_in_parens_ptr ());
     589                 :         713 : }
     590                 :             : 
     591                 :             : void
     592                 :         139 : ExpandVisitor::visit (AST::StructExprStruct &expr)
     593                 :         139 : {}
     594                 :             : 
     595                 :             : void
     596                 :       25992 : ExpandVisitor::visit (AST::CallExpr &expr)
     597                 :             : {
     598                 :       25992 :   visit (expr.get_function_expr ());
     599                 :             : 
     600                 :       57923 :   for (auto &param : expr.get_params ())
     601                 :       31931 :     maybe_expand_expr (param);
     602                 :       25992 : }
     603                 :             : 
     604                 :             : void
     605                 :        6147 : ExpandVisitor::visit (AST::MethodCallExpr &expr)
     606                 :             : {
     607                 :        6147 :   visit (expr.get_receiver_expr ());
     608                 :             : 
     609                 :       10219 :   for (auto &param : expr.get_params ())
     610                 :        4072 :     maybe_expand_expr (param);
     611                 :        6147 : }
     612                 :             : 
     613                 :             : void
     614                 :          69 : ExpandVisitor::visit (AST::ClosureExprInner &expr)
     615                 :             : {
     616                 :          69 :   expand_closure_params (expr.get_params ());
     617                 :             : 
     618                 :          69 :   visit (expr.get_definition_expr ());
     619                 :          69 : }
     620                 :             : 
     621                 :             : void
     622                 :       51588 : ExpandVisitor::visit (AST::BlockExpr &expr)
     623                 :             : {
     624                 :       51588 :   expand_inner_stmts (expr);
     625                 :             : 
     626                 :       51588 :   expand_tail_expr (expr, expander);
     627                 :       51588 :   if (expr.has_tail_expr ())
     628                 :       39014 :     maybe_expand_expr (expr.get_tail_expr_ptr ());
     629                 :       51588 : }
     630                 :             : 
     631                 :             : void
     632                 :          60 : ExpandVisitor::visit (AST::ClosureExprInnerTyped &expr)
     633                 :             : {
     634                 :          60 :   expand_closure_params (expr.get_params ());
     635                 :             : 
     636                 :          60 :   maybe_expand_type (expr.get_return_type_ptr ());
     637                 :             : 
     638                 :          60 :   visit (expr.get_definition_expr ());
     639                 :          60 : }
     640                 :             : 
     641                 :             : void
     642                 :          20 : ExpandVisitor::visit (AST::ContinueExpr &expr)
     643                 :          20 : {}
     644                 :             : 
     645                 :             : void
     646                 :         975 : ExpandVisitor::visit (AST::IfExpr &expr)
     647                 :             : {
     648                 :         975 :   maybe_expand_expr (expr.get_condition_expr_ptr ());
     649                 :             : 
     650                 :         975 :   visit (expr.get_if_block ());
     651                 :         975 : }
     652                 :             : 
     653                 :             : void
     654                 :        3154 : ExpandVisitor::visit (AST::IfExprConseqElse &expr)
     655                 :             : {
     656                 :        3154 :   maybe_expand_expr (expr.get_condition_expr_ptr ());
     657                 :             : 
     658                 :        3154 :   visit (expr.get_if_block ());
     659                 :        3154 :   visit (expr.get_else_block ());
     660                 :        3154 : }
     661                 :             : 
     662                 :             : void
     663                 :          36 : ExpandVisitor::visit (AST::IfLetExpr &expr)
     664                 :             : {
     665                 :          36 :   maybe_expand_expr (expr.get_value_expr_ptr ());
     666                 :             : 
     667                 :          36 :   visit (expr.get_if_block ());
     668                 :          36 : }
     669                 :             : 
     670                 :             : void
     671                 :          24 : ExpandVisitor::visit (AST::IfLetExprConseqElse &expr)
     672                 :             : {
     673                 :          24 :   maybe_expand_expr (expr.get_value_expr_ptr ());
     674                 :             : 
     675                 :          24 :   visit (expr.get_if_block ());
     676                 :          24 :   visit (expr.get_else_block ());
     677                 :          24 : }
     678                 :             : 
     679                 :             : void
     680                 :        2376 : ExpandVisitor::visit (AST::MatchExpr &expr)
     681                 :             : {
     682                 :        2376 :   visit (expr.get_scrutinee_expr ());
     683                 :             : 
     684                 :        7820 :   for (auto &match_case : expr.get_match_cases ())
     685                 :             :     {
     686                 :        5444 :       auto &arm = match_case.get_arm ();
     687                 :             : 
     688                 :       10888 :       for (auto &pattern : arm.get_patterns ())
     689                 :        5444 :         visit (pattern);
     690                 :             : 
     691                 :        5444 :       if (arm.has_match_arm_guard ())
     692                 :           2 :         maybe_expand_expr (arm.get_guard_expr_ptr ());
     693                 :             : 
     694                 :        5444 :       maybe_expand_expr (match_case.get_expr_ptr ());
     695                 :             :     }
     696                 :        2376 : }
     697                 :             : 
     698                 :             : void
     699                 :       10699 : ExpandVisitor::visit (AST::TypeParam &param)
     700                 :             : {
     701                 :       12649 :   for (auto &bound : param.get_type_param_bounds ())
     702                 :        1950 :     visit (bound);
     703                 :             : 
     704                 :       10699 :   if (param.has_type ())
     705                 :         915 :     maybe_expand_type (param.get_type_ptr ());
     706                 :       10699 : }
     707                 :             : 
     708                 :             : void
     709                 :           4 : ExpandVisitor::visit (AST::LifetimeWhereClauseItem &)
     710                 :           4 : {}
     711                 :             : 
     712                 :             : void
     713                 :         777 : ExpandVisitor::visit (AST::TypeBoundWhereClauseItem &item)
     714                 :             : {
     715                 :         777 :   maybe_expand_type (item.get_type_ptr ());
     716                 :             : 
     717                 :        1554 :   for (auto &bound : item.get_type_param_bounds ())
     718                 :         777 :     visit (bound);
     719                 :         777 : }
     720                 :             : 
     721                 :             : void
     722                 :        3124 : ExpandVisitor::visit (AST::Module &module)
     723                 :             : {
     724                 :        3124 :   expand_inner_items (module.get_items ());
     725                 :        3124 : }
     726                 :             : 
     727                 :             : void
     728                 :          48 : ExpandVisitor::visit (AST::ExternCrate &crate)
     729                 :          48 : {}
     730                 :             : 
     731                 :             : void
     732                 :           0 : ExpandVisitor::visit (AST::UseTreeGlob &)
     733                 :           0 : {}
     734                 :             : 
     735                 :             : void
     736                 :           0 : ExpandVisitor::visit (AST::UseTreeList &)
     737                 :           0 : {}
     738                 :             : 
     739                 :             : void
     740                 :           0 : ExpandVisitor::visit (AST::UseTreeRebind &)
     741                 :           0 : {}
     742                 :             : 
     743                 :             : void
     744                 :        1765 : ExpandVisitor::visit (AST::UseDeclaration &use_decl)
     745                 :        1765 : {}
     746                 :             : 
     747                 :             : void
     748                 :       43381 : ExpandVisitor::visit (AST::Function &function)
     749                 :             : {
     750                 :       43381 :   if (function.has_body ())
     751                 :       33827 :     visit_inner_using_attrs (
     752                 :       33827 :       function, function.get_definition ().value ()->get_inner_attrs ());
     753                 :       47689 :   for (auto &param : function.get_generic_params ())
     754                 :        4308 :     visit (param);
     755                 :             : 
     756                 :       43381 :   expand_function_params (function.get_function_params ());
     757                 :             : 
     758                 :       43381 :   if (function.has_return_type ())
     759                 :       31800 :     maybe_expand_type (function.get_return_type_ptr ());
     760                 :             : 
     761                 :       43381 :   if (function.has_where_clause ())
     762                 :         520 :     expand_where_clause (function.get_where_clause ());
     763                 :             : 
     764                 :       43381 :   if (function.has_body ())
     765                 :       33827 :     visit (*function.get_definition ());
     766                 :       43381 : }
     767                 :             : 
     768                 :             : void
     769                 :        3372 : ExpandVisitor::visit (AST::StructStruct &struct_item)
     770                 :             : {
     771                 :        4481 :   for (auto &generic : struct_item.get_generic_params ())
     772                 :        1109 :     visit (generic);
     773                 :             : 
     774                 :        3372 :   if (struct_item.has_where_clause ())
     775                 :           4 :     expand_where_clause (struct_item.get_where_clause ());
     776                 :             : 
     777                 :        3372 :   expand_struct_fields (struct_item.get_fields ());
     778                 :        3372 : }
     779                 :             : 
     780                 :             : void
     781                 :        2017 : ExpandVisitor::visit (AST::TupleStruct &tuple_struct)
     782                 :             : {
     783                 :        2753 :   for (auto &generic : tuple_struct.get_generic_params ())
     784                 :         736 :     visit (generic);
     785                 :             : 
     786                 :        2017 :   if (tuple_struct.has_where_clause ())
     787                 :           0 :     expand_where_clause (tuple_struct.get_where_clause ());
     788                 :             : 
     789                 :        2017 :   expand_tuple_fields (tuple_struct.get_fields ());
     790                 :        2017 : }
     791                 :             : 
     792                 :             : void
     793                 :        1016 : ExpandVisitor::visit (AST::EnumItem &item)
     794                 :        1016 : {}
     795                 :             : 
     796                 :             : void
     797                 :        1094 : ExpandVisitor::visit (AST::EnumItemTuple &item)
     798                 :             : {
     799                 :        1094 :   expand_tuple_fields (item.get_tuple_fields ());
     800                 :        1094 : }
     801                 :             : 
     802                 :             : void
     803                 :         202 : ExpandVisitor::visit (AST::EnumItemStruct &item)
     804                 :             : {
     805                 :         202 :   expand_struct_fields (item.get_struct_fields ());
     806                 :         202 : }
     807                 :             : 
     808                 :             : void
     809                 :         673 : ExpandVisitor::visit (AST::EnumItemDiscriminant &item)
     810                 :             : {
     811                 :         673 :   maybe_expand_expr (item.get_expr_ptr ());
     812                 :         673 : }
     813                 :             : 
     814                 :             : void
     815                 :         217 : ExpandVisitor::visit (AST::Union &union_item)
     816                 :             : {
     817                 :         374 :   for (auto &generic : union_item.get_generic_params ())
     818                 :         157 :     visit (generic);
     819                 :             : 
     820                 :         217 :   expand_struct_fields (union_item.get_variants ());
     821                 :         217 : }
     822                 :             : 
     823                 :             : void
     824                 :         982 : ExpandVisitor::visit (AST::ConstantItem &const_item)
     825                 :             : {
     826                 :         982 :   maybe_expand_type (const_item.get_type_ptr ());
     827                 :             : 
     828                 :         982 :   if (const_item.has_expr ())
     829                 :         976 :     maybe_expand_expr (const_item.get_expr_ptr ());
     830                 :         982 : }
     831                 :             : 
     832                 :             : void
     833                 :         107 : ExpandVisitor::visit (AST::StaticItem &static_item)
     834                 :             : {
     835                 :         107 :   maybe_expand_type (static_item.get_type_ptr ());
     836                 :             : 
     837                 :         107 :   maybe_expand_expr (static_item.get_expr_ptr ());
     838                 :         107 : }
     839                 :             : 
     840                 :             : void
     841                 :          87 : ExpandVisitor::visit (AST::TraitItemConst &const_item)
     842                 :             : {
     843                 :          87 :   maybe_expand_type (const_item.get_type_ptr ());
     844                 :             : 
     845                 :          87 :   if (const_item.has_expr ())
     846                 :          24 :     maybe_expand_expr (const_item.get_expr_ptr ());
     847                 :          87 : }
     848                 :             : 
     849                 :             : void
     850                 :        8450 : ExpandVisitor::visit (AST::Trait &trait)
     851                 :             : {
     852                 :       10077 :   for (auto &generic : trait.get_generic_params ())
     853                 :        1627 :     visit (generic);
     854                 :             : 
     855                 :       10116 :   for (auto &bound : trait.get_type_param_bounds ())
     856                 :        1666 :     visit (bound);
     857                 :             : 
     858                 :        8450 :   if (trait.has_where_clause ())
     859                 :          21 :     expand_where_clause (trait.get_where_clause ());
     860                 :             : 
     861                 :        8450 :   expander.push_context (MacroExpander::ContextType::TRAIT);
     862                 :             : 
     863                 :        8450 :   expand_macro_children (MacroExpander::ContextType::TRAIT,
     864                 :             :                          trait.get_trait_items (),
     865                 :             :                          &AST::SingleASTNode::take_assoc_item);
     866                 :             : 
     867                 :        8450 :   expander.pop_context ();
     868                 :        8450 : }
     869                 :             : 
     870                 :             : void
     871                 :        2139 : ExpandVisitor::visit (AST::InherentImpl &impl)
     872                 :             : {
     873                 :        4278 :   visit_inner_attrs (impl);
     874                 :             :   // just expand sub-stuff - can't actually strip generic params themselves
     875                 :        2857 :   for (auto &generic : impl.get_generic_params ())
     876                 :         718 :     visit (generic);
     877                 :             : 
     878                 :             :   // FIXME: Is that correct? How do we test that?
     879                 :        2139 :   expander.push_context (MacroExpander::ContextType::ITEM);
     880                 :             : 
     881                 :        2139 :   maybe_expand_type (impl.get_type_ptr ());
     882                 :             : 
     883                 :        2139 :   expander.pop_context ();
     884                 :             : 
     885                 :        2139 :   if (impl.has_where_clause ())
     886                 :           2 :     expand_where_clause (impl.get_where_clause ());
     887                 :             : 
     888                 :        2139 :   expand_macro_children (MacroExpander::ContextType::IMPL,
     889                 :             :                          impl.get_impl_items (),
     890                 :             :                          &AST::SingleASTNode::take_assoc_item);
     891                 :        2139 : }
     892                 :             : 
     893                 :             : void
     894                 :       11495 : ExpandVisitor::visit (AST::TraitImpl &impl)
     895                 :             : {
     896                 :       22990 :   visit_inner_attrs (impl);
     897                 :             :   // just expand sub-stuff - can't actually strip generic params themselves
     898                 :       13357 :   for (auto &param : impl.get_generic_params ())
     899                 :        1862 :     visit (param);
     900                 :             : 
     901                 :             :   // FIXME: Is that correct? How do we test that?
     902                 :       11495 :   expander.push_context (MacroExpander::ContextType::ITEM);
     903                 :             : 
     904                 :       11495 :   maybe_expand_type (impl.get_type_ptr ());
     905                 :             : 
     906                 :       11495 :   expander.pop_context ();
     907                 :             : 
     908                 :       11495 :   visit (impl.get_trait_path ());
     909                 :             : 
     910                 :       11495 :   if (impl.has_where_clause ())
     911                 :         214 :     expand_where_clause (impl.get_where_clause ());
     912                 :             : 
     913                 :       11495 :   expand_macro_children (MacroExpander::ContextType::TRAIT_IMPL,
     914                 :             :                          impl.get_impl_items (),
     915                 :             :                          &AST::SingleASTNode::take_assoc_item);
     916                 :       11495 : }
     917                 :             : 
     918                 :             : void
     919                 :           2 : ExpandVisitor::visit (AST::ExternalTypeItem &item)
     920                 :           2 : {}
     921                 :             : 
     922                 :             : void
     923                 :           2 : ExpandVisitor::visit (AST::ExternalStaticItem &static_item)
     924                 :             : {
     925                 :           2 :   maybe_expand_type (static_item.get_type_ptr ());
     926                 :           2 : }
     927                 :             : 
     928                 :             : void
     929                 :        3200 : ExpandVisitor::visit (AST::ExternBlock &block)
     930                 :             : {
     931                 :        6400 :   visit_inner_attrs (block);
     932                 :             : 
     933                 :        3200 :   expand_macro_children (MacroExpander::ContextType::EXTERN,
     934                 :             :                          block.get_extern_items (),
     935                 :             :                          &AST::SingleASTNode::take_external_item);
     936                 :        3200 : }
     937                 :             : 
     938                 :             : void
     939                 :           0 : ExpandVisitor::visit (AST::MacroMatchRepetition &)
     940                 :           0 : {}
     941                 :             : 
     942                 :             : void
     943                 :           0 : ExpandVisitor::visit (AST::MacroMatcher &)
     944                 :           0 : {}
     945                 :             : 
     946                 :             : void
     947                 :        3723 : ExpandVisitor::visit (AST::MacroRulesDefinition &rules_def)
     948                 :        3723 : {}
     949                 :             : 
     950                 :             : void
     951                 :           0 : ExpandVisitor::visit (AST::MetaItemPath &)
     952                 :           0 : {}
     953                 :             : 
     954                 :             : void
     955                 :           0 : ExpandVisitor::visit (AST::MetaItemSeq &)
     956                 :           0 : {}
     957                 :             : 
     958                 :             : void
     959                 :           0 : ExpandVisitor::visit (AST::MetaListPaths &)
     960                 :           0 : {}
     961                 :             : 
     962                 :             : void
     963                 :           0 : ExpandVisitor::visit (AST::MetaListNameValueStr &)
     964                 :           0 : {}
     965                 :             : 
     966                 :             : void
     967                 :         215 : ExpandVisitor::visit (AST::StructPatternFieldIdent &field)
     968                 :         215 : {}
     969                 :             : 
     970                 :             : void
     971                 :           2 : ExpandVisitor::visit (AST::GroupedPattern &pattern)
     972                 :             : {
     973                 :           2 :   visit (pattern.get_pattern_in_parens ());
     974                 :           2 : }
     975                 :             : 
     976                 :             : void
     977                 :       26897 : ExpandVisitor::visit (AST::LetStmt &stmt)
     978                 :             : {
     979                 :       26897 :   visit (stmt.get_pattern ());
     980                 :             : 
     981                 :       26897 :   if (stmt.has_type ())
     982                 :        4430 :     maybe_expand_type (stmt.get_type_ptr ());
     983                 :             : 
     984                 :       26897 :   if (stmt.has_init_expr ())
     985                 :       24482 :     maybe_expand_expr (stmt.get_init_expr_ptr ());
     986                 :       26897 : }
     987                 :             : 
     988                 :             : void
     989                 :       18789 : ExpandVisitor::visit (AST::ExprStmt &stmt)
     990                 :             : {
     991                 :       18789 :   maybe_expand_expr (stmt.get_expr_ptr ());
     992                 :       18789 : }
     993                 :             : 
     994                 :             : void
     995                 :          94 : ExpandVisitor::visit (AST::BareFunctionType &type)
     996                 :             : {
     997                 :         186 :   for (auto &param : type.get_function_params ())
     998                 :             :     {
     999                 :          92 :       maybe_expand_type (param.get_type_ptr ());
    1000                 :             :     }
    1001                 :             : 
    1002                 :          94 :   if (type.has_return_type ())
    1003                 :          72 :     visit (type.get_return_type ());
    1004                 :          94 : }
    1005                 :             : 
    1006                 :             : void
    1007                 :       27134 : ExpandVisitor::visit (AST::FunctionParam &param)
    1008                 :             : {
    1009                 :       27134 :   maybe_expand_type (param.get_type_ptr ());
    1010                 :       27134 : }
    1011                 :             : 
    1012                 :             : void
    1013                 :       19978 : ExpandVisitor::visit (AST::SelfParam &param)
    1014                 :             : {
    1015                 :             :   /* TODO: maybe check for invariants being violated - e.g. both type and
    1016                 :             :    * lifetime? */
    1017                 :       19978 :   if (param.has_type ())
    1018                 :           2 :     maybe_expand_type (param.get_type_ptr ());
    1019                 :       19978 : }
    1020                 :             : 
    1021                 :             : template <typename T>
    1022                 :             : void
    1023                 :           0 : ExpandVisitor::expand_inner_attribute (T &item, AST::SimplePath &path)
    1024                 :             : {
    1025                 :             :   // FIXME: Retrieve path from segments + local use statements instead of string
    1026                 :           0 :   expander.expand_attribute_proc_macro (item, path);
    1027                 :           0 : }
    1028                 :             : 
    1029                 :             : template <typename T>
    1030                 :             : void
    1031                 :       50661 : ExpandVisitor::visit_inner_using_attrs (T &item,
    1032                 :             :                                         std::vector<AST::Attribute> &attrs)
    1033                 :             : {
    1034                 :       50661 :   for (auto it = attrs.begin (); it != attrs.end (); /* erase => No increment*/)
    1035                 :             :     {
    1036                 :           0 :       auto current = *it;
    1037                 :             : 
    1038                 :           0 :       if (!is_builtin (current) && !current.is_derive ())
    1039                 :             :         {
    1040                 :           0 :           it = attrs.erase (it);
    1041                 :           0 :           expand_inner_attribute (item, current.get_path ());
    1042                 :             :         }
    1043                 :             :       else
    1044                 :             :         {
    1045                 :           0 :           it++;
    1046                 :             :         }
    1047                 :             :     }
    1048                 :       50661 : }
    1049                 :             : 
    1050                 :             : template <typename T>
    1051                 :             : void
    1052                 :        3200 : ExpandVisitor::visit_inner_attrs (T &item)
    1053                 :             : {
    1054                 :       16834 :   visit_inner_using_attrs (item, item.get_inner_attrs ());
    1055                 :             : }
    1056                 :             : 
    1057                 :             : } // 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.