LCOV - code coverage report
Current view: top level - gcc/rust/ast - rust-path.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 82.6 % 484 400
Test Date: 2025-08-30 13:27:53 Functions: 79.4 % 136 108
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // Copyright (C) 2020-2025 Free Software Foundation, Inc.
       2                 :             : 
       3                 :             : // This file is part of GCC.
       4                 :             : 
       5                 :             : // GCC is free software; you can redistribute it and/or modify it under
       6                 :             : // the terms of the GNU General Public License as published by the Free
       7                 :             : // Software Foundation; either version 3, or (at your option) any later
       8                 :             : // version.
       9                 :             : 
      10                 :             : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11                 :             : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12                 :             : // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13                 :             : // for more details.
      14                 :             : 
      15                 :             : // You should have received a copy of the GNU General Public License
      16                 :             : // along with GCC; see the file COPYING3.  If not see
      17                 :             : // <http://www.gnu.org/licenses/>.
      18                 :             : 
      19                 :             : #ifndef RUST_AST_PATH_H
      20                 :             : #define RUST_AST_PATH_H
      21                 :             : /* "Path" (identifier within namespaces, essentially) handling. Required include
      22                 :             :  * for virtually all AST-related functionality. */
      23                 :             : 
      24                 :             : #include "optional.h"
      25                 :             : #include "rust-ast.h"
      26                 :             : #include "rust-hir-map.h"
      27                 :             : #include "rust-mapping-common.h"
      28                 :             : #include "rust-system.h"
      29                 :             : #include "system.h"
      30                 :             : 
      31                 :             : namespace Rust {
      32                 :             : namespace AST {
      33                 :             : 
      34                 :             : // The "identifier" (not generic args) aspect of each path expression segment
      35                 :      575029 : class PathIdentSegment
      36                 :             : {
      37                 :             :   std::string segment_name;
      38                 :             :   location_t locus;
      39                 :             : 
      40                 :             :   // only allow identifiers, "super", "self", "Self", "crate", or "$crate"
      41                 :             : public:
      42                 :      220981 :   PathIdentSegment (std::string segment_name, location_t locus)
      43                 :      188189 :     : segment_name (std::move (segment_name)), locus (locus)
      44                 :             :   {}
      45                 :             : 
      46                 :             :   // Creates an error PathIdentSegment.
      47                 :         205 :   static PathIdentSegment create_error ()
      48                 :             :   {
      49                 :         205 :     return PathIdentSegment ("", UNDEF_LOCATION);
      50                 :             :   }
      51                 :             : 
      52                 :             :   // Returns whether PathIdentSegment is in an error state.
      53                 :      106601 :   bool is_error () const { return segment_name.empty (); }
      54                 :             : 
      55                 :      485938 :   std::string as_string () const { return segment_name; }
      56                 :             : 
      57                 :        5182 :   location_t get_locus () const { return locus; }
      58                 :             : 
      59                 :       31647 :   bool is_super_path_seg () const
      60                 :             :   {
      61                 :       63294 :     return as_string ().compare ("super") == 0;
      62                 :             :   }
      63                 :       46787 :   bool is_crate_path_seg () const
      64                 :             :   {
      65                 :       93574 :     return as_string ().compare ("crate") == 0;
      66                 :             :   }
      67                 :      189540 :   bool is_lower_self_seg () const { return as_string ().compare ("self") == 0; }
      68                 :      105974 :   bool is_big_self_seg () const { return as_string ().compare ("Self") == 0; }
      69                 :             : };
      70                 :             : 
      71                 :             : // A binding of an identifier to a type used in generic arguments in paths
      72                 :             : struct GenericArgsBinding
      73                 :             : {
      74                 :             : private:
      75                 :             :   Identifier identifier;
      76                 :             :   std::unique_ptr<Type> type;
      77                 :             :   location_t locus;
      78                 :             : 
      79                 :             : public:
      80                 :             :   // Returns whether binding is in an error state.
      81                 :          73 :   bool is_error () const
      82                 :             :   {
      83                 :          73 :     return type == nullptr;
      84                 :             :     // and also identifier is empty, but cheaper computation
      85                 :             :   }
      86                 :             : 
      87                 :             :   // Creates an error state generic args binding.
      88                 :           0 :   static GenericArgsBinding create_error ()
      89                 :             :   {
      90                 :           0 :     return GenericArgsBinding ({""}, nullptr);
      91                 :             :   }
      92                 :             : 
      93                 :             :   // Pointer type for type in constructor to enable polymorphism
      94                 :          73 :   GenericArgsBinding (Identifier ident, std::unique_ptr<Type> type_ptr,
      95                 :             :                       location_t locus = UNDEF_LOCATION)
      96                 :          73 :     : identifier (std::move (ident)), type (std::move (type_ptr)), locus (locus)
      97                 :             :   {}
      98                 :             : 
      99                 :             :   // Copy constructor has to deep copy the type as it is a unique pointer
     100                 :          14 :   GenericArgsBinding (GenericArgsBinding const &other)
     101                 :          14 :     : identifier (other.identifier), locus (other.locus)
     102                 :             :   {
     103                 :             :     // guard to protect from null pointer dereference
     104                 :          14 :     if (other.type != nullptr)
     105                 :          14 :       type = other.type->clone_type ();
     106                 :          14 :   }
     107                 :             : 
     108                 :             :   // default destructor
     109                 :          88 :   ~GenericArgsBinding () = default;
     110                 :             : 
     111                 :             :   // Overload assignment operator to deep copy the pointed-to type
     112                 :             :   GenericArgsBinding &operator= (GenericArgsBinding const &other)
     113                 :             :   {
     114                 :             :     identifier = other.identifier;
     115                 :             :     locus = other.locus;
     116                 :             : 
     117                 :             :     // guard to protect from null pointer dereference
     118                 :             :     if (other.type != nullptr)
     119                 :             :       type = other.type->clone_type ();
     120                 :             :     else
     121                 :             :       type = nullptr;
     122                 :             : 
     123                 :             :     return *this;
     124                 :             :   }
     125                 :             : 
     126                 :             :   // move constructors
     127                 :          74 :   GenericArgsBinding (GenericArgsBinding &&other) = default;
     128                 :             :   GenericArgsBinding &operator= (GenericArgsBinding &&other) = default;
     129                 :             : 
     130                 :             :   std::string as_string () const;
     131                 :             : 
     132                 :             :   // TODO: is this better? Or is a "vis_pattern" better?
     133                 :        1273 :   Type &get_type ()
     134                 :             :   {
     135                 :        1273 :     rust_assert (type != nullptr);
     136                 :        1273 :     return *type;
     137                 :             :   }
     138                 :             : 
     139                 :         205 :   std::unique_ptr<Type> &get_type_ptr ()
     140                 :             :   {
     141                 :         205 :     rust_assert (type != nullptr);
     142                 :         205 :     return type;
     143                 :             :   }
     144                 :             : 
     145                 :          79 :   location_t get_locus () const { return locus; }
     146                 :             : 
     147                 :          79 :   Identifier get_identifier () const { return identifier; }
     148                 :             : };
     149                 :             : 
     150                 :             : /* Class representing a const generic application */
     151                 :             : class GenericArg
     152                 :             : {
     153                 :             : public:
     154                 :             :   /**
     155                 :             :    * const generic arguments cannot always be differentiated with generic type
     156                 :             :    * arguments during parsing, e.g:
     157                 :             :    * ```rust
     158                 :             :    * let a: Foo<N>;
     159                 :             :    * ```
     160                 :             :    *
     161                 :             :    * Is N a type? A constant defined elsewhere? The parser cannot know, and must
     162                 :             :    * not draw any conclusions. We must wait until later passes of the compiler
     163                 :             :    * to decide whether this refers to a constant item or a type.
     164                 :             :    *
     165                 :             :    * On the other hand, simple expressions like literals or block expressions
     166                 :             :    * will always be constant expressions: There is no ambiguity at all.
     167                 :             :    */
     168                 :             :   enum class Kind
     169                 :             :   {
     170                 :             :     Const,  // A const value
     171                 :             :     Type,   // A type argument (not discernable during parsing)
     172                 :             :     Either, // Either a type or a const value, cleared up during resolving
     173                 :             :   };
     174                 :             : 
     175                 :          87 :   static GenericArg create_const (std::unique_ptr<Expr> expression)
     176                 :             :   {
     177                 :          87 :     auto locus = expression->get_locus ();
     178                 :          87 :     return GenericArg (std::move (expression), nullptr, {""}, Kind::Const,
     179                 :         174 :                        locus);
     180                 :             :   }
     181                 :             : 
     182                 :        3725 :   static GenericArg create_type (std::unique_ptr<Type> type)
     183                 :             :   {
     184                 :        3725 :     auto locus = type->get_locus ();
     185                 :       11175 :     return GenericArg (nullptr, std::move (type), {""}, Kind::Type, locus);
     186                 :             :   }
     187                 :             : 
     188                 :        2399 :   static GenericArg create_ambiguous (Identifier path, location_t locus)
     189                 :             :   {
     190                 :        4798 :     return GenericArg (nullptr, nullptr, std::move (path), Kind::Either, locus);
     191                 :             :   }
     192                 :             : 
     193                 :        5614 :   GenericArg (const GenericArg &other)
     194                 :        5614 :     : path (other.path), kind (other.kind), locus (other.locus)
     195                 :             :   {
     196                 :        5614 :     if (other.expression)
     197                 :          18 :       expression = other.expression->clone_expr ();
     198                 :        5614 :     if (other.type)
     199                 :        4184 :       type = other.type->clone_type ();
     200                 :        5614 :   }
     201                 :             : 
     202                 :             :   GenericArg operator= (const GenericArg &other)
     203                 :             :   {
     204                 :             :     kind = other.kind;
     205                 :             :     path = other.path;
     206                 :             :     locus = other.locus;
     207                 :             : 
     208                 :             :     if (other.expression)
     209                 :             :       expression = other.expression->clone_expr ();
     210                 :             :     if (other.type)
     211                 :             :       type = other.type->clone_type ();
     212                 :             : 
     213                 :             :     return *this;
     214                 :             :   }
     215                 :             : 
     216                 :       13201 :   GenericArg (GenericArg &&other) = default;
     217                 :        2295 :   GenericArg &operator= (GenericArg &&other) = default;
     218                 :             : 
     219                 :       79389 :   Kind get_kind () const { return kind; }
     220                 :           0 :   location_t get_locus () const { return locus; }
     221                 :             : 
     222                 :       42628 :   void accept_vis (AST::ASTVisitor &visitor)
     223                 :             :   {
     224                 :       42628 :     switch (get_kind ())
     225                 :             :       {
     226                 :         859 :       case Kind::Const:
     227                 :         859 :         get_expression ().accept_vis (visitor);
     228                 :         859 :         break;
     229                 :       17865 :       case Kind::Type:
     230                 :       17865 :         get_type ().accept_vis (visitor);
     231                 :       17865 :         break;
     232                 :             :       case Kind::Either:
     233                 :             :         break;
     234                 :             :       }
     235                 :       42628 :   }
     236                 :             : 
     237                 :        1201 :   Expr &get_expression ()
     238                 :             :   {
     239                 :        1201 :     rust_assert (kind == Kind::Const);
     240                 :             : 
     241                 :        1201 :     return *expression;
     242                 :             :   }
     243                 :             : 
     244                 :          92 :   std::unique_ptr<Expr> &get_expression_ptr ()
     245                 :             :   {
     246                 :          92 :     rust_assert (kind == Kind::Const);
     247                 :             : 
     248                 :          92 :     return expression;
     249                 :             :   }
     250                 :             : 
     251                 :       31226 :   Type &get_type ()
     252                 :             :   {
     253                 :       31226 :     rust_assert (kind == Kind::Type);
     254                 :             : 
     255                 :       31226 :     return *type;
     256                 :             :   }
     257                 :             : 
     258                 :        3819 :   std::unique_ptr<Type> &get_type_ptr ()
     259                 :             :   {
     260                 :        3819 :     rust_assert (kind == Kind::Type);
     261                 :             : 
     262                 :        3819 :     return type;
     263                 :             :   }
     264                 :             : 
     265                 :        4588 :   const std::string get_path () const
     266                 :             :   {
     267                 :        4588 :     rust_assert (kind == Kind::Either);
     268                 :             : 
     269                 :        4588 :     return path.as_string ();
     270                 :             :   }
     271                 :             : 
     272                 :           0 :   std::string as_string () const
     273                 :             :   {
     274                 :           0 :     switch (get_kind ())
     275                 :             :       {
     276                 :           0 :       case Kind::Either:
     277                 :           0 :         return "Ambiguous: " + path.as_string ();
     278                 :           0 :       case Kind::Const:
     279                 :           0 :         return "Const: { " + expression->as_string () + " }";
     280                 :           0 :       case Kind::Type:
     281                 :           0 :         return "Type: " + type->as_string ();
     282                 :             :       }
     283                 :             : 
     284                 :           0 :     return "";
     285                 :             :   }
     286                 :             : 
     287                 :             :   /**
     288                 :             :    * Disambiguate an ambiguous generic argument to a const generic argument,
     289                 :             :    * unequivocally
     290                 :             :    */
     291                 :             :   GenericArg disambiguate_to_const () const;
     292                 :             : 
     293                 :             :   /**
     294                 :             :    * Disambiguate an ambiguous generic argument to a type argument,
     295                 :             :    * unequivocally
     296                 :             :    */
     297                 :             :   GenericArg disambiguate_to_type () const;
     298                 :             : 
     299                 :             : private:
     300                 :        6211 :   GenericArg (std::unique_ptr<Expr> expression, std::unique_ptr<Type> type,
     301                 :             :               Identifier path, Kind kind, location_t locus)
     302                 :        4732 :     : expression (std::move (expression)), type (std::move (type)),
     303                 :        6211 :       path (std::move (path)), kind (kind), locus (locus)
     304                 :             :   {}
     305                 :             : 
     306                 :             :   /**
     307                 :             :    * Expression associated with a `Clear` const generic application
     308                 :             :    * A null pointer here is allowed in the case that the const argument is
     309                 :             :    * ambiguous.
     310                 :             :    */
     311                 :             :   std::unique_ptr<Expr> expression;
     312                 :             : 
     313                 :             :   /**
     314                 :             :    * If the argument ends up being a type argument instead. A null pointer will
     315                 :             :    * be present here until the resolving phase.
     316                 :             :    */
     317                 :             :   std::unique_ptr<Type> type;
     318                 :             : 
     319                 :             :   /**
     320                 :             :    * Optional path which cannot be differentiated between a constant item and
     321                 :             :    * a type. Only used for ambiguous const generic arguments, otherwise
     322                 :             :    * empty.
     323                 :             :    */
     324                 :             :   Identifier path;
     325                 :             : 
     326                 :             :   /* Which kind of const generic application are we dealing with */
     327                 :             :   Kind kind;
     328                 :             : 
     329                 :             :   location_t locus;
     330                 :             : };
     331                 :             : 
     332                 :             : /**
     333                 :             :  * Representation of const generic parameters
     334                 :             :  */
     335                 :             : class ConstGenericParam : public GenericParam
     336                 :             : {
     337                 :             :   /* Name of the parameter */
     338                 :             :   Identifier name;
     339                 :             : 
     340                 :             :   /* Mandatory type of the const parameter - a null pointer is an error */
     341                 :             :   std::unique_ptr<AST::Type> type;
     342                 :             : 
     343                 :             :   /**
     344                 :             :    * Default value for the const generic parameter
     345                 :             :    */
     346                 :             :   tl::optional<GenericArg> default_value;
     347                 :             : 
     348                 :             :   AST::AttrVec outer_attrs;
     349                 :             :   location_t locus;
     350                 :             : 
     351                 :             : public:
     352                 :          46 :   ConstGenericParam (Identifier name, std::unique_ptr<AST::Type> type,
     353                 :             :                      tl::optional<GenericArg> default_value,
     354                 :             :                      AST::AttrVec outer_attrs, location_t locus)
     355                 :          46 :     : name (name), type (std::move (type)),
     356                 :          46 :       default_value (std::move (default_value)), outer_attrs (outer_attrs),
     357                 :          46 :       locus (locus)
     358                 :          46 :   {}
     359                 :             : 
     360                 :           0 :   ConstGenericParam (const ConstGenericParam &other)
     361                 :           0 :     : GenericParam (), name (other.name), type (other.type->clone_type ()),
     362                 :           0 :       default_value (other.default_value), outer_attrs (other.outer_attrs),
     363                 :           0 :       locus (other.locus)
     364                 :           0 :   {}
     365                 :             : 
     366                 :         631 :   bool has_type () const { return type != nullptr; }
     367                 :         631 :   bool has_default_value () const { return default_value.has_value (); }
     368                 :             : 
     369                 :         138 :   const Identifier &get_name () const { return name; }
     370                 :             : 
     371                 :         642 :   AST::AttrVec &get_outer_attrs () { return outer_attrs; }
     372                 :             : 
     373                 :         631 :   AST::Type &get_type ()
     374                 :             :   {
     375                 :         631 :     rust_assert (has_type ());
     376                 :             : 
     377                 :         631 :     return *type;
     378                 :             :   }
     379                 :             : 
     380                 :         248 :   GenericArg &get_default_value_unchecked ()
     381                 :             :   {
     382                 :         248 :     rust_assert (has_default_value ());
     383                 :             : 
     384                 :         248 :     return default_value.value ();
     385                 :             :   }
     386                 :             : 
     387                 :           0 :   const GenericArg &get_default_value_unchecked () const
     388                 :             :   {
     389                 :           0 :     rust_assert (has_default_value ());
     390                 :             : 
     391                 :           0 :     return default_value.value ();
     392                 :             :   }
     393                 :             : 
     394                 :           0 :   tl::optional<GenericArg> &get_default_value () { return default_value; }
     395                 :             : 
     396                 :             :   const tl::optional<GenericArg> &get_default_value () const
     397                 :             :   {
     398                 :             :     return default_value;
     399                 :             :   }
     400                 :             : 
     401                 :             :   std::string as_string () const override;
     402                 :             : 
     403                 :             :   void accept_vis (ASTVisitor &vis) override;
     404                 :             : 
     405                 :         208 :   location_t get_locus () const override final { return locus; }
     406                 :             : 
     407                 :          92 :   Kind get_kind () const override final { return Kind::Const; }
     408                 :             : 
     409                 :             : protected:
     410                 :             :   /* Use covariance to implement clone function as returning this object rather
     411                 :             :    * than base */
     412                 :           0 :   ConstGenericParam *clone_generic_param_impl () const override
     413                 :             :   {
     414                 :           0 :     return new ConstGenericParam (*this);
     415                 :             :   }
     416                 :             : };
     417                 :             : 
     418                 :             : // Generic arguments allowed in each path expression segment - inline?
     419                 :             : struct GenericArgs
     420                 :             : {
     421                 :             :   std::vector<Lifetime> lifetime_args;
     422                 :             :   std::vector<GenericArg> generic_args;
     423                 :             :   std::vector<GenericArgsBinding> binding_args;
     424                 :             :   location_t locus;
     425                 :             : 
     426                 :             : public:
     427                 :             :   // Returns true if there are any generic arguments
     428                 :      882347 :   bool has_generic_args () const
     429                 :             :   {
     430                 :      881810 :     return !(lifetime_args.empty () && generic_args.empty ()
     431                 :      793828 :              && binding_args.empty ());
     432                 :             :   }
     433                 :             : 
     434                 :       88489 :   GenericArgs (std::vector<Lifetime> lifetime_args,
     435                 :             :                std::vector<GenericArg> generic_args,
     436                 :             :                std::vector<GenericArgsBinding> binding_args,
     437                 :             :                location_t locus = UNDEF_LOCATION)
     438                 :       88489 :     : lifetime_args (std::move (lifetime_args)),
     439                 :       88489 :       generic_args (std::move (generic_args)),
     440                 :       88489 :       binding_args (std::move (binding_args)), locus (locus)
     441                 :       88489 :   {}
     442                 :             : 
     443                 :             :   // copy constructor with vector clone
     444                 :       46279 :   GenericArgs (GenericArgs const &other)
     445                 :       46279 :     : lifetime_args (other.lifetime_args), binding_args (other.binding_args),
     446                 :       46279 :       locus (other.locus)
     447                 :             :   {
     448                 :       46279 :     generic_args.clear ();
     449                 :       46279 :     generic_args.reserve (other.generic_args.size ());
     450                 :       51670 :     for (const auto &arg : other.generic_args)
     451                 :             :       {
     452                 :        5391 :         generic_args.push_back (GenericArg (arg));
     453                 :             :       }
     454                 :       46279 :   }
     455                 :             : 
     456                 :      253417 :   ~GenericArgs () = default;
     457                 :             : 
     458                 :             :   // overloaded assignment operator to vector clone
     459                 :             :   GenericArgs &operator= (GenericArgs const &other)
     460                 :             :   {
     461                 :             :     lifetime_args = other.lifetime_args;
     462                 :             :     binding_args = other.binding_args;
     463                 :             :     locus = other.locus;
     464                 :             : 
     465                 :             :     generic_args.clear ();
     466                 :             :     generic_args.reserve (other.generic_args.size ());
     467                 :             :     for (const auto &arg : other.generic_args)
     468                 :             :       {
     469                 :             :         generic_args.push_back (GenericArg (arg));
     470                 :             :       }
     471                 :             : 
     472                 :             :     return *this;
     473                 :             :   }
     474                 :             : 
     475                 :             :   // move constructors
     476                 :      156190 :   GenericArgs (GenericArgs &&other) = default;
     477                 :         308 :   GenericArgs &operator= (GenericArgs &&other) = default;
     478                 :             : 
     479                 :             :   // Creates an empty GenericArgs (no arguments)
     480                 :       51565 :   static GenericArgs create_empty () { return GenericArgs ({}, {}, {}); }
     481                 :             : 
     482                 :             :   std::string as_string () const;
     483                 :             : 
     484                 :       73452 :   std::vector<GenericArg> &get_generic_args () { return generic_args; }
     485                 :             : 
     486                 :       73463 :   std::vector<GenericArgsBinding> &get_binding_args () { return binding_args; }
     487                 :             : 
     488                 :             :   const std::vector<GenericArgsBinding> &get_binding_args () const
     489                 :             :   {
     490                 :             :     return binding_args;
     491                 :             :   }
     492                 :             : 
     493                 :       44232 :   std::vector<Lifetime> &get_lifetime_args () { return lifetime_args; };
     494                 :             : 
     495                 :             :   const std::vector<Lifetime> &get_lifetime_args () const
     496                 :             :   {
     497                 :             :     return lifetime_args;
     498                 :             :   };
     499                 :             : 
     500                 :        3577 :   location_t get_locus () const { return locus; }
     501                 :             : };
     502                 :             : 
     503                 :             : /* A segment of a path in expression, including an identifier aspect and maybe
     504                 :             :  * generic args */
     505                 :      185758 : class PathExprSegment
     506                 :             : { // or should this extend PathIdentSegment?
     507                 :             : private:
     508                 :             :   PathIdentSegment segment_name;
     509                 :             :   GenericArgs generic_args;
     510                 :             :   location_t locus;
     511                 :             :   NodeId node_id;
     512                 :             : 
     513                 :             : public:
     514                 :             :   // Returns true if there are any generic arguments
     515                 :     1277345 :   bool has_generic_args () const { return generic_args.has_generic_args (); }
     516                 :             : 
     517                 :             :   // Constructor for segment (from IdentSegment and GenericArgs)
     518                 :       52427 :   PathExprSegment (PathIdentSegment segment_name, location_t locus,
     519                 :             :                    GenericArgs generic_args = GenericArgs::create_empty ())
     520                 :       52427 :     : segment_name (std::move (segment_name)),
     521                 :       52427 :       generic_args (std::move (generic_args)), locus (locus),
     522                 :       52427 :       node_id (Analysis::Mappings::get ().get_next_node_id ())
     523                 :       52427 :   {}
     524                 :             : 
     525                 :             :   /* Constructor for segment with generic arguments (from segment name and all
     526                 :             :    * args) */
     527                 :       32788 :   PathExprSegment (std::string segment_name, location_t locus,
     528                 :             :                    std::vector<Lifetime> lifetime_args = {},
     529                 :             :                    std::vector<GenericArg> generic_args = {},
     530                 :             :                    std::vector<GenericArgsBinding> binding_args = {})
     531                 :       32788 :     : segment_name (PathIdentSegment (std::move (segment_name), locus)),
     532                 :       32788 :       generic_args (GenericArgs (std::move (lifetime_args),
     533                 :             :                                  std::move (generic_args),
     534                 :       32788 :                                  std::move (binding_args))),
     535                 :       32788 :       locus (locus), node_id (Analysis::Mappings::get ().get_next_node_id ())
     536                 :       32788 :   {}
     537                 :             : 
     538                 :             :   // Returns whether path expression segment is in an error state.
     539                 :       85406 :   bool is_error () const { return segment_name.is_error (); }
     540                 :             : 
     541                 :             :   // Creates an error-state path expression segment.
     542                 :           2 :   static PathExprSegment create_error ()
     543                 :             :   {
     544                 :           2 :     return PathExprSegment (PathIdentSegment::create_error (), UNDEF_LOCATION);
     545                 :             :   }
     546                 :             : 
     547                 :             :   std::string as_string () const;
     548                 :             : 
     549                 :       38222 :   location_t get_locus () const { return locus; }
     550                 :             : 
     551                 :             :   // TODO: is this better? Or is a "vis_pattern" better?
     552                 :       19089 :   GenericArgs &get_generic_args ()
     553                 :             :   {
     554                 :       19089 :     rust_assert (has_generic_args ());
     555                 :       19089 :     return generic_args;
     556                 :             :   }
     557                 :             : 
     558                 :      462509 :   PathIdentSegment &get_ident_segment () { return segment_name; }
     559                 :       92741 :   const PathIdentSegment &get_ident_segment () const { return segment_name; }
     560                 :             : 
     561                 :       71974 :   NodeId get_node_id () const { return node_id; }
     562                 :             : 
     563                 :           0 :   bool is_super_path_seg () const
     564                 :             :   {
     565                 :           0 :     return !has_generic_args () && get_ident_segment ().is_super_path_seg ();
     566                 :             :   }
     567                 :             : 
     568                 :           0 :   bool is_crate_path_seg () const
     569                 :             :   {
     570                 :           0 :     return !has_generic_args () && get_ident_segment ().is_crate_path_seg ();
     571                 :             :   }
     572                 :             : 
     573                 :       41496 :   bool is_lower_self_seg () const
     574                 :             :   {
     575                 :       82730 :     return !has_generic_args () && get_ident_segment ().is_lower_self_seg ();
     576                 :             :   }
     577                 :             : };
     578                 :             : 
     579                 :             : // AST node representing a pattern that involves a "path" - abstract base
     580                 :             : // class
     581                 :             : class Path : public Pattern
     582                 :             : {
     583                 :             : public:
     584                 :             :   enum class Kind
     585                 :             :   {
     586                 :             :     LangItem,
     587                 :             :     Regular,
     588                 :             :   };
     589                 :             : 
     590                 :       72811 :   Path (std::vector<PathExprSegment> segments)
     591                 :       72811 :     : segments (std::move (segments)), lang_item (tl::nullopt),
     592                 :       72811 :       kind (Kind::Regular)
     593                 :             :   {}
     594                 :             : 
     595                 :         144 :   Path (LangItem::Kind lang_item)
     596                 :         144 :     : segments ({}), lang_item (lang_item), kind (Kind::LangItem)
     597                 :         144 :   {}
     598                 :             : 
     599                 :             :   // Returns whether path has segments.
     600                 :        8373 :   bool has_segments () const
     601                 :             :   {
     602                 :        8373 :     rust_assert (kind == Kind::Regular);
     603                 :        8373 :     return !segments.empty ();
     604                 :             :   }
     605                 :             : 
     606                 :             :   /* Converts path segments to their equivalent SimplePath segments if
     607                 :             :    * possible, and creates a SimplePath from them. */
     608                 :             :   SimplePath convert_to_simple_path (bool with_opening_scope_resolution) const;
     609                 :             : 
     610                 :             :   /* Returns whether the path is a single segment (excluding qualified path
     611                 :             :    * initial as segment). */
     612                 :       95062 :   bool is_single_segment () const
     613                 :             :   {
     614                 :       95062 :     rust_assert (kind == Kind::Regular);
     615                 :       95062 :     return segments.size () == 1;
     616                 :             :   }
     617                 :             : 
     618                 :             :   std::string as_string () const override;
     619                 :             : 
     620                 :      517391 :   bool is_lang_item () const { return kind == Kind::LangItem; }
     621                 :             : 
     622                 :             :   // TODO: this seems kinda dodgy
     623                 :      564254 :   std::vector<PathExprSegment> &get_segments ()
     624                 :             :   {
     625                 :      564254 :     rust_assert (kind == Kind::Regular);
     626                 :      564254 :     return segments;
     627                 :             :   }
     628                 :       23802 :   const std::vector<PathExprSegment> &get_segments () const
     629                 :             :   {
     630                 :       23802 :     rust_assert (kind == Kind::Regular);
     631                 :       23802 :     return segments;
     632                 :             :   }
     633                 :             : 
     634                 :         352 :   LangItem::Kind get_lang_item () const
     635                 :             :   {
     636                 :         352 :     rust_assert (kind == Kind::LangItem);
     637                 :         352 :     return *lang_item;
     638                 :             :   }
     639                 :             : 
     640                 :           0 :   Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Path; }
     641                 :             :   Path::Kind get_path_kind () { return kind; }
     642                 :             : 
     643                 :             : protected:
     644                 :             :   std::vector<PathExprSegment> segments;
     645                 :             :   tl::optional<LangItem::Kind> lang_item;
     646                 :             : 
     647                 :             :   Path::Kind kind;
     648                 :             : };
     649                 :             : 
     650                 :             : /* AST node representing a path-in-expression pattern (path that allows
     651                 :             :  * generic arguments) */
     652                 :             : class PathInExpression : public Path, public ExprWithoutBlock
     653                 :             : {
     654                 :             :   std::vector<Attribute> outer_attrs;
     655                 :             :   bool has_opening_scope_resolution;
     656                 :             :   location_t locus;
     657                 :             :   NodeId _node_id;
     658                 :             : 
     659                 :             :   bool marked_for_strip;
     660                 :             : 
     661                 :             : public:
     662                 :             :   std::string as_string () const override;
     663                 :             : 
     664                 :             :   // Constructor
     665                 :       72697 :   PathInExpression (std::vector<PathExprSegment> path_segments,
     666                 :             :                     std::vector<Attribute> outer_attrs, location_t locus,
     667                 :             :                     bool has_opening_scope_resolution = false)
     668                 :      145394 :     : Path (std::move (path_segments)), outer_attrs (std::move (outer_attrs)),
     669                 :       72697 :       has_opening_scope_resolution (has_opening_scope_resolution),
     670                 :       72697 :       locus (locus), _node_id (Analysis::Mappings::get ().get_next_node_id ()),
     671                 :       72697 :       marked_for_strip (false)
     672                 :       72697 :   {}
     673                 :             : 
     674                 :         144 :   PathInExpression (LangItem::Kind lang_item,
     675                 :             :                     std::vector<Attribute> outer_attrs, location_t locus)
     676                 :         288 :     : Path (lang_item), outer_attrs (std::move (outer_attrs)),
     677                 :         144 :       has_opening_scope_resolution (false), locus (locus),
     678                 :         144 :       _node_id (Analysis::Mappings::get ().get_next_node_id ()),
     679                 :         144 :       marked_for_strip (false)
     680                 :         144 :   {}
     681                 :             : 
     682                 :             :   // Creates an error state path in expression.
     683                 :           2 :   static PathInExpression create_error ()
     684                 :             :   {
     685                 :           2 :     return PathInExpression (std::vector<PathExprSegment> (), {},
     686                 :           4 :                              UNDEF_LOCATION);
     687                 :             :   }
     688                 :             : 
     689                 :             :   // Returns whether path in expression is in an error state.
     690                 :        5961 :   bool is_error () const { return !has_segments (); }
     691                 :             : 
     692                 :             :   /* Converts PathInExpression to SimplePath if possible (i.e. no generic
     693                 :             :    * arguments). Otherwise returns an empty SimplePath. */
     694                 :        2412 :   SimplePath as_simple_path () const
     695                 :             :   {
     696                 :             :     /* delegate to parent class as can't access segments. however,
     697                 :             :      * QualifiedPathInExpression conversion to simple path wouldn't make
     698                 :             :      * sense, so the method in the parent class should be protected, not
     699                 :             :      * public. Have to pass in opening scope resolution as parent class has no
     700                 :             :      * access to it.
     701                 :             :      */
     702                 :        2412 :     return convert_to_simple_path (has_opening_scope_resolution);
     703                 :             :   }
     704                 :             : 
     705                 :       61211 :   location_t get_locus () const override final { return locus; }
     706                 :             : 
     707                 :             :   void accept_vis (ASTVisitor &vis) override;
     708                 :             : 
     709                 :           0 :   void mark_for_strip () override { marked_for_strip = true; }
     710                 :      141663 :   bool is_marked_for_strip () const override { return marked_for_strip; }
     711                 :             : 
     712                 :       48580 :   bool opening_scope_resolution () const
     713                 :             :   {
     714                 :       48580 :     return has_opening_scope_resolution;
     715                 :             :   }
     716                 :             : 
     717                 :       44108 :   NodeId get_node_id () const override { return _node_id; }
     718                 :             : 
     719                 :             :   const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
     720                 :      572705 :   std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
     721                 :             : 
     722                 :        9716 :   void set_outer_attrs (std::vector<Attribute> new_attrs) override
     723                 :             :   {
     724                 :        9716 :     outer_attrs = std::move (new_attrs);
     725                 :           0 :   }
     726                 :             : 
     727                 :             :   PathExprSegment &get_final_segment () { return get_segments ().back (); }
     728                 :             :   const PathExprSegment &get_final_segment () const
     729                 :             :   {
     730                 :             :     return get_segments ().back ();
     731                 :             :   }
     732                 :             : 
     733                 :       13153 :   Expr::Kind get_expr_kind () const override
     734                 :             :   {
     735                 :       13153 :     return Expr::Kind::PathInExpression;
     736                 :             :   }
     737                 :             : 
     738                 :             : protected:
     739                 :             :   /* Use covariance to implement clone function as returning this object
     740                 :             :    * rather than base */
     741                 :         174 :   PathInExpression *clone_pattern_impl () const final override
     742                 :             :   {
     743                 :         174 :     return clone_path_in_expression_impl ();
     744                 :             :   }
     745                 :             : 
     746                 :             :   /* Use covariance to implement clone function as returning this object
     747                 :             :    * rather than base */
     748                 :           0 :   PathInExpression *clone_expr_without_block_impl () const final override
     749                 :             :   {
     750                 :           0 :     return clone_path_in_expression_impl ();
     751                 :             :   }
     752                 :             : 
     753                 :       23221 :   /*virtual*/ PathInExpression *clone_path_in_expression_impl () const
     754                 :             :   {
     755                 :       23221 :     return new PathInExpression (*this);
     756                 :             :   }
     757                 :             : };
     758                 :             : 
     759                 :             : /* Base class for segments used in type paths - not abstract (represents an
     760                 :             :  * ident-only segment) */
     761                 :             : class TypePathSegment
     762                 :             : {
     763                 :             : public:
     764                 :             :   enum SegmentType
     765                 :             :   {
     766                 :             :     REG,
     767                 :             :     GENERIC,
     768                 :             :     FUNCTION
     769                 :             :   };
     770                 :             : 
     771                 :             : private:
     772                 :             :   tl::optional<LangItem::Kind> lang_item;
     773                 :             :   tl::optional<PathIdentSegment> ident_segment;
     774                 :             :   location_t locus;
     775                 :             : 
     776                 :             : protected:
     777                 :             :   /* This is protected because it is only really used by derived classes, not
     778                 :             :    * the base. */
     779                 :             :   bool has_separating_scope_resolution;
     780                 :             :   NodeId node_id;
     781                 :             : 
     782                 :             : public:
     783                 :             :   // Clone function implementation - not pure virtual as overrided by
     784                 :             :   // subclasses
     785                 :       68811 :   virtual TypePathSegment *clone_type_path_segment_impl () const
     786                 :             :   {
     787                 :       68811 :     return new TypePathSegment (*this);
     788                 :             :   }
     789                 :          93 :   virtual TypePathSegment *reconstruct_impl () const
     790                 :             :   {
     791                 :         186 :     return new TypePathSegment (lang_item, ident_segment,
     792                 :          93 :                                 has_separating_scope_resolution, locus);
     793                 :             :   }
     794                 :             : 
     795                 :             : public:
     796                 :      144575 :   virtual ~TypePathSegment () {}
     797                 :             : 
     798                 :          75 :   virtual SegmentType get_type () const { return SegmentType::REG; }
     799                 :             : 
     800                 :             :   // Unique pointer custom clone function
     801                 :       70658 :   std::unique_ptr<TypePathSegment> clone_type_path_segment () const
     802                 :             :   {
     803                 :       70658 :     return std::unique_ptr<TypePathSegment> (clone_type_path_segment_impl ());
     804                 :             :   }
     805                 :             :   // Unique pointer custom reconstruct function
     806                 :           0 :   std::unique_ptr<TypePathSegment> reconstruct () const
     807                 :             :   {
     808                 :           0 :     return reconstruct_base (this);
     809                 :             :   }
     810                 :             : 
     811                 :      131196 :   TypePathSegment (PathIdentSegment ident_segment,
     812                 :             :                    bool has_separating_scope_resolution, location_t locus)
     813                 :      262392 :     : lang_item (tl::nullopt), ident_segment (std::move (ident_segment)),
     814                 :      131196 :       locus (locus),
     815                 :      131196 :       has_separating_scope_resolution (has_separating_scope_resolution),
     816                 :      131196 :       node_id (Analysis::Mappings::get ().get_next_node_id ())
     817                 :      131196 :   {}
     818                 :             : 
     819                 :         431 :   TypePathSegment (LangItem::Kind lang_item, location_t locus)
     820                 :         431 :     : lang_item (lang_item), ident_segment (tl::nullopt), locus (locus),
     821                 :         431 :       has_separating_scope_resolution (false),
     822                 :         431 :       node_id (Analysis::Mappings::get ().get_next_node_id ())
     823                 :         431 :   {}
     824                 :             : 
     825                 :        4369 :   TypePathSegment (std::string segment_name,
     826                 :             :                    bool has_separating_scope_resolution, location_t locus)
     827                 :        4369 :     : lang_item (tl::nullopt),
     828                 :        4369 :       ident_segment (PathIdentSegment (std::move (segment_name), locus)),
     829                 :        4369 :       locus (locus),
     830                 :        4369 :       has_separating_scope_resolution (has_separating_scope_resolution),
     831                 :        8738 :       node_id (Analysis::Mappings::get ().get_next_node_id ())
     832                 :        4369 :   {}
     833                 :             : 
     834                 :             :   // General constructor
     835                 :          93 :   TypePathSegment (tl::optional<LangItem::Kind> lang_item,
     836                 :             :                    tl::optional<PathIdentSegment> ident_segment,
     837                 :             :                    bool has_separating_scope_resolution, location_t locus)
     838                 :         186 :     : lang_item (lang_item), ident_segment (ident_segment), locus (locus),
     839                 :          93 :       has_separating_scope_resolution (has_separating_scope_resolution),
     840                 :          93 :       node_id (Analysis::Mappings::get ().get_next_node_id ())
     841                 :          93 :   {}
     842                 :             : 
     843                 :       71283 :   TypePathSegment (TypePathSegment const &other)
     844                 :      142566 :     : lang_item (other.lang_item), ident_segment (other.ident_segment),
     845                 :       71283 :       locus (other.locus),
     846                 :       71283 :       has_separating_scope_resolution (other.has_separating_scope_resolution),
     847                 :       71283 :       node_id (other.node_id)
     848                 :       71283 :   {}
     849                 :             : 
     850                 :             :   TypePathSegment &operator= (TypePathSegment const &other)
     851                 :             :   {
     852                 :             :     ident_segment = other.ident_segment;
     853                 :             :     lang_item = other.lang_item;
     854                 :             :     locus = other.locus;
     855                 :             :     has_separating_scope_resolution = other.has_separating_scope_resolution;
     856                 :             :     node_id = other.node_id;
     857                 :             : 
     858                 :             :     return *this;
     859                 :             :   }
     860                 :             : 
     861                 :             :   TypePathSegment (TypePathSegment &&other) = default;
     862                 :             :   TypePathSegment &operator= (TypePathSegment &&other) = default;
     863                 :             : 
     864                 :          58 :   virtual std::string as_string () const
     865                 :             :   {
     866                 :          58 :     if (lang_item.has_value ())
     867                 :           0 :       return LangItem::PrettyString (*lang_item);
     868                 :             : 
     869                 :          58 :     return ident_segment->as_string ();
     870                 :             :   }
     871                 :             : 
     872                 :             :   /* Returns whether the type path segment is in an error state. May be
     873                 :             :    * virtual in future. */
     874                 :          50 :   bool is_error () const
     875                 :             :   {
     876                 :          50 :     rust_assert (ident_segment);
     877                 :          50 :     return ident_segment->is_error ();
     878                 :             :   }
     879                 :             : 
     880                 :             :   /* Returns whether segment is identifier only (as opposed to generic args or
     881                 :             :    * function). Overridden in derived classes with other segments. */
     882                 :          29 :   virtual bool is_ident_only () const { return true; }
     883                 :             : 
     884                 :      169172 :   bool is_lang_item () const { return lang_item.has_value (); }
     885                 :             : 
     886                 :        3046 :   location_t get_locus () const { return locus; }
     887                 :             : 
     888                 :             :   // not pure virtual as class not abstract
     889                 :             :   virtual void accept_vis (ASTVisitor &vis);
     890                 :             : 
     891                 :       54384 :   bool get_separating_scope_resolution () const
     892                 :             :   {
     893                 :       54384 :     return has_separating_scope_resolution;
     894                 :             :   }
     895                 :             : 
     896                 :      116964 :   PathIdentSegment &get_ident_segment ()
     897                 :             :   {
     898                 :      116964 :     rust_assert (!is_lang_item ());
     899                 :      116964 :     return *ident_segment;
     900                 :             :   };
     901                 :             : 
     902                 :       51528 :   const PathIdentSegment &get_ident_segment () const
     903                 :             :   {
     904                 :       51528 :     rust_assert (!is_lang_item ());
     905                 :       51528 :     return *ident_segment;
     906                 :             :   };
     907                 :             : 
     908                 :         758 :   LangItem::Kind get_lang_item () const
     909                 :             :   {
     910                 :         758 :     rust_assert (is_lang_item ());
     911                 :         758 :     return *lang_item;
     912                 :             :   }
     913                 :             : 
     914                 :      109670 :   NodeId get_node_id () const { return node_id; }
     915                 :             : 
     916                 :           0 :   bool is_crate_path_seg () const
     917                 :             :   {
     918                 :           0 :     return get_ident_segment ().is_crate_path_seg ();
     919                 :             :   }
     920                 :           0 :   bool is_super_path_seg () const
     921                 :             :   {
     922                 :           0 :     return get_ident_segment ().is_super_path_seg ();
     923                 :             :   }
     924                 :       51526 :   bool is_big_self_seg () const
     925                 :             :   {
     926                 :       51526 :     return get_ident_segment ().is_big_self_seg ();
     927                 :             :   }
     928                 :           0 :   bool is_lower_self_seg () const
     929                 :             :   {
     930                 :           0 :     return get_ident_segment ().is_lower_self_seg ();
     931                 :             :   }
     932                 :             : };
     933                 :             : 
     934                 :             : // Segment used in type path with generic args
     935                 :             : class TypePathSegmentGeneric : public TypePathSegment
     936                 :             : {
     937                 :             :   GenericArgs generic_args;
     938                 :             : 
     939                 :             : public:
     940                 :          11 :   SegmentType get_type () const override { return SegmentType::GENERIC; }
     941                 :             : 
     942                 :      102398 :   bool has_generic_args () const { return generic_args.has_generic_args (); }
     943                 :             : 
     944                 :           0 :   bool is_ident_only () const override { return false; }
     945                 :             : 
     946                 :             :   // Constructor with PathIdentSegment and GenericArgs
     947                 :        2806 :   TypePathSegmentGeneric (PathIdentSegment ident_segment,
     948                 :             :                           bool has_separating_scope_resolution,
     949                 :             :                           GenericArgs generic_args, location_t locus)
     950                 :        2806 :     : TypePathSegment (std::move (ident_segment),
     951                 :             :                        has_separating_scope_resolution, locus),
     952                 :        2806 :       generic_args (std::move (generic_args))
     953                 :        2806 :   {}
     954                 :             : 
     955                 :          47 :   TypePathSegmentGeneric (LangItem::Kind lang_item, GenericArgs generic_args,
     956                 :             :                           location_t locus)
     957                 :          47 :     : TypePathSegment (lang_item, locus),
     958                 :          47 :       generic_args (std::move (generic_args))
     959                 :          47 :   {}
     960                 :             : 
     961                 :             :   // Constructor from segment name and all args
     962                 :             :   TypePathSegmentGeneric (std::string segment_name,
     963                 :             :                           bool has_separating_scope_resolution,
     964                 :             :                           std::vector<Lifetime> lifetime_args,
     965                 :             :                           std::vector<GenericArg> generic_args,
     966                 :             :                           std::vector<GenericArgsBinding> binding_args,
     967                 :             :                           location_t locus)
     968                 :             :     : TypePathSegment (std::move (segment_name),
     969                 :             :                        has_separating_scope_resolution, locus),
     970                 :             :       generic_args (GenericArgs (std::move (lifetime_args),
     971                 :             :                                  std::move (generic_args),
     972                 :             :                                  std::move (binding_args)))
     973                 :             :   {}
     974                 :             : 
     975                 :             :   // Copy constructor with vector clone
     976                 :        2472 :   TypePathSegmentGeneric (TypePathSegmentGeneric const &other)
     977                 :        2472 :     : TypePathSegment (other), generic_args (other.generic_args)
     978                 :        2472 :   {}
     979                 :             : 
     980                 :             :   // Overloaded assignment operator with vector clone
     981                 :             :   TypePathSegmentGeneric &operator= (TypePathSegmentGeneric const &other)
     982                 :             :   {
     983                 :             :     generic_args = other.generic_args;
     984                 :             : 
     985                 :             :     return *this;
     986                 :             :   }
     987                 :             : 
     988                 :             :   // move constructors
     989                 :             :   TypePathSegmentGeneric (TypePathSegmentGeneric &&other) = default;
     990                 :             :   TypePathSegmentGeneric &operator= (TypePathSegmentGeneric &&other) = default;
     991                 :             : 
     992                 :             :   std::string as_string () const override;
     993                 :             : 
     994                 :             :   void accept_vis (ASTVisitor &vis) override;
     995                 :             : 
     996                 :             :   // TODO: is this better? Or is a "vis_pattern" better?
     997                 :       54126 :   GenericArgs &get_generic_args () { return generic_args; }
     998                 :             : 
     999                 :             :   // Use covariance to override base class method
    1000                 :        2472 :   TypePathSegmentGeneric *clone_type_path_segment_impl () const override
    1001                 :             :   {
    1002                 :        2472 :     return new TypePathSegmentGeneric (*this);
    1003                 :             :   }
    1004                 :             : };
    1005                 :             : 
    1006                 :             : // A function as represented in a type path
    1007                 :             : struct TypePathFunction
    1008                 :             : {
    1009                 :             : private:
    1010                 :             :   // TODO: remove
    1011                 :             :   /*bool has_inputs;
    1012                 :             :   TypePathFnInputs inputs;*/
    1013                 :             :   // inlined from TypePathFnInputs
    1014                 :             :   std::vector<std::unique_ptr<Type>> inputs;
    1015                 :             : 
    1016                 :             :   // bool has_type;
    1017                 :             :   std::unique_ptr<Type> return_type;
    1018                 :             : 
    1019                 :             :   // FIXME: think of better way to mark as invalid than taking up storage
    1020                 :             :   bool is_invalid;
    1021                 :             : 
    1022                 :             :   location_t locus;
    1023                 :             : 
    1024                 :             : protected:
    1025                 :             :   // Constructor only used to create invalid type path functions.
    1026                 :           0 :   TypePathFunction (bool is_invalid, location_t locus)
    1027                 :           0 :     : is_invalid (is_invalid), locus (locus)
    1028                 :             :   {}
    1029                 :             : 
    1030                 :             : public:
    1031                 :             :   // Returns whether the return type of the function has been specified.
    1032                 :         552 :   bool has_return_type () const { return return_type != nullptr; }
    1033                 :             : 
    1034                 :             :   // Returns whether the function has inputs.
    1035                 :           5 :   bool has_inputs () const { return !inputs.empty (); }
    1036                 :             : 
    1037                 :             :   // Returns whether function is in an error state.
    1038                 :         582 :   bool is_error () const { return is_invalid; }
    1039                 :             : 
    1040                 :             :   // Creates an error state function.
    1041                 :           0 :   static TypePathFunction create_error ()
    1042                 :             :   {
    1043                 :           0 :     return TypePathFunction (true, UNDEF_LOCATION);
    1044                 :             :   }
    1045                 :             : 
    1046                 :             :   // Constructor
    1047                 :          30 :   TypePathFunction (std::vector<std::unique_ptr<Type>> inputs, location_t locus,
    1048                 :             :                     std::unique_ptr<Type> type = nullptr)
    1049                 :          30 :     : inputs (std::move (inputs)), return_type (std::move (type)),
    1050                 :          30 :       is_invalid (false), locus (locus)
    1051                 :             :   {}
    1052                 :             : 
    1053                 :             :   // Copy constructor with clone
    1054                 :           0 :   TypePathFunction (TypePathFunction const &other)
    1055                 :           0 :     : is_invalid (other.is_invalid)
    1056                 :             :   {
    1057                 :             :     // guard to protect from null pointer dereference
    1058                 :           0 :     if (other.return_type != nullptr)
    1059                 :           0 :       return_type = other.return_type->clone_type ();
    1060                 :             : 
    1061                 :           0 :     inputs.reserve (other.inputs.size ());
    1062                 :           0 :     for (const auto &e : other.inputs)
    1063                 :           0 :       inputs.push_back (e->clone_type ());
    1064                 :           0 :   }
    1065                 :             : 
    1066                 :          30 :   ~TypePathFunction () = default;
    1067                 :             : 
    1068                 :             :   // Overloaded assignment operator to clone type
    1069                 :             :   TypePathFunction &operator= (TypePathFunction const &other)
    1070                 :             :   {
    1071                 :             :     is_invalid = other.is_invalid;
    1072                 :             : 
    1073                 :             :     // guard to protect from null pointer dereference
    1074                 :             :     if (other.return_type != nullptr)
    1075                 :             :       return_type = other.return_type->clone_type ();
    1076                 :             :     else
    1077                 :             :       return_type = nullptr;
    1078                 :             : 
    1079                 :             :     inputs.reserve (other.inputs.size ());
    1080                 :             :     for (const auto &e : other.inputs)
    1081                 :             :       inputs.push_back (e->clone_type ());
    1082                 :             : 
    1083                 :             :     return *this;
    1084                 :             :   }
    1085                 :             : 
    1086                 :             :   // move constructors
    1087                 :          30 :   TypePathFunction (TypePathFunction &&other) = default;
    1088                 :             :   TypePathFunction &operator= (TypePathFunction &&other) = default;
    1089                 :             : 
    1090                 :             :   std::string as_string () const;
    1091                 :             : 
    1092                 :             :   // TODO: this mutable getter seems really dodgy. Think up better way.
    1093                 :             :   const std::vector<std::unique_ptr<Type>> &get_params () const
    1094                 :             :   {
    1095                 :             :     return inputs;
    1096                 :             :   }
    1097                 :         552 :   std::vector<std::unique_ptr<Type>> &get_params () { return inputs; }
    1098                 :             : 
    1099                 :             :   // TODO: is this better? Or is a "vis_pattern" better?
    1100                 :         462 :   Type &get_return_type ()
    1101                 :             :   {
    1102                 :         462 :     rust_assert (has_return_type ());
    1103                 :         462 :     return *return_type;
    1104                 :             :   }
    1105                 :             : 
    1106                 :          56 :   std::unique_ptr<Type> &get_return_type_ptr ()
    1107                 :             :   {
    1108                 :          56 :     rust_assert (has_return_type ());
    1109                 :          56 :     return return_type;
    1110                 :             :   }
    1111                 :             : 
    1112                 :           5 :   location_t get_locus () const { return locus; }
    1113                 :             : };
    1114                 :             : 
    1115                 :             : // Segment used in type path with a function argument
    1116                 :             : class TypePathSegmentFunction : public TypePathSegment
    1117                 :             : {
    1118                 :             :   TypePathFunction function_path;
    1119                 :             : 
    1120                 :             : public:
    1121                 :           7 :   SegmentType get_type () const override { return SegmentType::FUNCTION; }
    1122                 :             : 
    1123                 :             :   // Constructor with PathIdentSegment and TypePathFn
    1124                 :          30 :   TypePathSegmentFunction (PathIdentSegment ident_segment,
    1125                 :             :                            bool has_separating_scope_resolution,
    1126                 :             :                            TypePathFunction function_path, location_t locus)
    1127                 :          30 :     : TypePathSegment (std::move (ident_segment),
    1128                 :             :                        has_separating_scope_resolution, locus),
    1129                 :          30 :       function_path (std::move (function_path))
    1130                 :          30 :   {}
    1131                 :             : 
    1132                 :             :   // Constructor with segment name and TypePathFn
    1133                 :             :   TypePathSegmentFunction (std::string segment_name,
    1134                 :             :                            bool has_separating_scope_resolution,
    1135                 :             :                            TypePathFunction function_path, location_t locus)
    1136                 :             :     : TypePathSegment (std::move (segment_name),
    1137                 :             :                        has_separating_scope_resolution, locus),
    1138                 :             :       function_path (std::move (function_path))
    1139                 :             :   {}
    1140                 :             : 
    1141                 :             :   std::string as_string () const override;
    1142                 :             : 
    1143                 :           5 :   bool is_ident_only () const override { return false; }
    1144                 :             : 
    1145                 :             :   void accept_vis (ASTVisitor &vis) override;
    1146                 :             : 
    1147                 :             :   // TODO: is this better? Or is a "vis_pattern" better?
    1148                 :         552 :   TypePathFunction &get_type_path_function ()
    1149                 :             :   {
    1150                 :         552 :     rust_assert (!function_path.is_error ());
    1151                 :         552 :     return function_path;
    1152                 :             :   }
    1153                 :             : 
    1154                 :             :   // Use covariance to override base class method
    1155                 :           0 :   TypePathSegmentFunction *clone_type_path_segment_impl () const override
    1156                 :             :   {
    1157                 :           0 :     return new TypePathSegmentFunction (*this);
    1158                 :             :   }
    1159                 :             : };
    1160                 :             : 
    1161                 :       63343 : class TypePath : public TypeNoBounds
    1162                 :             : {
    1163                 :             :   bool has_opening_scope_resolution;
    1164                 :             :   std::vector<std::unique_ptr<TypePathSegment>> segments;
    1165                 :             :   location_t locus;
    1166                 :             : 
    1167                 :             : protected:
    1168                 :             :   /* Use covariance to implement clone function as returning this object
    1169                 :             :    * rather than base */
    1170                 :       50995 :   TypePath *clone_type_no_bounds_impl () const override
    1171                 :             :   {
    1172                 :       50995 :     return new TypePath (*this);
    1173                 :             :   }
    1174                 :          93 :   TypePath *reconstruct_impl () const override
    1175                 :             :   {
    1176                 :         465 :     return new TypePath (reconstruct_vec (segments), locus,
    1177                 :         186 :                          has_opening_scope_resolution);
    1178                 :             :   }
    1179                 :             : 
    1180                 :             : public:
    1181                 :             :   /* Returns whether the TypePath has an opening scope resolution operator
    1182                 :             :    * (i.e. is global path or crate-relative path, not module-relative) */
    1183                 :      108894 :   bool has_opening_scope_resolution_op () const
    1184                 :             :   {
    1185                 :      108894 :     return has_opening_scope_resolution;
    1186                 :             :   }
    1187                 :             : 
    1188                 :             :   // Returns whether the TypePath is in an invalid state.
    1189                 :       69031 :   bool is_error () const { return segments.empty (); }
    1190                 :             : 
    1191                 :             :   // Creates an error state TypePath.
    1192                 :         621 :   static TypePath create_error ()
    1193                 :             :   {
    1194                 :         621 :     return TypePath (std::vector<std::unique_ptr<TypePathSegment>> (),
    1195                 :         621 :                      UNDEF_LOCATION);
    1196                 :             :   }
    1197                 :             : 
    1198                 :             :   // Constructor
    1199                 :      134309 :   TypePath (std::vector<std::unique_ptr<TypePathSegment>> segments,
    1200                 :             :             location_t locus, bool has_opening_scope_resolution = false)
    1201                 :       80453 :     : TypeNoBounds (),
    1202                 :      134309 :       has_opening_scope_resolution (has_opening_scope_resolution),
    1203                 :      134309 :       segments (std::move (segments)), locus (locus)
    1204                 :             :   {}
    1205                 :             : 
    1206                 :           0 :   TypePath (LangItem::Kind lang_item,
    1207                 :             :             std::vector<std::unique_ptr<TypePathSegment>> segments,
    1208                 :             :             location_t locus, bool has_opening_scope_resolution = false)
    1209                 :           0 :     : TypeNoBounds (),
    1210                 :           0 :       has_opening_scope_resolution (has_opening_scope_resolution),
    1211                 :           0 :       segments (std::move (segments)), locus (locus)
    1212                 :             :   {}
    1213                 :             : 
    1214                 :             :   // Copy constructor with vector clone
    1215                 :       68414 :   TypePath (TypePath const &other)
    1216                 :      136828 :     : has_opening_scope_resolution (other.has_opening_scope_resolution),
    1217                 :       68414 :       locus (other.locus)
    1218                 :             :   {
    1219                 :       68414 :     node_id = other.node_id;
    1220                 :       68414 :     segments.reserve (other.segments.size ());
    1221                 :      139072 :     for (const auto &e : other.segments)
    1222                 :       70658 :       segments.push_back (e->clone_type_path_segment ());
    1223                 :       68414 :   }
    1224                 :             : 
    1225                 :             :   // Overloaded assignment operator with clone
    1226                 :             :   TypePath &operator= (TypePath const &other)
    1227                 :             :   {
    1228                 :             :     node_id = other.node_id;
    1229                 :             :     has_opening_scope_resolution = other.has_opening_scope_resolution;
    1230                 :             :     locus = other.locus;
    1231                 :             : 
    1232                 :             :     segments.reserve (other.segments.size ());
    1233                 :             :     for (const auto &e : other.segments)
    1234                 :             :       segments.push_back (e->clone_type_path_segment ());
    1235                 :             : 
    1236                 :             :     return *this;
    1237                 :             :   }
    1238                 :             : 
    1239                 :             :   // move constructors
    1240                 :       52398 :   TypePath (TypePath &&other) = default;
    1241                 :         423 :   TypePath &operator= (TypePath &&other) = default;
    1242                 :             : 
    1243                 :             :   std::string as_string () const override;
    1244                 :             : 
    1245                 :             :   std::string make_debug_string () const;
    1246                 :             : 
    1247                 :             :   /* Converts TypePath to SimplePath if possible (i.e. no generic or function
    1248                 :             :    * arguments). Otherwise returns an empty SimplePath. */
    1249                 :             :   SimplePath as_simple_path () const;
    1250                 :             : 
    1251                 :             :   // Creates a trait bound with a clone of this type path as its only element.
    1252                 :             :   TraitBound *to_trait_bound (bool in_parens) const override;
    1253                 :             : 
    1254                 :       97410 :   location_t get_locus () const override final { return locus; }
    1255                 :      470675 :   NodeId get_node_id () const { return node_id; }
    1256                 :             : 
    1257                 :           0 :   void mark_for_strip () override {}
    1258                 :      244164 :   bool is_marked_for_strip () const override { return false; }
    1259                 :             : 
    1260                 :             :   void accept_vis (ASTVisitor &vis) override;
    1261                 :             : 
    1262                 :             :   // TODO: this seems kinda dodgy
    1263                 :        3055 :   std::vector<std::unique_ptr<TypePathSegment>> &get_segments ()
    1264                 :             :   {
    1265                 :     1094364 :     return segments;
    1266                 :             :   }
    1267                 :       53334 :   const std::vector<std::unique_ptr<TypePathSegment>> &get_segments () const
    1268                 :             :   {
    1269                 :       53336 :     return segments;
    1270                 :             :   }
    1271                 :             : 
    1272                 :             :   size_t get_num_segments () const { return segments.size (); }
    1273                 :             : };
    1274                 :             : 
    1275                 :             : struct QualifiedPathType
    1276                 :             : {
    1277                 :             : private:
    1278                 :             :   std::unique_ptr<Type> type_to_invoke_on;
    1279                 :             :   TypePath trait_path;
    1280                 :             :   location_t locus;
    1281                 :             :   NodeId node_id;
    1282                 :             : 
    1283                 :             : public:
    1284                 :             :   // Constructor
    1285                 :         437 :   QualifiedPathType (std::unique_ptr<Type> invoke_on_type,
    1286                 :             :                      location_t locus = UNDEF_LOCATION,
    1287                 :             :                      TypePath trait_path = TypePath::create_error ())
    1288                 :         437 :     : type_to_invoke_on (std::move (invoke_on_type)), trait_path (trait_path),
    1289                 :         437 :       locus (locus), node_id (Analysis::Mappings::get ().get_next_node_id ())
    1290                 :         437 :   {}
    1291                 :             : 
    1292                 :             :   // Copy constructor uses custom deep copy for Type to preserve polymorphism
    1293                 :         738 :   QualifiedPathType (QualifiedPathType const &other)
    1294                 :         738 :     : trait_path (other.trait_path), locus (other.locus)
    1295                 :             :   {
    1296                 :         738 :     node_id = other.node_id;
    1297                 :             :     // guard to prevent null dereference
    1298                 :         738 :     if (other.type_to_invoke_on != nullptr)
    1299                 :         738 :       type_to_invoke_on = other.type_to_invoke_on->clone_type ();
    1300                 :         738 :   }
    1301                 :             : 
    1302                 :             :   // default destructor
    1303                 :        2065 :   ~QualifiedPathType () = default;
    1304                 :             : 
    1305                 :             :   // overload assignment operator to use custom clone method
    1306                 :             :   QualifiedPathType &operator= (QualifiedPathType const &other)
    1307                 :             :   {
    1308                 :             :     node_id = other.node_id;
    1309                 :             :     trait_path = other.trait_path;
    1310                 :             :     locus = other.locus;
    1311                 :             : 
    1312                 :             :     // guard to prevent null dereference
    1313                 :             :     if (other.type_to_invoke_on != nullptr)
    1314                 :             :       type_to_invoke_on = other.type_to_invoke_on->clone_type ();
    1315                 :             :     else
    1316                 :             :       type_to_invoke_on = nullptr;
    1317                 :             : 
    1318                 :             :     return *this;
    1319                 :             :   }
    1320                 :             : 
    1321                 :             :   // move constructor
    1322                 :        1277 :   QualifiedPathType (QualifiedPathType &&other) = default;
    1323                 :           0 :   QualifiedPathType &operator= (QualifiedPathType &&other) = default;
    1324                 :             : 
    1325                 :             :   // Returns whether the qualified path type has a rebind as clause.
    1326                 :        9218 :   bool has_as_clause () const { return !trait_path.is_error (); }
    1327                 :             : 
    1328                 :             :   // Returns whether the qualified path type is in an error state.
    1329                 :       10164 :   bool is_error () const { return type_to_invoke_on == nullptr; }
    1330                 :             : 
    1331                 :             :   // Creates an error state qualified path type.
    1332                 :           0 :   static QualifiedPathType create_error ()
    1333                 :             :   {
    1334                 :           0 :     return QualifiedPathType (nullptr);
    1335                 :             :   }
    1336                 :             : 
    1337                 :             :   std::string as_string () const;
    1338                 :             : 
    1339                 :         503 :   location_t get_locus () const { return locus; }
    1340                 :             : 
    1341                 :             :   // TODO: is this better? Or is a "vis_pattern" better?
    1342                 :        8254 :   Type &get_type ()
    1343                 :             :   {
    1344                 :        8254 :     rust_assert (type_to_invoke_on != nullptr);
    1345                 :        8254 :     return *type_to_invoke_on;
    1346                 :             :   }
    1347                 :             : 
    1348                 :         964 :   std::unique_ptr<Type> &get_type_ptr ()
    1349                 :             :   {
    1350                 :         964 :     rust_assert (type_to_invoke_on != nullptr);
    1351                 :         964 :     return type_to_invoke_on;
    1352                 :             :   }
    1353                 :             : 
    1354                 :             :   // TODO: is this better? Or is a "vis_pattern" better?
    1355                 :        8326 :   TypePath &get_as_type_path ()
    1356                 :             :   {
    1357                 :        8326 :     rust_assert (has_as_clause ());
    1358                 :        8326 :     return trait_path;
    1359                 :             :   }
    1360                 :             : 
    1361                 :         349 :   NodeId get_node_id () const { return node_id; }
    1362                 :             : };
    1363                 :             : 
    1364                 :             : /* AST node representing a qualified path-in-expression pattern (path that
    1365                 :             :  * allows specifying trait functions) */
    1366                 :             : class QualifiedPathInExpression : public Path, public ExprWithoutBlock
    1367                 :             : {
    1368                 :             :   std::vector<Attribute> outer_attrs;
    1369                 :             :   QualifiedPathType path_type;
    1370                 :             :   location_t locus;
    1371                 :             :   NodeId _node_id;
    1372                 :             : 
    1373                 :             : public:
    1374                 :             :   std::string as_string () const override;
    1375                 :             : 
    1376                 :         114 :   QualifiedPathInExpression (QualifiedPathType qual_path_type,
    1377                 :             :                              std::vector<PathExprSegment> path_segments,
    1378                 :             :                              std::vector<Attribute> outer_attrs,
    1379                 :             :                              location_t locus)
    1380                 :         228 :     : Path (std::move (path_segments)), outer_attrs (std::move (outer_attrs)),
    1381                 :         114 :       path_type (std::move (qual_path_type)), locus (locus),
    1382                 :         114 :       _node_id (Analysis::Mappings::get ().get_next_node_id ())
    1383                 :         114 :   {}
    1384                 :             : 
    1385                 :             :   /* TODO: maybe make a shortcut constructor that has QualifiedPathType
    1386                 :             :    * elements as params */
    1387                 :             : 
    1388                 :             :   // Returns whether qualified path in expression is in an error state.
    1389                 :         526 :   bool is_error () const { return path_type.is_error (); }
    1390                 :             : 
    1391                 :             :   // Creates an error qualified path in expression.
    1392                 :           0 :   static QualifiedPathInExpression create_error ()
    1393                 :             :   {
    1394                 :           0 :     return QualifiedPathInExpression (QualifiedPathType::create_error (), {},
    1395                 :           0 :                                       {}, UNDEF_LOCATION);
    1396                 :             :   }
    1397                 :             : 
    1398                 :         310 :   location_t get_locus () const override final { return locus; }
    1399                 :             : 
    1400                 :             :   void accept_vis (ASTVisitor &vis) override;
    1401                 :             : 
    1402                 :             :   // Invalid if path_type is error, so base stripping on that.
    1403                 :           0 :   void mark_for_strip () override
    1404                 :             :   {
    1405                 :           0 :     path_type = QualifiedPathType::create_error ();
    1406                 :           0 :   }
    1407                 :         526 :   bool is_marked_for_strip () const override { return is_error (); }
    1408                 :             : 
    1409                 :             :   // TODO: is this better? Or is a "vis_pattern" better?
    1410                 :        2606 :   QualifiedPathType &get_qualified_path_type ()
    1411                 :             :   {
    1412                 :        2606 :     rust_assert (!path_type.is_error ());
    1413                 :        2606 :     return path_type;
    1414                 :             :   }
    1415                 :             : 
    1416                 :             :   const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
    1417                 :        2840 :   std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
    1418                 :             : 
    1419                 :          97 :   void set_outer_attrs (std::vector<Attribute> new_attrs) override
    1420                 :             :   {
    1421                 :          97 :     outer_attrs = std::move (new_attrs);
    1422                 :           0 :   }
    1423                 :             : 
    1424                 :         114 :   NodeId get_node_id () const override { return _node_id; }
    1425                 :             : 
    1426                 :          99 :   Expr::Kind get_expr_kind () const override
    1427                 :             :   {
    1428                 :          99 :     return Expr::Kind::QualifiedPathInExpression;
    1429                 :             :   }
    1430                 :             : 
    1431                 :             : protected:
    1432                 :             :   /* Use covariance to implement clone function as returning this object
    1433                 :             :    * rather than base */
    1434                 :           0 :   QualifiedPathInExpression *clone_pattern_impl () const final override
    1435                 :             :   {
    1436                 :           0 :     return clone_qual_path_in_expression_impl ();
    1437                 :             :   }
    1438                 :             : 
    1439                 :             :   /* Use covariance to implement clone function as returning this object
    1440                 :             :    * rather than base */
    1441                 :             :   QualifiedPathInExpression *
    1442                 :           0 :   clone_expr_without_block_impl () const final override
    1443                 :             :   {
    1444                 :           0 :     return clone_qual_path_in_expression_impl ();
    1445                 :             :   }
    1446                 :             : 
    1447                 :             :   /*virtual*/ QualifiedPathInExpression *
    1448                 :          96 :   clone_qual_path_in_expression_impl () const
    1449                 :             :   {
    1450                 :          96 :     return new QualifiedPathInExpression (*this);
    1451                 :             :   }
    1452                 :             : };
    1453                 :             : 
    1454                 :             : /* Represents a qualified path in a type; used for disambiguating trait
    1455                 :             :  * function calls */
    1456                 :             : class QualifiedPathInType : public TypeNoBounds
    1457                 :             : {
    1458                 :             :   QualifiedPathType path_type;
    1459                 :             :   std::unique_ptr<TypePathSegment> associated_segment;
    1460                 :             :   std::vector<std::unique_ptr<TypePathSegment>> segments;
    1461                 :             :   location_t locus;
    1462                 :             : 
    1463                 :             : protected:
    1464                 :             :   /* Use covariance to implement clone function as returning this object
    1465                 :             :    * rather than base */
    1466                 :         625 :   QualifiedPathInType *clone_type_no_bounds_impl () const override
    1467                 :             :   {
    1468                 :         625 :     return new QualifiedPathInType (*this);
    1469                 :             :   }
    1470                 :           0 :   QualifiedPathInType *reconstruct_impl () const override
    1471                 :             :   {
    1472                 :           0 :     return new QualifiedPathInType (path_type,
    1473                 :           0 :                                     associated_segment->reconstruct (),
    1474                 :           0 :                                     reconstruct_vec (segments), locus);
    1475                 :             :   }
    1476                 :             : 
    1477                 :             : public:
    1478                 :         323 :   QualifiedPathInType (
    1479                 :             :     QualifiedPathType qual_path_type,
    1480                 :             :     std::unique_ptr<TypePathSegment> associated_segment,
    1481                 :             :     std::vector<std::unique_ptr<TypePathSegment>> path_segments,
    1482                 :             :     location_t locus)
    1483                 :         646 :     : path_type (std::move (qual_path_type)),
    1484                 :         323 :       associated_segment (std::move (associated_segment)),
    1485                 :         323 :       segments (std::move (path_segments)), locus (locus)
    1486                 :         323 :   {}
    1487                 :             : 
    1488                 :             :   // Copy constructor with vector clone
    1489                 :         625 :   QualifiedPathInType (QualifiedPathInType const &other)
    1490                 :         625 :     : path_type (other.path_type), locus (other.locus)
    1491                 :             :   {
    1492                 :         625 :     auto seg = other.associated_segment->clone_type_path_segment_impl ();
    1493                 :         625 :     associated_segment = std::unique_ptr<TypePathSegment> (seg);
    1494                 :             : 
    1495                 :         625 :     segments.reserve (other.segments.size ());
    1496                 :         625 :     for (const auto &e : other.segments)
    1497                 :           0 :       segments.push_back (e->clone_type_path_segment ());
    1498                 :         625 :   }
    1499                 :             : 
    1500                 :             :   // Overloaded assignment operator with vector clone
    1501                 :             :   QualifiedPathInType &operator= (QualifiedPathInType const &other)
    1502                 :             :   {
    1503                 :             :     auto seg = other.associated_segment->clone_type_path_segment_impl ();
    1504                 :             :     associated_segment = std::unique_ptr<TypePathSegment> (seg);
    1505                 :             : 
    1506                 :             :     path_type = other.path_type;
    1507                 :             :     locus = other.locus;
    1508                 :             : 
    1509                 :             :     segments.reserve (other.segments.size ());
    1510                 :             :     for (const auto &e : other.segments)
    1511                 :             :       segments.push_back (e->clone_type_path_segment ());
    1512                 :             : 
    1513                 :             :     return *this;
    1514                 :             :   }
    1515                 :             : 
    1516                 :             :   // move constructors
    1517                 :         323 :   QualifiedPathInType (QualifiedPathInType &&other) = default;
    1518                 :             :   QualifiedPathInType &operator= (QualifiedPathInType &&other) = default;
    1519                 :             : 
    1520                 :             :   // Returns whether qualified path in type is in an error state.
    1521                 :         323 :   bool is_error () const { return path_type.is_error (); }
    1522                 :             : 
    1523                 :             :   // Creates an error state qualified path in type.
    1524                 :           0 :   static QualifiedPathInType create_error ()
    1525                 :             :   {
    1526                 :           0 :     return QualifiedPathInType (
    1527                 :           0 :       QualifiedPathType::create_error (), nullptr,
    1528                 :           0 :       std::vector<std::unique_ptr<TypePathSegment>> (), UNDEF_LOCATION);
    1529                 :             :   }
    1530                 :             : 
    1531                 :             :   std::string as_string () const override;
    1532                 :             : 
    1533                 :             :   void accept_vis (ASTVisitor &vis) override;
    1534                 :             : 
    1535                 :             :   // TODO: is this better? Or is a "vis_pattern" better?
    1536                 :        7317 :   QualifiedPathType &get_qualified_path_type ()
    1537                 :             :   {
    1538                 :        7317 :     rust_assert (!path_type.is_error ());
    1539                 :        7317 :     return path_type;
    1540                 :             :   }
    1541                 :             : 
    1542                 :             :   std::unique_ptr<TypePathSegment> &get_associated_segment ()
    1543                 :             :   {
    1544                 :        4678 :     return associated_segment;
    1545                 :             :   }
    1546                 :             : 
    1547                 :             :   // TODO: this seems kinda dodgy
    1548                 :             :   std::vector<std::unique_ptr<TypePathSegment>> &get_segments ()
    1549                 :             :   {
    1550                 :        5373 :     return segments;
    1551                 :             :   }
    1552                 :             :   const std::vector<std::unique_ptr<TypePathSegment>> &get_segments () const
    1553                 :             :   {
    1554                 :             :     return segments;
    1555                 :             :   }
    1556                 :             : 
    1557                 :         241 :   location_t get_locus () const override final { return locus; }
    1558                 :             : };
    1559                 :             : } // namespace AST
    1560                 :             : } // namespace Rust
    1561                 :             : 
    1562                 :             : #endif
        

Generated by: LCOV version 2.1-beta

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