LCOV - code coverage report
Current view: top level - gcc/rust/hir/tree - rust-hir-path.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 84.9 % 166 141
Test Date: 2026-08-22 16:33:35 Functions: 83.3 % 48 40
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Copyright (C) 2020-2026 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_HIR_PATH_H
      20              : #define RUST_HIR_PATH_H
      21              : 
      22              : #include "rust-hir-map.h"
      23              : #include "rust-hir-simple-path.h"
      24              : #include "rust-hir-type-no-bounds.h"
      25              : #include "rust-hir-pattern-abstract.h"
      26              : #include "rust-hir-expr-abstract.h"
      27              : 
      28              : namespace Rust {
      29              : namespace HIR {
      30              : 
      31              : // The "identifier" (not generic args) aspect of each path expression segment
      32       167599 : class PathIdentSegment
      33              : {
      34              :   std::string segment_name;
      35              : 
      36              :   // TODO: should this have location info stored?
      37              : 
      38              :   // only allow identifiers, "super", "self", "Self", "crate", or "$crate"
      39              : public:
      40       146999 :   PathIdentSegment (std::string segment_name)
      41       137910 :     : segment_name (std::move (segment_name))
      42              :   {}
      43              : 
      44       382528 :   PathIdentSegment (const PathIdentSegment &other)
      45       705625 :     : segment_name (other.segment_name)
      46              :   {}
      47              : 
      48            0 :   PathIdentSegment &operator= (PathIdentSegment const &other)
      49              :   {
      50            0 :     segment_name = other.segment_name;
      51            0 :     return *this;
      52              :   }
      53              : 
      54              :   // Creates an error PathIdentSegment.
      55         9089 :   static PathIdentSegment create_error () { return PathIdentSegment (""); }
      56              : 
      57              :   // Returns whether PathIdentSegment is in an error state.
      58        14725 :   bool is_error () const { return segment_name.empty (); }
      59              : 
      60       652939 :   std::string to_string () const { return segment_name; }
      61              : };
      62              : 
      63              : // A binding of an identifier to a type used in generic arguments in paths
      64              : class GenericArgsBinding
      65              : {
      66              :   Identifier identifier;
      67              :   std::unique_ptr<Type> type;
      68              : 
      69              :   location_t locus;
      70              : 
      71              : public:
      72              :   // Returns whether binding is in an error state.
      73              :   bool is_error () const
      74              :   {
      75              :     return type == nullptr;
      76              :     // and also identifier is empty, but cheaper computation
      77              :   }
      78              : 
      79              :   // Creates an error state generic args binding.
      80              :   static GenericArgsBinding create_error ()
      81              :   {
      82              :     return GenericArgsBinding ({""}, nullptr);
      83              :   }
      84              : 
      85              :   // Pointer type for type in constructor to enable polymorphism
      86              :   GenericArgsBinding (Identifier ident, std::unique_ptr<Type> type_ptr,
      87              :                       location_t locus = UNDEF_LOCATION);
      88              : 
      89              :   // Copy constructor has to deep copy the type as it is a unique pointer
      90              :   GenericArgsBinding (GenericArgsBinding const &other);
      91              : 
      92              :   // default destructor
      93          312 :   ~GenericArgsBinding () = default;
      94              : 
      95              :   // Overload assignment operator to deep copy the pointed-to type
      96              :   GenericArgsBinding &operator= (GenericArgsBinding const &other);
      97              : 
      98              :   // move constructors
      99           72 :   GenericArgsBinding (GenericArgsBinding &&other) = default;
     100              :   GenericArgsBinding &operator= (GenericArgsBinding &&other) = default;
     101              : 
     102              :   std::string to_string () const;
     103              : 
     104              :   Identifier &get_identifier () { return identifier; }
     105              :   const Identifier &get_identifier () const { return identifier; }
     106              : 
     107          162 :   Type &get_type ()
     108              :   {
     109          162 :     rust_assert (type);
     110          162 :     return *type;
     111              :   }
     112              :   const Type &get_type () const
     113              :   {
     114              :     rust_assert (type);
     115              :     return *type;
     116              :   }
     117              : 
     118            3 :   location_t get_locus () const { return locus; }
     119              : };
     120              : 
     121          201 : class ConstGenericArg
     122              : {
     123              :   // FIXME: Do we need to disambiguate or no? We should be able to disambiguate
     124              :   // at name-resolution, hence no need for ambiguities here
     125              : 
     126              : public:
     127              :   ConstGenericArg (std::unique_ptr<Expr> expression, location_t locus);
     128              : 
     129              :   ConstGenericArg (const ConstGenericArg &other);
     130              : 
     131              :   ConstGenericArg operator= (const ConstGenericArg &other);
     132              : 
     133          153 :   std::unique_ptr<Expr> &get_expression () { return expression; }
     134              : 
     135          118 :   location_t get_locus () const { return locus; }
     136              : 
     137              : private:
     138              :   std::unique_ptr<Expr> expression;
     139              :   location_t locus;
     140              : };
     141              : 
     142              : class GenericArgs
     143              : {
     144              :   std::vector<Lifetime> lifetime_args;
     145              :   std::vector<std::unique_ptr<Type> > type_args;
     146              :   std::vector<GenericArgsBinding> binding_args;
     147              :   std::vector<ConstGenericArg> const_args;
     148              :   location_t locus;
     149              : 
     150              : public:
     151              :   // Returns true if there are any generic arguments
     152       116207 :   bool has_generic_args () const
     153              :   {
     154       227745 :     return !(lifetime_args.empty () && type_args.empty ()
     155       111674 :              && binding_args.empty () && const_args.empty ());
     156              :   }
     157              : 
     158              :   GenericArgs (std::vector<Lifetime> lifetime_args,
     159              :                std::vector<std::unique_ptr<Type> > type_args,
     160              :                std::vector<GenericArgsBinding> binding_args,
     161              :                std::vector<ConstGenericArg> const_args, location_t locus);
     162              : 
     163              :   // copy constructor with vector clone
     164              :   GenericArgs (GenericArgs const &other);
     165              : 
     166       233979 :   ~GenericArgs () = default;
     167              : 
     168              :   // overloaded assignment operator to vector clone
     169              :   GenericArgs &operator= (GenericArgs const &other);
     170              : 
     171              :   // move constructors
     172       104485 :   GenericArgs (GenericArgs &&other) = default;
     173         6074 :   GenericArgs &operator= (GenericArgs &&other) = default;
     174              : 
     175              :   // Creates an empty GenericArgs (no arguments)
     176        69689 :   static GenericArgs create_empty (location_t locus = UNDEF_LOCATION)
     177              :   {
     178        69689 :     return GenericArgs ({}, {}, {}, {}, locus);
     179              :   }
     180              : 
     181              :   bool is_empty () const;
     182              : 
     183              :   std::string to_string () const;
     184              : 
     185         8412 :   std::vector<Lifetime> &get_lifetime_args () { return lifetime_args; }
     186              :   const std::vector<Lifetime> &get_lifetime_args () const
     187              :   {
     188         9413 :     return lifetime_args;
     189              :   }
     190              : 
     191        12508 :   std::vector<std::unique_ptr<Type> > &get_type_args () { return type_args; }
     192              : 
     193         8490 :   std::vector<GenericArgsBinding> &get_binding_args () { return binding_args; }
     194              : 
     195        17837 :   std::vector<ConstGenericArg> &get_const_args () { return const_args; }
     196              : 
     197        16652 :   location_t get_locus () const { return locus; }
     198              : };
     199              : 
     200              : /* A segment of a path in expression, including an identifier aspect and maybe
     201              :  * generic args */
     202       151125 : class PathExprSegment
     203              : {
     204              : private:
     205              :   Analysis::NodeMapping mappings;
     206              :   PathIdentSegment segment_name;
     207              :   GenericArgs generic_args;
     208              :   location_t locus;
     209              : 
     210              : public:
     211              :   PathExprSegment (Analysis::NodeMapping mappings,
     212              :                    PathIdentSegment segment_name, location_t locus,
     213              :                    GenericArgs generic_args);
     214              : 
     215              :   PathExprSegment (PathExprSegment const &other);
     216              : 
     217              :   PathExprSegment &operator= (PathExprSegment const &other);
     218              : 
     219              :   // move constructors
     220        76548 :   PathExprSegment (PathExprSegment &&other) = default;
     221              :   PathExprSegment &operator= (PathExprSegment &&other) = default;
     222              : 
     223              :   std::string to_string () const;
     224              : 
     225        41516 :   location_t get_locus () const { return locus; }
     226              : 
     227        47693 :   PathIdentSegment &get_segment () { return segment_name; }
     228        43732 :   const PathIdentSegment &get_segment () const { return segment_name; }
     229              : 
     230              :   GenericArgs &get_generic_args () { return generic_args; }
     231              : 
     232       156675 :   const Analysis::NodeMapping &get_mappings () const { return mappings; }
     233              : 
     234       112975 :   bool has_generic_args () const { return generic_args.has_generic_args (); }
     235              : };
     236              : 
     237              : // HIR node representing a pattern that involves a "path" - abstract base class
     238              : class PathPattern : public Pattern
     239              : {
     240              : public:
     241              :   enum class Kind
     242              :   {
     243              :     Segmented,
     244              :     LangItem
     245              :   };
     246              : 
     247              : private:
     248              :   std::vector<PathExprSegment> segments;
     249              :   tl::optional<LangItem::Kind> lang_item;
     250              :   Kind kind;
     251              : 
     252              : protected:
     253        51147 :   PathPattern (std::vector<PathExprSegment> segments)
     254        51147 :     : segments (std::move (segments)), lang_item (tl::nullopt),
     255        51147 :       kind (Kind::Segmented)
     256        51147 :   {}
     257              : 
     258          151 :   PathPattern (LangItem::Kind lang_item)
     259          151 :     : segments ({}), lang_item (lang_item), kind (Kind::LangItem)
     260          151 :   {}
     261              :   bool is_refutable (const TyTy::BaseType &scrutinee) const override;
     262            0 :   bool is_refutable () const override
     263              :   {
     264              :     // Needs to be called with the other overload
     265            0 :     rust_unreachable ();
     266              :   }
     267              : 
     268              :   // Returns whether path has segments.
     269            5 :   bool has_segments () const
     270              :   {
     271            5 :     rust_assert (kind == Kind::Segmented);
     272            5 :     return !segments.empty ();
     273              :   }
     274              : 
     275              :   /* Converts path segments to their equivalent SimplePath segments if possible,
     276              :    * and creates a SimplePath from them. */
     277              :   AST::SimplePath
     278              :   convert_to_simple_path (bool with_opening_scope_resolution) const;
     279              : 
     280              : public:
     281              :   /* Returns whether the path is a single segment (excluding qualified path
     282              :    * initial as segment). */
     283            0 :   bool is_single_segment () const
     284              :   {
     285            0 :     rust_assert (kind == Kind::Segmented);
     286            0 :     return segments.size () == 1;
     287              :   }
     288              : 
     289              :   std::string to_string () const override;
     290              : 
     291              :   void iterate_path_segments (std::function<bool (PathExprSegment &)> cb);
     292              : 
     293       109363 :   size_t get_num_segments () const
     294              :   {
     295       109363 :     rust_assert (kind == Kind::Segmented);
     296       109363 :     return segments.size ();
     297              :   }
     298              : 
     299       111151 :   std::vector<PathExprSegment> &get_segments ()
     300              :   {
     301       111151 :     rust_assert (kind == Kind::Segmented);
     302       111151 :     return segments;
     303              :   }
     304              : 
     305              :   const std::vector<PathExprSegment> &get_segments () const
     306              :   {
     307              :     rust_assert (kind == Kind::Segmented);
     308              :     return segments;
     309              :   }
     310              : 
     311              :   PathExprSegment &get_root_seg ()
     312              :   {
     313              :     rust_assert (kind == Kind::Segmented);
     314              :     return segments.at (0);
     315              :   }
     316              : 
     317        43741 :   const PathExprSegment &get_final_segment () const
     318              :   {
     319        43741 :     rust_assert (kind == Kind::Segmented);
     320        43741 :     return segments.back ();
     321              :   }
     322              : 
     323          423 :   LangItem::Kind get_lang_item () const
     324              :   {
     325          423 :     rust_assert (kind == Kind::LangItem);
     326              : 
     327          423 :     return *lang_item;
     328              :   }
     329              : 
     330          768 :   PatternType get_pattern_type () const override final
     331              :   {
     332          768 :     return PatternType::PATH;
     333              :   }
     334              : 
     335       186873 :   bool is_lang_item () const { return kind == Kind::LangItem; }
     336              : 
     337            0 :   Kind get_path_kind () const { return kind; }
     338              : };
     339              : 
     340              : /* HIR node representing a path-in-expression pattern (path that allows generic
     341              :  * arguments) */
     342              : class PathInExpression : public PathPattern, public PathExpr
     343              : {
     344              :   bool has_opening_scope_resolution;
     345              :   location_t locus;
     346              : 
     347              : public:
     348              :   std::string to_string () const override;
     349              : 
     350              :   // Constructor
     351              :   PathInExpression (Analysis::NodeMapping mappings,
     352              :                     std::vector<PathExprSegment> path_segments,
     353              :                     location_t locus = UNDEF_LOCATION,
     354              :                     bool has_opening_scope_resolution = false,
     355              :                     std::vector<AST::Attribute> outer_attrs
     356              :                     = std::vector<AST::Attribute> ());
     357              : 
     358              :   // lang-item Constructor
     359              :   PathInExpression (Analysis::NodeMapping mappings, LangItem::Kind kind,
     360              :                     location_t locus = UNDEF_LOCATION,
     361              :                     bool has_opening_scope_resolution = false,
     362              :                     std::vector<AST::Attribute> outer_attrs
     363              :                     = std::vector<AST::Attribute> ());
     364              : 
     365              :   // Creates an error state path in expression.
     366              :   static PathInExpression create_error ()
     367              :   {
     368              :     return PathInExpression (Analysis::NodeMapping::get_error (),
     369              :                              std::vector<PathExprSegment> ());
     370              :   }
     371              : 
     372              :   // Returns whether path in expression is in an error state.
     373              :   bool is_error () const { return !has_segments (); }
     374              : 
     375              :   /* Converts PathInExpression to SimplePath if possible (i.e. no generic
     376              :    * arguments). Otherwise returns an empty SimplePath. */
     377            5 :   AST::SimplePath as_simple_path () const
     378              :   {
     379              :     /* delegate to parent class as can't access segments. however,
     380              :      * QualifiedPathInExpression conversion to simple path wouldn't make sense,
     381              :      * so the method in the parent class should be protected, not public. Have
     382              :      * to pass in opening scope resolution as parent class has no access to it.
     383              :      */
     384            5 :     return convert_to_simple_path (has_opening_scope_resolution);
     385              :   }
     386              : 
     387       219458 :   location_t get_locus () const override final { return locus; }
     388              : 
     389              :   void accept_vis (HIRFullVisitor &vis) override;
     390              :   void accept_vis (HIRExpressionVisitor &vis) override;
     391              :   void accept_vis (HIRPatternVisitor &vis) override;
     392              : 
     393            0 :   bool opening_scope_resolution () { return has_opening_scope_resolution; }
     394              : 
     395              :   bool is_self () const;
     396              : 
     397       180883 :   const Analysis::NodeMapping &get_mappings () const override final
     398              :   {
     399       180883 :     return mappings;
     400              :   }
     401              : 
     402              : protected:
     403              :   /* Use covariance to implement clone function as returning this object rather
     404              :    * than base */
     405         1981 :   PathInExpression *clone_pattern_impl () const override
     406              :   {
     407         1981 :     return new PathInExpression (*this);
     408              :   }
     409              : 
     410              :   /* Use covariance to implement clone function as returning this object rather
     411              :    * than base */
     412          826 :   PathInExpression *clone_expr_without_block_impl () const override
     413              :   {
     414          826 :     return new PathInExpression (*this);
     415              :   }
     416              : };
     417              : 
     418              : /* Base class for segments used in type paths - not abstract (represents an
     419              :  * ident-only segment) */
     420              : class TypePathSegment
     421              : {
     422              : public:
     423              :   enum SegmentType
     424              :   {
     425              :     REG,
     426              :     GENERIC,
     427              :     FUNCTION
     428              :   };
     429              : 
     430              : private:
     431              :   Analysis::NodeMapping mappings;
     432              :   tl::optional<PathIdentSegment> ident_segment;
     433              :   tl::optional<LangItem::Kind> lang_item;
     434              :   location_t locus;
     435              : 
     436              : protected:
     437              :   bool has_separating_scope_resolution;
     438              :   SegmentType type;
     439              : 
     440              : public:
     441              :   // Clone function implementation - not pure virtual as overrided by subclasses
     442        14119 :   virtual TypePathSegment *clone_type_path_segment_impl () const
     443              :   {
     444        14119 :     return new TypePathSegment (*this);
     445              :   }
     446              : 
     447              : public:
     448        24096 :   virtual ~TypePathSegment () {}
     449              : 
     450        53388 :   virtual SegmentType get_type () const { return SegmentType::REG; }
     451              : 
     452              :   // Unique pointer custom clone function
     453        15151 :   std::unique_ptr<TypePathSegment> clone_type_path_segment () const
     454              :   {
     455        15151 :     return std::unique_ptr<TypePathSegment> (clone_type_path_segment_impl ());
     456              :   }
     457              : 
     458              :   TypePathSegment (Analysis::NodeMapping mappings,
     459              :                    PathIdentSegment ident_segment,
     460              :                    bool has_separating_scope_resolution, location_t locus);
     461              : 
     462              :   TypePathSegment (Analysis::NodeMapping mappings, LangItem::Kind lang_item,
     463              :                    location_t locus);
     464              : 
     465              :   TypePathSegment (Analysis::NodeMapping mappings, std::string segment_name,
     466              :                    bool has_separating_scope_resolution, location_t locus);
     467              : 
     468        98927 :   virtual std::string to_string () const
     469              :   {
     470        98927 :     if (ident_segment)
     471        98927 :       return ident_segment->to_string ();
     472              : 
     473            0 :     return LangItem::PrettyString (*lang_item);
     474              :   }
     475              : 
     476              :   /* Returns whether the type path segment is in an error state. May be virtual
     477              :    * in future. */
     478            3 :   bool is_error () const
     479              :   {
     480            3 :     rust_assert (ident_segment);
     481            3 :     return ident_segment->is_error ();
     482              :   }
     483              : 
     484              :   /* Returns whether segment is identifier only (as opposed to generic args or
     485              :    * function). Overriden in derived classes with other segments. */
     486        46435 :   virtual bool is_ident_only () const { return true; }
     487              : 
     488           90 :   location_t get_locus () const { return locus; }
     489              : 
     490              :   // not pure virtual as class not abstract
     491              :   virtual void accept_vis (HIRFullVisitor &vis);
     492              : 
     493        49407 :   const Analysis::NodeMapping &get_mappings () const { return mappings; }
     494              : 
     495          585 :   const PathIdentSegment &get_ident_segment () const
     496              :   {
     497          585 :     rust_assert (ident_segment);
     498          585 :     return *ident_segment;
     499              :   }
     500              : 
     501           49 :   const LangItem::Kind &get_lang_item () const
     502              :   {
     503           49 :     rust_assert (lang_item);
     504           49 :     return *lang_item;
     505              :   }
     506              : 
     507        49067 :   bool is_generic_segment () const
     508              :   {
     509        49067 :     return get_type () == SegmentType::GENERIC;
     510              :   }
     511              : 
     512        49376 :   bool is_lang_item () const { return lang_item.has_value (); }
     513              : };
     514              : 
     515              : // Segment used in type path with generic args
     516              : class TypePathSegmentGeneric : public TypePathSegment
     517              : {
     518              :   GenericArgs generic_args;
     519              : 
     520              : public:
     521         3232 :   bool has_generic_args () const { return generic_args.has_generic_args (); }
     522              : 
     523         1921 :   bool is_ident_only () const override { return false; }
     524              : 
     525              :   // Constructor with PathIdentSegment and GenericArgs
     526              :   TypePathSegmentGeneric (Analysis::NodeMapping mappings,
     527              :                           PathIdentSegment ident_segment,
     528              :                           bool has_separating_scope_resolution,
     529              :                           GenericArgs generic_args, location_t locus);
     530              : 
     531              :   TypePathSegmentGeneric (Analysis::NodeMapping mappings,
     532              :                           LangItem::Kind lang_item, GenericArgs generic_args,
     533              :                           location_t locus);
     534              : 
     535              :   // Constructor from segment name and all args
     536              :   TypePathSegmentGeneric (Analysis::NodeMapping mappings,
     537              :                           std::string segment_name,
     538              :                           bool has_separating_scope_resolution,
     539              :                           std::vector<Lifetime> lifetime_args,
     540              :                           std::vector<std::unique_ptr<Type> > type_args,
     541              :                           std::vector<GenericArgsBinding> binding_args,
     542              :                           std::vector<ConstGenericArg> const_args,
     543              :                           location_t locus);
     544              : 
     545              :   std::string to_string () const override;
     546              : 
     547              :   void accept_vis (HIRFullVisitor &vis) override;
     548              : 
     549         1941 :   GenericArgs &get_generic_args () { return generic_args; }
     550              : 
     551         2828 :   virtual SegmentType get_type () const override final
     552              :   {
     553         2828 :     return SegmentType::GENERIC;
     554              :   }
     555              : 
     556              :   // Use covariance to override base class method
     557         1031 :   TypePathSegmentGeneric *clone_type_path_segment_impl () const override
     558              :   {
     559         1031 :     return new TypePathSegmentGeneric (*this);
     560              :   }
     561              : };
     562              : 
     563              : // A function as represented in a type path
     564              : class TypePathFunction
     565              : {
     566              :   std::vector<std::unique_ptr<Type> > inputs;
     567              :   std::unique_ptr<Type> return_type;
     568              : 
     569              : public:
     570              :   // Returns whether the return type of the function has been specified.
     571           84 :   bool has_return_type () const { return return_type != nullptr; }
     572              : 
     573              :   // Returns whether the function has inputs.
     574           27 :   bool has_inputs () const { return !inputs.empty (); }
     575              : 
     576              :   // Constructor
     577              :   TypePathFunction (std::vector<std::unique_ptr<Type> > inputs,
     578              :                     std::unique_ptr<Type> type);
     579              : 
     580              :   // Copy constructor with clone
     581              :   TypePathFunction (TypePathFunction const &other);
     582              : 
     583           30 :   ~TypePathFunction () = default;
     584              : 
     585              :   // Overloaded assignment operator to clone type
     586              :   TypePathFunction &operator= (TypePathFunction const &other);
     587              : 
     588              :   // move constructors
     589           60 :   TypePathFunction (TypePathFunction &&other) = default;
     590              :   TypePathFunction &operator= (TypePathFunction &&other) = default;
     591              : 
     592              :   std::string to_string () const;
     593              : 
     594              :   const std::vector<std::unique_ptr<Type> > &get_params () const
     595              :   {
     596              :     return inputs;
     597              :   };
     598           54 :   std::vector<std::unique_ptr<Type> > &get_params () { return inputs; };
     599              : 
     600           28 :   const Type &get_return_type () const { return *return_type; };
     601           81 :   Type &get_return_type () { return *return_type; };
     602              : };
     603              : 
     604              : // Segment used in type path with a function argument
     605              : class TypePathSegmentFunction : public TypePathSegment
     606              : {
     607              :   TypePathFunction function_path;
     608              : 
     609              : public:
     610              :   // Constructor with PathIdentSegment and TypePathFn
     611              :   TypePathSegmentFunction (Analysis::NodeMapping mappings,
     612              :                            PathIdentSegment ident_segment,
     613              :                            bool has_separating_scope_resolution,
     614              :                            TypePathFunction function_path, location_t locus);
     615              : 
     616              :   // Constructor with segment name and TypePathFn
     617              :   TypePathSegmentFunction (Analysis::NodeMapping mappings,
     618              :                            std::string segment_name,
     619              :                            bool has_separating_scope_resolution,
     620              :                            TypePathFunction function_path, location_t locus);
     621              : 
     622              :   std::string to_string () const override;
     623              : 
     624            0 :   bool is_ident_only () const override { return false; }
     625              : 
     626              :   void accept_vis (HIRFullVisitor &vis) override;
     627              : 
     628           27 :   SegmentType get_type () const override final { return SegmentType::FUNCTION; }
     629              : 
     630           54 :   TypePathFunction &get_function_path () { return function_path; }
     631              : 
     632              :   // Use covariance to override base class method
     633           30 :   TypePathSegmentFunction *clone_type_path_segment_impl () const override
     634              :   {
     635           30 :     return new TypePathSegmentFunction (*this);
     636              :   }
     637              : };
     638              : 
     639              : // Path used inside types
     640         3192 : class TypePath : public TypeNoBounds
     641              : {
     642              : public:
     643              :   bool has_opening_scope_resolution;
     644              :   std::vector<std::unique_ptr<TypePathSegment> > segments;
     645              : 
     646              : protected:
     647              :   /* Use covariance to implement clone function as returning this object rather
     648              :    * than base */
     649        13023 :   TypePath *clone_type_impl () const override { return new TypePath (*this); }
     650              : 
     651              :   /* Use covariance to implement clone function as returning this object rather
     652              :    * than base */
     653            0 :   TypePath *clone_type_no_bounds_impl () const override
     654              :   {
     655            0 :     return new TypePath (*this);
     656              :   }
     657              : 
     658              : public:
     659              :   /* Returns whether the TypePath has an opening scope resolution operator (i.e.
     660              :    * is global path or crate-relative path, not module-relative) */
     661            0 :   bool has_opening_scope_resolution_op () const
     662              :   {
     663            0 :     return has_opening_scope_resolution;
     664              :   }
     665              : 
     666              :   // Returns whether the TypePath is in an invalid state.
     667              :   bool is_error () const { return segments.empty (); }
     668              : 
     669              :   // Creates an error state TypePath.
     670              :   static TypePath create_error ()
     671              :   {
     672              :     return TypePath (Analysis::NodeMapping::get_error (),
     673              :                      std::vector<std::unique_ptr<TypePathSegment> > (),
     674              :                      UNDEF_LOCATION);
     675              :   }
     676              : 
     677              :   // Constructor
     678              :   TypePath (Analysis::NodeMapping mappings,
     679              :             std::vector<std::unique_ptr<TypePathSegment> > segments,
     680              :             location_t locus, bool has_opening_scope_resolution = false);
     681              : 
     682              :   // Copy constructor with vector clone
     683              :   TypePath (TypePath const &other);
     684              : 
     685              :   // Overloaded assignment operator with clone
     686              :   TypePath &operator= (TypePath const &other);
     687              : 
     688              :   // move constructors
     689         3192 :   TypePath (TypePath &&other) = default;
     690              :   TypePath &operator= (TypePath &&other) = default;
     691              : 
     692              :   std::string to_string () const override;
     693              : 
     694              :   /* Converts TypePath to SimplePath if possible (i.e. no generic or function
     695              :    * arguments). Otherwise returns an empty SimplePath. */
     696              :   AST::SimplePath as_simple_path () const;
     697              : 
     698              :   // Creates a trait bound with a clone of this type path as its only element.
     699              :   std::unique_ptr<TraitBound> to_trait_bound (bool in_parens) const override;
     700              : 
     701              :   void accept_vis (HIRFullVisitor &vis) override;
     702              :   void accept_vis (HIRTypeVisitor &vis) override;
     703              : 
     704       144108 :   size_t get_num_segments () const { return segments.size (); }
     705              : 
     706        50400 :   std::vector<std::unique_ptr<TypePathSegment> > &get_segments ()
     707              :   {
     708        96989 :     return segments;
     709              :   }
     710              : 
     711         6936 :   TypePathSegment &get_final_segment () { return *segments.back (); }
     712              : };
     713              : 
     714              : class QualifiedPathType
     715              : {
     716              :   std::unique_ptr<Type> type;
     717              :   std::unique_ptr<TypePath> trait;
     718              :   location_t locus;
     719              :   Analysis::NodeMapping mappings;
     720              : 
     721              : public:
     722              :   // Constructor
     723              :   QualifiedPathType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type,
     724              :                      std::unique_ptr<TypePath> trait, location_t locus);
     725              : 
     726              :   // Copy constructor uses custom deep copy for Type to preserve polymorphism
     727              :   QualifiedPathType (QualifiedPathType const &other);
     728              : 
     729              :   // default destructor
     730         1074 :   ~QualifiedPathType () = default;
     731              : 
     732              :   // overload assignment operator to use custom clone method
     733              :   QualifiedPathType &operator= (QualifiedPathType const &other);
     734              : 
     735              :   // move constructor
     736          600 :   QualifiedPathType (QualifiedPathType &&other) = default;
     737              :   QualifiedPathType &operator= (QualifiedPathType &&other) = default;
     738              : 
     739              :   // Returns whether the qualified path type has a rebind as clause.
     740         1138 :   bool has_as_clause () const { return trait != nullptr; }
     741              : 
     742              :   std::string to_string () const;
     743              : 
     744              :   location_t get_locus () const { return locus; }
     745              : 
     746            0 :   Analysis::NodeMapping get_mappings () const { return mappings; }
     747              : 
     748            0 :   bool has_type () { return type != nullptr; }
     749            0 :   bool has_trait () { return trait != nullptr; }
     750              : 
     751          950 :   Type &get_type ()
     752              :   {
     753          950 :     rust_assert (type);
     754          950 :     return *type;
     755              :   }
     756              : 
     757          804 :   TypePath &get_trait ()
     758              :   {
     759          804 :     rust_assert (trait);
     760          804 :     return *trait;
     761              :   }
     762              : 
     763              :   bool trait_has_generic_args () const;
     764              : 
     765              :   GenericArgs &get_trait_generic_args ();
     766              : };
     767              : 
     768              : /* HIR node representing a qualified path-in-expression pattern (path that
     769              :  * allows specifying trait functions) */
     770              : class QualifiedPathInExpression : public PathPattern, public PathExpr
     771              : {
     772              :   QualifiedPathType path_type;
     773              :   location_t locus;
     774              : 
     775              : public:
     776              :   std::string to_string () const override;
     777              : 
     778              :   QualifiedPathInExpression (Analysis::NodeMapping mappings,
     779              :                              QualifiedPathType qual_path_type,
     780              :                              std::vector<PathExprSegment> path_segments,
     781              :                              location_t locus = UNDEF_LOCATION,
     782              :                              std::vector<AST::Attribute> outer_attrs
     783              :                              = std::vector<AST::Attribute> ());
     784              : 
     785              :   // lang-item constructor
     786              :   QualifiedPathInExpression (Analysis::NodeMapping mappings,
     787              :                              QualifiedPathType qual_path_type,
     788              :                              LangItem::Kind lang_item,
     789              :                              location_t locus = UNDEF_LOCATION,
     790              :                              std::vector<AST::Attribute> outer_attrs
     791              :                              = std::vector<AST::Attribute> ());
     792              : 
     793          155 :   location_t get_locus () const override final { return locus; }
     794              : 
     795              :   void accept_vis (HIRFullVisitor &vis) override;
     796              :   void accept_vis (HIRExpressionVisitor &vis) override;
     797              :   void accept_vis (HIRPatternVisitor &vis) override;
     798              : 
     799          188 :   QualifiedPathType &get_path_type () { return path_type; }
     800              : 
     801          220 :   location_t get_locus () { return locus; }
     802              : 
     803          334 :   const Analysis::NodeMapping &get_mappings () const override final
     804              :   {
     805          334 :     return mappings;
     806              :   }
     807              : 
     808              : protected:
     809              :   /* Use covariance to implement clone function as returning this object rather
     810              :    * than base */
     811            0 :   QualifiedPathInExpression *clone_pattern_impl () const override
     812              :   {
     813            0 :     return new QualifiedPathInExpression (*this);
     814              :   }
     815              : 
     816              :   /* Use covariance to implement clone function as returning this object rather
     817              :    * than base */
     818            0 :   QualifiedPathInExpression *clone_expr_without_block_impl () const override
     819              :   {
     820            0 :     return new QualifiedPathInExpression (*this);
     821              :   }
     822              : };
     823              : 
     824              : /* Represents a qualified path in a type; used for disambiguating trait function
     825              :  * calls */
     826              : class QualifiedPathInType : public TypeNoBounds
     827              : {
     828              :   QualifiedPathType path_type;
     829              :   std::unique_ptr<TypePathSegment> associated_segment;
     830              :   std::vector<std::unique_ptr<TypePathSegment> > segments;
     831              : 
     832              : protected:
     833              :   /* Use covariance to implement clone function as returning this object rather
     834              :    * than base */
     835           29 :   QualifiedPathInType *clone_type_impl () const override
     836              :   {
     837           29 :     return new QualifiedPathInType (*this);
     838              :   }
     839              : 
     840              :   /* Use covariance to implement clone function as returning this object rather
     841              :    * than base */
     842            0 :   QualifiedPathInType *clone_type_no_bounds_impl () const override
     843              :   {
     844            0 :     return new QualifiedPathInType (*this);
     845              :   }
     846              : 
     847              : public:
     848              :   QualifiedPathInType (
     849              :     Analysis::NodeMapping mappings, QualifiedPathType qual_path_type,
     850              :     std::unique_ptr<TypePathSegment> associated_segment,
     851              :     std::vector<std::unique_ptr<TypePathSegment> > path_segments,
     852              :     location_t locus = UNDEF_LOCATION);
     853              : 
     854              :   // Copy constructor with vector clone
     855              :   QualifiedPathInType (QualifiedPathInType const &other);
     856              : 
     857              :   // Overloaded assignment operator with vector clone
     858              :   QualifiedPathInType &operator= (QualifiedPathInType const &other);
     859              : 
     860              :   // move constructors
     861              :   QualifiedPathInType (QualifiedPathInType &&other) = default;
     862              :   QualifiedPathInType &operator= (QualifiedPathInType &&other) = default;
     863              : 
     864              :   std::string to_string () const override;
     865              : 
     866              :   void accept_vis (HIRFullVisitor &vis) override;
     867              :   void accept_vis (HIRTypeVisitor &vis) override;
     868              : 
     869          441 :   QualifiedPathType &get_path_type () { return path_type; }
     870              : 
     871          440 :   TypePathSegment &get_associated_segment () { return *associated_segment; }
     872              : 
     873            1 :   std::vector<std::unique_ptr<TypePathSegment> > &get_segments ()
     874              :   {
     875          440 :     return segments;
     876              :   }
     877              : };
     878              : 
     879              : } // namespace HIR
     880              : } // namespace Rust
     881              : 
     882              : #endif
        

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