LCOV - code coverage report
Current view: top level - gcc/rust/ast - rust-ast.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 33.6 % 2530 849
Test Date: 2026-10-24 16:24:59 Functions: 51.4 % 331 170
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* General AST-related method implementations for Rust frontend.
       2              :    Copyright (C) 2009-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify it under
       7              : the terms of the GNU General Public License as published by the Free
       8              : Software Foundation; either version 3, or (at your option) any later
       9              : version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14              : for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : #include "rust-ast.h"
      21              : #include "optional.h"
      22              : #include "rust-builtin-ast-nodes.h"
      23              : #include "rust-common.h"
      24              : #include "rust-expr.h"
      25              : #include "rust-system.h"
      26              : #include "rust-ast-full.h"
      27              : #include "rust-diagnostics.h"
      28              : #include "rust-ast-visitor.h"
      29              : #include "rust-macro.h"
      30              : #include "rust-session-manager.h"
      31              : #include "rust-lex.h"
      32              : #include "rust-parse.h"
      33              : #include "rust-operators.h"
      34              : #include "rust-dir-owner.h"
      35              : #include "rust-attribute-values.h"
      36              : #include "rust-macro-invoc-lexer.h"
      37              : 
      38              : /* Compilation unit used for various AST-related functions that would make
      39              :  * the headers too long if they were defined inline and don't receive any
      40              :  * benefits from being defined inline because they are virtual. Also used
      41              :  * for various other stuff. */
      42              : 
      43              : namespace Rust {
      44              : namespace AST {
      45              : 
      46       348367 : SingleASTNode::SingleASTNode (SingleASTNode const &other)
      47              : {
      48       348367 :   kind = other.kind;
      49       348367 :   switch (kind)
      50              :     {
      51       287873 :     case Kind::Expr:
      52       287873 :       expr = other.expr->clone_expr ();
      53       287873 :       break;
      54              : 
      55        45511 :     case Kind::Item:
      56        45511 :       item = other.item->clone_item ();
      57        45511 :       break;
      58              : 
      59         3436 :     case Kind::Stmt:
      60         3436 :       stmt = other.stmt->clone_stmt ();
      61         3436 :       break;
      62              : 
      63           12 :     case Kind::Extern:
      64           12 :       external_item = other.external_item->clone_external_item ();
      65           12 :       break;
      66              : 
      67         9044 :     case Kind::Assoc:
      68         9044 :       assoc_item = other.assoc_item->clone_associated_item ();
      69         9044 :       break;
      70              : 
      71         2485 :     case Kind::Type:
      72         2485 :       type = other.type->clone_type ();
      73         2485 :       break;
      74              : 
      75            6 :     case Kind::Pattern:
      76            6 :       pattern = other.pattern->clone_pattern ();
      77            6 :       break;
      78              :     }
      79       348367 : }
      80              : 
      81              : SingleASTNode
      82            0 : SingleASTNode::operator= (SingleASTNode const &other)
      83              : {
      84            0 :   kind = other.kind;
      85            0 :   switch (kind)
      86              :     {
      87            0 :     case Kind::Expr:
      88            0 :       expr = other.expr->clone_expr ();
      89            0 :       break;
      90              : 
      91            0 :     case Kind::Item:
      92            0 :       item = other.item->clone_item ();
      93            0 :       break;
      94              : 
      95            0 :     case Kind::Stmt:
      96            0 :       stmt = other.stmt->clone_stmt ();
      97            0 :       break;
      98              : 
      99            0 :     case Kind::Extern:
     100            0 :       external_item = other.external_item->clone_external_item ();
     101            0 :       break;
     102              : 
     103            0 :     case Kind::Assoc:
     104            0 :       assoc_item = other.assoc_item->clone_associated_item ();
     105            0 :       break;
     106              : 
     107            0 :     case Kind::Type:
     108            0 :       type = other.type->clone_type ();
     109            0 :       break;
     110              : 
     111            0 :     case Kind::Pattern:
     112            0 :       pattern = other.pattern->clone_pattern ();
     113            0 :       break;
     114              :     }
     115            0 :   return *this;
     116              : }
     117              : 
     118              : void
     119          174 : SingleASTNode::accept_vis (ASTVisitor &vis)
     120              : {
     121          174 :   switch (kind)
     122              :     {
     123          174 :     case Kind::Expr:
     124          174 :       expr->accept_vis (vis);
     125          174 :       break;
     126              : 
     127            0 :     case Kind::Item:
     128            0 :       item->accept_vis (vis);
     129            0 :       break;
     130              : 
     131            0 :     case Kind::Stmt:
     132            0 :       stmt->accept_vis (vis);
     133            0 :       break;
     134              : 
     135            0 :     case Kind::Extern:
     136            0 :       external_item->accept_vis (vis);
     137            0 :       break;
     138              : 
     139            0 :     case Kind::Assoc:
     140            0 :       assoc_item->accept_vis (vis);
     141            0 :       break;
     142              : 
     143            0 :     case Kind::Type:
     144            0 :       type->accept_vis (vis);
     145            0 :       break;
     146              : 
     147            0 :     case Kind::Pattern:
     148            0 :       pattern->accept_vis (vis);
     149            0 :       break;
     150              :     }
     151          174 : }
     152              : 
     153              : bool
     154        81908 : SingleASTNode::is_error ()
     155              : {
     156        81908 :   switch (kind)
     157              :     {
     158        52536 :     case Kind::Expr:
     159        52536 :       return expr == nullptr;
     160        22727 :     case Kind::Item:
     161        22727 :       return item == nullptr;
     162         1619 :     case Kind::Stmt:
     163         1619 :       return stmt == nullptr;
     164            6 :     case Kind::Extern:
     165            6 :       return external_item == nullptr;
     166         4522 :     case Kind::Assoc:
     167         4522 :       return assoc_item == nullptr;
     168          497 :     case Kind::Type:
     169          497 :       return type == nullptr;
     170            1 :     case Kind::Pattern:
     171            1 :       return pattern == nullptr;
     172              :     }
     173              : 
     174            0 :   rust_unreachable ();
     175              :   return true;
     176              : }
     177              : 
     178              : std::string
     179            0 : SingleASTNode::as_string () const
     180              : {
     181            0 :   switch (kind)
     182              :     {
     183            0 :     case Kind::Expr:
     184            0 :       return "Expr: " + expr->as_string ();
     185            0 :     case Kind::Item:
     186            0 :       return "Item: " + item->as_string ();
     187            0 :     case Kind::Stmt:
     188            0 :       return "Stmt: " + stmt->as_string ();
     189            0 :     case Kind::Extern:
     190            0 :       return "External Item: " + external_item->as_string ();
     191            0 :     case Kind::Assoc:
     192            0 :       return "Associated Item: " + assoc_item->as_string ();
     193            0 :     case Kind::Type:
     194            0 :       return "Type: " + type->as_string ();
     195            0 :     case Kind::Pattern:
     196            0 :       return "Pattern: " + pattern->as_string ();
     197              :     }
     198              : 
     199            0 :   rust_unreachable ();
     200              :   return "";
     201              : }
     202              : 
     203              : std::string
     204            0 : Crate::as_string () const
     205              : {
     206            0 :   rust_debug ("beginning crate recursive as-string");
     207              : 
     208            0 :   std::string str ("Crate: ");
     209              : 
     210              :   // inner attributes
     211            0 :   str += append_attributes (inner_attrs, INNER);
     212              : 
     213              :   // items
     214            0 :   str += "\n items: ";
     215            0 :   if (items.empty ())
     216              :     {
     217            0 :       str += "none";
     218              :     }
     219              :   else
     220              :     {
     221            0 :       for (const auto &item : items)
     222              :         {
     223              :           // DEBUG: null pointer check
     224            0 :           if (item == nullptr)
     225              :             {
     226            0 :               rust_debug ("something really terrible has gone wrong - "
     227              :                           "null pointer item in crate.");
     228            0 :               return "NULL_POINTER_MARK";
     229              :             }
     230              : 
     231            0 :           str += "\n  " + item->as_string ();
     232              :         }
     233              :     }
     234              : 
     235            0 :   return str + "\n";
     236            0 : }
     237              : 
     238              : void
     239            0 : Crate::inject_extern_crate (std::string name)
     240              : {
     241            0 :   items.push_back (std::make_unique<AST::ExternCrate> (
     242            0 :     AST::ExternCrate (name, AST::Visibility::create_public (UNKNOWN_LOCATION),
     243            0 :                       {}, UNKNOWN_LOCATION)));
     244            0 : }
     245              : 
     246              : void
     247            1 : Crate::inject_inner_attribute (Attribute attribute)
     248              : {
     249            1 :   inner_attrs.push_back (attribute);
     250            1 : }
     251              : 
     252              : std::string
     253     24628787 : Attribute::as_string () const
     254              : {
     255     24628787 :   std::string path_str = path.as_string ();
     256     24628787 :   if (attr_input == nullptr)
     257       710766 :     return path_str;
     258              :   else
     259     23918021 :     return path_str + attr_input->as_string ();
     260     24628787 : }
     261              : 
     262              : void
     263            0 : Attribute::accept_vis (ASTVisitor &vis)
     264              : {
     265            0 :   vis.visit (*this);
     266            0 : }
     267              : 
     268              : bool
     269      3810589 : Attribute::is_derive () const
     270              : {
     271      7201990 :   return has_attr_input () && get_path () == Values::Attributes::DERIVE_ATTR;
     272              : }
     273              : 
     274              : /**
     275              :  * Returns a list of traits to derive from within a given attribute.
     276              :  *
     277              :  * @param attrs The attributes on the item to derive
     278              :  */
     279              : std::vector<std::reference_wrapper<AST::SimplePath>>
     280          998 : Attribute::get_traits_to_derive ()
     281              : {
     282          998 :   rust_assert (this->is_derive ());
     283              : 
     284          998 :   this->parse_attr_to_meta_item ();
     285          998 :   std::vector<std::reference_wrapper<AST::SimplePath>> result;
     286          998 :   auto &input = get_attr_input ();
     287          998 :   switch (input.get_attr_input_type ())
     288              :     {
     289          998 :     case AST::AttrInput::META_ITEM:
     290          998 :       {
     291          998 :         auto &meta = static_cast<AST::AttrInputMetaItemContainer &> (input);
     292         3648 :         for (auto &current : meta.get_items ())
     293              :           {
     294              :             // HACK: Find a better way to achieve the downcast.
     295         2650 :             switch (current->get_kind ())
     296              :               {
     297         2650 :               case AST::MetaItemInner::Kind::MetaItem:
     298         2650 :                 {
     299              :                   // Let raw pointer go out of scope without freeing, it doesn't
     300              :                   // own the data anyway
     301         2650 :                   auto meta_item
     302         2650 :                     = static_cast<AST::MetaItem *> (current.get ());
     303         2650 :                   switch (meta_item->get_item_kind ())
     304              :                     {
     305         1325 :                     case AST::MetaItem::ItemKind::Path:
     306         1325 :                       {
     307         1325 :                         auto path
     308              :                           = static_cast<AST::MetaItemPath *> (meta_item);
     309         1325 :                         result.push_back (path->get_path ());
     310              :                       }
     311         1325 :                       break;
     312         1325 :                     case AST::MetaItem::ItemKind::Word:
     313         1325 :                       {
     314         1325 :                         auto word = static_cast<AST::MetaWord *> (meta_item);
     315              :                         // Convert current word to path
     316         1325 :                         current = std::make_unique<AST::MetaItemPath> (
     317         2650 :                           AST::MetaItemPath (AST::SimplePath::from_str (
     318         1325 :                             word->get_ident ().as_string (),
     319         2650 :                             word->get_locus ())));
     320         1325 :                         auto path
     321         1325 :                           = static_cast<AST::MetaItemPath *> (current.get ());
     322              : 
     323         1325 :                         result.push_back (path->get_path ());
     324              :                       }
     325         1325 :                       break;
     326            0 :                     case AST::MetaItem::ItemKind::ListPaths:
     327            0 :                     case AST::MetaItem::ItemKind::NameValueStr:
     328            0 :                     case AST::MetaItem::ItemKind::PathExpr:
     329            0 :                     case AST::MetaItem::ItemKind::Seq:
     330            0 :                     case AST::MetaItem::ItemKind::ListNameValueStr:
     331            0 :                     default:
     332            0 :                       gcc_unreachable ();
     333         2650 :                       break;
     334              :                     }
     335              :                 }
     336         2650 :                 break;
     337            0 :               case AST::MetaItemInner::Kind::LitExpr:
     338            0 :               default:
     339            0 :                 gcc_unreachable ();
     340         2650 :                 break;
     341              :               }
     342              :           }
     343              :       }
     344              :       break;
     345            0 :     case AST::AttrInput::TOKEN_TREE:
     346            0 :     case AST::AttrInput::LITERAL:
     347            0 :     case AST::AttrInput::EXPR:
     348            0 :       rust_unreachable ();
     349          998 :       break;
     350              :     }
     351          998 :   return result;
     352              : }
     353              : 
     354              : // Copy constructor must deep copy attr_input as unique pointer
     355      1715388 : Attribute::Attribute (Attribute const &other)
     356      1715388 :   : path (other.path), locus (other.locus),
     357      1715388 :     inner_attribute (other.inner_attribute)
     358              : {
     359              :   // guard to protect from null pointer dereference
     360      1715388 :   if (other.attr_input != nullptr)
     361      1557477 :     attr_input = other.attr_input->clone_attr_input ();
     362      1715388 : }
     363              : 
     364              : // overload assignment operator to use custom clone method
     365              : Attribute &
     366           83 : Attribute::operator= (Attribute const &other)
     367              : {
     368           83 :   path = other.path;
     369           83 :   locus = other.locus;
     370           83 :   inner_attribute = other.inner_attribute;
     371              :   // guard to protect from null pointer dereference
     372           83 :   if (other.attr_input != nullptr)
     373           76 :     attr_input = other.attr_input->clone_attr_input ();
     374              :   else
     375            7 :     attr_input = nullptr;
     376              : 
     377           83 :   return *this;
     378              : }
     379              : 
     380              : std::string
     381      4538750 : DelimTokenTree::as_string () const
     382              : {
     383      4538750 :   std::string start_delim;
     384      4538750 :   std::string end_delim;
     385      4538750 :   switch (delim_type)
     386              :     {
     387      4538750 :     case PARENS:
     388      4538750 :       start_delim = "(";
     389      4538750 :       end_delim = ")";
     390      4538750 :       break;
     391            0 :     case SQUARE:
     392            0 :       start_delim = "[";
     393            0 :       end_delim = "]";
     394            0 :       break;
     395            0 :     case CURLY:
     396            0 :       start_delim = "{";
     397            0 :       end_delim = "}";
     398            0 :       break;
     399            0 :     default:
     400            0 :       rust_debug ("Invalid delimiter type, "
     401              :                   "Should be PARENS, SQUARE, or CURLY.");
     402            0 :       return "Invalid delimiter type";
     403              :     }
     404      9077500 :   std::string str = start_delim;
     405      4538750 :   if (!token_trees.empty ())
     406              :     {
     407     36800647 :       for (const auto &tree : token_trees)
     408              :         {
     409              :           // DEBUG: null pointer check
     410     32261897 :           if (tree == nullptr)
     411              :             {
     412            0 :               rust_debug (
     413              :                 "something really terrible has gone wrong - null pointer "
     414              :                 "token tree in delim token tree.");
     415            0 :               return "NULL_POINTER_MARK";
     416              :             }
     417              : 
     418     64523794 :           str += tree->as_string ();
     419              :         }
     420              :     }
     421      4538750 :   str += end_delim;
     422              : 
     423      4538750 :   return str;
     424      4538750 : }
     425              : 
     426              : std::string
     427     28984512 : Token::as_string () const
     428              : {
     429     28984512 :   if (tok_ref->should_have_str ())
     430              :     {
     431     12224281 :       std::string str = tok_ref->get_str ();
     432              : 
     433     21715021 :       std::string quote = is_string_lit () ? "\"" : "";
     434     12224281 :       return quote + str + quote;
     435     12224281 :     }
     436              :   else
     437              :     {
     438     16760231 :       return tok_ref->get_token_description ();
     439              :     }
     440              : }
     441              : 
     442              : std::string
     443     41961646 : SimplePathSegment::as_string () const
     444              : {
     445     41961646 :   return segment_name;
     446              : }
     447              : 
     448              : const std::string
     449     26060032 : SimplePath::as_string () const
     450              : {
     451     26060032 :   std::string path;
     452     26060032 :   if (opening_scope_resolution)
     453            0 :     path = "::";
     454              : 
     455              :   // crappy hack because doing proper for loop would be more code
     456     26060032 :   bool first_time = true;
     457     52121063 :   for (const auto &segment : segments)
     458              :     {
     459     26061031 :       if (first_time)
     460              :         {
     461     52120064 :           path += segment.as_string ();
     462     26060032 :           first_time = false;
     463              :         }
     464              :       else
     465              :         {
     466         1998 :           path += "::" + segment.as_string ();
     467              :         }
     468              : 
     469              :       // DEBUG: remove later. Checks for path error.
     470     26061031 :       if (segment.is_error ())
     471              :         {
     472            0 :           rust_debug ("segment in path is error - this should've been filtered "
     473              :                       "out. first segment "
     474              :                       "was '%s'",
     475              :                       segments.at (0).as_string ().c_str ());
     476              :         }
     477              :     }
     478              : 
     479     26060032 :   return path;
     480              : }
     481              : 
     482              : std::string
     483           10 : Visibility::as_string () const
     484              : {
     485           10 :   switch (vis_type)
     486              :     {
     487            0 :     case PRIV:
     488            0 :       return std::string ("");
     489           10 :     case PUB:
     490           10 :       return std::string ("pub");
     491            0 :     case PUB_CRATE:
     492            0 :       return std::string ("pub(crate)");
     493            0 :     case PUB_SELF:
     494            0 :       return std::string ("pub(self)");
     495            0 :     case PUB_SUPER:
     496            0 :       return std::string ("pub(super)");
     497            0 :     case PUB_IN_PATH:
     498            0 :       return std::string ("pub(in ") + in_path.as_string () + std::string (")");
     499            0 :     default:
     500            0 :       rust_unreachable ();
     501              :     }
     502              : }
     503              : 
     504              : // Creates a string that reflects the visibility stored.
     505              : std::string
     506            0 : VisItem::as_string () const
     507              : {
     508              :   // FIXME: can't do formatting on string to make identation occur.
     509            0 :   std::string str;
     510              : 
     511            0 :   if (!outer_attrs.empty ())
     512              :     {
     513            0 :       for (const auto &attr : outer_attrs)
     514            0 :         str += attr.as_string () + "\n";
     515              :     }
     516              : 
     517            0 :   if (has_visibility ())
     518            0 :     str += visibility.as_string () + " ";
     519              : 
     520            0 :   return str;
     521              : }
     522              : 
     523              : std::string
     524            0 : Module::as_string () const
     525              : {
     526            0 :   std::string str = VisItem::as_string () + "mod " + module_name.as_string ();
     527              : 
     528              :   // Return early if we're dealing with an unloaded module as their body resides
     529              :   // in a different file
     530            0 :   if (kind == ModuleKind::UNLOADED)
     531            0 :     return str + "\n no body (reference to external file)\n";
     532              : 
     533              :   // inner attributes
     534            0 :   str += append_attributes (inner_attrs, INNER);
     535              : 
     536              :   // items
     537            0 :   str += "\n items: ";
     538              : 
     539              :   // This can still happen if the module is loaded but empty, i.e. `mod foo {}`
     540            0 :   if (items.empty ())
     541              :     {
     542            0 :       str += "none";
     543              :     }
     544              :   else
     545              :     {
     546            0 :       for (const auto &item : items)
     547              :         {
     548              :           // DEBUG: null pointer check
     549            0 :           if (item == nullptr)
     550              :             {
     551            0 :               rust_debug ("something really terrible has gone wrong - "
     552              :                           "null pointer item in crate.");
     553            0 :               return "NULL_POINTER_MARK";
     554              :             }
     555              : 
     556            0 :           str += "\n  " + item->as_string ();
     557              :         }
     558              :     }
     559              : 
     560            0 :   return str + "\n";
     561            0 : }
     562              : 
     563              : std::string
     564            0 : StaticItem::as_string () const
     565              : {
     566            0 :   std::string str = VisItem::as_string ();
     567              : 
     568            0 :   str += indent_spaces (stay) + "static";
     569              : 
     570            0 :   if (has_mut)
     571            0 :     str += " mut";
     572              : 
     573            0 :   str += " " + name.as_string ();
     574              : 
     575              :   // DEBUG: null pointer check
     576            0 :   if (type == nullptr)
     577              :     {
     578            0 :       rust_debug ("something really terrible has gone wrong - null "
     579              :                   "pointer type in static item.");
     580            0 :       return "NULL_POINTER_MARK";
     581              :     }
     582            0 :   str += "\n" + indent_spaces (stay) + "Type: " + type->as_string ();
     583              : 
     584              :   // DEBUG: null pointer check
     585            0 :   if (expr == nullptr)
     586              :     {
     587            0 :       rust_debug ("something really terrible has gone wrong - null "
     588              :                   "pointer expr in static item.");
     589            0 :       return "NULL_POINTER_MARK";
     590              :     }
     591            0 :   str += "\n" + indent_spaces (stay) + "Expression: " + expr->as_string ();
     592              : 
     593            0 :   return str + "\n";
     594            0 : }
     595              : 
     596              : std::string
     597            0 : ExternCrate::as_string () const
     598              : {
     599            0 :   std::string str = VisItem::as_string ();
     600              : 
     601            0 :   str += "extern crate " + referenced_crate;
     602              : 
     603            0 :   if (has_as_clause ())
     604            0 :     str += " as " + as_clause_name;
     605              : 
     606            0 :   return str;
     607              : }
     608              : 
     609              : std::string
     610            0 : TupleStruct::as_string () const
     611              : {
     612            0 :   std::string str = VisItem::as_string ();
     613              : 
     614            0 :   str += "struct " + struct_name.as_string ();
     615              : 
     616              :   // generic params
     617            0 :   str += "\n Generic params: ";
     618            0 :   if (generic_params.empty ())
     619              :     {
     620            0 :       str += "none";
     621              :     }
     622              :   else
     623              :     {
     624            0 :       for (const auto &param : generic_params)
     625              :         {
     626              :           // DEBUG: null pointer check
     627            0 :           if (param == nullptr)
     628              :             {
     629            0 :               rust_debug (
     630              :                 "something really terrible has gone wrong - null pointer "
     631              :                 "generic param in enum.");
     632            0 :               return "NULL_POINTER_MARK";
     633              :             }
     634              : 
     635            0 :           str += "\n  " + param->as_string ();
     636              :         }
     637              :     }
     638              : 
     639              :   // tuple fields
     640            0 :   str += "\n Tuple fields: ";
     641            0 :   if (fields.empty ())
     642              :     {
     643            0 :       str += "none";
     644              :     }
     645              :   else
     646              :     {
     647            0 :       for (const auto &field : fields)
     648            0 :         str += "\n  " + field.as_string ();
     649              :     }
     650              : 
     651            0 :   str += "\n Where clause: ";
     652            0 :   if (has_where_clause ())
     653            0 :     str += where_clause.as_string ();
     654              :   else
     655            0 :     str += "none";
     656              : 
     657            0 :   return str;
     658            0 : }
     659              : 
     660              : std::string
     661            0 : ConstantItem::as_string () const
     662              : {
     663            0 :   std::string str = VisItem::as_string ();
     664              : 
     665            0 :   str += "const " + identifier.as_string ();
     666              : 
     667              :   // DEBUG: null pointer check
     668            0 :   if (type == nullptr)
     669              :     {
     670            0 :       rust_debug ("something really terrible has gone wrong - null "
     671              :                   "pointer type in const item.");
     672            0 :       return "NULL_POINTER_MARK";
     673              :     }
     674            0 :   str += "\n  Type: " + type->as_string ();
     675              : 
     676            0 :   if (has_expr ())
     677            0 :     str += "\n  Expression: " + const_expr->as_string ();
     678              : 
     679            0 :   return str + "\n";
     680            0 : }
     681              : 
     682              : std::string
     683            0 : InherentImpl::as_string () const
     684              : {
     685            0 :   std::string str = VisItem::as_string ();
     686              : 
     687            0 :   str += "impl ";
     688              : 
     689              :   // generic params
     690            0 :   str += "\n Generic params: ";
     691            0 :   if (generic_params.empty ())
     692              :     {
     693            0 :       str += "none";
     694              :     }
     695              :   else
     696              :     {
     697            0 :       for (const auto &param : generic_params)
     698              :         {
     699              :           // DEBUG: null pointer check
     700            0 :           if (param == nullptr)
     701              :             {
     702            0 :               rust_debug (
     703              :                 "something really terrible has gone wrong - null pointer "
     704              :                 "generic param in inherent impl.");
     705            0 :               return "NULL_POINTER_MARK";
     706              :             }
     707              : 
     708            0 :           str += "\n  " + param->as_string ();
     709              :         }
     710              :     }
     711              : 
     712            0 :   str += "\n Type: " + trait_type->as_string ();
     713              : 
     714            0 :   str += "\n Where clause: ";
     715            0 :   if (has_where_clause ())
     716            0 :     str += where_clause.as_string ();
     717              :   else
     718            0 :     str += "none";
     719              : 
     720              :   // inner attributes
     721            0 :   str += append_attributes (inner_attrs, INNER);
     722              : 
     723              :   // inherent impl items
     724            0 :   str += "\n Inherent impl items: ";
     725            0 :   if (!has_impl_items ())
     726              :     {
     727            0 :       str += "none";
     728              :     }
     729              :   else
     730              :     {
     731            0 :       for (const auto &item : impl_items)
     732            0 :         str += "\n  " + item->as_string ();
     733              :     }
     734              : 
     735            0 :   return str;
     736            0 : }
     737              : 
     738              : std::string
     739            0 : StructStruct::as_string () const
     740              : {
     741            0 :   std::string str = VisItem::as_string ();
     742              : 
     743            0 :   str += "struct " + struct_name.as_string ();
     744              : 
     745              :   // generic params
     746            0 :   str += "\n Generic params: ";
     747            0 :   if (generic_params.empty ())
     748              :     {
     749            0 :       str += "none";
     750              :     }
     751              :   else
     752              :     {
     753            0 :       for (const auto &param : generic_params)
     754              :         {
     755              :           // DEBUG: null pointer check
     756            0 :           if (param == nullptr)
     757              :             {
     758            0 :               rust_debug (
     759              :                 "something really terrible has gone wrong - null pointer "
     760              :                 "generic param in enum.");
     761            0 :               return "NULL_POINTER_MARK";
     762              :             }
     763              : 
     764            0 :           str += "\n  " + param->as_string ();
     765              :         }
     766              :     }
     767              : 
     768            0 :   str += "\n Where clause: ";
     769            0 :   if (has_where_clause ())
     770            0 :     str += where_clause.as_string ();
     771              :   else
     772            0 :     str += "none";
     773              : 
     774              :   // struct fields
     775            0 :   str += "\n Struct fields: ";
     776            0 :   if (is_unit)
     777              :     {
     778            0 :       str += "none (unit)";
     779              :     }
     780            0 :   else if (fields.empty ())
     781              :     {
     782            0 :       str += "none (non-unit)";
     783              :     }
     784              :   else
     785              :     {
     786            0 :       for (const auto &field : fields)
     787            0 :         str += "\n  " + field.as_string ();
     788              :     }
     789              : 
     790            0 :   return str;
     791            0 : }
     792              : 
     793              : std::string
     794            0 : UseDeclaration::as_string () const
     795              : {
     796            0 :   std::string str = VisItem::as_string ();
     797              : 
     798              :   // DEBUG: null pointer check
     799            0 :   if (use_tree == nullptr)
     800              :     {
     801            0 :       rust_debug (
     802              :         "something really terrible has gone wrong - null pointer use tree in "
     803              :         "use declaration.");
     804            0 :       return "NULL_POINTER_MARK";
     805              :     }
     806              : 
     807            0 :   str += "use " + use_tree->as_string ();
     808              : 
     809            0 :   return str;
     810            0 : }
     811              : 
     812              : std::string
     813            0 : UseTreeGlob::as_string () const
     814              : {
     815            0 :   switch (glob_type)
     816              :     {
     817            0 :     case NO_PATH:
     818            0 :       return "*";
     819            0 :     case GLOBAL:
     820            0 :       return "::*";
     821            0 :     case PATH_PREFIXED:
     822            0 :       {
     823            0 :         std::string path_str = path.as_string ();
     824            0 :         return path_str + "::*";
     825            0 :       }
     826            0 :     default:
     827              :       // some kind of error
     828            0 :       return "ERROR-PATH";
     829              :     }
     830              :   rust_unreachable ();
     831              : }
     832              : 
     833              : std::string
     834            0 : UseTreeList::as_string () const
     835              : {
     836            0 :   std::string path_str;
     837            0 :   switch (path_type)
     838              :     {
     839            0 :     case NO_PATH:
     840            0 :       path_str = "{";
     841            0 :       break;
     842            0 :     case GLOBAL:
     843            0 :       path_str = "::{";
     844            0 :       break;
     845            0 :     case PATH_PREFIXED:
     846            0 :       {
     847            0 :         path_str = path.as_string () + "::{";
     848            0 :         break;
     849              :       }
     850            0 :     default:
     851              :       // some kind of error
     852            0 :       return "ERROR-PATH-LIST";
     853              :     }
     854              : 
     855            0 :   if (has_trees ())
     856              :     {
     857            0 :       auto i = trees.begin ();
     858            0 :       auto e = trees.end ();
     859              : 
     860              :       // DEBUG: null pointer check
     861            0 :       if (*i == nullptr)
     862              :         {
     863            0 :           rust_debug ("something really terrible has gone wrong - null pointer "
     864              :                       "tree in use tree list.");
     865            0 :           return "NULL_POINTER_MARK";
     866              :         }
     867              : 
     868            0 :       for (; i != e; i++)
     869              :         {
     870            0 :           path_str += (*i)->as_string ();
     871            0 :           if (e != i + 1)
     872            0 :             path_str += ", ";
     873              :         }
     874              :     }
     875              :   else
     876              :     {
     877            0 :       path_str += "none";
     878              :     }
     879              : 
     880            0 :   return path_str + "}";
     881            0 : }
     882              : 
     883              : std::string
     884            0 : UseTreeRebind::as_string () const
     885              : {
     886            0 :   std::string path_str = path.as_string ();
     887              : 
     888            0 :   switch (bind_type)
     889              :     {
     890              :     case NONE:
     891              :       // nothing to add, just path
     892              :       break;
     893            0 :     case IDENTIFIER:
     894            0 :       path_str += " as " + identifier.as_string ();
     895            0 :       break;
     896            0 :     case WILDCARD:
     897            0 :       path_str += " as _";
     898            0 :       break;
     899            0 :     default:
     900              :       // error
     901            0 :       return "ERROR-PATH-REBIND";
     902              :     }
     903              : 
     904            0 :   return path_str;
     905            0 : }
     906              : 
     907              : std::string
     908            0 : Enum::as_string () const
     909              : {
     910            0 :   std::string str = VisItem::as_string ();
     911            0 :   str += enum_name.as_string ();
     912              : 
     913              :   // generic params
     914            0 :   str += "\n Generic params: ";
     915            0 :   if (generic_params.empty ())
     916              :     {
     917            0 :       str += "none";
     918              :     }
     919              :   else
     920              :     {
     921            0 :       for (const auto &param : generic_params)
     922              :         {
     923              :           // DEBUG: null pointer check
     924            0 :           if (param == nullptr)
     925              :             {
     926            0 :               rust_debug (
     927              :                 "something really terrible has gone wrong - null pointer "
     928              :                 "generic param in enum.");
     929            0 :               return "NULL_POINTER_MARK";
     930              :             }
     931              : 
     932            0 :           str += "\n  " + param->as_string ();
     933              :         }
     934              :     }
     935              : 
     936            0 :   str += "\n Where clause: ";
     937            0 :   if (has_where_clause ())
     938            0 :     str += where_clause.as_string ();
     939              :   else
     940            0 :     str += "none";
     941              : 
     942              :   // items
     943            0 :   str += "\n Items: ";
     944            0 :   if (items.empty ())
     945              :     {
     946            0 :       str += "none";
     947              :     }
     948              :   else
     949              :     {
     950            0 :       for (const auto &item : items)
     951              :         {
     952              :           // DEBUG: null pointer check
     953            0 :           if (item == nullptr)
     954              :             {
     955            0 :               rust_debug (
     956              :                 "something really terrible has gone wrong - null pointer "
     957              :                 "enum item in enum.");
     958            0 :               return "NULL_POINTER_MARK";
     959              :             }
     960              : 
     961            0 :           str += "\n  " + item->as_string ();
     962              :         }
     963              :     }
     964              : 
     965            0 :   return str;
     966            0 : }
     967              : 
     968              : std::string
     969            0 : Trait::as_string () const
     970              : {
     971            0 :   std::string str = VisItem::as_string ();
     972              : 
     973            0 :   if (has_unsafe)
     974            0 :     str += "unsafe ";
     975              : 
     976            0 :   str += "trait " + name.as_string ();
     977              : 
     978              :   // generic params
     979            0 :   str += "\n Generic params: ";
     980            0 :   if (generic_params.empty ())
     981              :     {
     982            0 :       str += "none";
     983              :     }
     984              :   else
     985              :     {
     986            0 :       for (const auto &param : generic_params)
     987              :         {
     988              :           // DEBUG: null pointer check
     989            0 :           if (param == nullptr)
     990              :             {
     991            0 :               rust_debug (
     992              :                 "something really terrible has gone wrong - null pointer "
     993              :                 "generic param in trait.");
     994            0 :               return "NULL_POINTER_MARK";
     995              :             }
     996              : 
     997            0 :           str += "\n  " + param->as_string ();
     998              :         }
     999              :     }
    1000              : 
    1001            0 :   str += "\n Type param bounds: ";
    1002            0 :   if (!has_type_param_bounds ())
    1003              :     {
    1004            0 :       str += "none";
    1005              :     }
    1006              :   else
    1007              :     {
    1008            0 :       for (const auto &bound : type_param_bounds)
    1009              :         {
    1010              :           // DEBUG: null pointer check
    1011            0 :           if (bound == nullptr)
    1012              :             {
    1013            0 :               rust_debug (
    1014              :                 "something really terrible has gone wrong - null pointer "
    1015              :                 "type param bound in trait.");
    1016            0 :               return "NULL_POINTER_MARK";
    1017              :             }
    1018              : 
    1019            0 :           str += "\n  " + bound->as_string ();
    1020              :         }
    1021              :     }
    1022              : 
    1023            0 :   str += "\n Where clause: ";
    1024            0 :   if (!has_where_clause ())
    1025            0 :     str += "none";
    1026              :   else
    1027            0 :     str += where_clause.as_string ();
    1028              : 
    1029            0 :   str += "\n Trait items: ";
    1030            0 :   if (!has_trait_items ())
    1031              :     {
    1032            0 :       str += "none";
    1033              :     }
    1034              :   else
    1035              :     {
    1036            0 :       for (const auto &item : trait_items)
    1037              :         {
    1038              :           // DEBUG: null pointer check
    1039            0 :           if (item == nullptr)
    1040              :             {
    1041            0 :               rust_debug (
    1042              :                 "something really terrible has gone wrong - null pointer "
    1043              :                 "trait item in trait.");
    1044            0 :               return "NULL_POINTER_MARK";
    1045              :             }
    1046              : 
    1047            0 :           str += "\n  " + item->as_string ();
    1048              :         }
    1049              :     }
    1050              : 
    1051            0 :   return str;
    1052            0 : }
    1053              : 
    1054              : std::string
    1055            0 : Union::as_string () const
    1056              : {
    1057            0 :   std::string str = VisItem::as_string ();
    1058              : 
    1059            0 :   str += "union " + union_name.as_string ();
    1060              : 
    1061              :   // generic params
    1062            0 :   str += "\n Generic params: ";
    1063            0 :   if (generic_params.empty ())
    1064              :     {
    1065            0 :       str += "none";
    1066              :     }
    1067              :   else
    1068              :     {
    1069            0 :       for (const auto &param : generic_params)
    1070              :         {
    1071              :           // DEBUG: null pointer check
    1072            0 :           if (param == nullptr)
    1073              :             {
    1074            0 :               rust_debug (
    1075              :                 "something really terrible has gone wrong - null pointer "
    1076              :                 "generic param in union.");
    1077            0 :               return "NULL_POINTER_MARK";
    1078              :             }
    1079              : 
    1080            0 :           str += "\n  " + param->as_string ();
    1081              :         }
    1082              :     }
    1083              : 
    1084            0 :   str += "\n Where clause: ";
    1085            0 :   if (has_where_clause ())
    1086            0 :     str += where_clause.as_string ();
    1087              :   else
    1088            0 :     str += "none";
    1089              : 
    1090              :   // struct fields
    1091            0 :   str += "\n Struct fields (variants): ";
    1092            0 :   if (variants.empty ())
    1093              :     {
    1094            0 :       str += "none";
    1095              :     }
    1096              :   else
    1097              :     {
    1098            0 :       for (const auto &field : variants)
    1099            0 :         str += "\n  " + field.as_string ();
    1100              :     }
    1101              : 
    1102            0 :   return str;
    1103            0 : }
    1104              : 
    1105       116646 : Function::Function (Function const &other)
    1106       116646 :   : VisItem (other), ExternalItem (other.get_node_id ()),
    1107       116646 :     qualifiers (other.qualifiers), function_name (other.function_name),
    1108       116646 :     where_clause (other.where_clause), locus (other.locus),
    1109       233292 :     is_external_function (other.is_external_function)
    1110              : {
    1111              :   // guard to prevent null dereference (always required)
    1112       116646 :   if (other.return_type != nullptr)
    1113        97476 :     return_type = other.return_type->clone_type ();
    1114              : 
    1115              :   // guard to prevent null dereference (only required if error state)
    1116       116646 :   if (other.has_body ())
    1117       102461 :     function_body = other.function_body.value ()->clone_block_expr ();
    1118              :   else
    1119        14185 :     function_body = tl::nullopt;
    1120              : 
    1121       116646 :   generic_params.reserve (other.generic_params.size ());
    1122       127144 :   for (const auto &e : other.generic_params)
    1123        10498 :     generic_params.push_back (e->clone_generic_param ());
    1124              : 
    1125       116646 :   function_params.reserve (other.function_params.size ());
    1126       303768 :   for (const auto &e : other.function_params)
    1127       187122 :     function_params.push_back (e->clone_param ());
    1128       116646 : }
    1129              : 
    1130              : Function &
    1131            0 : Function::operator= (Function const &other)
    1132              : {
    1133            0 :   VisItem::operator= (other);
    1134            0 :   function_name = other.function_name;
    1135            0 :   qualifiers = other.qualifiers;
    1136            0 :   where_clause = other.where_clause;
    1137              :   // visibility = other.visibility->clone_visibility();
    1138              :   // outer_attrs = other.outer_attrs;
    1139            0 :   locus = other.locus;
    1140            0 :   is_external_function = other.is_external_function;
    1141              : 
    1142              :   // guard to prevent null dereference (always required)
    1143            0 :   if (other.return_type != nullptr)
    1144            0 :     return_type = other.return_type->clone_type ();
    1145              :   else
    1146            0 :     return_type = nullptr;
    1147              : 
    1148              :   // guard to prevent null dereference (only required if error state)
    1149            0 :   if (other.has_body ())
    1150            0 :     function_body = other.function_body.value ()->clone_block_expr ();
    1151              :   else
    1152            0 :     function_body = tl::nullopt;
    1153              : 
    1154            0 :   generic_params.reserve (other.generic_params.size ());
    1155            0 :   for (const auto &e : other.generic_params)
    1156            0 :     generic_params.push_back (e->clone_generic_param ());
    1157              : 
    1158            0 :   function_params.reserve (other.function_params.size ());
    1159            0 :   for (const auto &e : other.function_params)
    1160            0 :     function_params.push_back (e->clone_param ());
    1161              : 
    1162            0 :   return *this;
    1163              : }
    1164              : std::string
    1165            0 : Function::as_string () const
    1166              : {
    1167            0 :   std::string str = VisItem::as_string () + "\n";
    1168            0 :   std::string qstr = qualifiers.as_string ();
    1169            0 :   if ("" != qstr)
    1170            0 :     str += qstr + " ";
    1171              : 
    1172            0 :   if (has_return_type ())
    1173              :     {
    1174              :       // DEBUG: null pointer check
    1175            0 :       if (return_type == nullptr)
    1176              :         {
    1177              :           rust_debug (
    1178              :             "something really terrible has gone wrong - null pointer return "
    1179              :             "type in function.");
    1180              :           return "NULL_POINTER_MARK";
    1181              :         }
    1182              : 
    1183            0 :       str += return_type->as_string () + " ";
    1184              :     }
    1185              :   else
    1186              :     {
    1187            0 :       str += "void ";
    1188              :     }
    1189              : 
    1190            0 :   str += function_name.as_string ();
    1191              : 
    1192            0 :   if (has_generics ())
    1193              :     {
    1194            0 :       str += "<";
    1195              : 
    1196            0 :       auto i = generic_params.begin ();
    1197            0 :       auto e = generic_params.end ();
    1198              : 
    1199              :       // DEBUG: null pointer check
    1200            0 :       if (i == e)
    1201              :         {
    1202            0 :           rust_debug ("something really terrible has gone wrong - null pointer "
    1203              :                       "generic param in function item.");
    1204            0 :           return "NULL_POINTER_MARK";
    1205              :         }
    1206              : 
    1207            0 :       for (; i != e; i++)
    1208              :         {
    1209            0 :           str += (*i)->as_string ();
    1210            0 :           if (e != i + 1)
    1211            0 :             str += ", ";
    1212              :         }
    1213            0 :       str += ">";
    1214              :     }
    1215              : 
    1216            0 :   if (has_function_params ())
    1217              :     {
    1218            0 :       auto i = function_params.begin ();
    1219            0 :       auto e = function_params.end ();
    1220            0 :       str += "(";
    1221            0 :       for (; i != e; i++)
    1222              :         {
    1223            0 :           str += (*i)->as_string ();
    1224            0 :           if (e != i + 1)
    1225            0 :             str += ", ";
    1226              :         }
    1227            0 :       str += ")";
    1228              :     }
    1229              :   else
    1230              :     {
    1231            0 :       str += "()";
    1232              :     }
    1233              : 
    1234            0 :   if (has_where_clause ())
    1235            0 :     str += " where " + where_clause.as_string ();
    1236              : 
    1237            0 :   str += "\n";
    1238              : 
    1239            0 :   if (has_body ())
    1240            0 :     str += function_body.value ()->as_string () + "\n";
    1241              : 
    1242            0 :   return str;
    1243            0 : }
    1244              : 
    1245              : std::string
    1246            0 : WhereClause::as_string () const
    1247              : {
    1248              :   // just print where clause items, don't mention "where" or "where clause"
    1249            0 :   std::string str;
    1250              : 
    1251            0 :   if (where_clause_items.empty ())
    1252              :     {
    1253            0 :       str = "none";
    1254              :     }
    1255              :   else
    1256              :     {
    1257            0 :       for (const auto &item : where_clause_items)
    1258            0 :         str += "\n  " + item->as_string ();
    1259              :     }
    1260              : 
    1261            0 :   return str;
    1262              : }
    1263              : 
    1264              : std::string
    1265            0 : BlockExpr::as_string () const
    1266              : {
    1267            0 :   std::string istr = indent_spaces (enter);
    1268            0 :   std::string str = istr + "BlockExpr:\n" + istr;
    1269              : 
    1270              :   // get outer attributes
    1271            0 :   str += append_attributes (outer_attrs, OUTER);
    1272              : 
    1273              :   // inner attributes
    1274            0 :   str += append_attributes (inner_attrs, INNER);
    1275              : 
    1276              :   // statements
    1277            0 :   str += "\n" + indent_spaces (stay) + "statements: ";
    1278            0 :   if (statements.empty ())
    1279              :     {
    1280            0 :       str += "none";
    1281              :     }
    1282              :   else
    1283              :     {
    1284            0 :       for (const auto &stmt : statements)
    1285              :         {
    1286              :           // DEBUG: null pointer check
    1287            0 :           if (stmt == nullptr)
    1288              :             {
    1289            0 :               rust_debug (
    1290              :                 "something really terrible has gone wrong - null pointer "
    1291              :                 "stmt in block expr.");
    1292            0 :               return "NULL_POINTER_MARK";
    1293              :             }
    1294              : 
    1295            0 :           str += "\n" + indent_spaces (stay) + stmt->as_string ();
    1296              :         }
    1297              :     }
    1298              : 
    1299              :   // final expression
    1300            0 :   str += "\n" + indent_spaces (stay) + "final expression: ";
    1301            0 :   if (expr == nullptr)
    1302            0 :     str += "none";
    1303              :   else
    1304            0 :     str += "\n" + expr->as_string ();
    1305              : 
    1306            0 :   str += "\n" + indent_spaces (out);
    1307            0 :   return str;
    1308            0 : }
    1309              : 
    1310              : std::string
    1311            0 : AnonConst::as_string () const
    1312              : {
    1313            0 :   std::string str = "AnonConst: ";
    1314              : 
    1315            0 :   if (kind == AnonConst::Kind::DeferredInference)
    1316            0 :     str += "_";
    1317              :   else
    1318            0 :     str += expr.value ()->as_string ();
    1319              : 
    1320            0 :   return str;
    1321              : }
    1322              : 
    1323              : std::string
    1324            0 : ConstBlock::as_string () const
    1325              : {
    1326            0 :   return "ConstBlock: " + expr.as_string ();
    1327              : }
    1328              : 
    1329              : std::string
    1330            0 : TraitImpl::as_string () const
    1331              : {
    1332            0 :   std::string str = VisItem::as_string ();
    1333              : 
    1334            0 :   if (has_unsafe)
    1335            0 :     str += "unsafe ";
    1336              : 
    1337            0 :   str += "impl ";
    1338              : 
    1339              :   // generic params
    1340            0 :   str += "\n Generic params: ";
    1341            0 :   if (!has_generics ())
    1342              :     {
    1343            0 :       str += "none";
    1344              :     }
    1345              :   else
    1346              :     {
    1347            0 :       for (const auto &param : generic_params)
    1348            0 :         str += "\n  " + param->as_string ();
    1349              :     }
    1350              : 
    1351            0 :   str += "\n Has exclam: ";
    1352            0 :   if (has_exclam)
    1353            0 :     str += "true";
    1354              :   else
    1355            0 :     str += "false";
    1356              : 
    1357            0 :   str += "\n TypePath (to trait): " + trait_path.as_string ();
    1358              : 
    1359            0 :   str += "\n Type (struct to impl on): " + trait_type->as_string ();
    1360              : 
    1361            0 :   str += "\n Where clause: ";
    1362            0 :   if (!has_where_clause ())
    1363            0 :     str += "none";
    1364              :   else
    1365            0 :     str += where_clause.as_string ();
    1366              : 
    1367              :   // inner attributes
    1368            0 :   str += append_attributes (inner_attrs, INNER);
    1369              : 
    1370            0 :   str += "\n trait impl items: ";
    1371            0 :   if (!has_impl_items ())
    1372              :     {
    1373            0 :       str += "none";
    1374              :     }
    1375              :   else
    1376              :     {
    1377            0 :       for (const auto &item : impl_items)
    1378            0 :         str += "\n  " + item->as_string ();
    1379              :     }
    1380              : 
    1381            0 :   return str;
    1382              : }
    1383              : 
    1384              : std::string
    1385            0 : TypeAlias::as_string () const
    1386              : {
    1387            0 :   std::string str = VisItem::as_string ();
    1388              : 
    1389            0 :   str += " " + new_type_name.as_string ();
    1390              : 
    1391              :   // generic params
    1392            0 :   str += "\n Generic params: ";
    1393            0 :   if (!has_generics ())
    1394              :     {
    1395            0 :       str += "none";
    1396              :     }
    1397              :   else
    1398              :     {
    1399            0 :       auto i = generic_params.begin ();
    1400            0 :       auto e = generic_params.end ();
    1401              : 
    1402            0 :       for (; i != e; i++)
    1403              :         {
    1404            0 :           str += (*i)->as_string ();
    1405            0 :           if (e != i + 1)
    1406            0 :             str += ", ";
    1407              :         }
    1408              :     }
    1409              : 
    1410            0 :   str += "\n Where clause: ";
    1411            0 :   if (!has_where_clause ())
    1412            0 :     str += "none";
    1413              :   else
    1414            0 :     str += where_clause.as_string ();
    1415              : 
    1416            0 :   str += "\n Type: " + existing_type->as_string ();
    1417              : 
    1418            0 :   return str;
    1419              : }
    1420              : 
    1421              : std::string
    1422            0 : TraitAlias::as_string () const
    1423              : {
    1424            0 :   std::string str = VisItem::as_string ();
    1425              : 
    1426            0 :   str += " " + alias_name.as_string ();
    1427              : 
    1428              :   // generic params
    1429            0 :   str += "\n Generic params: ";
    1430            0 :   if (!has_generics ())
    1431              :     {
    1432            0 :       str += "none";
    1433              :     }
    1434              :   else
    1435              :     {
    1436            0 :       auto i = generic_params.begin ();
    1437            0 :       auto e = generic_params.end ();
    1438              : 
    1439            0 :       for (; i != e; i++)
    1440              :         {
    1441            0 :           str += (*i)->as_string ();
    1442            0 :           if (e != i + 1)
    1443            0 :             str += ", ";
    1444              :         }
    1445              :     }
    1446              : 
    1447            0 :   str += "\n Bounds: ";
    1448            0 :   if (alias_bounds.empty ())
    1449              :     {
    1450            0 :       str += "none";
    1451              :     }
    1452              :   else
    1453              :     {
    1454            0 :       bool needs_plus = false;
    1455              : 
    1456            0 :       for (auto &bound : alias_bounds)
    1457              :         {
    1458            0 :           if (needs_plus)
    1459            0 :             str += " + ";
    1460            0 :           needs_plus = true;
    1461            0 :           str += bound->as_string ();
    1462              :         }
    1463              :     }
    1464              : 
    1465            0 :   str += "\n Where clause: ";
    1466            0 :   if (!has_where_clause ())
    1467            0 :     str += "none";
    1468              :   else
    1469            0 :     str += where_clause.as_string ();
    1470              : 
    1471            0 :   return str;
    1472              : }
    1473              : 
    1474              : std::string
    1475            0 : ExternBlock::as_string () const
    1476              : {
    1477            0 :   std::string str = VisItem::as_string ();
    1478              : 
    1479            0 :   str += "extern ";
    1480            0 :   if (has_abi ())
    1481            0 :     str += "\"" + abi + "\" ";
    1482              : 
    1483            0 :   str += append_attributes (inner_attrs, INNER);
    1484              : 
    1485            0 :   str += "\n external items: ";
    1486            0 :   if (!has_extern_items ())
    1487              :     {
    1488            0 :       str += "none";
    1489              :     }
    1490              :   else
    1491              :     {
    1492            0 :       for (const auto &item : extern_items)
    1493            0 :         str += "\n  " + item->as_string ();
    1494              :     }
    1495              : 
    1496            0 :   return str;
    1497              : }
    1498              : 
    1499              : std::string
    1500            0 : MacroRule::as_string () const
    1501              : {
    1502            0 :   std::string str ("Macro rule: ");
    1503              : 
    1504            0 :   str += "\n Matcher: \n  ";
    1505            0 :   str += matcher.as_string ();
    1506              : 
    1507            0 :   str += "\n Transcriber: \n  ";
    1508            0 :   str += transcriber.as_string ();
    1509              : 
    1510            0 :   return str;
    1511              : }
    1512              : 
    1513              : std::string
    1514            0 : MacroRulesDefinition::as_string () const
    1515              : {
    1516            0 :   std::string str;
    1517              : 
    1518              :   // get outer attrs
    1519            0 :   str += append_attributes (outer_attrs, OUTER);
    1520              : 
    1521              :   // TODO: deal with macro_2_0
    1522            0 :   str += "macro_rules!";
    1523              : 
    1524            0 :   str += rule_name.as_string ();
    1525              : 
    1526            0 :   str += "\n Macro rules: ";
    1527            0 :   if (rules.empty ())
    1528              :     {
    1529            0 :       str += "none";
    1530              :     }
    1531              :   else
    1532              :     {
    1533            0 :       for (const auto &rule : rules)
    1534            0 :         str += "\n  " + rule.as_string ();
    1535              :     }
    1536              : 
    1537            0 :   str += "\n Delim type: ";
    1538            0 :   switch (delim_type)
    1539              :     {
    1540            0 :     case PARENS:
    1541            0 :       str += "parentheses";
    1542            0 :       break;
    1543            0 :     case SQUARE:
    1544            0 :       str += "square";
    1545            0 :       break;
    1546            0 :     case CURLY:
    1547            0 :       str += "curly";
    1548            0 :       break;
    1549            0 :     default:
    1550            0 :       return "ERROR_MARK_STRING - delim type in macro invocation";
    1551              :     }
    1552              : 
    1553            0 :   return str;
    1554            0 : }
    1555              : 
    1556              : std::string
    1557            0 : MacroInvocation::as_string () const
    1558              : {
    1559            0 :   std::string str = "MacroInvocation: ";
    1560            0 :   auto is_builtin = kind == InvocKind::Builtin;
    1561              : 
    1562            0 :   if (is_builtin)
    1563            0 :     str += "[builtin] ";
    1564              :   else
    1565            0 :     str += "[regular] ";
    1566              : 
    1567            0 :   str += append_attributes (outer_attrs, OUTER);
    1568              : 
    1569            0 :   str += "\n " + invoc_data.as_string ();
    1570              : 
    1571            0 :   str += "\n has semicolon: ";
    1572            0 :   str += has_semicolon () ? "true" : "false";
    1573              : 
    1574            0 :   if (is_builtin)
    1575              :     {
    1576            0 :       str += "[PENDING EAGER INVOCATIONS]: ";
    1577            0 :       for (auto &pending : pending_eager_invocs)
    1578              :         {
    1579            0 :           str += pending->as_string ();
    1580            0 :           str += "\n";
    1581              :         }
    1582              :     }
    1583              : 
    1584            0 :   return str;
    1585              : }
    1586              : 
    1587              : std::string
    1588            0 : MacroInvocData::as_string () const
    1589              : {
    1590            0 :   return path.as_string () + "!" + token_tree.as_string ();
    1591              : }
    1592              : 
    1593              : std::string
    1594            0 : ExprStmt::as_string () const
    1595              : {
    1596            0 :   std::string str = indent_spaces (enter) + "ExprStmt: \n";
    1597              : 
    1598            0 :   if (expr == nullptr)
    1599              :     {
    1600            0 :       str += "none (this should not happen and is an error)";
    1601              :     }
    1602              :   else
    1603              :     {
    1604            0 :       indent_spaces (enter);
    1605            0 :       str += expr->as_string ();
    1606            0 :       if (semicolon_followed)
    1607            0 :         str += ";";
    1608            0 :       indent_spaces (out);
    1609              :     }
    1610              : 
    1611            0 :   indent_spaces (out);
    1612            0 :   return str;
    1613              : }
    1614              : 
    1615              : std::string
    1616            0 : ClosureParam::as_string () const
    1617              : {
    1618            0 :   std::string str (pattern->as_string ());
    1619              : 
    1620            0 :   if (has_type_given ())
    1621            0 :     str += " : " + type->as_string ();
    1622              : 
    1623            0 :   return str;
    1624              : }
    1625              : 
    1626              : std::string
    1627            0 : ClosureExpr::as_string () const
    1628              : {
    1629            0 :   std::string str = "ClosureExpr:";
    1630              : 
    1631            0 :   str += append_attributes (outer_attrs, OUTER);
    1632              : 
    1633            0 :   str += "\n Has move: ";
    1634            0 :   if (has_move)
    1635            0 :     str += "true";
    1636              :   else
    1637            0 :     str += "false";
    1638              : 
    1639            0 :   str += "\n Params: ";
    1640            0 :   if (params.empty ())
    1641              :     {
    1642            0 :       str += "none";
    1643              :     }
    1644              :   else
    1645              :     {
    1646            0 :       for (const auto &param : params)
    1647            0 :         str += "\n  " + param.as_string ();
    1648              :     }
    1649              : 
    1650            0 :   return str;
    1651              : }
    1652              : 
    1653              : std::string
    1654            0 : ClosureExprInnerTyped::as_string () const
    1655              : {
    1656            0 :   std::string str = ClosureExpr::as_string ();
    1657              : 
    1658            0 :   str += "\n Return type: " + return_type->as_string ();
    1659              : 
    1660            0 :   str += "\n Body: " + expr->as_string ();
    1661              : 
    1662            0 :   return str;
    1663              : }
    1664              : 
    1665              : std::string
    1666            0 : QualifiedPathType::as_string () const
    1667              : {
    1668            0 :   std::string str ("<");
    1669            0 :   str += type_to_invoke_on->as_string ();
    1670              : 
    1671            0 :   if (has_as_clause ())
    1672            0 :     str += " as " + trait_path.as_string ();
    1673              : 
    1674            0 :   return str + ">";
    1675            0 : }
    1676              : 
    1677              : std::string
    1678            0 : BorrowExpr::as_string () const
    1679              : {
    1680              :   /* TODO: find way to incorporate outer attrs - may have to represent in
    1681              :    * different style (i.e. something more like BorrowExpr: \n outer attrs) */
    1682              : 
    1683            0 :   std::string str ("&");
    1684              : 
    1685            0 :   if (raw_borrow)
    1686              :     {
    1687            0 :       str += "raw ";
    1688            0 :       str += get_is_mut () ? "const " : "mut ";
    1689              :     }
    1690              :   else
    1691              :     {
    1692            0 :       if (double_borrow)
    1693            0 :         str += "&";
    1694              : 
    1695            0 :       if (get_is_mut ())
    1696            0 :         str += "mut ";
    1697              :     }
    1698            0 :   str += main_or_left_expr->as_string ();
    1699              : 
    1700            0 :   return str;
    1701              : }
    1702              : 
    1703              : std::string
    1704            0 : BoxExpr::as_string () const
    1705              : {
    1706            0 :   return "box " + expr->as_string ();
    1707              : }
    1708              : 
    1709              : void
    1710          807 : BoxExpr::accept_vis (ASTVisitor &vis)
    1711              : {
    1712          807 :   vis.visit (*this);
    1713          807 : }
    1714              : 
    1715              : std::string
    1716            0 : ReturnExpr::as_string () const
    1717              : {
    1718              :   /* TODO: find way to incorporate outer attrs - may have to represent in
    1719              :    * different style (i.e. something more like BorrowExpr: \n outer attrs) */
    1720              : 
    1721            0 :   std::string str ("return ");
    1722              : 
    1723            0 :   if (has_returned_expr ())
    1724            0 :     str += get_returned_expr ().as_string ();
    1725              : 
    1726            0 :   return str;
    1727              : }
    1728              : 
    1729              : std::string
    1730            0 : TryExpr::as_string () const
    1731              : {
    1732              :   /* TODO: find way to incorporate outer attrs - may have to represent in
    1733              :    * different style (i.e. something more like BorrowExpr: \n outer attrs) */
    1734              : 
    1735            0 :   std::string str ("try ");
    1736              : 
    1737            0 :   str += block_expr->as_string ();
    1738              : 
    1739            0 :   return str;
    1740              : }
    1741              : 
    1742              : std::string
    1743            0 : RangeToExpr::as_string () const
    1744              : {
    1745            0 :   return ".." + to->as_string ();
    1746              : }
    1747              : 
    1748              : std::string
    1749            0 : ContinueExpr::as_string () const
    1750              : {
    1751              :   // TODO: rewrite format to allow outer attributes
    1752            0 :   std::string str ("continue ");
    1753              : 
    1754            0 :   if (has_label ())
    1755            0 :     str += get_label_unchecked ().as_string ();
    1756              : 
    1757            0 :   return str;
    1758              : }
    1759              : 
    1760              : std::string
    1761            0 : NegationExpr::as_string () const
    1762              : {
    1763              :   // TODO: rewrite formula to allow outer attributes
    1764            0 :   std::string str;
    1765              : 
    1766            0 :   switch (expr_type)
    1767              :     {
    1768            0 :     case NegationOperator::NEGATE:
    1769            0 :       str = "-";
    1770            0 :       break;
    1771            0 :     case NegationOperator::NOT:
    1772            0 :       str = "!";
    1773            0 :       break;
    1774            0 :     default:
    1775            0 :       return "ERROR_MARK_STRING - negation expr";
    1776              :     }
    1777              : 
    1778            0 :   str += main_or_left_expr->as_string ();
    1779              : 
    1780            0 :   return str;
    1781            0 : }
    1782              : 
    1783              : std::string
    1784            0 : RangeFromExpr::as_string () const
    1785              : {
    1786            0 :   return from->as_string () + "..";
    1787              : }
    1788              : 
    1789              : std::string
    1790            0 : RangeFullExpr::as_string () const
    1791              : {
    1792            0 :   return "..";
    1793              : }
    1794              : 
    1795              : std::string
    1796            0 : ArrayIndexExpr::as_string () const
    1797              : {
    1798              :   // TODO: rewrite formula to allow outer attributes
    1799            0 :   return array_expr->as_string () + "[" + index_expr->as_string () + "]";
    1800              : }
    1801              : 
    1802              : std::string
    1803            0 : AssignmentExpr::as_string () const
    1804              : {
    1805            0 :   std::string str ("AssignmentExpr: ");
    1806              : 
    1807            0 :   if (main_or_left_expr == nullptr || right_expr == nullptr)
    1808              :     {
    1809            0 :       str += "error (either or both expressions are null)";
    1810              :     }
    1811              :   else
    1812              :     {
    1813              :       // left expr
    1814            0 :       str += "\n left: " + main_or_left_expr->as_string ();
    1815              : 
    1816              :       // right expr
    1817            0 :       str += "\n right: " + right_expr->as_string ();
    1818              :     }
    1819              : 
    1820            0 :   return str;
    1821              : }
    1822              : 
    1823              : std::string
    1824            0 : AsyncBlockExpr::as_string () const
    1825              : {
    1826            0 :   std::string str = "AsyncBlockExpr: ";
    1827              : 
    1828              :   // get outer attributes
    1829              :   // str += "\n " + Expr::as_string ();
    1830            0 :   str += append_attributes (outer_attrs, OUTER);
    1831              : 
    1832            0 :   str += "\n Has move: ";
    1833            0 :   str += has_move ? "true" : "false";
    1834              : 
    1835            0 :   return str + "\n" + block_expr->as_string ();
    1836            0 : }
    1837              : 
    1838              : std::string
    1839            0 : ComparisonExpr::as_string () const
    1840              : {
    1841              :   // TODO: rewrite to better reflect non-literal expressions
    1842            0 :   std::string str (main_or_left_expr->as_string ());
    1843              : 
    1844            0 :   switch (expr_type)
    1845              :     {
    1846            0 :     case ComparisonOperator::EQUAL:
    1847            0 :       str += " == ";
    1848            0 :       break;
    1849            0 :     case ComparisonOperator::NOT_EQUAL:
    1850            0 :       str += " != ";
    1851            0 :       break;
    1852            0 :     case ComparisonOperator::GREATER_THAN:
    1853            0 :       str += " > ";
    1854            0 :       break;
    1855            0 :     case ComparisonOperator::LESS_THAN:
    1856            0 :       str += " < ";
    1857            0 :       break;
    1858            0 :     case ComparisonOperator::GREATER_OR_EQUAL:
    1859            0 :       str += " >= ";
    1860            0 :       break;
    1861            0 :     case ComparisonOperator::LESS_OR_EQUAL:
    1862            0 :       str += " <= ";
    1863            0 :       break;
    1864            0 :     default:
    1865            0 :       return "ERROR_MARK_STRING - comparison expr";
    1866              :     }
    1867              : 
    1868            0 :   str += right_expr->as_string ();
    1869              : 
    1870            0 :   return str;
    1871            0 : }
    1872              : 
    1873              : std::string
    1874            0 : MethodCallExpr::as_string () const
    1875              : {
    1876            0 :   std::string str = "MethodCallExpr: ";
    1877              : 
    1878            0 :   str += append_attributes (outer_attrs, OUTER);
    1879              : 
    1880            0 :   str += "\n Object (receiver) expr: \n";
    1881            0 :   str += receiver->as_string ();
    1882              : 
    1883            0 :   str += "\n Method path segment: \n";
    1884            0 :   str += method_name.as_string ();
    1885              : 
    1886            0 :   str += "\n Call params:";
    1887            0 :   if (params.empty ())
    1888              :     {
    1889            0 :       str += "none";
    1890              :     }
    1891              :   else
    1892              :     {
    1893            0 :       for (const auto &param : params)
    1894              :         {
    1895            0 :           if (param == nullptr)
    1896            0 :             return "ERROR_MARK_STRING - method call expr param is null";
    1897              : 
    1898            0 :           str += "\n  " + param->as_string ();
    1899              :         }
    1900              :     }
    1901              : 
    1902            0 :   return str;
    1903            0 : }
    1904              : 
    1905              : std::string
    1906            0 : TupleIndexExpr::as_string () const
    1907              : {
    1908              :   // TODO: rewrite dump to better reflect non-literal exprs
    1909            0 :   return tuple_expr->as_string () + "." + std::to_string (tuple_index);
    1910              : }
    1911              : 
    1912              : std::string
    1913            0 : DereferenceExpr::as_string () const
    1914              : {
    1915              :   // TODO: rewrite dump to better reflect non-literal exprs
    1916            0 :   return "*" + main_or_left_expr->as_string ();
    1917              : }
    1918              : 
    1919              : std::string
    1920            0 : FieldAccessExpr::as_string () const
    1921              : {
    1922              :   // TODO: rewrite dump to better reflect non-literal exprs
    1923            0 :   return receiver->as_string () + "." + field.as_string ();
    1924              : }
    1925              : 
    1926              : std::string
    1927            0 : LazyBooleanExpr::as_string () const
    1928              : {
    1929              :   // TODO: rewrite dump to better reflect non-literal exprs
    1930            0 :   std::string str (main_or_left_expr->as_string ());
    1931              : 
    1932            0 :   switch (expr_type)
    1933              :     {
    1934            0 :     case LazyBooleanOperator::LOGICAL_OR:
    1935            0 :       str += " || ";
    1936            0 :       break;
    1937            0 :     case LazyBooleanOperator::LOGICAL_AND:
    1938            0 :       str += " && ";
    1939            0 :       break;
    1940            0 :     default:
    1941            0 :       return "ERROR_MARK_STRING - lazy boolean expr out of bounds";
    1942              :     }
    1943              : 
    1944            0 :   str += right_expr->as_string ();
    1945              : 
    1946            0 :   return str;
    1947            0 : }
    1948              : 
    1949              : std::string
    1950            0 : RangeFromToExpr::as_string () const
    1951              : {
    1952              :   // TODO: rewrite dump to better reflect non-literal exprs
    1953            0 :   return from->as_string () + ".." + to->as_string ();
    1954              : }
    1955              : 
    1956              : std::string
    1957            0 : RangeToInclExpr::as_string () const
    1958              : {
    1959              :   // TODO: rewrite dump to better reflect non-literal exprs
    1960            0 :   return "..=" + to->as_string ();
    1961              : }
    1962              : 
    1963              : std::string
    1964            0 : UnsafeBlockExpr::as_string () const
    1965              : {
    1966            0 :   std::string str = "UnsafeBlockExpr:" + indent_spaces (enter);
    1967              : 
    1968              :   // get outer attributes
    1969            0 :   str += append_attributes (outer_attrs, OUTER);
    1970              : 
    1971            0 :   str += indent_spaces (stay) + expr->as_string () + "\n" + indent_spaces (out);
    1972              : 
    1973            0 :   return str;
    1974              : }
    1975              : 
    1976              : std::string
    1977            0 : ClosureExprInner::as_string () const
    1978              : {
    1979            0 :   std::string str = ClosureExpr::as_string ();
    1980              : 
    1981            0 :   str += "\n Expression: " + closure_inner->as_string ();
    1982              : 
    1983            0 :   return str;
    1984              : }
    1985              : 
    1986              : std::string
    1987            0 : IfExpr::as_string () const
    1988              : {
    1989            0 :   std::string str = "IfExpr: ";
    1990              : 
    1991            0 :   str += append_attributes (outer_attrs, OUTER);
    1992              : 
    1993            0 :   str += "\n Condition expr: " + condition->as_string ();
    1994              : 
    1995            0 :   str += "\n If block expr: " + if_block->as_string ();
    1996              : 
    1997            0 :   return str;
    1998              : }
    1999              : 
    2000              : std::string
    2001            0 : IfExprConseqElse::as_string () const
    2002              : {
    2003            0 :   std::string str = IfExpr::as_string ();
    2004              : 
    2005            0 :   str += "\n Else expr: " + else_block->as_string ();
    2006              : 
    2007            0 :   return str;
    2008              : }
    2009              : 
    2010              : std::string
    2011            0 : IfLetExpr::as_string () const
    2012              : {
    2013            0 :   std::string str = "IfLetExpr: ";
    2014              : 
    2015            0 :   str += append_attributes (outer_attrs, OUTER);
    2016              : 
    2017            0 :   str += "\n Condition match arm patterns: ";
    2018            0 :   if (match_arm_pattern == nullptr)
    2019              :     {
    2020            0 :       str += "none";
    2021              :     }
    2022              :   else
    2023              :     {
    2024            0 :       str += "\n  " + match_arm_pattern->as_string ();
    2025              :     }
    2026              : 
    2027            0 :   str += "\n Scrutinee expr: " + value->as_string ();
    2028              : 
    2029            0 :   str += "\n If let block expr: " + if_block->as_string ();
    2030              : 
    2031            0 :   return str;
    2032              : }
    2033              : 
    2034              : std::string
    2035            0 : IfLetExprConseqElse::as_string () const
    2036              : {
    2037            0 :   std::string str = IfLetExpr::as_string ();
    2038              : 
    2039            0 :   str += "\n Else expr: " + else_block->as_string ();
    2040              : 
    2041            0 :   return str;
    2042              : }
    2043              : 
    2044              : std::string
    2045            0 : RangeFromToInclExpr::as_string () const
    2046              : {
    2047              :   // TODO: rewrite to allow dumps with non-literal exprs
    2048            0 :   return from->as_string () + "..=" + to->as_string ();
    2049              : }
    2050              : 
    2051              : std::string
    2052            0 : ErrorPropagationExpr::as_string () const
    2053              : {
    2054              :   // TODO: rewrite to allow dumps with non-literal exprs
    2055            0 :   return main_or_left_expr->as_string () + "?";
    2056              : }
    2057              : 
    2058              : std::string
    2059            0 : CompoundAssignmentExpr::as_string () const
    2060              : {
    2061            0 :   std::string operator_str;
    2062            0 :   operator_str.reserve (1);
    2063              : 
    2064              :   // get operator string
    2065            0 :   switch (expr_type)
    2066              :     {
    2067            0 :     case CompoundAssignmentOperator::ADD:
    2068            0 :       operator_str = "+";
    2069            0 :       break;
    2070            0 :     case CompoundAssignmentOperator::SUBTRACT:
    2071            0 :       operator_str = "-";
    2072            0 :       break;
    2073            0 :     case CompoundAssignmentOperator::MULTIPLY:
    2074            0 :       operator_str = "*";
    2075            0 :       break;
    2076            0 :     case CompoundAssignmentOperator::DIVIDE:
    2077            0 :       operator_str = "/";
    2078            0 :       break;
    2079            0 :     case CompoundAssignmentOperator::MODULUS:
    2080            0 :       operator_str = "%";
    2081            0 :       break;
    2082            0 :     case CompoundAssignmentOperator::BITWISE_AND:
    2083            0 :       operator_str = "&";
    2084            0 :       break;
    2085            0 :     case CompoundAssignmentOperator::BITWISE_OR:
    2086            0 :       operator_str = "|";
    2087            0 :       break;
    2088            0 :     case CompoundAssignmentOperator::BITWISE_XOR:
    2089            0 :       operator_str = "^";
    2090            0 :       break;
    2091            0 :     case CompoundAssignmentOperator::LEFT_SHIFT:
    2092            0 :       operator_str = "<<";
    2093            0 :       break;
    2094            0 :     case CompoundAssignmentOperator::RIGHT_SHIFT:
    2095            0 :       operator_str = ">>";
    2096            0 :       break;
    2097            0 :     default:
    2098            0 :       operator_str = "invalid operator. wtf";
    2099            0 :       break;
    2100              :     }
    2101              : 
    2102            0 :   operator_str += "=";
    2103              : 
    2104            0 :   std::string str ("CompoundAssignmentExpr: ");
    2105            0 :   if (main_or_left_expr == nullptr || right_expr == nullptr)
    2106              :     {
    2107            0 :       str += "error. this is probably a parsing failure.";
    2108              :     }
    2109              :   else
    2110              :     {
    2111            0 :       str += "\n left: " + main_or_left_expr->as_string ();
    2112            0 :       str += "\n right: " + right_expr->as_string ();
    2113            0 :       str += "\n operator: " + operator_str;
    2114              :     }
    2115              : 
    2116            0 :   return str;
    2117            0 : }
    2118              : 
    2119              : std::string
    2120            0 : ArithmeticOrLogicalExpr::as_string () const
    2121              : {
    2122            0 :   std::string operator_str;
    2123            0 :   operator_str.reserve (1);
    2124              : 
    2125              :   // get operator string
    2126            0 :   switch (expr_type)
    2127              :     {
    2128            0 :     case ArithmeticOrLogicalOperator::ADD:
    2129            0 :       operator_str = "+";
    2130            0 :       break;
    2131            0 :     case ArithmeticOrLogicalOperator::SUBTRACT:
    2132            0 :       operator_str = "-";
    2133            0 :       break;
    2134            0 :     case ArithmeticOrLogicalOperator::MULTIPLY:
    2135            0 :       operator_str = "*";
    2136            0 :       break;
    2137            0 :     case ArithmeticOrLogicalOperator::DIVIDE:
    2138            0 :       operator_str = "/";
    2139            0 :       break;
    2140            0 :     case ArithmeticOrLogicalOperator::MODULUS:
    2141            0 :       operator_str = "%";
    2142            0 :       break;
    2143            0 :     case ArithmeticOrLogicalOperator::BITWISE_AND:
    2144            0 :       operator_str = "&";
    2145            0 :       break;
    2146            0 :     case ArithmeticOrLogicalOperator::BITWISE_OR:
    2147            0 :       operator_str = "|";
    2148            0 :       break;
    2149            0 :     case ArithmeticOrLogicalOperator::BITWISE_XOR:
    2150            0 :       operator_str = "^";
    2151            0 :       break;
    2152            0 :     case ArithmeticOrLogicalOperator::LEFT_SHIFT:
    2153            0 :       operator_str = "<<";
    2154            0 :       break;
    2155            0 :     case ArithmeticOrLogicalOperator::RIGHT_SHIFT:
    2156            0 :       operator_str = ">>";
    2157            0 :       break;
    2158            0 :     default:
    2159            0 :       operator_str = "invalid operator. wtf";
    2160            0 :       break;
    2161              :     }
    2162              : 
    2163            0 :   std::string str ("ArithmeticOrLogicalExpr: ");
    2164            0 :   if (main_or_left_expr == nullptr || right_expr == nullptr)
    2165              :     {
    2166            0 :       str += "error. this is probably a parsing failure.";
    2167              :     }
    2168              :   else
    2169              :     {
    2170            0 :       str += main_or_left_expr->as_string () + " ";
    2171            0 :       str += operator_str + " ";
    2172            0 :       str += right_expr->as_string ();
    2173              :     }
    2174              : 
    2175            0 :   return str;
    2176            0 : }
    2177              : 
    2178              : std::string
    2179            0 : CallExpr::as_string () const
    2180              : {
    2181            0 :   std::string str = "CallExpr: ";
    2182              : 
    2183            0 :   str += append_attributes (outer_attrs, OUTER);
    2184              : 
    2185            0 :   str += "\n Function expr: ";
    2186            0 :   str += function->as_string ();
    2187              : 
    2188            0 :   str += "\n Call params:";
    2189            0 :   if (!has_params ())
    2190              :     {
    2191            0 :       str += "none";
    2192              :     }
    2193              :   else
    2194              :     {
    2195            0 :       for (const auto &param : params)
    2196              :         {
    2197            0 :           if (param == nullptr)
    2198            0 :             return "ERROR_MARK_STRING - call expr param is null";
    2199              : 
    2200            0 :           str += "\n  " + param->as_string ();
    2201              :         }
    2202              :     }
    2203              : 
    2204            0 :   return str;
    2205            0 : }
    2206              : 
    2207              : std::string
    2208            0 : WhileLoopExpr::as_string () const
    2209              : {
    2210            0 :   std::string str = "WhileLoopExpr: ";
    2211              : 
    2212            0 :   str += append_attributes (outer_attrs, OUTER);
    2213              : 
    2214            0 :   str += "\n Label: ";
    2215            0 :   if (!has_loop_label ())
    2216            0 :     str += "none";
    2217              :   else
    2218            0 :     str += get_loop_label ().as_string ();
    2219              : 
    2220            0 :   str += "\n Conditional expr: " + condition->as_string ();
    2221              : 
    2222            0 :   str += "\n Loop block: " + loop_block->as_string ();
    2223              : 
    2224            0 :   return str;
    2225              : }
    2226              : 
    2227              : std::string
    2228            0 : WhileLetLoopExpr::as_string () const
    2229              : {
    2230            0 :   std::string str = "WhileLetLoopExpr: ";
    2231              : 
    2232            0 :   str += append_attributes (outer_attrs, OUTER);
    2233              : 
    2234            0 :   str += "\n Label: ";
    2235            0 :   if (!has_loop_label ())
    2236            0 :     str += "none";
    2237              :   else
    2238            0 :     str += get_loop_label ().as_string ();
    2239              : 
    2240            0 :   str += "\n Match arm patterns: ";
    2241            0 :   if (match_arm_pattern == nullptr)
    2242              :     {
    2243            0 :       str += "none";
    2244              :     }
    2245              :   else
    2246              :     {
    2247            0 :       str += "\n  " + match_arm_pattern->as_string ();
    2248              :     }
    2249              : 
    2250            0 :   str += "\n Scrutinee expr: " + scrutinee->as_string ();
    2251              : 
    2252            0 :   str += "\n Loop block: " + loop_block->as_string ();
    2253              : 
    2254            0 :   return str;
    2255              : }
    2256              : 
    2257              : std::string
    2258            0 : LoopExpr::as_string () const
    2259              : {
    2260            0 :   std::string str = "LoopExpr: (infinite loop)";
    2261              : 
    2262            0 :   str += append_attributes (outer_attrs, OUTER);
    2263              : 
    2264            0 :   str += "\n Label: ";
    2265            0 :   if (!has_loop_label ())
    2266            0 :     str += "none";
    2267              :   else
    2268            0 :     str += get_loop_label ().as_string ();
    2269              : 
    2270            0 :   str += "\n Loop block: " + loop_block->as_string ();
    2271              : 
    2272            0 :   return str;
    2273              : }
    2274              : 
    2275              : std::string
    2276            0 : ArrayExpr::as_string () const
    2277              : {
    2278            0 :   std::string str = "ArrayExpr:";
    2279              : 
    2280            0 :   str += append_attributes (outer_attrs, OUTER);
    2281              : 
    2282              :   // inner attributes
    2283            0 :   str += append_attributes (inner_attrs, INNER);
    2284              : 
    2285            0 :   str += "\n Array elems: ";
    2286            0 :   str += internal_elements->as_string ();
    2287              : 
    2288            0 :   return str;
    2289              : }
    2290              : 
    2291              : std::string
    2292            0 : AwaitExpr::as_string () const
    2293              : {
    2294              :   // TODO: rewrite dump to allow non-literal exprs
    2295            0 :   return awaited_expr->as_string () + ".await";
    2296              : }
    2297              : 
    2298              : std::string
    2299            0 : BreakExpr::as_string () const
    2300              : {
    2301              :   // TODO: rewrite dump to allow outer attrs, non-literal exprs
    2302            0 :   std::string str ("break ");
    2303              : 
    2304            0 :   if (has_label ())
    2305            0 :     str += get_label_unchecked ().as_string () + " ";
    2306              : 
    2307            0 :   if (has_break_expr ())
    2308            0 :     str += get_break_expr_unchecked ().as_string ();
    2309              : 
    2310            0 :   return str;
    2311              : }
    2312              : 
    2313              : std::string
    2314            0 : LoopLabel::as_string () const
    2315              : {
    2316            0 :   return label.as_string () + ": (label) ";
    2317              : }
    2318              : 
    2319              : std::string
    2320            0 : MatchArm::as_string () const
    2321              : {
    2322              :   // outer attributes
    2323            0 :   std::string str = append_attributes (outer_attrs, OUTER);
    2324              : 
    2325            0 :   str += "\nPatterns: ";
    2326            0 :   if (match_arm_pattern == nullptr)
    2327              :     {
    2328            0 :       str += "none";
    2329              :     }
    2330              :   else
    2331              :     {
    2332            0 :       str += "\n " + match_arm_pattern->as_string ();
    2333              :     }
    2334              : 
    2335            0 :   str += "\nGuard expr: ";
    2336            0 :   if (!has_match_arm_guard ())
    2337            0 :     str += "none";
    2338              :   else
    2339            0 :     str += guard_expr->as_string ();
    2340              : 
    2341            0 :   return str;
    2342              : }
    2343              : 
    2344              : std::string
    2345            0 : MatchCase::as_string () const
    2346              : {
    2347            0 :   std::string str ("MatchCase: (match arm) ");
    2348              : 
    2349            0 :   str += "\n Match arm matcher: \n" + arm.as_string ();
    2350            0 :   str += "\n Expr: " + expr->as_string ();
    2351              : 
    2352            0 :   return str;
    2353              : }
    2354              : 
    2355              : std::string
    2356            0 : MatchExpr::as_string () const
    2357              : {
    2358            0 :   std::string str ("MatchExpr:");
    2359              : 
    2360            0 :   str += append_attributes (outer_attrs, OUTER);
    2361              : 
    2362            0 :   str += "\n Scrutinee expr: " + branch_value->as_string ();
    2363              : 
    2364              :   // inner attributes
    2365            0 :   str += append_attributes (inner_attrs, INNER);
    2366              : 
    2367              :   // match arms
    2368            0 :   str += "\n Match arms: ";
    2369            0 :   if (match_arms.empty ())
    2370              :     {
    2371            0 :       str += "none";
    2372              :     }
    2373              :   else
    2374              :     {
    2375            0 :       for (const auto &arm : match_arms)
    2376            0 :         str += "\n  " + arm.as_string ();
    2377              :     }
    2378              : 
    2379            0 :   return str;
    2380              : }
    2381              : 
    2382              : std::string
    2383            0 : TupleExpr::as_string () const
    2384              : {
    2385            0 :   std::string str ("TupleExpr:");
    2386              : 
    2387            0 :   str += append_attributes (outer_attrs, OUTER);
    2388              : 
    2389              :   // inner attributes
    2390            0 :   str += append_attributes (inner_attrs, INNER);
    2391              : 
    2392            0 :   str += "\n Tuple elements: ";
    2393            0 :   if (tuple_elems.empty ())
    2394              :     {
    2395            0 :       str += "none";
    2396              :     }
    2397              :   else
    2398              :     {
    2399            0 :       for (const auto &elem : tuple_elems)
    2400            0 :         str += "\n  " + elem->as_string ();
    2401              :     }
    2402              : 
    2403            0 :   return str;
    2404              : }
    2405              : 
    2406              : std::string
    2407            0 : FunctionParam::as_string () const
    2408              : {
    2409              :   // TODO: rewrite dump to allow non-literal types
    2410            0 :   return param_name->as_string () + " : " + type->as_string ();
    2411              : }
    2412              : 
    2413              : void
    2414      3763685 : FunctionParam::accept_vis (ASTVisitor &vis)
    2415              : {
    2416      3763685 :   vis.visit (*this);
    2417      3763685 : }
    2418              : 
    2419              : void
    2420      2275223 : SelfParam::accept_vis (ASTVisitor &vis)
    2421              : {
    2422      2275223 :   vis.visit (*this);
    2423      2275223 : }
    2424              : 
    2425              : void
    2426        20379 : VariadicParam::accept_vis (ASTVisitor &vis)
    2427              : {
    2428        20379 :   vis.visit (*this);
    2429        20379 : }
    2430              : 
    2431              : std::string
    2432            0 : VariadicParam::as_string () const
    2433              : {
    2434            0 :   if (has_pattern ())
    2435            0 :     return get_pattern ().as_string () + " : ...";
    2436              :   else
    2437            0 :     return "...";
    2438              : }
    2439              : 
    2440              : std::string
    2441            0 : FunctionQualifiers::as_string () const
    2442              : {
    2443            0 :   std::string str;
    2444              : 
    2445            0 :   if (is_async ())
    2446            0 :     str += "async ";
    2447            0 :   if (is_const ())
    2448            0 :     str += "const ";
    2449            0 :   if (is_unsafe ())
    2450            0 :     str += "unsafe ";
    2451              : 
    2452            0 :   if (has_extern)
    2453              :     {
    2454            0 :       str += "extern";
    2455            0 :       if (extern_abi != "")
    2456            0 :         str += " \"" + extern_abi + "\"";
    2457              :     }
    2458              : 
    2459            0 :   return str;
    2460              : }
    2461              : 
    2462              : std::string
    2463            0 : TraitBound::as_string () const
    2464              : {
    2465            0 :   std::string str ("TraitBound:");
    2466              : 
    2467            0 :   str += "\n Has opening question mark: ";
    2468            0 :   if (opening_question_mark)
    2469            0 :     str += "true";
    2470              :   else
    2471            0 :     str += "false";
    2472              : 
    2473            0 :   str += "\n For lifetimes: ";
    2474            0 :   if (!has_for_lifetimes ())
    2475              :     {
    2476            0 :       str += "none";
    2477              :     }
    2478              :   else
    2479              :     {
    2480            0 :       for (const auto &lifetime : for_lifetimes)
    2481            0 :         str += "\n  " + lifetime.as_string ();
    2482              :     }
    2483              : 
    2484            0 :   str += "\n Type path: " + type_path.as_string ();
    2485              : 
    2486            0 :   return str;
    2487              : }
    2488              : 
    2489              : std::string
    2490            0 : MacroMatcher::as_string () const
    2491              : {
    2492            0 :   std::string str ("Macro matcher: ");
    2493              : 
    2494            0 :   str += "\n Delim type: ";
    2495              : 
    2496            0 :   switch (delim_type)
    2497              :     {
    2498            0 :     case PARENS:
    2499            0 :       str += "parentheses";
    2500            0 :       break;
    2501            0 :     case SQUARE:
    2502            0 :       str += "square";
    2503            0 :       break;
    2504            0 :     case CURLY:
    2505            0 :       str += "curly";
    2506            0 :       break;
    2507            0 :     default:
    2508            0 :       return "ERROR_MARK_STRING - macro matcher delim";
    2509              :     }
    2510              : 
    2511            0 :   str += "\n Matches: ";
    2512              : 
    2513            0 :   if (matches.empty ())
    2514              :     {
    2515            0 :       str += "none";
    2516              :     }
    2517              :   else
    2518              :     {
    2519            0 :       for (const auto &match : matches)
    2520            0 :         str += "\n  " + match->as_string ();
    2521              :     }
    2522              : 
    2523            0 :   return str;
    2524            0 : }
    2525              : 
    2526              : std::string
    2527            0 : LifetimeParam::as_string () const
    2528              : {
    2529            0 :   std::string str ("LifetimeParam: ");
    2530              : 
    2531            0 :   str += "\n Outer attribute:";
    2532            0 :   if (!has_outer_attribute ())
    2533            0 :     str += "none";
    2534            0 :   for (auto &attr : outer_attrs)
    2535            0 :     str += " " + attr.as_string ();
    2536              : 
    2537            0 :   str += "\n Lifetime: " + lifetime.as_string ();
    2538              : 
    2539            0 :   str += "\n Lifetime bounds: ";
    2540            0 :   if (!has_lifetime_bounds ())
    2541              :     {
    2542            0 :       str += "none";
    2543              :     }
    2544              :   else
    2545              :     {
    2546            0 :       for (const auto &bound : lifetime_bounds)
    2547            0 :         str += "\n  " + bound.as_string ();
    2548              :     }
    2549              : 
    2550            0 :   return str;
    2551              : }
    2552              : 
    2553              : std::string
    2554            0 : MacroMatchFragment::as_string () const
    2555              : {
    2556            0 :   return "$" + ident.as_string () + ": " + frag_spec.as_string ();
    2557              : }
    2558              : 
    2559              : std::string
    2560            0 : MacroMatchRepetition::as_string () const
    2561              : {
    2562            0 :   std::string str ("Macro match repetition: ");
    2563              : 
    2564            0 :   str += "\n Matches: ";
    2565            0 :   if (matches.empty ())
    2566              :     {
    2567            0 :       str += "none";
    2568              :     }
    2569              :   else
    2570              :     {
    2571            0 :       for (const auto &match : matches)
    2572            0 :         str += "\n  " + match->as_string ();
    2573              :     }
    2574              : 
    2575            0 :   str += "\n Sep: ";
    2576            0 :   if (!has_sep ())
    2577            0 :     str += "none";
    2578              :   else
    2579            0 :     str += sep->as_string ();
    2580              : 
    2581            0 :   str += "\n Op: ";
    2582            0 :   switch (op)
    2583              :     {
    2584            0 :     case ANY:
    2585            0 :       str += "*";
    2586            0 :       break;
    2587            0 :     case ONE_OR_MORE:
    2588            0 :       str += "+";
    2589            0 :       break;
    2590            0 :     case ZERO_OR_ONE:
    2591            0 :       str += "?";
    2592            0 :       break;
    2593            0 :     case NONE:
    2594            0 :       str += "no op? shouldn't be allowed";
    2595            0 :       break;
    2596            0 :     default:
    2597            0 :       return "ERROR_MARK_STRING - unknown op in macro match repetition";
    2598              :     }
    2599              : 
    2600            0 :   return str;
    2601            0 : }
    2602              : 
    2603              : std::string
    2604          120 : Lifetime::as_string () const
    2605              : {
    2606          120 :   switch (lifetime_type)
    2607              :     {
    2608          120 :     case NAMED:
    2609          120 :       return "'" + lifetime_name;
    2610            0 :     case STATIC:
    2611            0 :       return "'static";
    2612            0 :     case WILDCARD:
    2613            0 :       return "'_";
    2614            0 :     default:
    2615            0 :       return "ERROR-MARK-STRING: lifetime type failure";
    2616              :     }
    2617              : }
    2618              : 
    2619              : std::string
    2620            0 : TypeParam::as_string () const
    2621              : {
    2622            0 :   std::string str ("TypeParam: ");
    2623              : 
    2624            0 :   str += "\n Outer attribute:";
    2625            0 :   if (!has_outer_attribute ())
    2626            0 :     str += "none";
    2627            0 :   for (auto &attr : outer_attrs)
    2628            0 :     str += " " + attr.as_string ();
    2629              : 
    2630            0 :   str += "\n Identifier: " + type_representation.as_string ();
    2631              : 
    2632            0 :   str += "\n Type param bounds: ";
    2633            0 :   if (!has_type_param_bounds ())
    2634              :     {
    2635            0 :       str += "none";
    2636              :     }
    2637              :   else
    2638              :     {
    2639            0 :       for (const auto &bound : type_param_bounds)
    2640            0 :         str += "\n  " + bound->as_string ();
    2641              :     }
    2642              : 
    2643            0 :   str += "\n Type: ";
    2644            0 :   if (!has_type ())
    2645            0 :     str += "none";
    2646              :   else
    2647            0 :     str += type->as_string ();
    2648              : 
    2649            0 :   return str;
    2650              : }
    2651              : 
    2652              : std::string
    2653            0 : ForLoopExpr::as_string () const
    2654              : {
    2655            0 :   std::string str = "ForLoopExpr: ";
    2656              : 
    2657            0 :   str += append_attributes (outer_attrs, OUTER);
    2658              : 
    2659            0 :   str += "\n Label: ";
    2660            0 :   if (!has_loop_label ())
    2661            0 :     str += "none";
    2662              :   else
    2663            0 :     str += get_loop_label ().as_string ();
    2664              : 
    2665            0 :   str += "\n Pattern: " + pattern->as_string ();
    2666              : 
    2667            0 :   str += "\n Iterator expr: " + iterator_expr->as_string ();
    2668              : 
    2669            0 :   str += "\n Loop block: " + loop_block->as_string ();
    2670              : 
    2671            0 :   return str;
    2672              : }
    2673              : 
    2674              : std::string
    2675            0 : LetStmt::as_string () const
    2676              : {
    2677              :   // TODO: rewrite to work with non-linearisable types and exprs
    2678            0 :   std::string str = append_attributes (outer_attrs, OUTER);
    2679              : 
    2680            0 :   str += "\n" + indent_spaces (stay) + "let " + variables_pattern->as_string ();
    2681              : 
    2682            0 :   if (has_type ())
    2683            0 :     str += " : " + type->as_string ();
    2684              : 
    2685            0 :   if (has_init_expr ())
    2686            0 :     str += " = " + init_expr->as_string ();
    2687              : 
    2688            0 :   return str;
    2689              : }
    2690              : 
    2691              : std::string
    2692            0 : InferredType::as_string () const
    2693              : {
    2694            0 :   return "_ (inferred)";
    2695              : }
    2696              : 
    2697              : std::string
    2698            0 : TypeCastExpr::as_string () const
    2699              : {
    2700              :   // TODO: rewrite to work with non-linearisable exprs and types
    2701            0 :   return main_or_left_expr->as_string () + " as "
    2702            0 :          + type_to_convert_to->as_string ();
    2703              : }
    2704              : 
    2705              : std::string
    2706            0 : ImplTraitType::as_string () const
    2707              : {
    2708            0 :   std::string str ("ImplTraitType: \n TypeParamBounds: ");
    2709              : 
    2710            0 :   if (type_param_bounds.empty ())
    2711              :     {
    2712            0 :       str += "none";
    2713              :     }
    2714              :   else
    2715              :     {
    2716            0 :       for (const auto &bound : type_param_bounds)
    2717            0 :         str += "\n  " + bound->as_string ();
    2718              :     }
    2719              : 
    2720            0 :   return str;
    2721              : }
    2722              : 
    2723              : std::string
    2724            0 : ReferenceType::as_string () const
    2725              : {
    2726              :   // TODO: rewrite to work with non-linearisable types
    2727            0 :   std::string str ("&");
    2728              : 
    2729            0 :   if (has_lifetime ())
    2730            0 :     str += get_lifetime ().as_string () + " ";
    2731              : 
    2732            0 :   if (has_mut)
    2733            0 :     str += "mut ";
    2734              : 
    2735            0 :   str += type->as_string ();
    2736              : 
    2737            0 :   return str;
    2738              : }
    2739              : 
    2740              : std::string
    2741            0 : RawPointerType::as_string () const
    2742              : {
    2743              :   // TODO: rewrite to work with non-linearisable types
    2744            0 :   std::string str ("*");
    2745              : 
    2746            0 :   switch (pointer_type)
    2747              :     {
    2748            0 :     case MUT:
    2749            0 :       str += "mut ";
    2750            0 :       break;
    2751            0 :     case CONST:
    2752            0 :       str += "const ";
    2753            0 :       break;
    2754            0 :     default:
    2755            0 :       return "ERROR_MARK_STRING - unknown pointer type in raw pointer type";
    2756              :     }
    2757              : 
    2758            0 :   str += type->as_string ();
    2759              : 
    2760            0 :   return str;
    2761            0 : }
    2762              : 
    2763              : std::string
    2764            0 : TraitObjectType::as_string () const
    2765              : {
    2766            0 :   std::string str ("TraitObjectType: \n Has dyn dispatch: ");
    2767              : 
    2768            0 :   if (has_dyn)
    2769            0 :     str += "true";
    2770              :   else
    2771            0 :     str += "false";
    2772              : 
    2773            0 :   str += "\n TypeParamBounds: ";
    2774            0 :   if (type_param_bounds.empty ())
    2775              :     {
    2776            0 :       str += "none";
    2777              :     }
    2778              :   else
    2779              :     {
    2780            0 :       for (const auto &bound : type_param_bounds)
    2781            0 :         str += "\n  " + bound->as_string ();
    2782              :     }
    2783              : 
    2784            0 :   return str;
    2785              : }
    2786              : 
    2787              : std::string
    2788            0 : BareFunctionType::as_string () const
    2789              : {
    2790            0 :   std::string str ("BareFunctionType: \n For lifetimes: ");
    2791              : 
    2792            0 :   if (!has_for_lifetimes ())
    2793              :     {
    2794            0 :       str += "none";
    2795              :     }
    2796              :   else
    2797              :     {
    2798            0 :       for (const auto &for_lifetime : for_lifetimes)
    2799            0 :         str += "\n  " + for_lifetime.as_string ();
    2800              :     }
    2801              : 
    2802            0 :   str += "\n Qualifiers: " + function_qualifiers.as_string ();
    2803              : 
    2804            0 :   str += "\n Params: ";
    2805            0 :   if (params.empty ())
    2806              :     {
    2807            0 :       str += "none";
    2808              :     }
    2809              :   else
    2810              :     {
    2811            0 :       for (const auto &param : params)
    2812            0 :         str += "\n  " + param.as_string ();
    2813              :     }
    2814              : 
    2815            0 :   str += "\n Is variadic: ";
    2816            0 :   if (_is_variadic)
    2817            0 :     str += "true";
    2818              :   else
    2819            0 :     str += "false";
    2820              : 
    2821            0 :   str += "\n Return type: ";
    2822            0 :   if (!has_return_type ())
    2823            0 :     str += "none (void)";
    2824              :   else
    2825            0 :     str += return_type->as_string ();
    2826              : 
    2827            0 :   return str;
    2828              : }
    2829              : 
    2830              : std::string
    2831            0 : ImplTraitTypeOneBound::as_string () const
    2832              : {
    2833            0 :   std::string str ("ImplTraitTypeOneBound: \n TraitBound: ");
    2834              : 
    2835            0 :   return str + trait_bound->as_string ();
    2836            0 : }
    2837              : 
    2838              : std::string
    2839            0 : TraitObjectTypeOneBound::as_string () const
    2840              : {
    2841            0 :   std::string str ("TraitObjectTypeOneBound: \n Has dyn dispatch: ");
    2842              : 
    2843            0 :   if (has_dyn)
    2844            0 :     str += "true";
    2845              :   else
    2846            0 :     str += "false";
    2847              : 
    2848            0 :   str += "\n TraitBound: " + trait_bound.as_string ();
    2849              : 
    2850            0 :   return str;
    2851              : }
    2852              : 
    2853              : std::string
    2854            0 : ArrayType::as_string () const
    2855              : {
    2856              :   // TODO: rewrite to work with non-linearisable types and exprs
    2857            0 :   return "[" + elem_type->as_string () + "; " + size.as_string () + "]";
    2858              : }
    2859              : 
    2860              : std::string
    2861            0 : SliceType::as_string () const
    2862              : {
    2863              :   // TODO: rewrite to work with non-linearisable types
    2864            0 :   return "[" + elem_type->as_string () + "]";
    2865              : }
    2866              : 
    2867              : std::string
    2868            0 : TupleType::as_string () const
    2869              : {
    2870              :   // TODO: rewrite to work with non-linearisable types
    2871            0 :   std::string str ("(");
    2872              : 
    2873            0 :   if (!is_unit_type ())
    2874              :     {
    2875            0 :       auto i = elems.begin ();
    2876            0 :       auto e = elems.end ();
    2877              : 
    2878            0 :       for (; i != e; i++)
    2879              :         {
    2880            0 :           str += (*i)->as_string ();
    2881            0 :           if (e != i + 1)
    2882            0 :             str += ", ";
    2883              :         }
    2884              :     }
    2885              : 
    2886            0 :   str += ")";
    2887              : 
    2888            0 :   return str;
    2889              : }
    2890              : 
    2891              : std::string
    2892            0 : StructExpr::as_string () const
    2893              : {
    2894            0 :   std::string str = append_attributes (outer_attrs, OUTER);
    2895            0 :   indent_spaces (enter);
    2896            0 :   str += "\n" + indent_spaces (stay) + "StructExpr:";
    2897            0 :   indent_spaces (enter);
    2898            0 :   str += "\n" + indent_spaces (stay) + "PathInExpr:\n";
    2899            0 :   str += indent_spaces (stay) + struct_name.as_string ();
    2900            0 :   indent_spaces (out);
    2901            0 :   indent_spaces (out);
    2902            0 :   return str;
    2903              : }
    2904              : 
    2905              : std::string
    2906            0 : StructExprStruct::as_string () const
    2907              : {
    2908              :   // TODO: doesn't this require data from StructExpr?
    2909            0 :   std::string str ("StructExprStruct (or subclass): ");
    2910              : 
    2911            0 :   str += "\n Path: " + get_struct_name ().as_string ();
    2912              : 
    2913              :   // inner attributes
    2914            0 :   str += append_attributes (inner_attrs, INNER);
    2915              : 
    2916            0 :   return str;
    2917              : }
    2918              : 
    2919              : std::string
    2920            0 : StructBase::as_string () const
    2921              : {
    2922            0 :   if (base_struct != nullptr)
    2923            0 :     return base_struct->as_string ();
    2924              :   else
    2925            0 :     return "ERROR_MARK_STRING - invalid struct base had as string applied";
    2926              : }
    2927              : 
    2928              : std::string
    2929            0 : StructExprFieldWithVal::as_string () const
    2930              : {
    2931              :   // used to get value string
    2932            0 :   return value->as_string ();
    2933              : }
    2934              : 
    2935              : std::string
    2936            0 : StructExprFieldIdentifierValue::as_string () const
    2937              : {
    2938              :   // TODO: rewrite to work with non-linearisable exprs
    2939            0 :   return field_name.as_string () + " : " + StructExprFieldWithVal::as_string ();
    2940              : }
    2941              : 
    2942              : std::string
    2943            0 : StructExprFieldIndexValue::as_string () const
    2944              : {
    2945              :   // TODO: rewrite to work with non-linearisable exprs
    2946            0 :   return std::to_string (index) + " : " + StructExprFieldWithVal::as_string ();
    2947              : }
    2948              : 
    2949              : std::string
    2950            0 : StructExprStructFields::as_string () const
    2951              : {
    2952            0 :   std::string str = StructExprStruct::as_string ();
    2953              : 
    2954            0 :   str += "\n Fields: ";
    2955            0 :   if (fields.empty ())
    2956              :     {
    2957            0 :       str += "none";
    2958              :     }
    2959              :   else
    2960              :     {
    2961            0 :       for (const auto &field : fields)
    2962            0 :         str += "\n  " + field->as_string ();
    2963              :     }
    2964              : 
    2965            0 :   str += "\n Struct base: ";
    2966            0 :   if (!has_struct_base ())
    2967            0 :     str += "none";
    2968              :   else
    2969            0 :     str += struct_base.as_string ();
    2970              : 
    2971            0 :   return str;
    2972              : }
    2973              : 
    2974              : std::string
    2975            0 : EnumItem::as_string () const
    2976              : {
    2977            0 :   std::string str = VisItem::as_string ();
    2978            0 :   str += variant_name.as_string ();
    2979              : 
    2980            0 :   return str;
    2981              : }
    2982              : 
    2983              : std::string
    2984            0 : EnumItemTuple::as_string () const
    2985              : {
    2986            0 :   std::string str = EnumItem::as_string ();
    2987              : 
    2988              :   // add tuple opening parens
    2989            0 :   str += "(";
    2990              : 
    2991              :   // tuple fields
    2992            0 :   if (has_tuple_fields ())
    2993              :     {
    2994            0 :       auto i = tuple_fields.begin ();
    2995            0 :       auto e = tuple_fields.end ();
    2996              : 
    2997            0 :       for (; i != e; i++)
    2998              :         {
    2999            0 :           str += (*i).as_string ();
    3000            0 :           if (e != i + 1)
    3001            0 :             str += ", ";
    3002              :         }
    3003              :     }
    3004              : 
    3005              :   // add tuple closing parens
    3006            0 :   str += ")";
    3007              : 
    3008            0 :   return str;
    3009              : }
    3010              : 
    3011              : std::string
    3012            0 : TupleField::as_string () const
    3013              : {
    3014              :   // TODO: rewrite to work with non-linearisable exprs
    3015              : 
    3016              :   // outer attributes
    3017            0 :   std::string str = append_attributes (outer_attrs, OUTER);
    3018              : 
    3019            0 :   if (has_visibility ())
    3020            0 :     str += "\n" + visibility.as_string ();
    3021              : 
    3022            0 :   str += " " + field_type->as_string ();
    3023              : 
    3024            0 :   return str;
    3025              : }
    3026              : 
    3027              : std::string
    3028            0 : EnumItemStruct::as_string () const
    3029              : {
    3030            0 :   std::string str = EnumItem::as_string ();
    3031              : 
    3032              :   // add struct opening parens
    3033            0 :   str += "{";
    3034              : 
    3035              :   // tuple fields
    3036            0 :   if (has_struct_fields ())
    3037              :     {
    3038            0 :       auto i = struct_fields.begin ();
    3039            0 :       auto e = struct_fields.end ();
    3040              : 
    3041            0 :       for (; i != e; i++)
    3042              :         {
    3043            0 :           str += (*i).as_string ();
    3044            0 :           if (e != i + 1)
    3045            0 :             str += ", ";
    3046              :         }
    3047              :     }
    3048              : 
    3049              :   // add struct closing parens
    3050            0 :   str += "}";
    3051              : 
    3052            0 :   return str;
    3053              : }
    3054              : 
    3055              : std::string
    3056            0 : StructField::as_string () const
    3057              : {
    3058              :   // TODO: rewrite to work with non-linearisable exprs
    3059              :   // outer attributes
    3060            0 :   std::string str = append_attributes (outer_attrs, OUTER);
    3061              : 
    3062            0 :   if (has_visibility ())
    3063            0 :     str += "\n" + visibility.as_string ();
    3064              : 
    3065            0 :   str += " " + field_name.as_string () + " : " + field_type->as_string ();
    3066              : 
    3067            0 :   return str;
    3068              : }
    3069              : 
    3070              : std::string
    3071            0 : EnumItemDiscriminant::as_string () const
    3072              : {
    3073              :   // TODO: rewrite to work with non-linearisable exprs
    3074            0 :   std::string str = EnumItem::as_string ();
    3075              : 
    3076              :   // add equal and expression
    3077            0 :   str += " = " + expression->as_string ();
    3078              : 
    3079            0 :   return str;
    3080              : }
    3081              : 
    3082              : std::string
    3083            0 : ExternalTypeItem::as_string () const
    3084              : {
    3085            0 :   auto str = append_attributes (outer_attrs, OUTER);
    3086              : 
    3087            0 :   str += "type " + item_name.as_string () + ";";
    3088              : 
    3089            0 :   return str;
    3090              : }
    3091              : 
    3092              : std::string
    3093            0 : ExternalStaticItem::as_string () const
    3094              : {
    3095              :   // outer attributes
    3096            0 :   std::string str = append_attributes (outer_attrs, OUTER);
    3097              : 
    3098              :   // start visibility on new line and with a space
    3099            0 :   str += "\n" + visibility.as_string () + " ";
    3100              : 
    3101            0 :   str += "static ";
    3102              : 
    3103            0 :   if (has_mut)
    3104            0 :     str += "mut ";
    3105              : 
    3106              :   // add name
    3107            0 :   str += item_name.as_string ();
    3108              : 
    3109              :   // add type on new line
    3110            0 :   str += "\n Type: " + item_type->as_string ();
    3111              : 
    3112            0 :   return str;
    3113              : }
    3114              : 
    3115              : std::string
    3116            0 : TraitItemType::as_string () const
    3117              : {
    3118            0 :   std::string str = append_attributes (outer_attrs, OUTER);
    3119              : 
    3120            0 :   str += "\ntype " + name.as_string ();
    3121              : 
    3122            0 :   if (has_generics ())
    3123              :     {
    3124            0 :       str += "<";
    3125            0 :       for (size_t i = 0; i < generic_params.size (); i++)
    3126              :         {
    3127            0 :           if (i > 0)
    3128            0 :             str += ", ";
    3129            0 :           str += generic_params[i]->as_string ();
    3130              :         }
    3131            0 :       str += ">";
    3132              :     }
    3133              : 
    3134            0 :   str += "\n Type param bounds: ";
    3135            0 :   if (!has_type_param_bounds ())
    3136              :     {
    3137            0 :       str += "none";
    3138              :     }
    3139              :   else
    3140              :     {
    3141            0 :       for (const auto &bound : type_param_bounds)
    3142              :         {
    3143              :           // DEBUG: null pointer check
    3144            0 :           if (bound == nullptr)
    3145              :             {
    3146            0 :               rust_debug (
    3147              :                 "something really terrible has gone wrong - null pointer "
    3148              :                 "type param bound in trait item type.");
    3149            0 :               return "NULL_POINTER_MARK";
    3150              :             }
    3151              : 
    3152            0 :           str += "\n  " + bound->as_string ();
    3153              :         }
    3154              :     }
    3155              : 
    3156            0 :   return str;
    3157            0 : }
    3158              : 
    3159              : std::string
    3160            0 : SelfParam::as_string () const
    3161              : {
    3162              :   // TODO: rewrite to allow non-linearisable types
    3163            0 :   if (is_error ())
    3164              :     {
    3165            0 :       return "error";
    3166              :     }
    3167              :   else
    3168              :     {
    3169            0 :       if (has_type ())
    3170              :         {
    3171              :           // type (i.e. not ref, no lifetime)
    3172            0 :           std::string str;
    3173              : 
    3174            0 :           if (is_mut)
    3175            0 :             str += "mut ";
    3176              : 
    3177            0 :           str += "self : ";
    3178              : 
    3179            0 :           str += type->as_string ();
    3180              : 
    3181            0 :           return str;
    3182            0 :         }
    3183            0 :       else if (has_lifetime ())
    3184              :         {
    3185              :           // ref and lifetime
    3186            0 :           std::string str = "&" + get_lifetime ().as_string () + " ";
    3187              : 
    3188            0 :           if (is_mut)
    3189            0 :             str += "mut ";
    3190              : 
    3191            0 :           str += "self";
    3192              : 
    3193            0 :           return str;
    3194            0 :         }
    3195            0 :       else if (has_ref)
    3196              :         {
    3197              :           // ref with no lifetime
    3198            0 :           std::string str = "&";
    3199              : 
    3200            0 :           if (is_mut)
    3201            0 :             str += " mut ";
    3202              : 
    3203            0 :           str += "self";
    3204              : 
    3205            0 :           return str;
    3206            0 :         }
    3207              :       else
    3208              :         {
    3209              :           // no ref, no type
    3210            0 :           std::string str;
    3211              : 
    3212            0 :           if (is_mut)
    3213            0 :             str += "mut ";
    3214              : 
    3215            0 :           str += "self";
    3216              : 
    3217            0 :           return str;
    3218            0 :         }
    3219              :     }
    3220              : }
    3221              : 
    3222              : std::string
    3223            0 : ArrayElemsCopied::as_string () const
    3224              : {
    3225              :   // TODO: rewrite to allow non-linearisable exprs
    3226            0 :   return elem_to_copy->as_string () + "; " + num_copies->as_string ();
    3227              : }
    3228              : 
    3229              : std::string
    3230            0 : LifetimeWhereClauseItem::as_string () const
    3231              : {
    3232            0 :   std::string str ("Lifetime: ");
    3233              : 
    3234            0 :   str += lifetime.as_string ();
    3235              : 
    3236            0 :   str += "\nLifetime bounds: ";
    3237              : 
    3238            0 :   for (const auto &bound : lifetime_bounds)
    3239            0 :     str += "\n " + bound.as_string ();
    3240              : 
    3241            0 :   return str;
    3242              : }
    3243              : 
    3244              : std::string
    3245            0 : TypeBoundWhereClauseItem::as_string () const
    3246              : {
    3247            0 :   std::string str ("For lifetimes: ");
    3248              : 
    3249            0 :   if (!has_for_lifetimes ())
    3250              :     {
    3251            0 :       str += "none";
    3252              :     }
    3253              :   else
    3254              :     {
    3255            0 :       for (const auto &for_lifetime : for_lifetimes)
    3256            0 :         str += "\n " + for_lifetime.as_string ();
    3257              :     }
    3258              : 
    3259            0 :   str += "\nType: " + bound_type->as_string ();
    3260              : 
    3261            0 :   str += "\nType param bounds bounds: ";
    3262              : 
    3263            0 :   for (const auto &bound : type_param_bounds)
    3264              :     {
    3265              :       // debug null pointer check
    3266            0 :       if (bound == nullptr)
    3267            0 :         return "NULL_POINTER_MARK - type param bounds";
    3268              : 
    3269            0 :       str += "\n " + bound->as_string ();
    3270              :     }
    3271              : 
    3272            0 :   return str;
    3273            0 : }
    3274              : 
    3275              : std::string
    3276            0 : ArrayElemsValues::as_string () const
    3277              : {
    3278            0 :   std::string str;
    3279              : 
    3280            0 :   for (const auto &expr : values)
    3281              :     {
    3282              :       // DEBUG: null pointer check
    3283            0 :       if (expr == nullptr)
    3284              :         {
    3285            0 :           rust_debug ("something really terrible has gone wrong - null pointer "
    3286              :                       "expr in array elems values.");
    3287            0 :           return "NULL_POINTER_MARK";
    3288              :         }
    3289              : 
    3290            0 :       str += "\n  " + expr->as_string ();
    3291              :     }
    3292              : 
    3293            0 :   return str;
    3294            0 : }
    3295              : 
    3296              : std::string
    3297            0 : MaybeNamedParam::as_string () const
    3298              : {
    3299              :   // TODO: rewrite to allow using non-linearisable types in dump
    3300            0 :   std::string str;
    3301              : 
    3302            0 :   switch (param_kind)
    3303              :     {
    3304              :     case UNNAMED:
    3305              :       break;
    3306            0 :     case IDENTIFIER:
    3307            0 :       str = name.as_string () + " : ";
    3308            0 :       break;
    3309            0 :     case WILDCARD:
    3310            0 :       str = "_ : ";
    3311            0 :       break;
    3312            0 :     default:
    3313            0 :       return "ERROR_MARK_STRING - maybe named param unrecognised param kind";
    3314              :     }
    3315              : 
    3316            0 :   str += param_type->as_string ();
    3317              : 
    3318            0 :   return str;
    3319            0 : }
    3320              : 
    3321        44562 : MetaItemInner::~MetaItemInner () = default;
    3322              : 
    3323              : std::unique_ptr<MetaNameValueStr>
    3324            0 : MetaItemInner::to_meta_name_value_str () const
    3325              : {
    3326            0 :   if (is_key_value_pair ())
    3327              :     {
    3328            0 :       auto converted_item = static_cast<const MetaNameValueStr *> (this);
    3329            0 :       return converted_item->to_meta_name_value_str ();
    3330              :     }
    3331              :   // TODO actually parse foo = bar
    3332            0 :   return nullptr;
    3333              : }
    3334              : 
    3335              : std::string
    3336       546714 : MetaItemSeq::as_string () const
    3337              : {
    3338       546714 :   std::string path_str = path.as_string () + "(";
    3339              : 
    3340       546714 :   auto i = seq.begin ();
    3341       546714 :   auto e = seq.end ();
    3342              : 
    3343      1093428 :   for (; i != e; i++)
    3344              :     {
    3345      1093428 :       path_str += (*i)->as_string ();
    3346       546714 :       if (e != i + 1)
    3347            0 :         path_str += ", ";
    3348              :     }
    3349              : 
    3350       546714 :   return path_str + ")";
    3351       546714 : }
    3352              : 
    3353              : std::string
    3354            0 : MetaListPaths::as_string () const
    3355              : {
    3356            0 :   std::string str = ident.as_string () + "(";
    3357              : 
    3358            0 :   auto i = paths.begin ();
    3359            0 :   auto e = paths.end ();
    3360              : 
    3361            0 :   for (; i != e; i++)
    3362              :     {
    3363            0 :       str += (*i).as_string ();
    3364            0 :       if (e != i + 1)
    3365            0 :         str += ", ";
    3366              :     }
    3367              : 
    3368            0 :   return str + ")";
    3369            0 : }
    3370              : 
    3371              : std::string
    3372            0 : MetaListNameValueStr::as_string () const
    3373              : {
    3374            0 :   std::string str = ident.as_string () + "(";
    3375              : 
    3376            0 :   auto i = strs.begin ();
    3377            0 :   auto e = strs.end ();
    3378              : 
    3379            0 :   for (; i != e; i++)
    3380              :     {
    3381            0 :       str += (*i).as_string ();
    3382            0 :       if (e != i + 1)
    3383            0 :         str += ", ";
    3384              :     }
    3385              : 
    3386            0 :   return str + ")";
    3387            0 : }
    3388              : 
    3389              : std::string
    3390       546707 : AttrInputMetaItemContainer::as_string () const
    3391              : {
    3392       546707 :   std::string str = "(";
    3393              : 
    3394       546707 :   auto i = items.begin ();
    3395       546707 :   auto e = items.end ();
    3396              : 
    3397      1093414 :   for (; i != e; i++)
    3398              :     {
    3399      1093414 :       str += (*i)->as_string ();
    3400       546707 :       if (e != i + 1)
    3401            0 :         str += ", ";
    3402              :     }
    3403              : 
    3404       546707 :   return str + ")";
    3405       546707 : }
    3406              : 
    3407         5998 : AttrInputExpr::AttrInputExpr (const AttrInputExpr &oth)
    3408         5998 :   : expr (oth.expr->clone_expr ())
    3409         5998 : {}
    3410              : 
    3411              : AttrInputExpr &
    3412            0 : AttrInputExpr::operator= (const AttrInputExpr &oth)
    3413              : {
    3414            0 :   expr = oth.expr->clone_expr ();
    3415            0 :   return *this;
    3416              : }
    3417              : 
    3418              : std::string
    3419            0 : AttrInputExpr::as_string () const
    3420              : {
    3421            0 :   return expr->as_string ();
    3422              : }
    3423              : 
    3424              : void
    3425        25677 : AttrInputExpr::accept_vis (ASTVisitor &vis)
    3426              : {
    3427        25677 :   vis.visit (*this);
    3428        25677 : }
    3429              : 
    3430              : /* Override that calls the function recursively on all items contained within
    3431              :  * the module. */
    3432              : void
    3433            0 : Module::add_crate_name (std::vector<std::string> &names) const
    3434              : {
    3435              :   /* TODO: test whether module has been 'cfg'-ed out to determine whether to
    3436              :    * exclude it from search */
    3437              : 
    3438            0 :   for (const auto &item : items)
    3439            0 :     item->add_crate_name (names);
    3440            0 : }
    3441              : 
    3442              : static bool
    3443          557 : file_exists (const std::string path)
    3444              : {
    3445              :   // Simply check if the file exists
    3446              :   // FIXME: This does not work on Windows
    3447            0 :   return access (path.c_str (), F_OK) != -1;
    3448              : }
    3449              : 
    3450              : static std::string
    3451          315 : filename_from_path_attribute (std::vector<Attribute> &outer_attrs)
    3452              : {
    3453              :   // An out-of-line module cannot have inner attributes. Additionally, the
    3454              :   // default name is specified as `""` so that the caller can detect the case
    3455              :   // of "no path given" and use the default path logic (`name.rs` or
    3456              :   // `name/mod.rs`).
    3457          315 :   return extract_module_path ({}, outer_attrs, "");
    3458              : }
    3459              : 
    3460              : void
    3461          318 : Module::process_file_path ()
    3462              : {
    3463          318 :   rust_assert (kind == Module::ModuleKind::UNLOADED);
    3464              : 
    3465          318 :   if (!module_file.empty ())
    3466              :     {
    3467            3 :       rust_error_at (locus, "error handling module file for %qs",
    3468            3 :                      module_name.as_string ().c_str ());
    3469           85 :       return;
    3470              :     }
    3471              : 
    3472              :   // This corresponds to the path of the file 'including' the module. So the
    3473              :   // file that contains the 'mod <file>;' directive
    3474          315 :   std::string including_fpath (outer_filename);
    3475              : 
    3476          315 :   std::string expected_file_path = module_name.as_string () + ".rs";
    3477          315 :   std::string expected_dir_path = "mod.rs";
    3478              : 
    3479          315 :   auto dir_slash_pos = including_fpath.rfind (file_separator);
    3480          315 :   std::string current_directory_name;
    3481          315 :   std::string including_fname;
    3482              : 
    3483              :   // If we haven't found a file_separator, then we may have to look for files in
    3484              :   // the current directory ('.')
    3485          315 :   if (dir_slash_pos == std::string::npos)
    3486              :     {
    3487            1 :       including_fname = std::move (including_fpath);
    3488            2 :       including_fpath = std::string (".") + file_separator + including_fname;
    3489            1 :       dir_slash_pos = 1;
    3490              :     }
    3491              :   else
    3492              :     {
    3493          314 :       including_fname = including_fpath.substr (dir_slash_pos + 1);
    3494              :     }
    3495              : 
    3496          315 :   current_directory_name
    3497          630 :     = including_fpath.substr (0, dir_slash_pos) + file_separator;
    3498              : 
    3499          315 :   auto path_string = filename_from_path_attribute (get_outer_attrs ());
    3500              : 
    3501          315 :   std::string including_subdir;
    3502          315 :   bool subdir_was_added = false;
    3503          315 :   if (path_string.empty () && module_scope.empty ()
    3504          568 :       && get_file_subdir (including_fname, including_subdir))
    3505              :     {
    3506           82 :       current_directory_name += including_subdir + file_separator;
    3507           41 :       subdir_was_added = true;
    3508              :     }
    3509              : 
    3510              :   // Handle inline module declarations adding path components.
    3511          323 :   for (auto const &name : module_scope)
    3512              :     {
    3513            8 :       current_directory_name.append (name);
    3514            8 :       current_directory_name.append (file_separator);
    3515              :     }
    3516              : 
    3517          315 :   if (!path_string.empty ())
    3518              :     {
    3519           58 :       module_file = current_directory_name + path_string;
    3520           58 :       return;
    3521              :     }
    3522              : 
    3523              :   // FIXME: We also have to search for
    3524              :   // <directory>/<including_fname>/<module_name>.rs In rustc, this is done via
    3525              :   // the concept of `DirOwnernship`, which is based on whether or not the
    3526              :   // current file is titled `mod.rs`.
    3527              : 
    3528              :   // First, we search for <directory>/<module_name>.rs
    3529          257 :   std::string file_mod_path = current_directory_name + expected_file_path;
    3530          514 :   bool file_mod_found = file_exists (file_mod_path);
    3531              : 
    3532              :   // Then, search for <directory>/<module_name>/mod.rs
    3533          257 :   std::string dir_mod_path = current_directory_name + module_name.as_string ()
    3534          257 :                              + file_separator + expected_dir_path;
    3535          514 :   bool dir_mod_found = file_exists (dir_mod_path);
    3536              : 
    3537          257 :   if (!file_mod_found && !dir_mod_found && subdir_was_added)
    3538              :     {
    3539           22 :       size_t suffix_len
    3540           22 :         = including_subdir.length () + std::string (file_separator).length ();
    3541           22 :       std::string fallback_dir
    3542           22 :         = current_directory_name.substr (0, current_directory_name.length ()
    3543           22 :                                               - suffix_len);
    3544           22 :       std::string fallback_file = fallback_dir + expected_file_path;
    3545           22 :       std::string fallback_dir_mod = fallback_dir + module_name.as_string ()
    3546           22 :                                      + file_separator + expected_dir_path;
    3547           44 :       if (file_exists (fallback_file))
    3548              :         {
    3549            1 :           file_mod_found = true;
    3550            1 :           file_mod_path = fallback_file;
    3551              :         }
    3552           42 :       else if (file_exists (fallback_dir_mod))
    3553              :         {
    3554            0 :           dir_mod_found = true;
    3555            0 :           dir_mod_path = fallback_dir_mod;
    3556              :         }
    3557           22 :     }
    3558              : 
    3559          257 :   bool multiple_candidates_found = file_mod_found && dir_mod_found;
    3560          257 :   bool no_candidates_found = !file_mod_found && !dir_mod_found;
    3561              : 
    3562          257 :   if (multiple_candidates_found)
    3563            0 :     rust_error_at (locus,
    3564              :                    "two candidates found for module %s: %s.rs and %s%smod.rs",
    3565            0 :                    module_name.as_string ().c_str (),
    3566            0 :                    module_name.as_string ().c_str (),
    3567            0 :                    module_name.as_string ().c_str (), file_separator);
    3568              : 
    3569          257 :   if (no_candidates_found)
    3570           21 :     rust_error_at (locus, "no candidate found for module %s",
    3571           21 :                    module_name.as_string ().c_str ());
    3572              : 
    3573          257 :   if (no_candidates_found || multiple_candidates_found)
    3574           21 :     return;
    3575              : 
    3576          279 :   module_file = std::move (file_mod_found ? file_mod_path : dir_mod_path);
    3577          336 : }
    3578              : 
    3579              : void
    3580          318 : Module::load_items ()
    3581              : {
    3582          318 :   process_file_path ();
    3583              : 
    3584              :   // We will already have errored out appropriately in the process_file_path ()
    3585              :   // method
    3586          318 :   if (module_file.empty ())
    3587           32 :     return;
    3588              : 
    3589          297 :   RAIIFile file_wrap (module_file.c_str ());
    3590          297 :   Linemap *linemap = Session::get_instance ().linemap;
    3591          297 :   if (!file_wrap.ok ())
    3592              :     {
    3593           11 :       rust_error_at (get_locus (), "cannot open module file %s: %m",
    3594              :                      module_file.c_str ());
    3595           11 :       return;
    3596              :     }
    3597              : 
    3598          286 :   rust_debug ("Attempting to parse file %s", module_file.c_str ());
    3599              : 
    3600          286 :   Lexer lex (module_file.c_str (), std::move (file_wrap), linemap);
    3601          286 :   Parser<Lexer> parser (lex);
    3602              : 
    3603              :   // we need to parse any possible inner attributes for this module
    3604          286 :   inner_attrs = parser.parse_inner_attributes ();
    3605          286 :   auto parsed_items = parser.parse_items ().value_or (
    3606          286 :     std::vector<std::unique_ptr<AST::Item>>{});
    3607              : 
    3608          286 :   for (const auto &error : parser.get_errors ())
    3609            0 :     error.emit ();
    3610              : 
    3611          286 :   items = std::move (parsed_items);
    3612          286 :   kind = ModuleKind::LOADED;
    3613          583 : }
    3614              : 
    3615              : void
    3616         4149 : Attribute::parse_attr_to_meta_item ()
    3617              : {
    3618              :   // only parse if has attribute input and not already parsed
    3619         4149 :   if (!has_attr_input () || is_parsed_to_meta_item ())
    3620          997 :     return;
    3621              : 
    3622         3152 :   auto res = attr_input->parse_to_meta_item ();
    3623         3152 :   std::unique_ptr<AttrInput> converted_input (res);
    3624              : 
    3625         3152 :   if (converted_input != nullptr)
    3626         3152 :     attr_input = std::move (converted_input);
    3627         3152 : }
    3628              : 
    3629              : AttrInputMetaItemContainer *
    3630        18540 : DelimTokenTree::parse_to_meta_item () const
    3631              : {
    3632              :   // must have token trees
    3633        18540 :   if (token_trees.empty ())
    3634              :     return nullptr;
    3635              : 
    3636              :   /* assume top-level delim token tree in attribute - convert all nested ones
    3637              :    * to token stream */
    3638        18540 :   std::vector<std::unique_ptr<Token>> token_stream_wrapped = to_token_stream ();
    3639              : 
    3640        18540 :   std::vector<const_TokenPtr> token_stream;
    3641        18540 :   token_stream.reserve (token_stream_wrapped.size ());
    3642       127460 :   for (auto &tk : token_stream_wrapped)
    3643       217840 :     token_stream.push_back (tk->get_tok_ptr ());
    3644              : 
    3645        18540 :   AttributeParser parser (std::move (token_stream));
    3646        18540 :   std::vector<std::unique_ptr<MetaItemInner>> meta_items (
    3647        18540 :     parser.parse_meta_item_seq ());
    3648              : 
    3649        18540 :   return new AttrInputMetaItemContainer (std::move (meta_items));
    3650        18540 : }
    3651              : 
    3652        18569 : AttributeParser::AttributeParser (std::vector<const_TokenPtr> token_stream,
    3653              :                                   int stream_start_pos)
    3654        18569 :   : lexer (new MacroInvocLexer (std::move (token_stream))),
    3655        18569 :     parser (new Parser<MacroInvocLexer> (*lexer))
    3656              : {
    3657        18569 :   if (stream_start_pos)
    3658            0 :     lexer->skip_token (stream_start_pos - 1);
    3659        18569 : }
    3660              : 
    3661        18569 : AttributeParser::~AttributeParser () {}
    3662              : 
    3663              : std::unique_ptr<MetaItemInner>
    3664        30336 : AttributeParser::parse_meta_item_inner ()
    3665              : {
    3666              :   // if first tok not identifier, not a "special" case one
    3667        60672 :   if (lexer->peek_token ()->get_id () != IDENTIFIER)
    3668              :     {
    3669           74 :       switch (lexer->peek_token ()->get_id ())
    3670              :         {
    3671           37 :         case CHAR_LITERAL:
    3672           37 :         case STRING_LITERAL:
    3673           37 :         case BYTE_CHAR_LITERAL:
    3674           37 :         case BYTE_STRING_LITERAL:
    3675           37 :         case RAW_STRING_LITERAL:
    3676           37 :         case C_STRING_LITERAL:
    3677           37 :         case INT_LITERAL:
    3678           37 :         case FLOAT_LITERAL:
    3679           37 :         case TRUE_LITERAL:
    3680           37 :         case FALSE_LITERAL:
    3681           37 :           return parse_meta_item_lit ();
    3682              : 
    3683            0 :         case SUPER:
    3684            0 :         case SELF:
    3685            0 :         case CRATE:
    3686            0 :         case DOLLAR_SIGN:
    3687            0 :         case SCOPE_RESOLUTION:
    3688            0 :           return parse_path_meta_item ();
    3689              : 
    3690            0 :         default:
    3691            0 :           rust_error_at (lexer->peek_token ()->get_locus (),
    3692              :                          "unrecognised token '%s' in meta item",
    3693              :                          get_token_description (
    3694            0 :                            lexer->peek_token ()->get_id ()));
    3695            0 :           return nullptr;
    3696              :         }
    3697              :     }
    3698              : 
    3699              :   // else, check for path
    3700        60598 :   if (lexer->peek_token (1)->get_id () == SCOPE_RESOLUTION)
    3701              :     {
    3702              :       // path
    3703            0 :       return parse_path_meta_item ();
    3704              :     }
    3705              : 
    3706        60598 :   auto ident = lexer->peek_token ()->get_str ();
    3707        30299 :   auto ident_locus = lexer->peek_token ()->get_locus ();
    3708              : 
    3709        60598 :   if (is_end_meta_item_tok (lexer->peek_token (1)->get_id ()))
    3710              :     {
    3711              :       // meta word syntax
    3712        13812 :       lexer->skip_token ();
    3713        41436 :       return std::unique_ptr<MetaWord> (new MetaWord (ident, ident_locus));
    3714              :     }
    3715              : 
    3716        32974 :   if (lexer->peek_token (1)->get_id () == EQUAL)
    3717              :     {
    3718              :       // maybe meta name value str syntax - check next 2 tokens
    3719        28510 :       if (lexer->peek_token (2)->get_id () == STRING_LITERAL
    3720        28065 :           && is_end_meta_item_tok (lexer->peek_token (3)->get_id ()))
    3721              :         {
    3722              :           // meta name value str syntax
    3723        13810 :           const_TokenPtr value_tok = lexer->peek_token (2);
    3724        13810 :           auto value = value_tok->get_str ();
    3725        13810 :           auto locus = value_tok->get_locus ();
    3726              : 
    3727        13810 :           lexer->skip_token (2);
    3728              : 
    3729        13810 :           return std::unique_ptr<MetaNameValueStr> (
    3730        27620 :             new MetaNameValueStr (ident, ident_locus, std::move (value),
    3731        41430 :                                   locus));
    3732        27620 :         }
    3733              :       else
    3734              :         {
    3735              :           // just interpret as path-based meta item
    3736          445 :           return parse_path_meta_item ();
    3737              :         }
    3738              :     }
    3739              : 
    3740         4464 :   if (lexer->peek_token (1)->get_id () != LEFT_PAREN)
    3741              :     {
    3742            0 :       rust_error_at (lexer->peek_token (1)->get_locus (),
    3743              :                      "unexpected token '%s' after identifier in attribute",
    3744            0 :                      get_token_description (lexer->peek_token (1)->get_id ()));
    3745            0 :       return nullptr;
    3746              :     }
    3747              : 
    3748              :   // is it one of those special cases like not?
    3749         4464 :   if (lexer->peek_token ()->get_id () == IDENTIFIER)
    3750              :     {
    3751         2232 :       return parse_path_meta_item ();
    3752              :     }
    3753              : 
    3754            0 :   auto meta_items = parse_meta_item_seq ();
    3755              : 
    3756              :   // pass for meta name value str
    3757            0 :   std::vector<MetaNameValueStr> meta_name_value_str_items;
    3758            0 :   for (const auto &item : meta_items)
    3759              :     {
    3760            0 :       std::unique_ptr<MetaNameValueStr> converted_item
    3761            0 :         = item->to_meta_name_value_str ();
    3762            0 :       if (converted_item == nullptr)
    3763              :         {
    3764            0 :           meta_name_value_str_items.clear ();
    3765            0 :           break;
    3766              :         }
    3767            0 :       meta_name_value_str_items.push_back (std::move (*converted_item));
    3768            0 :     }
    3769              :   // if valid, return this
    3770            0 :   if (!meta_name_value_str_items.empty ())
    3771              :     {
    3772            0 :       return std::unique_ptr<MetaListNameValueStr> (
    3773            0 :         new MetaListNameValueStr (ident, ident_locus,
    3774            0 :                                   std::move (meta_name_value_str_items)));
    3775              :     }
    3776              : 
    3777              :   // // pass for meta list idents
    3778              :   // std::vector<Identifier> ident_items;
    3779              :   // for (const auto &item : meta_items)
    3780              :   //   {
    3781              :   //     std::unique_ptr<Identifier> converted_ident (item->to_ident_item ());
    3782              :   //     if (converted_ident == nullptr)
    3783              :   //       {
    3784              :   //         ident_items.clear ();
    3785              :   //         break;
    3786              :   //       }
    3787              :   //     ident_items.push_back (std::move (*converted_ident));
    3788              :   //   }
    3789              :   // // if valid return this
    3790              :   // if (!ident_items.empty ())
    3791              :   //   {
    3792              :   //     return std::unique_ptr<MetaListIdents> (
    3793              :   //       new MetaListIdents (std::move (ident), std::move (ident_items)));
    3794              :   //   }
    3795              :   // // as currently no meta list ident, currently no path. may change in future
    3796              : 
    3797              :   // pass for meta list paths
    3798            0 :   std::vector<SimplePath> path_items;
    3799            0 :   for (const auto &item : meta_items)
    3800              :     {
    3801            0 :       SimplePath converted_path (item->to_path_item ());
    3802            0 :       if (converted_path.is_empty ())
    3803              :         {
    3804            0 :           path_items.clear ();
    3805            0 :           break;
    3806              :         }
    3807            0 :       path_items.push_back (std::move (converted_path));
    3808            0 :     }
    3809            0 :   if (!path_items.empty ())
    3810              :     {
    3811            0 :       return std::unique_ptr<MetaListPaths> (
    3812            0 :         new MetaListPaths (ident, ident_locus, std::move (path_items)));
    3813              :     }
    3814              : 
    3815            0 :   rust_error_at (UNKNOWN_LOCATION, "failed to parse any meta item inner");
    3816            0 :   return nullptr;
    3817        30299 : }
    3818              : 
    3819              : bool
    3820        44109 : AttributeParser::is_end_meta_item_tok (TokenId id) const
    3821              : {
    3822        44109 :   return id == COMMA || id == RIGHT_PAREN;
    3823              : }
    3824              : 
    3825              : std::unique_ptr<MetaItem>
    3826         2677 : AttributeParser::parse_path_meta_item ()
    3827              : {
    3828         2677 :   auto path = parser->parse_simple_path ();
    3829         2677 :   if (!path)
    3830              :     {
    3831            0 :       rust_error_at (lexer->peek_token ()->get_locus (),
    3832              :                      "failed to parse simple path in attribute");
    3833            0 :       return nullptr;
    3834              :     }
    3835              : 
    3836         5354 :   switch (lexer->peek_token ()->get_id ())
    3837              :     {
    3838         2232 :     case LEFT_PAREN:
    3839         2232 :       {
    3840         2232 :         std::vector<std::unique_ptr<MetaItemInner>> meta_items
    3841         2232 :           = parse_meta_item_seq ();
    3842              : 
    3843         2232 :         return std::unique_ptr<MetaItemSeq> (
    3844         4464 :           new MetaItemSeq (std::move (path.value ()), std::move (meta_items)));
    3845         2232 :       }
    3846          445 :     case EQUAL:
    3847          445 :       {
    3848          445 :         lexer->skip_token ();
    3849              : 
    3850          445 :         auto expr = parser->parse_expr ();
    3851              : 
    3852              :         // handle error
    3853              :         // parse_expr should already emit an error and return nullptr
    3854          445 :         if (!expr)
    3855            0 :           return nullptr;
    3856              : 
    3857          445 :         return std::unique_ptr<MetaItemPathExpr> (
    3858          445 :           new MetaItemPathExpr (std::move (path.value ()),
    3859          890 :                                 std::move (expr.value ())));
    3860          445 :       }
    3861            0 :     case COMMA:
    3862              :       // just simple path
    3863            0 :       return std::unique_ptr<MetaItemPath> (
    3864            0 :         new MetaItemPath (std::move (path.value ())));
    3865            0 :     default:
    3866            0 :       rust_error_at (lexer->peek_token ()->get_locus (),
    3867              :                      "unrecognised token '%s' in meta item",
    3868            0 :                      get_token_description (lexer->peek_token ()->get_id ()));
    3869            0 :       return nullptr;
    3870              :     }
    3871         2677 : }
    3872              : 
    3873              : /* Parses a parenthesised sequence of meta item inners. Parentheses are
    3874              :  * required here. */
    3875              : std::vector<std::unique_ptr<MetaItemInner>>
    3876        20801 : AttributeParser::parse_meta_item_seq ()
    3877              : {
    3878        20801 :   std::vector<std::unique_ptr<MetaItemInner>> meta_items;
    3879              : 
    3880        41602 :   if (lexer->peek_token ()->get_id () != LEFT_PAREN)
    3881              :     {
    3882            0 :       rust_error_at (lexer->peek_token ()->get_locus (),
    3883              :                      "missing left paren in delim token tree");
    3884            0 :       return {};
    3885              :     }
    3886        20801 :   lexer->skip_token ();
    3887              : 
    3888        20801 :   while (lexer->peek_token ()->get_id () != END_OF_FILE
    3889        91188 :          && lexer->peek_token ()->get_id () != RIGHT_PAREN)
    3890              :     {
    3891        30336 :       std::unique_ptr<MetaItemInner> inner = parse_meta_item_inner ();
    3892        30336 :       if (inner == nullptr)
    3893              :         {
    3894            0 :           rust_error_at (lexer->peek_token ()->get_locus (),
    3895              :                          "failed to parse inner meta item in attribute");
    3896            0 :           return {};
    3897              :         }
    3898        30336 :       meta_items.push_back (std::move (inner));
    3899              : 
    3900        60672 :       if (lexer->peek_token ()->get_id () != COMMA)
    3901              :         break;
    3902              : 
    3903         9595 :       lexer->skip_token ();
    3904        30336 :     }
    3905              : 
    3906        41602 :   if (lexer->peek_token ()->get_id () != RIGHT_PAREN)
    3907              :     {
    3908            0 :       rust_error_at (lexer->peek_token ()->get_locus (),
    3909              :                      "missing right paren in delim token tree");
    3910            0 :       return {};
    3911              :     }
    3912        20801 :   lexer->skip_token ();
    3913              : 
    3914        20801 :   return meta_items;
    3915        20801 : }
    3916              : 
    3917              : /* Collects any nested token trees into a flat token stream, suitable for
    3918              :  * parsing. */
    3919              : std::vector<std::unique_ptr<Token>>
    3920       434266 : DelimTokenTree::to_token_stream () const
    3921              : {
    3922       434266 :   std::vector<std::unique_ptr<Token>> tokens;
    3923      4418459 :   for (const auto &tree : token_trees)
    3924              :     {
    3925      3984193 :       std::vector<std::unique_ptr<Token>> stream = tree->to_token_stream ();
    3926              : 
    3927      3984193 :       tokens.insert (tokens.end (), std::make_move_iterator (stream.begin ()),
    3928              :                      std::make_move_iterator (stream.end ()));
    3929      3984193 :     }
    3930              : 
    3931       434266 :   tokens.shrink_to_fit ();
    3932       434266 :   return tokens;
    3933              : }
    3934              : 
    3935              : std::unique_ptr<MetaItemLitExpr>
    3936           37 : AttributeParser::parse_meta_item_lit ()
    3937              : {
    3938           37 :   auto lit_expr = parser->parse_literal_expr ({});
    3939              : 
    3940              :   // TODO: return nullptr instead?
    3941           37 :   if (!lit_expr)
    3942            0 :     lit_expr = std::unique_ptr<LiteralExpr> (
    3943            0 :       new LiteralExpr (Literal::create_error (), {},
    3944            0 :                        lexer->peek_token ()->get_locus ()));
    3945              : 
    3946           37 :   return std::unique_ptr<MetaItemLitExpr> (
    3947           37 :     new MetaItemLitExpr (std::move (*lit_expr.value ())));
    3948           37 : }
    3949              : 
    3950              : bool
    3951            0 : AttrInputMetaItemContainer::check_cfg_predicate (const Session &session) const
    3952              : {
    3953            0 :   if (items.empty ())
    3954              :     return false;
    3955              : 
    3956            0 :   for (const auto &inner_item : items)
    3957              :     {
    3958            0 :       if (!inner_item->check_cfg_predicate (session))
    3959            0 :         return false;
    3960              :     }
    3961              : 
    3962              :   return true;
    3963              : }
    3964              : 
    3965              : bool
    3966            1 : MetaItemLitExpr::check_cfg_predicate (const Session &) const
    3967              : {
    3968              :   /* as far as I can tell, a literal expr can never be a valid cfg body, so
    3969              :    * false */
    3970            1 :   rust_error_at (this->get_locus (), "'%s' predicate key cannot be a literal",
    3971            1 :                  this->as_string ().c_str ());
    3972              : 
    3973            1 :   return false;
    3974              : }
    3975              : 
    3976              : bool
    3977            0 : MetaListNameValueStr::check_cfg_predicate (const Session &session) const
    3978              : {
    3979            0 :   if (ident.as_string () == "all")
    3980              :     {
    3981            0 :       for (const auto &str : strs)
    3982              :         {
    3983            0 :           if (!str.check_cfg_predicate (session))
    3984            0 :             return false;
    3985              :         }
    3986              :       return true;
    3987              :     }
    3988            0 :   else if (ident.as_string () == "any")
    3989              :     {
    3990            0 :       for (const auto &str : strs)
    3991              :         {
    3992            0 :           if (str.check_cfg_predicate (session))
    3993            0 :             return true;
    3994              :         }
    3995              :       return false;
    3996              :     }
    3997            0 :   else if (ident.as_string () == "not")
    3998              :     {
    3999            0 :       if (strs.size () != 1)
    4000              :         {
    4001              :           /* HACK: convert vector platform-dependent size_type to string to
    4002              :            * use in printf */
    4003            0 :           rust_error_at (UNKNOWN_LOCATION,
    4004              :                          "cfg predicate could not be checked for "
    4005              :                          "MetaListNameValueStr with ident of "
    4006              :                          "'not' because there are '%s' elements, not '1'",
    4007            0 :                          std::to_string (strs.size ()).c_str ());
    4008            0 :           return false;
    4009              :         }
    4010              : 
    4011            0 :       return !strs[0].check_cfg_predicate (session);
    4012              :     }
    4013              :   else
    4014              :     {
    4015            0 :       rust_error_at (UNKNOWN_LOCATION,
    4016              :                      "cfg predicate could not be checked for "
    4017              :                      "MetaListNameValueStr with ident of "
    4018              :                      "'%s' - ident must be 'all' or 'any'",
    4019            0 :                      ident.as_string ().c_str ());
    4020            0 :       return false;
    4021              :     }
    4022              : }
    4023              : 
    4024              : bool
    4025            0 : MetaListPaths::check_cfg_predicate (const Session &session) const
    4026              : {
    4027            0 :   if (ident.as_string () == "all")
    4028              :     {
    4029            0 :       for (const auto &path : paths)
    4030              :         {
    4031            0 :           if (!check_path_exists_in_cfg (session, path))
    4032            0 :             return false;
    4033              :         }
    4034              :       return true;
    4035              :     }
    4036            0 :   else if (ident.as_string () == "any")
    4037              :     {
    4038            0 :       for (const auto &path : paths)
    4039              :         {
    4040            0 :           if (check_path_exists_in_cfg (session, path))
    4041            0 :             return true;
    4042              :         }
    4043              :       return false;
    4044              :     }
    4045            0 :   else if (ident.as_string () == "not")
    4046              :     {
    4047            0 :       if (paths.size () != 1)
    4048              :         {
    4049              :           // HACK: convert vector platform-dependent size_type to string to
    4050              :           // use in printf
    4051            0 :           rust_error_at (UNKNOWN_LOCATION,
    4052              :                          "cfg predicate could not be checked for MetaListPaths "
    4053              :                          "with ident of 'not' "
    4054              :                          "because there are '%s' elements, not '1'",
    4055            0 :                          std::to_string (paths.size ()).c_str ());
    4056            0 :           return false;
    4057              :         }
    4058              : 
    4059            0 :       return !check_path_exists_in_cfg (session, paths[0]);
    4060              :     }
    4061              :   else
    4062              :     {
    4063            0 :       rust_error_at (UNKNOWN_LOCATION,
    4064              :                      "cfg predicate could not be checked for "
    4065              :                      "MetaListNameValueStr with ident of "
    4066              :                      "'%s' - ident must be 'all' or 'any'",
    4067            0 :                      ident.as_string ().c_str ());
    4068            0 :       return false;
    4069              :     }
    4070              : }
    4071              : 
    4072              : bool
    4073            0 : MetaListPaths::check_path_exists_in_cfg (const Session &session,
    4074              :                                          const SimplePath &path) const
    4075              : {
    4076            0 :   return session.options.target_data.has_key (path.as_string ());
    4077              : }
    4078              : 
    4079              : bool
    4080         4192 : MetaItemSeq::check_cfg_predicate (const Session &session) const
    4081              : {
    4082         4192 :   if (path.as_string () == "all")
    4083              :     {
    4084          894 :       for (const auto &item : seq)
    4085              :         {
    4086          713 :           if (!item->check_cfg_predicate (session))
    4087         4192 :             return false;
    4088              :         }
    4089              :       return true;
    4090              :     }
    4091         3924 :   else if (path.as_string () == "any")
    4092              :     {
    4093          893 :       for (const auto &item : seq)
    4094              :         {
    4095          840 :           if (item->check_cfg_predicate (session))
    4096         4192 :             return true;
    4097              :         }
    4098              :       return false;
    4099              :     }
    4100         3513 :   else if (path.as_string () == "not")
    4101              :     {
    4102         3513 :       if (seq.size () != 1)
    4103              :         {
    4104              :           /* HACK: convert vector platform-dependent size_type to string to
    4105              :            * use in printf */
    4106            0 :           rust_error_at (UNKNOWN_LOCATION,
    4107              :                          "cfg predicate could not be checked for MetaItemSeq "
    4108              :                          "with ident of 'not' "
    4109              :                          "because there are '%s' elements, not '1'",
    4110            0 :                          std::to_string (seq.size ()).c_str ());
    4111            0 :           return false;
    4112              :         }
    4113              : 
    4114         3513 :       return !seq[0]->check_cfg_predicate (session);
    4115              :     }
    4116              :   else
    4117              :     {
    4118            0 :       rust_error_at (
    4119              :         UNKNOWN_LOCATION,
    4120              :         "cfg predicate could not be checked for MetaItemSeq with path of "
    4121              :         "'%s' - path must be 'all' or 'any'",
    4122            0 :         path.as_string ().c_str ());
    4123            0 :       return false;
    4124              :     }
    4125              : }
    4126              : 
    4127              : bool
    4128         3008 : MetaWord::check_cfg_predicate (const Session &session) const
    4129              : {
    4130         6016 :   return session.options.target_data.has_key (ident.as_string ());
    4131              : }
    4132              : 
    4133              : bool
    4134            0 : MetaItemPath::check_cfg_predicate (const Session &session) const
    4135              : {
    4136              :   /* Strictly speaking, this should always be false, but maybe do check
    4137              :    * relating to SimplePath being identifier. Currently, it would return true
    4138              :    * if path as identifier existed, and if the path in string form existed
    4139              :    * (though this shouldn't occur). */
    4140            0 :   return session.options.target_data.has_key (path.as_string ());
    4141              : }
    4142              : 
    4143              : bool
    4144         7815 : MetaNameValueStr::check_cfg_predicate (const Session &session) const
    4145              : {
    4146              :   // DEBUG
    4147         7815 :   rust_debug (
    4148              :     "checked key-value pair for cfg: '%s', '%s' - is%s in target data",
    4149              :     ident.as_string ().c_str (), str.c_str (),
    4150              :     session.options.target_data.has_key_value_pair (ident.as_string (), str)
    4151              :       ? ""
    4152              :       : " not");
    4153              : 
    4154        15630 :   return session.options.target_data.has_key_value_pair (ident.as_string (),
    4155         7815 :                                                          str);
    4156              : }
    4157              : 
    4158              : bool
    4159            0 : MetaItemPathExpr::check_cfg_predicate (const Session &session) const
    4160              : {
    4161              :   // FIXME: Accept path expressions
    4162            0 :   rust_assert (expr->is_literal ());
    4163            0 :   return session.options.target_data.has_key_value_pair (path.as_string (),
    4164            0 :                                                          expr->as_string ());
    4165              : }
    4166              : 
    4167              : std::vector<std::unique_ptr<Token>>
    4168      3767522 : Token::to_token_stream () const
    4169              : {
    4170              :   /* initialisation list doesn't work as it needs copy constructor, so have to
    4171              :    * do this */
    4172      3767522 :   std::vector<std::unique_ptr<Token>> dummy_vector;
    4173      3767522 :   dummy_vector.reserve (1);
    4174      3767522 :   dummy_vector.push_back (std::unique_ptr<Token> (clone_token_impl ()));
    4175      3767522 :   return dummy_vector;
    4176              : }
    4177              : 
    4178              : Attribute
    4179            9 : MetaNameValueStr::to_attribute () const
    4180              : {
    4181            9 :   LiteralExpr lit_expr (str, Literal::LitType::STRING,
    4182           18 :                         PrimitiveCoreType::CORETYPE_UNKNOWN, {}, str_locus);
    4183              :   // FIXME: What location do we put here? Is the literal above supposed to have
    4184              :   // an empty location as well?
    4185              :   // Should MetaNameValueStr keep a location?
    4186           18 :   return Attribute (SimplePath::from_str (ident.as_string (), ident_locus),
    4187           18 :                     std::unique_ptr<AttrInputLiteral> (
    4188           27 :                       new AttrInputLiteral (std::move (lit_expr))));
    4189            9 : }
    4190              : 
    4191              : Attribute
    4192            0 : MetaItemPath::to_attribute () const
    4193              : {
    4194            0 :   return Attribute (path, nullptr);
    4195              : }
    4196              : 
    4197              : Attribute
    4198           50 : MetaItemSeq::to_attribute () const
    4199              : {
    4200           50 :   std::vector<std::unique_ptr<MetaItemInner>> new_seq;
    4201           50 :   new_seq.reserve (seq.size ());
    4202          101 :   for (const auto &e : seq)
    4203           51 :     new_seq.push_back (e->clone_meta_item_inner ());
    4204              : 
    4205           50 :   std::unique_ptr<AttrInputMetaItemContainer> new_seq_container (
    4206           50 :     new AttrInputMetaItemContainer (std::move (new_seq)));
    4207           50 :   return Attribute (path, std::move (new_seq_container));
    4208           50 : }
    4209              : 
    4210              : Attribute
    4211            1 : MetaWord::to_attribute () const
    4212              : {
    4213            2 :   return Attribute (SimplePath::from_str (ident.as_string (), ident_locus),
    4214            3 :                     nullptr);
    4215              : }
    4216              : 
    4217              : Attribute
    4218            0 : MetaListPaths::to_attribute () const
    4219              : {
    4220              :   /* probably one of the most annoying conversions - have to lose specificity by
    4221              :    * turning it into just AttrInputMetaItemContainer (i.e. paths-only nature is
    4222              :    * no longer known). If conversions back are required, might have to do a
    4223              :    * "check all are paths" pass or something. */
    4224              : 
    4225            0 :   std::vector<std::unique_ptr<MetaItemInner>> new_seq;
    4226            0 :   new_seq.reserve (paths.size ());
    4227            0 :   for (const auto &e : paths)
    4228            0 :     new_seq.push_back (std::unique_ptr<MetaItemPath> (new MetaItemPath (e)));
    4229              : 
    4230            0 :   std::unique_ptr<AttrInputMetaItemContainer> new_seq_container (
    4231            0 :     new AttrInputMetaItemContainer (std::move (new_seq)));
    4232            0 :   return Attribute (SimplePath::from_str (ident.as_string (), ident_locus),
    4233            0 :                     std::move (new_seq_container));
    4234            0 : }
    4235              : 
    4236              : Attribute
    4237            0 : MetaListNameValueStr::to_attribute () const
    4238              : {
    4239            0 :   std::vector<std::unique_ptr<MetaItemInner>> new_seq;
    4240            0 :   new_seq.reserve (strs.size ());
    4241            0 :   for (const auto &e : strs)
    4242            0 :     new_seq.push_back (
    4243            0 :       std::unique_ptr<MetaNameValueStr> (new MetaNameValueStr (e)));
    4244              : 
    4245            0 :   std::unique_ptr<AttrInputMetaItemContainer> new_seq_container (
    4246            0 :     new AttrInputMetaItemContainer (std::move (new_seq)));
    4247            0 :   return Attribute (SimplePath::from_str (ident.as_string (), ident_locus),
    4248            0 :                     std::move (new_seq_container));
    4249            0 : }
    4250              : 
    4251              : Attribute
    4252            1 : MetaItemPathExpr::to_attribute () const
    4253              : {
    4254            1 :   auto input = std::make_unique<AttrInputExpr> (expr->clone_expr ());
    4255            1 :   return Attribute (path, std::move (input));
    4256            1 : }
    4257              : 
    4258              : std::vector<Attribute>
    4259           61 : AttrInputMetaItemContainer::separate_cfg_attrs () const
    4260              : {
    4261           61 :   rust_assert (!items.empty ());
    4262              : 
    4263           61 :   if (items.size () == 1)
    4264            0 :     return {};
    4265              : 
    4266           61 :   std::vector<Attribute> attrs;
    4267           61 :   attrs.reserve (items.size () - 1);
    4268              : 
    4269          122 :   for (auto it = items.begin () + 1; it != items.end (); ++it)
    4270              :     {
    4271           61 :       auto &item = **it;
    4272              : 
    4273           61 :       Attribute attr = item.to_attribute ();
    4274           61 :       if (attr.is_empty ())
    4275              :         {
    4276              :           /* TODO should this be an error that causes us to chuck out
    4277              :            * everything? */
    4278            0 :           continue;
    4279              :         }
    4280           61 :       attrs.push_back (std::move (attr));
    4281           61 :     }
    4282              : 
    4283           61 :   attrs.shrink_to_fit ();
    4284           61 :   return attrs;
    4285           61 : }
    4286              : 
    4287              : bool
    4288         9794 : Attribute::check_cfg_predicate (const Session &session) const
    4289              : {
    4290         9794 :   auto string_path = path.as_string ();
    4291              :   /* assume that cfg predicate actually can exist, i.e. attribute has cfg or
    4292              :    * cfg_attr path */
    4293         9794 :   if (!has_attr_input ())
    4294              :     {
    4295            1 :       rust_error_at (path.get_locus (), "%qs is not followed by parentheses",
    4296              :                      string_path.c_str ());
    4297            1 :       return false;
    4298              :     }
    4299              : 
    4300              :   // assume that it has already been parsed
    4301         9793 :   if (!is_parsed_to_meta_item ())
    4302              :     return false;
    4303              : 
    4304         9793 :   auto &meta_item = static_cast<AttrInputMetaItemContainer &> (*attr_input);
    4305         9793 :   if (meta_item.get_items ().empty ())
    4306              :     {
    4307            3 :       rust_error_at (path.get_locus (), "malformed %<%s%> attribute input",
    4308              :                      string_path.c_str ());
    4309            3 :       return false;
    4310              :     }
    4311              : 
    4312         9790 :   if (string_path == Values::Attributes::CFG
    4313         9790 :       && meta_item.get_items ().size () != 1)
    4314              :     {
    4315            1 :       rust_error_at (path.get_locus (), "multiple %qs predicates are specified",
    4316            1 :                      path.as_string ().c_str ());
    4317            1 :       return false;
    4318              :     }
    4319         9789 :   return meta_item.get_items ().front ()->check_cfg_predicate (session);
    4320         9794 : }
    4321              : 
    4322              : std::vector<Attribute>
    4323           61 : Attribute::separate_cfg_attrs () const
    4324              : {
    4325          122 :   if (!has_attr_input () || path.as_string () != Values::Attributes::CFG_ATTR)
    4326            0 :     return {};
    4327              : 
    4328              :   // assume that it has already been parsed
    4329           61 :   if (!is_parsed_to_meta_item ())
    4330            0 :     return {};
    4331              : 
    4332           61 :   return attr_input->separate_cfg_attrs ();
    4333              : }
    4334              : 
    4335              : bool
    4336        31858 : Attribute::is_parsed_to_meta_item () const
    4337              : {
    4338        31858 :   return has_attr_input () && attr_input->is_meta_item ();
    4339              : }
    4340              : 
    4341              : void
    4342       128531 : BlockExpr::normalize_tail_expr ()
    4343              : {
    4344       128531 :   if (!expr)
    4345              :     {
    4346              :       // HACK: try to turn the last statement into a tail expression
    4347        93020 :       if (!statements.empty () && statements.back ()->is_expr ())
    4348              :         {
    4349              :           // Watch out: This reference become invalid when the vector is
    4350              :           // modified.
    4351        77941 :           auto &stmt = static_cast<ExprStmt &> (*statements.back ());
    4352              : 
    4353        77941 :           if (!stmt.is_semicolon_followed ())
    4354              :             {
    4355           85 :               expr = stmt.take_expr ();
    4356           85 :               statements.pop_back ();
    4357              :             }
    4358              :         }
    4359              :     }
    4360       128531 : }
    4361              : 
    4362              : /* Visitor implementations - these are short but inlining can't happen anyway
    4363              :  * due to virtual functions and I didn't want to make the ast header includes
    4364              :  * any longer than they already are. */
    4365              : 
    4366              : void
    4367     33909823 : Token::accept_vis (ASTVisitor &vis)
    4368              : {
    4369     33909823 :   vis.visit (*this);
    4370     33909823 : }
    4371              : 
    4372              : void
    4373      4759448 : DelimTokenTree::accept_vis (ASTVisitor &vis)
    4374              : {
    4375      4759448 :   vis.visit (*this);
    4376      4759448 : }
    4377              : 
    4378              : void
    4379     36076766 : IdentifierExpr::accept_vis (ASTVisitor &vis)
    4380              : {
    4381     36076766 :   vis.visit (*this);
    4382     36076765 : }
    4383              : 
    4384              : void
    4385        36158 : Lifetime::accept_vis (ASTVisitor &vis)
    4386              : {
    4387        36158 :   vis.visit (*this);
    4388        36158 : }
    4389              : 
    4390              : void
    4391       270752 : LifetimeParam::accept_vis (ASTVisitor &vis)
    4392              : {
    4393       270752 :   vis.visit (*this);
    4394       270752 : }
    4395              : 
    4396              : void
    4397     52904382 : LiteralExpr::accept_vis (ASTVisitor &vis)
    4398              : {
    4399     52904382 :   vis.visit (*this);
    4400     52904382 : }
    4401              : 
    4402              : void
    4403     12124474 : AttrInputLiteral::accept_vis (ASTVisitor &vis)
    4404              : {
    4405     12124474 :   vis.visit (*this);
    4406     12124474 : }
    4407              : 
    4408              : void
    4409            0 : MetaItemLitExpr::accept_vis (ASTVisitor &vis)
    4410              : {
    4411            0 :   vis.visit (*this);
    4412            0 : }
    4413              : 
    4414              : void
    4415            2 : MetaItemPathExpr::accept_vis (ASTVisitor &vis)
    4416              : {
    4417            2 :   vis.visit (*this);
    4418            2 : }
    4419              : 
    4420              : void
    4421      1462906 : BorrowExpr::accept_vis (ASTVisitor &vis)
    4422              : {
    4423      1462906 :   vis.visit (*this);
    4424      1462906 : }
    4425              : 
    4426              : void
    4427      1842378 : DereferenceExpr::accept_vis (ASTVisitor &vis)
    4428              : {
    4429      1842378 :   vis.visit (*this);
    4430      1842378 : }
    4431              : 
    4432              : void
    4433        99040 : ErrorPropagationExpr::accept_vis (ASTVisitor &vis)
    4434              : {
    4435        99040 :   vis.visit (*this);
    4436        99040 : }
    4437              : 
    4438              : void
    4439       257039 : NegationExpr::accept_vis (ASTVisitor &vis)
    4440              : {
    4441       257039 :   vis.visit (*this);
    4442       257039 : }
    4443              : 
    4444              : void
    4445      8787229 : ArithmeticOrLogicalExpr::accept_vis (ASTVisitor &vis)
    4446              : {
    4447      8787229 :   vis.visit (*this);
    4448      8787229 : }
    4449              : 
    4450              : void
    4451       808502 : ComparisonExpr::accept_vis (ASTVisitor &vis)
    4452              : {
    4453       808502 :   vis.visit (*this);
    4454       808502 : }
    4455              : 
    4456              : void
    4457       201922 : LazyBooleanExpr::accept_vis (ASTVisitor &vis)
    4458              : {
    4459       201922 :   vis.visit (*this);
    4460       201922 : }
    4461              : 
    4462              : void
    4463      1271341 : TypeCastExpr::accept_vis (ASTVisitor &vis)
    4464              : {
    4465      1271341 :   vis.visit (*this);
    4466      1271341 : }
    4467              : 
    4468              : void
    4469       502821 : AssignmentExpr::accept_vis (ASTVisitor &vis)
    4470              : {
    4471       502821 :   vis.visit (*this);
    4472       502821 : }
    4473              : 
    4474              : void
    4475       306178 : CompoundAssignmentExpr::accept_vis (ASTVisitor &vis)
    4476              : {
    4477       306178 :   vis.visit (*this);
    4478       306178 : }
    4479              : 
    4480              : void
    4481      3346161 : ArrayElemsValues::accept_vis (ASTVisitor &vis)
    4482              : {
    4483      3346161 :   vis.visit (*this);
    4484      3346161 : }
    4485              : 
    4486              : void
    4487        15368 : ArrayElemsCopied::accept_vis (ASTVisitor &vis)
    4488              : {
    4489        15368 :   vis.visit (*this);
    4490        15368 : }
    4491              : 
    4492              : void
    4493      3361545 : ArrayExpr::accept_vis (ASTVisitor &vis)
    4494              : {
    4495      3361545 :   vis.visit (*this);
    4496      3361545 : }
    4497              : 
    4498              : void
    4499       207995 : ArrayIndexExpr::accept_vis (ASTVisitor &vis)
    4500              : {
    4501       207995 :   vis.visit (*this);
    4502       207995 : }
    4503              : 
    4504              : void
    4505       973334 : TupleExpr::accept_vis (ASTVisitor &vis)
    4506              : {
    4507       973334 :   vis.visit (*this);
    4508       973334 : }
    4509              : 
    4510              : void
    4511      1057337 : TupleIndexExpr::accept_vis (ASTVisitor &vis)
    4512              : {
    4513      1057337 :   vis.visit (*this);
    4514      1057337 : }
    4515              : 
    4516              : void
    4517         8402 : StructExprStruct::accept_vis (ASTVisitor &vis)
    4518              : {
    4519         8402 :   vis.visit (*this);
    4520         8402 : }
    4521              : 
    4522              : void
    4523        53455 : StructExprFieldIdentifier::accept_vis (ASTVisitor &vis)
    4524              : {
    4525        53455 :   vis.visit (*this);
    4526        53455 : }
    4527              : 
    4528              : void
    4529       260068 : StructExprFieldIdentifierValue::accept_vis (ASTVisitor &vis)
    4530              : {
    4531       260068 :   vis.visit (*this);
    4532       260068 : }
    4533              : 
    4534              : void
    4535         1054 : StructExprFieldIndexValue::accept_vis (ASTVisitor &vis)
    4536              : {
    4537         1054 :   vis.visit (*this);
    4538         1054 : }
    4539              : 
    4540              : void
    4541       165884 : StructExprStructFields::accept_vis (ASTVisitor &vis)
    4542              : {
    4543       165884 :   vis.visit (*this);
    4544       165884 : }
    4545              : 
    4546              : void
    4547            0 : StructExprStructBase::accept_vis (ASTVisitor &vis)
    4548              : {
    4549            0 :   vis.visit (*this);
    4550            0 : }
    4551              : 
    4552              : void
    4553     15051850 : CallExpr::accept_vis (ASTVisitor &vis)
    4554              : {
    4555     15051850 :   vis.visit (*this);
    4556     15051849 : }
    4557              : 
    4558              : void
    4559      8288558 : MethodCallExpr::accept_vis (ASTVisitor &vis)
    4560              : {
    4561      8288558 :   vis.visit (*this);
    4562      8288558 : }
    4563              : 
    4564              : void
    4565      1379599 : FieldAccessExpr::accept_vis (ASTVisitor &vis)
    4566              : {
    4567      1379599 :   vis.visit (*this);
    4568      1379599 : }
    4569              : 
    4570              : void
    4571       107822 : ClosureExprInner::accept_vis (ASTVisitor &vis)
    4572              : {
    4573       107822 :   vis.visit (*this);
    4574       107822 : }
    4575              : 
    4576              : void
    4577      3996144 : BlockExpr::accept_vis (ASTVisitor &vis)
    4578              : {
    4579      3996144 :   vis.visit (*this);
    4580      3996140 : }
    4581              : 
    4582              : void
    4583         1172 : AnonConst::accept_vis (ASTVisitor &vis)
    4584              : {
    4585         1172 :   vis.visit (*this);
    4586         1172 : }
    4587              : 
    4588              : void
    4589          309 : ConstBlock::accept_vis (ASTVisitor &vis)
    4590              : {
    4591          309 :   vis.visit (*this);
    4592          309 : }
    4593              : 
    4594              : void
    4595          973 : ClosureExprInnerTyped::accept_vis (ASTVisitor &vis)
    4596              : {
    4597          973 :   vis.visit (*this);
    4598          973 : }
    4599              : 
    4600              : void
    4601         7970 : ContinueExpr::accept_vis (ASTVisitor &vis)
    4602              : {
    4603         7970 :   vis.visit (*this);
    4604         7970 : }
    4605              : 
    4606              : void
    4607        19367 : BreakExpr::accept_vis (ASTVisitor &vis)
    4608              : {
    4609        19367 :   vis.visit (*this);
    4610        19366 : }
    4611              : 
    4612              : void
    4613        65559 : RangeFromToExpr::accept_vis (ASTVisitor &vis)
    4614              : {
    4615        65559 :   vis.visit (*this);
    4616        65559 : }
    4617              : 
    4618              : void
    4619        26429 : RangeFromExpr::accept_vis (ASTVisitor &vis)
    4620              : {
    4621        26429 :   vis.visit (*this);
    4622        26429 : }
    4623              : 
    4624              : void
    4625        42491 : RangeToExpr::accept_vis (ASTVisitor &vis)
    4626              : {
    4627        42491 :   vis.visit (*this);
    4628        42491 : }
    4629              : 
    4630              : void
    4631        18840 : RangeFullExpr::accept_vis (ASTVisitor &vis)
    4632              : {
    4633        18840 :   vis.visit (*this);
    4634        18840 : }
    4635              : 
    4636              : void
    4637         2029 : RangeFromToInclExpr::accept_vis (ASTVisitor &vis)
    4638              : {
    4639         2029 :   vis.visit (*this);
    4640         2029 : }
    4641              : 
    4642              : void
    4643            0 : RangeToInclExpr::accept_vis (ASTVisitor &vis)
    4644              : {
    4645            0 :   vis.visit (*this);
    4646            0 : }
    4647              : 
    4648              : void
    4649       178856 : ReturnExpr::accept_vis (ASTVisitor &vis)
    4650              : {
    4651       178856 :   vis.visit (*this);
    4652       178856 : }
    4653              : 
    4654              : void
    4655         9185 : TryExpr::accept_vis (ASTVisitor &vis)
    4656              : {
    4657         9185 :   vis.visit (*this);
    4658         9185 : }
    4659              : 
    4660              : void
    4661       423539 : UnsafeBlockExpr::accept_vis (ASTVisitor &vis)
    4662              : {
    4663       423539 :   vis.visit (*this);
    4664       423539 : }
    4665              : 
    4666              : void
    4667        21621 : LoopExpr::accept_vis (ASTVisitor &vis)
    4668              : {
    4669        21621 :   vis.visit (*this);
    4670        21620 : }
    4671              : 
    4672              : void
    4673        36273 : WhileLoopExpr::accept_vis (ASTVisitor &vis)
    4674              : {
    4675        36273 :   vis.visit (*this);
    4676        36273 : }
    4677              : 
    4678              : void
    4679         7743 : WhileLetLoopExpr::accept_vis (ASTVisitor &vis)
    4680              : {
    4681         7743 :   vis.visit (*this);
    4682         7743 : }
    4683              : 
    4684              : void
    4685        35610 : ForLoopExpr::accept_vis (ASTVisitor &vis)
    4686              : {
    4687        35610 :   vis.visit (*this);
    4688        35610 : }
    4689              : 
    4690              : void
    4691       260952 : IfExpr::accept_vis (ASTVisitor &vis)
    4692              : {
    4693       260952 :   vis.visit (*this);
    4694       260952 : }
    4695              : 
    4696              : void
    4697       327391 : IfExprConseqElse::accept_vis (ASTVisitor &vis)
    4698              : {
    4699       327391 :   vis.visit (*this);
    4700       327391 : }
    4701              : 
    4702              : void
    4703        20162 : IfLetExpr::accept_vis (ASTVisitor &vis)
    4704              : {
    4705        20162 :   vis.visit (*this);
    4706        20162 : }
    4707              : 
    4708              : void
    4709         9760 : IfLetExprConseqElse::accept_vis (ASTVisitor &vis)
    4710              : {
    4711         9760 :   vis.visit (*this);
    4712         9760 : }
    4713              : 
    4714              : void
    4715      1125104 : MatchExpr::accept_vis (ASTVisitor &vis)
    4716              : {
    4717      1125104 :   vis.visit (*this);
    4718      1125102 : }
    4719              : 
    4720              : void
    4721            0 : AwaitExpr::accept_vis (ASTVisitor &vis)
    4722              : {
    4723            0 :   vis.visit (*this);
    4724            0 : }
    4725              : 
    4726              : void
    4727            0 : AsyncBlockExpr::accept_vis (ASTVisitor &vis)
    4728              : {
    4729            0 :   vis.visit (*this);
    4730            0 : }
    4731              : 
    4732              : void
    4733          479 : InlineAsm::accept_vis (ASTVisitor &vis)
    4734              : {
    4735          479 :   vis.visit (*this);
    4736          479 : }
    4737              : 
    4738              : void
    4739         3069 : LlvmInlineAsm::accept_vis (ASTVisitor &vis)
    4740              : {
    4741         3069 :   vis.visit (*this);
    4742         3069 : }
    4743              : 
    4744              : void
    4745      1823815 : TypeParam::accept_vis (ASTVisitor &vis)
    4746              : {
    4747      1823815 :   vis.visit (*this);
    4748      1823815 : }
    4749              : 
    4750              : void
    4751          298 : LifetimeWhereClauseItem::accept_vis (ASTVisitor &vis)
    4752              : {
    4753          298 :   vis.visit (*this);
    4754          298 : }
    4755              : 
    4756              : void
    4757       272167 : TypeBoundWhereClauseItem::accept_vis (ASTVisitor &vis)
    4758              : {
    4759       272167 :   vis.visit (*this);
    4760       272167 : }
    4761              : 
    4762              : void
    4763        92560 : Module::accept_vis (ASTVisitor &vis)
    4764              : {
    4765        92560 :   vis.visit (*this);
    4766        92560 : }
    4767              : 
    4768              : void
    4769         1443 : ExternCrate::accept_vis (ASTVisitor &vis)
    4770              : {
    4771         1443 :   vis.visit (*this);
    4772         1435 : }
    4773              : 
    4774              : void
    4775         8374 : UseTreeGlob::accept_vis (ASTVisitor &vis)
    4776              : {
    4777         8374 :   vis.visit (*this);
    4778         8374 : }
    4779              : 
    4780              : void
    4781        28778 : UseTreeList::accept_vis (ASTVisitor &vis)
    4782              : {
    4783        28778 :   vis.visit (*this);
    4784        28778 : }
    4785              : 
    4786              : void
    4787        60725 : UseTreeRebind::accept_vis (ASTVisitor &vis)
    4788              : {
    4789        60725 :   vis.visit (*this);
    4790        60725 : }
    4791              : 
    4792              : void
    4793       188167 : UseDeclaration::accept_vis (ASTVisitor &vis)
    4794              : {
    4795       188167 :   vis.visit (*this);
    4796       188167 : }
    4797              : 
    4798              : void
    4799      3545366 : Function::accept_vis (ASTVisitor &vis)
    4800              : {
    4801      3545366 :   vis.visit (*this);
    4802      3545364 : }
    4803              : 
    4804              : void
    4805       676346 : TypeAlias::accept_vis (ASTVisitor &vis)
    4806              : {
    4807       676346 :   vis.visit (*this);
    4808       676346 : }
    4809              : 
    4810              : void
    4811           44 : TraitAlias::accept_vis (ASTVisitor &vis)
    4812              : {
    4813           44 :   vis.visit (*this);
    4814           44 : }
    4815              : 
    4816              : void
    4817       267903 : StructStruct::accept_vis (ASTVisitor &vis)
    4818              : {
    4819       267903 :   vis.visit (*this);
    4820       267903 : }
    4821              : 
    4822              : void
    4823        49853 : TupleStruct::accept_vis (ASTVisitor &vis)
    4824              : {
    4825        49853 :   vis.visit (*this);
    4826        49853 : }
    4827              : 
    4828              : void
    4829        29444 : EnumItem::accept_vis (ASTVisitor &vis)
    4830              : {
    4831        29444 :   vis.visit (*this);
    4832        29444 : }
    4833              : 
    4834              : void
    4835        22372 : EnumItemTuple::accept_vis (ASTVisitor &vis)
    4836              : {
    4837        22372 :   vis.visit (*this);
    4838        22372 : }
    4839              : 
    4840              : void
    4841         2691 : EnumItemStruct::accept_vis (ASTVisitor &vis)
    4842              : {
    4843         2691 :   vis.visit (*this);
    4844         2691 : }
    4845              : 
    4846              : void
    4847         9003 : EnumItemDiscriminant::accept_vis (ASTVisitor &vis)
    4848              : {
    4849         9003 :   vis.visit (*this);
    4850         9003 : }
    4851              : 
    4852              : void
    4853        23731 : Enum::accept_vis (ASTVisitor &vis)
    4854              : {
    4855        23731 :   vis.visit (*this);
    4856        23731 : }
    4857              : 
    4858              : void
    4859         3206 : Union::accept_vis (ASTVisitor &vis)
    4860              : {
    4861         3206 :   vis.visit (*this);
    4862         3206 : }
    4863              : 
    4864              : void
    4865       176635 : ConstantItem::accept_vis (ASTVisitor &vis)
    4866              : {
    4867       176635 :   vis.visit (*this);
    4868       176635 : }
    4869              : 
    4870              : void
    4871         9905 : StaticItem::accept_vis (ASTVisitor &vis)
    4872              : {
    4873         9905 :   vis.visit (*this);
    4874         9905 : }
    4875              : 
    4876              : void
    4877        35409 : TraitItemType::accept_vis (ASTVisitor &vis)
    4878              : {
    4879        35409 :   vis.visit (*this);
    4880        35409 : }
    4881              : 
    4882              : void
    4883       143769 : Trait::accept_vis (ASTVisitor &vis)
    4884              : {
    4885       143769 :   vis.visit (*this);
    4886       143769 : }
    4887              : 
    4888              : void
    4889        96057 : InherentImpl::accept_vis (ASTVisitor &vis)
    4890              : {
    4891        96057 :   vis.visit (*this);
    4892        96057 : }
    4893              : 
    4894              : void
    4895      1563338 : TraitImpl::accept_vis (ASTVisitor &vis)
    4896              : {
    4897      1563338 :   vis.visit (*this);
    4898      1563338 : }
    4899              : 
    4900              : void
    4901          308 : ExternalTypeItem::accept_vis (ASTVisitor &vis)
    4902              : {
    4903          308 :   vis.visit (*this);
    4904          308 : }
    4905              : 
    4906              : void
    4907           22 : ExternalStaticItem::accept_vis (ASTVisitor &vis)
    4908              : {
    4909           22 :   vis.visit (*this);
    4910           22 : }
    4911              : 
    4912              : void
    4913        53844 : ExternBlock::accept_vis (ASTVisitor &vis)
    4914              : {
    4915        53844 :   vis.visit (*this);
    4916        53844 : }
    4917              : 
    4918              : void
    4919       226215 : MacroMatchFragment::accept_vis (ASTVisitor &vis)
    4920              : {
    4921       226215 :   vis.visit (*this);
    4922       226215 : }
    4923              : 
    4924              : void
    4925        31576 : MacroMatchRepetition::accept_vis (ASTVisitor &vis)
    4926              : {
    4927        31576 :   vis.visit (*this);
    4928        31576 : }
    4929              : 
    4930              : void
    4931         5739 : MacroMatcher::accept_vis (ASTVisitor &vis)
    4932              : {
    4933         5739 :   vis.visit (*this);
    4934         5739 : }
    4935              : 
    4936              : void
    4937       213908 : MacroRulesDefinition::accept_vis (ASTVisitor &vis)
    4938              : {
    4939       213908 :   vis.visit (*this);
    4940       213908 : }
    4941              : 
    4942              : void
    4943       399700 : MacroInvocation::accept_vis (ASTVisitor &vis)
    4944              : {
    4945       399700 :   vis.visit (*this);
    4946       399700 : }
    4947              : 
    4948              : void
    4949         1583 : EmptyStmt::accept_vis (ASTVisitor &vis)
    4950              : {
    4951         1583 :   vis.visit (*this);
    4952         1583 : }
    4953              : 
    4954              : void
    4955      1516209 : LetStmt::accept_vis (ASTVisitor &vis)
    4956              : {
    4957      1516209 :   vis.visit (*this);
    4958      1516208 : }
    4959              : 
    4960              : void
    4961      1868933 : ExprStmt::accept_vis (ASTVisitor &vis)
    4962              : {
    4963      1868933 :   vis.visit (*this);
    4964      1868931 : }
    4965              : 
    4966              : void
    4967       935613 : TraitBound::accept_vis (ASTVisitor &vis)
    4968              : {
    4969       935613 :   vis.visit (*this);
    4970       935613 : }
    4971              : 
    4972              : void
    4973        18283 : ImplTraitType::accept_vis (ASTVisitor &vis)
    4974              : {
    4975        18283 :   vis.visit (*this);
    4976        18283 : }
    4977              : 
    4978              : void
    4979        13105 : TraitObjectType::accept_vis (ASTVisitor &vis)
    4980              : {
    4981        13105 :   vis.visit (*this);
    4982        13105 : }
    4983              : 
    4984              : void
    4985         2622 : ParenthesisedType::accept_vis (ASTVisitor &vis)
    4986              : {
    4987         2622 :   vis.visit (*this);
    4988         2622 : }
    4989              : 
    4990              : void
    4991        44837 : ImplTraitTypeOneBound::accept_vis (ASTVisitor &vis)
    4992              : {
    4993        44837 :   vis.visit (*this);
    4994        44837 : }
    4995              : 
    4996              : void
    4997        12403 : TraitObjectTypeOneBound::accept_vis (ASTVisitor &vis)
    4998              : {
    4999        12403 :   vis.visit (*this);
    5000        12403 : }
    5001              : 
    5002              : void
    5003       266711 : TupleType::accept_vis (ASTVisitor &vis)
    5004              : {
    5005       266711 :   vis.visit (*this);
    5006       266711 : }
    5007              : 
    5008              : void
    5009        17814 : NeverType::accept_vis (ASTVisitor &vis)
    5010              : {
    5011        17814 :   vis.visit (*this);
    5012        17814 : }
    5013              : 
    5014              : void
    5015       557276 : RawPointerType::accept_vis (ASTVisitor &vis)
    5016              : {
    5017       557276 :   vis.visit (*this);
    5018       557276 : }
    5019              : 
    5020              : void
    5021      2238964 : ReferenceType::accept_vis (ASTVisitor &vis)
    5022              : {
    5023      2238964 :   vis.visit (*this);
    5024      2238964 : }
    5025              : 
    5026              : void
    5027       100027 : ArrayType::accept_vis (ASTVisitor &vis)
    5028              : {
    5029       100027 :   vis.visit (*this);
    5030       100027 : }
    5031              : 
    5032              : void
    5033       191672 : SliceType::accept_vis (ASTVisitor &vis)
    5034              : {
    5035       191672 :   vis.visit (*this);
    5036       191672 : }
    5037              : 
    5038              : void
    5039        64126 : InferredType::accept_vis (ASTVisitor &vis)
    5040              : {
    5041        64126 :   vis.visit (*this);
    5042        64126 : }
    5043              : 
    5044              : void
    5045       116191 : BareFunctionType::accept_vis (ASTVisitor &vis)
    5046              : {
    5047       116191 :   vis.visit (*this);
    5048       116191 : }
    5049              : 
    5050              : void
    5051        16400 : MetaItemSeq::accept_vis (ASTVisitor &vis)
    5052              : {
    5053        16400 :   vis.visit (*this);
    5054        16400 : }
    5055              : 
    5056              : void
    5057         2670 : MetaItemPath::accept_vis (ASTVisitor &vis)
    5058              : {
    5059         2670 :   vis.visit (*this);
    5060         2670 : }
    5061              : 
    5062              : void
    5063            0 : MetaListPaths::accept_vis (ASTVisitor &vis)
    5064              : {
    5065            0 :   vis.visit (*this);
    5066            0 : }
    5067              : 
    5068              : void
    5069        30470 : MetaNameValueStr::accept_vis (ASTVisitor &vis)
    5070              : {
    5071        30470 :   vis.visit (*this);
    5072        30470 : }
    5073              : 
    5074              : void
    5075            0 : MetaListNameValueStr::accept_vis (ASTVisitor &vis)
    5076              : {
    5077            0 :   vis.visit (*this);
    5078            0 : }
    5079              : 
    5080              : void
    5081        42517 : AttrInputMetaItemContainer::accept_vis (ASTVisitor &vis)
    5082              : {
    5083        42517 :   vis.visit (*this);
    5084        42517 : }
    5085              : 
    5086              : void
    5087        12291 : MetaWord::accept_vis (ASTVisitor &vis)
    5088              : {
    5089        12291 :   vis.visit (*this);
    5090        12291 : }
    5091              : 
    5092              : void
    5093            0 : FormatArgs::accept_vis (ASTVisitor &vis)
    5094              : {
    5095            0 :   vis.visit (*this);
    5096            0 : }
    5097              : 
    5098              : void
    5099          244 : OffsetOf::accept_vis (ASTVisitor &vis)
    5100              : {
    5101          244 :   vis.visit (*this);
    5102          244 : }
    5103              : 
    5104              : std::string
    5105            0 : FormatArgs::as_string () const
    5106              : {
    5107              :   // FIXME(Arthur): Improve
    5108            0 :   return "FormatArgs";
    5109              : }
    5110              : 
    5111              : std::string
    5112            0 : OffsetOf::as_string () const
    5113              : {
    5114            0 :   return "OffsetOf(" + type->as_string () + ", " + field.as_string () + ")";
    5115              : }
    5116              : 
    5117              : location_t
    5118           76 : FormatArgs::get_locus () const
    5119              : {
    5120           76 :   return loc;
    5121              : }
    5122              : 
    5123              : bool
    5124            0 : FormatArgs::is_expr_without_block () const
    5125              : {
    5126            0 :   return false;
    5127              : }
    5128              : 
    5129              : void
    5130            0 : FormatArgs::mark_for_strip ()
    5131              : {
    5132            0 :   marked_for_strip = true;
    5133            0 : }
    5134              : 
    5135              : bool
    5136            0 : FormatArgs::is_marked_for_strip () const
    5137              : {
    5138            0 :   return marked_for_strip;
    5139              : }
    5140              : 
    5141              : std::vector<Attribute> &
    5142            0 : FormatArgs::get_outer_attrs ()
    5143              : {
    5144            0 :   rust_unreachable ();
    5145              : }
    5146              : 
    5147              : void
    5148            0 : FormatArgs::set_outer_attrs (std::vector<Attribute>)
    5149              : {
    5150            0 :   rust_unreachable ();
    5151              : }
    5152              : 
    5153              : Expr *
    5154            0 : FormatArgs::clone_expr_impl () const
    5155              : {
    5156            0 :   std::cerr << "[ARTHUR] cloning FormatArgs! " << std::endl;
    5157              : 
    5158            0 :   return new FormatArgs (*this);
    5159              : }
    5160              : 
    5161              : std::vector<Attribute> &
    5162            0 : OffsetOf::get_outer_attrs ()
    5163              : {
    5164            0 :   rust_unreachable ();
    5165              : }
    5166              : 
    5167              : void
    5168            0 : OffsetOf::set_outer_attrs (std::vector<Attribute>)
    5169              : {
    5170            0 :   rust_unreachable ();
    5171              : }
    5172              : 
    5173              : Expr *
    5174           96 : OffsetOf::clone_expr_impl () const
    5175              : {
    5176           96 :   return new OffsetOf (*this);
    5177              : }
    5178              : 
    5179              : } // namespace AST
    5180              : 
    5181              : std::ostream &
    5182            0 : operator<< (std::ostream &os, Identifier const &i)
    5183              : {
    5184            0 :   return os << i.as_string ();
    5185              : }
    5186              : 
    5187              : } // namespace Rust
        

Generated by: LCOV version 2.5.0-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.