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: 86.6 % 164 142
Test Date: 2026-02-28 14:20:25 Functions: 85.1 % 47 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       159314 : 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       139880 :   PathIdentSegment (std::string segment_name)
      41       131042 :     : segment_name (std::move (segment_name))
      42              :   {}
      43              : 
      44       368337 :   PathIdentSegment (const PathIdentSegment &other)
      45       678904 :     : 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         8838 :   static PathIdentSegment create_error () { return PathIdentSegment (""); }
      56              : 
      57              :   // Returns whether PathIdentSegment is in an error state.
      58        13079 :   bool is_error () const { return segment_name.empty (); }
      59              : 
      60       647167 :   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          287 :   ~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          137 :   Type &get_type ()
     108              :   {
     109          137 :     rust_assert (type);
     110          137 :     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          197 : 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          151 :   std::unique_ptr<Expr> &get_expression () { return expression; }
     134              : 
     135          115 :   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        61530 :   bool has_generic_args () const
     153              :   {
     154       119079 :     return !(lifetime_args.empty () && type_args.empty ()
     155        57660 :              && 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       224492 :   ~GenericArgs () = default;
     167              : 
     168              :   // overloaded assignment operator to vector clone
     169              :   GenericArgs &operator= (GenericArgs const &other);
     170              : 
     171              :   // move constructors
     172        99642 :   GenericArgs (GenericArgs &&other) = default;
     173         5977 :   GenericArgs &operator= (GenericArgs &&other) = default;
     174              : 
     175              :   // Creates an empty GenericArgs (no arguments)
     176        66851 :   static GenericArgs create_empty (location_t locus = UNDEF_LOCATION)
     177              :   {
     178        66851 :     return GenericArgs ({}, {}, {}, {}, locus);
     179              :   }
     180              : 
     181              :   bool is_empty () const;
     182              : 
     183              :   std::string to_string () const;
     184              : 
     185         8257 :   std::vector<Lifetime> &get_lifetime_args () { return lifetime_args; }
     186              :   const std::vector<Lifetime> &get_lifetime_args () const
     187              :   {
     188         9243 :     return lifetime_args;
     189              :   }
     190              : 
     191        11626 :   std::vector<std::unique_ptr<Type> > &get_type_args () { return type_args; }
     192              : 
     193         8330 :   std::vector<GenericArgsBinding> &get_binding_args () { return binding_args; }
     194              : 
     195        17507 :   std::vector<ConstGenericArg> &get_const_args () { return const_args; }
     196              : 
     197        16350 :   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       144707 : 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        72282 :   PathExprSegment (PathExprSegment &&other) = default;
     221              :   PathExprSegment &operator= (PathExprSegment &&other) = default;
     222              : 
     223              :   std::string to_string () const;
     224              : 
     225        39391 :   location_t get_locus () const { return locus; }
     226              : 
     227        45283 :   PathIdentSegment &get_segment () { return segment_name; }
     228        41508 :   const PathIdentSegment &get_segment () const { return segment_name; }
     229              : 
     230              :   GenericArgs &get_generic_args () { return generic_args; }
     231              : 
     232       148874 :   const Analysis::NodeMapping &get_mappings () const { return mappings; }
     233              : 
     234        58369 :   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        48743 :   PathPattern (std::vector<PathExprSegment> segments)
     254        48743 :     : segments (std::move (segments)), lang_item (tl::nullopt),
     255        48743 :       kind (Kind::Segmented)
     256        48743 :   {}
     257              : 
     258          144 :   PathPattern (LangItem::Kind lang_item)
     259          144 :     : segments ({}), lang_item (lang_item), kind (Kind::LangItem)
     260          144 :   {}
     261              : 
     262              :   // Returns whether path has segments.
     263            5 :   bool has_segments () const
     264              :   {
     265            5 :     rust_assert (kind == Kind::Segmented);
     266            5 :     return !segments.empty ();
     267              :   }
     268              : 
     269              :   /* Converts path segments to their equivalent SimplePath segments if possible,
     270              :    * and creates a SimplePath from them. */
     271              :   AST::SimplePath
     272              :   convert_to_simple_path (bool with_opening_scope_resolution) const;
     273              : 
     274              : public:
     275              :   /* Returns whether the path is a single segment (excluding qualified path
     276              :    * initial as segment). */
     277            0 :   bool is_single_segment () const
     278              :   {
     279            0 :     rust_assert (kind == Kind::Segmented);
     280            0 :     return segments.size () == 1;
     281              :   }
     282              : 
     283              :   std::string to_string () const override;
     284              : 
     285              :   void iterate_path_segments (std::function<bool (PathExprSegment &)> cb);
     286              : 
     287       104442 :   size_t get_num_segments () const
     288              :   {
     289       104442 :     rust_assert (kind == Kind::Segmented);
     290       104442 :     return segments.size ();
     291              :   }
     292              : 
     293       106206 :   std::vector<PathExprSegment> &get_segments ()
     294              :   {
     295       106206 :     rust_assert (kind == Kind::Segmented);
     296       106206 :     return segments;
     297              :   }
     298              : 
     299              :   const std::vector<PathExprSegment> &get_segments () const
     300              :   {
     301              :     rust_assert (kind == Kind::Segmented);
     302              :     return segments;
     303              :   }
     304              : 
     305              :   PathExprSegment &get_root_seg ()
     306              :   {
     307              :     rust_assert (kind == Kind::Segmented);
     308              :     return segments.at (0);
     309              :   }
     310              : 
     311        41515 :   const PathExprSegment &get_final_segment () const
     312              :   {
     313        41515 :     rust_assert (kind == Kind::Segmented);
     314        41515 :     return segments.back ();
     315              :   }
     316              : 
     317          395 :   LangItem::Kind get_lang_item () const
     318              :   {
     319          395 :     rust_assert (kind == Kind::LangItem);
     320              : 
     321          395 :     return *lang_item;
     322              :   }
     323              : 
     324          741 :   PatternType get_pattern_type () const override final
     325              :   {
     326          741 :     return PatternType::PATH;
     327              :   }
     328              : 
     329       176732 :   bool is_lang_item () const { return kind == Kind::LangItem; }
     330              : 
     331            0 :   Kind get_path_kind () const { return kind; }
     332              : };
     333              : 
     334              : /* HIR node representing a path-in-expression pattern (path that allows generic
     335              :  * arguments) */
     336              : class PathInExpression : public PathPattern, public PathExpr
     337              : {
     338              :   bool has_opening_scope_resolution;
     339              :   location_t locus;
     340              : 
     341              : public:
     342              :   std::string to_string () const override;
     343              : 
     344              :   // Constructor
     345              :   PathInExpression (Analysis::NodeMapping mappings,
     346              :                     std::vector<PathExprSegment> path_segments,
     347              :                     location_t locus = UNDEF_LOCATION,
     348              :                     bool has_opening_scope_resolution = false,
     349              :                     std::vector<AST::Attribute> outer_attrs
     350              :                     = std::vector<AST::Attribute> ());
     351              : 
     352              :   // lang-item Constructor
     353              :   PathInExpression (Analysis::NodeMapping mappings, LangItem::Kind kind,
     354              :                     location_t locus = UNDEF_LOCATION,
     355              :                     bool has_opening_scope_resolution = false,
     356              :                     std::vector<AST::Attribute> outer_attrs
     357              :                     = std::vector<AST::Attribute> ());
     358              : 
     359              :   // Creates an error state path in expression.
     360              :   static PathInExpression create_error ()
     361              :   {
     362              :     return PathInExpression (Analysis::NodeMapping::get_error (),
     363              :                              std::vector<PathExprSegment> ());
     364              :   }
     365              : 
     366              :   // Returns whether path in expression is in an error state.
     367              :   bool is_error () const { return !has_segments (); }
     368              : 
     369              :   /* Converts PathInExpression to SimplePath if possible (i.e. no generic
     370              :    * arguments). Otherwise returns an empty SimplePath. */
     371            5 :   AST::SimplePath as_simple_path () const
     372              :   {
     373              :     /* delegate to parent class as can't access segments. however,
     374              :      * QualifiedPathInExpression conversion to simple path wouldn't make sense,
     375              :      * so the method in the parent class should be protected, not public. Have
     376              :      * to pass in opening scope resolution as parent class has no access to it.
     377              :      */
     378            5 :     return convert_to_simple_path (has_opening_scope_resolution);
     379              :   }
     380              : 
     381       212234 :   location_t get_locus () const override final { return locus; }
     382              : 
     383              :   void accept_vis (HIRFullVisitor &vis) override;
     384              :   void accept_vis (HIRExpressionVisitor &vis) override;
     385              :   void accept_vis (HIRPatternVisitor &vis) override;
     386              : 
     387            0 :   bool opening_scope_resolution () { return has_opening_scope_resolution; }
     388              : 
     389              :   bool is_self () const;
     390              : 
     391       172814 :   const Analysis::NodeMapping &get_mappings () const override final
     392              :   {
     393       172814 :     return mappings;
     394              :   }
     395              : 
     396              : protected:
     397              :   /* Use covariance to implement clone function as returning this object rather
     398              :    * than base */
     399         1911 :   PathInExpression *clone_pattern_impl () const override
     400              :   {
     401         1911 :     return new PathInExpression (*this);
     402              :   }
     403              : 
     404              :   /* Use covariance to implement clone function as returning this object rather
     405              :    * than base */
     406          821 :   PathInExpression *clone_expr_without_block_impl () const override
     407              :   {
     408          821 :     return new PathInExpression (*this);
     409              :   }
     410              : };
     411              : 
     412              : /* Base class for segments used in type paths - not abstract (represents an
     413              :  * ident-only segment) */
     414              : class TypePathSegment
     415              : {
     416              : public:
     417              :   enum SegmentType
     418              :   {
     419              :     REG,
     420              :     GENERIC,
     421              :     FUNCTION
     422              :   };
     423              : 
     424              : private:
     425              :   Analysis::NodeMapping mappings;
     426              :   tl::optional<PathIdentSegment> ident_segment;
     427              :   tl::optional<LangItem::Kind> lang_item;
     428              :   location_t locus;
     429              : 
     430              : protected:
     431              :   bool has_separating_scope_resolution;
     432              :   SegmentType type;
     433              : 
     434              : public:
     435              :   // Clone function implementation - not pure virtual as overrided by subclasses
     436        13804 :   virtual TypePathSegment *clone_type_path_segment_impl () const
     437              :   {
     438        13804 :     return new TypePathSegment (*this);
     439              :   }
     440              : 
     441              : public:
     442        23620 :   virtual ~TypePathSegment () {}
     443              : 
     444        51738 :   virtual SegmentType get_type () const { return SegmentType::REG; }
     445              : 
     446              :   // Unique pointer custom clone function
     447        14827 :   std::unique_ptr<TypePathSegment> clone_type_path_segment () const
     448              :   {
     449        14827 :     return std::unique_ptr<TypePathSegment> (clone_type_path_segment_impl ());
     450              :   }
     451              : 
     452              :   TypePathSegment (Analysis::NodeMapping mappings,
     453              :                    PathIdentSegment ident_segment,
     454              :                    bool has_separating_scope_resolution, location_t locus);
     455              : 
     456              :   TypePathSegment (Analysis::NodeMapping mappings, LangItem::Kind lang_item,
     457              :                    location_t locus);
     458              : 
     459              :   TypePathSegment (Analysis::NodeMapping mappings, std::string segment_name,
     460              :                    bool has_separating_scope_resolution, location_t locus);
     461              : 
     462        95885 :   virtual std::string to_string () const
     463              :   {
     464        95885 :     if (ident_segment)
     465        95836 :       return ident_segment->to_string ();
     466              : 
     467           49 :     return LangItem::PrettyString (*lang_item);
     468              :   }
     469              : 
     470              :   /* Returns whether the type path segment is in an error state. May be virtual
     471              :    * in future. */
     472            2 :   bool is_error () const
     473              :   {
     474            2 :     rust_assert (ident_segment);
     475            2 :     return ident_segment->is_error ();
     476              :   }
     477              : 
     478              :   /* Returns whether segment is identifier only (as opposed to generic args or
     479              :    * function). Overriden in derived classes with other segments. */
     480        44967 :   virtual bool is_ident_only () const { return true; }
     481              : 
     482           89 :   location_t get_locus () const { return locus; }
     483              : 
     484              :   // not pure virtual as class not abstract
     485              :   virtual void accept_vis (HIRFullVisitor &vis);
     486              : 
     487        47862 :   const Analysis::NodeMapping &get_mappings () const { return mappings; }
     488              : 
     489          555 :   const PathIdentSegment &get_ident_segment () const
     490              :   {
     491          555 :     rust_assert (ident_segment);
     492          555 :     return *ident_segment;
     493              :   }
     494              : 
     495           49 :   const LangItem::Kind &get_lang_item () const
     496              :   {
     497           49 :     rust_assert (lang_item);
     498           49 :     return *lang_item;
     499              :   }
     500              : 
     501        47521 :   bool is_generic_segment () const
     502              :   {
     503        47521 :     return get_type () == SegmentType::GENERIC;
     504              :   }
     505              : 
     506        47832 :   bool is_lang_item () const { return lang_item.has_value (); }
     507              : };
     508              : 
     509              : // Segment used in type path with generic args
     510              : class TypePathSegmentGeneric : public TypePathSegment
     511              : {
     512              :   GenericArgs generic_args;
     513              : 
     514              : public:
     515         3161 :   bool has_generic_args () const { return generic_args.has_generic_args (); }
     516              : 
     517         1890 :   bool is_ident_only () const override { return false; }
     518              : 
     519              :   // Constructor with PathIdentSegment and GenericArgs
     520              :   TypePathSegmentGeneric (Analysis::NodeMapping mappings,
     521              :                           PathIdentSegment ident_segment,
     522              :                           bool has_separating_scope_resolution,
     523              :                           GenericArgs generic_args, location_t locus);
     524              : 
     525              :   TypePathSegmentGeneric (Analysis::NodeMapping mappings,
     526              :                           LangItem::Kind lang_item, GenericArgs generic_args,
     527              :                           location_t locus);
     528              : 
     529              :   // Constructor from segment name and all args
     530              :   TypePathSegmentGeneric (Analysis::NodeMapping mappings,
     531              :                           std::string segment_name,
     532              :                           bool has_separating_scope_resolution,
     533              :                           std::vector<Lifetime> lifetime_args,
     534              :                           std::vector<std::unique_ptr<Type> > type_args,
     535              :                           std::vector<GenericArgsBinding> binding_args,
     536              :                           std::vector<ConstGenericArg> const_args,
     537              :                           location_t locus);
     538              : 
     539              :   std::string to_string () const override;
     540              : 
     541              :   void accept_vis (HIRFullVisitor &vis) override;
     542              : 
     543         1890 :   GenericArgs &get_generic_args () { return generic_args; }
     544              : 
     545         2744 :   virtual SegmentType get_type () const override final
     546              :   {
     547         2744 :     return SegmentType::GENERIC;
     548              :   }
     549              : 
     550              :   // Use covariance to override base class method
     551         1022 :   TypePathSegmentGeneric *clone_type_path_segment_impl () const override
     552              :   {
     553         1022 :     return new TypePathSegmentGeneric (*this);
     554              :   }
     555              : };
     556              : 
     557              : // A function as represented in a type path
     558              : class TypePathFunction
     559              : {
     560              :   std::vector<std::unique_ptr<Type> > inputs;
     561              :   std::unique_ptr<Type> return_type;
     562              : 
     563              : public:
     564              :   // Returns whether the return type of the function has been specified.
     565           84 :   bool has_return_type () const { return return_type != nullptr; }
     566              : 
     567              :   // Returns whether the function has inputs.
     568           27 :   bool has_inputs () const { return !inputs.empty (); }
     569              : 
     570              :   // Constructor
     571              :   TypePathFunction (std::vector<std::unique_ptr<Type> > inputs,
     572              :                     std::unique_ptr<Type> type);
     573              : 
     574              :   // Copy constructor with clone
     575              :   TypePathFunction (TypePathFunction const &other);
     576              : 
     577           30 :   ~TypePathFunction () = default;
     578              : 
     579              :   // Overloaded assignment operator to clone type
     580              :   TypePathFunction &operator= (TypePathFunction const &other);
     581              : 
     582              :   // move constructors
     583           60 :   TypePathFunction (TypePathFunction &&other) = default;
     584              :   TypePathFunction &operator= (TypePathFunction &&other) = default;
     585              : 
     586              :   std::string to_string () const;
     587              : 
     588              :   const std::vector<std::unique_ptr<Type> > &get_params () const
     589              :   {
     590              :     return inputs;
     591              :   };
     592           27 :   std::vector<std::unique_ptr<Type> > &get_params () { return inputs; };
     593              : 
     594           28 :   const Type &get_return_type () const { return *return_type; };
     595           81 :   Type &get_return_type () { return *return_type; };
     596              : };
     597              : 
     598              : // Segment used in type path with a function argument
     599              : class TypePathSegmentFunction : public TypePathSegment
     600              : {
     601              :   TypePathFunction function_path;
     602              : 
     603              : public:
     604              :   // Constructor with PathIdentSegment and TypePathFn
     605              :   TypePathSegmentFunction (Analysis::NodeMapping mappings,
     606              :                            PathIdentSegment ident_segment,
     607              :                            bool has_separating_scope_resolution,
     608              :                            TypePathFunction function_path, location_t locus);
     609              : 
     610              :   // Constructor with segment name and TypePathFn
     611              :   TypePathSegmentFunction (Analysis::NodeMapping mappings,
     612              :                            std::string segment_name,
     613              :                            bool has_separating_scope_resolution,
     614              :                            TypePathFunction function_path, location_t locus);
     615              : 
     616              :   std::string to_string () const override;
     617              : 
     618            0 :   bool is_ident_only () const override { return false; }
     619              : 
     620              :   void accept_vis (HIRFullVisitor &vis) override;
     621              : 
     622           27 :   SegmentType get_type () const override final { return SegmentType::FUNCTION; }
     623              : 
     624           54 :   TypePathFunction &get_function_path () { return function_path; }
     625              : 
     626              :   // Use covariance to override base class method
     627           30 :   TypePathSegmentFunction *clone_type_path_segment_impl () const override
     628              :   {
     629           30 :     return new TypePathSegmentFunction (*this);
     630              :   }
     631              : };
     632              : 
     633              : // Path used inside types
     634         3079 : class TypePath : public TypeNoBounds
     635              : {
     636              : public:
     637              :   bool has_opening_scope_resolution;
     638              :   std::vector<std::unique_ptr<TypePathSegment> > segments;
     639              : 
     640              : protected:
     641              :   /* Use covariance to implement clone function as returning this object rather
     642              :    * than base */
     643        12785 :   TypePath *clone_type_impl () const override { return new TypePath (*this); }
     644              : 
     645              :   /* Use covariance to implement clone function as returning this object rather
     646              :    * than base */
     647            0 :   TypePath *clone_type_no_bounds_impl () const override
     648              :   {
     649            0 :     return new TypePath (*this);
     650              :   }
     651              : 
     652              : public:
     653              :   /* Returns whether the TypePath has an opening scope resolution operator (i.e.
     654              :    * is global path or crate-relative path, not module-relative) */
     655            0 :   bool has_opening_scope_resolution_op () const
     656              :   {
     657            0 :     return has_opening_scope_resolution;
     658              :   }
     659              : 
     660              :   // Returns whether the TypePath is in an invalid state.
     661              :   bool is_error () const { return segments.empty (); }
     662              : 
     663              :   // Creates an error state TypePath.
     664              :   static TypePath create_error ()
     665              :   {
     666              :     return TypePath (Analysis::NodeMapping::get_error (),
     667              :                      std::vector<std::unique_ptr<TypePathSegment> > (),
     668              :                      UNDEF_LOCATION);
     669              :   }
     670              : 
     671              :   // Constructor
     672              :   TypePath (Analysis::NodeMapping mappings,
     673              :             std::vector<std::unique_ptr<TypePathSegment> > segments,
     674              :             location_t locus, bool has_opening_scope_resolution = false);
     675              : 
     676              :   // Copy constructor with vector clone
     677              :   TypePath (TypePath const &other);
     678              : 
     679              :   // Overloaded assignment operator with clone
     680              :   TypePath &operator= (TypePath const &other);
     681              : 
     682              :   // move constructors
     683         3079 :   TypePath (TypePath &&other) = default;
     684              :   TypePath &operator= (TypePath &&other) = default;
     685              : 
     686              :   std::string to_string () const override;
     687              : 
     688              :   /* Converts TypePath to SimplePath if possible (i.e. no generic or function
     689              :    * arguments). Otherwise returns an empty SimplePath. */
     690              :   AST::SimplePath as_simple_path () const;
     691              : 
     692              :   // Creates a trait bound with a clone of this type path as its only element.
     693              :   std::unique_ptr<TraitBound> to_trait_bound (bool in_parens) const override;
     694              : 
     695              :   void accept_vis (HIRFullVisitor &vis) override;
     696              :   void accept_vis (HIRTypeVisitor &vis) override;
     697              : 
     698       139586 :   size_t get_num_segments () const { return segments.size (); }
     699              : 
     700        48810 :   std::vector<std::unique_ptr<TypePathSegment> > &get_segments ()
     701              :   {
     702        94111 :     return segments;
     703              :   }
     704              : 
     705         6748 :   TypePathSegment &get_final_segment () { return *segments.back (); }
     706              : };
     707              : 
     708              : class QualifiedPathType
     709              : {
     710              :   std::unique_ptr<Type> type;
     711              :   std::unique_ptr<TypePath> trait;
     712              :   location_t locus;
     713              :   Analysis::NodeMapping mappings;
     714              : 
     715              : public:
     716              :   // Constructor
     717              :   QualifiedPathType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type,
     718              :                      std::unique_ptr<TypePath> trait, location_t locus);
     719              : 
     720              :   // Copy constructor uses custom deep copy for Type to preserve polymorphism
     721              :   QualifiedPathType (QualifiedPathType const &other);
     722              : 
     723              :   // default destructor
     724         1068 :   ~QualifiedPathType () = default;
     725              : 
     726              :   // overload assignment operator to use custom clone method
     727              :   QualifiedPathType &operator= (QualifiedPathType const &other);
     728              : 
     729              :   // move constructor
     730          598 :   QualifiedPathType (QualifiedPathType &&other) = default;
     731              :   QualifiedPathType &operator= (QualifiedPathType &&other) = default;
     732              : 
     733              :   // Returns whether the qualified path type has a rebind as clause.
     734         1132 :   bool has_as_clause () const { return trait != nullptr; }
     735              : 
     736              :   std::string to_string () const;
     737              : 
     738              :   location_t get_locus () const { return locus; }
     739              : 
     740            0 :   Analysis::NodeMapping get_mappings () const { return mappings; }
     741              : 
     742            0 :   bool has_type () { return type != nullptr; }
     743            0 :   bool has_trait () { return trait != nullptr; }
     744              : 
     745          948 :   Type &get_type ()
     746              :   {
     747          948 :     rust_assert (type);
     748          948 :     return *type;
     749              :   }
     750              : 
     751          802 :   TypePath &get_trait ()
     752              :   {
     753          802 :     rust_assert (trait);
     754          802 :     return *trait;
     755              :   }
     756              : 
     757              :   bool trait_has_generic_args () const;
     758              : 
     759              :   GenericArgs &get_trait_generic_args ();
     760              : };
     761              : 
     762              : /* HIR node representing a qualified path-in-expression pattern (path that
     763              :  * allows specifying trait functions) */
     764              : class QualifiedPathInExpression : public PathPattern, public PathExpr
     765              : {
     766              :   QualifiedPathType path_type;
     767              :   location_t locus;
     768              : 
     769              : public:
     770              :   std::string to_string () const override;
     771              : 
     772              :   QualifiedPathInExpression (Analysis::NodeMapping mappings,
     773              :                              QualifiedPathType qual_path_type,
     774              :                              std::vector<PathExprSegment> path_segments,
     775              :                              location_t locus = UNDEF_LOCATION,
     776              :                              std::vector<AST::Attribute> outer_attrs
     777              :                              = std::vector<AST::Attribute> ());
     778              : 
     779              :   // lang-item constructor
     780              :   QualifiedPathInExpression (Analysis::NodeMapping mappings,
     781              :                              QualifiedPathType qual_path_type,
     782              :                              LangItem::Kind lang_item,
     783              :                              location_t locus = UNDEF_LOCATION,
     784              :                              std::vector<AST::Attribute> outer_attrs
     785              :                              = std::vector<AST::Attribute> ());
     786              : 
     787          147 :   location_t get_locus () const override final { return locus; }
     788              : 
     789              :   void accept_vis (HIRFullVisitor &vis) override;
     790              :   void accept_vis (HIRExpressionVisitor &vis) override;
     791              :   void accept_vis (HIRPatternVisitor &vis) override;
     792              : 
     793          186 :   QualifiedPathType &get_path_type () { return path_type; }
     794              : 
     795          219 :   location_t get_locus () { return locus; }
     796              : 
     797          333 :   const Analysis::NodeMapping &get_mappings () const override final
     798              :   {
     799          333 :     return mappings;
     800              :   }
     801              : 
     802              : protected:
     803              :   /* Use covariance to implement clone function as returning this object rather
     804              :    * than base */
     805            0 :   QualifiedPathInExpression *clone_pattern_impl () const override
     806              :   {
     807            0 :     return new QualifiedPathInExpression (*this);
     808              :   }
     809              : 
     810              :   /* Use covariance to implement clone function as returning this object rather
     811              :    * than base */
     812            0 :   QualifiedPathInExpression *clone_expr_without_block_impl () const override
     813              :   {
     814            0 :     return new QualifiedPathInExpression (*this);
     815              :   }
     816              : };
     817              : 
     818              : /* Represents a qualified path in a type; used for disambiguating trait function
     819              :  * calls */
     820              : class QualifiedPathInType : public TypeNoBounds
     821              : {
     822              :   QualifiedPathType path_type;
     823              :   std::unique_ptr<TypePathSegment> associated_segment;
     824              :   std::vector<std::unique_ptr<TypePathSegment> > segments;
     825              : 
     826              : protected:
     827              :   /* Use covariance to implement clone function as returning this object rather
     828              :    * than base */
     829           29 :   QualifiedPathInType *clone_type_impl () const override
     830              :   {
     831           29 :     return new QualifiedPathInType (*this);
     832              :   }
     833              : 
     834              :   /* Use covariance to implement clone function as returning this object rather
     835              :    * than base */
     836            0 :   QualifiedPathInType *clone_type_no_bounds_impl () const override
     837              :   {
     838            0 :     return new QualifiedPathInType (*this);
     839              :   }
     840              : 
     841              : public:
     842              :   QualifiedPathInType (
     843              :     Analysis::NodeMapping mappings, QualifiedPathType qual_path_type,
     844              :     std::unique_ptr<TypePathSegment> associated_segment,
     845              :     std::vector<std::unique_ptr<TypePathSegment> > path_segments,
     846              :     location_t locus = UNDEF_LOCATION);
     847              : 
     848              :   // Copy constructor with vector clone
     849              :   QualifiedPathInType (QualifiedPathInType const &other);
     850              : 
     851              :   // Overloaded assignment operator with vector clone
     852              :   QualifiedPathInType &operator= (QualifiedPathInType const &other);
     853              : 
     854              :   // move constructors
     855              :   QualifiedPathInType (QualifiedPathInType &&other) = default;
     856              :   QualifiedPathInType &operator= (QualifiedPathInType &&other) = default;
     857              : 
     858              :   std::string to_string () const override;
     859              : 
     860              :   void accept_vis (HIRFullVisitor &vis) override;
     861              :   void accept_vis (HIRTypeVisitor &vis) override;
     862              : 
     863          441 :   QualifiedPathType &get_path_type () { return path_type; }
     864              : 
     865          440 :   TypePathSegment &get_associated_segment () { return *associated_segment; }
     866              : 
     867            1 :   std::vector<std::unique_ptr<TypePathSegment> > &get_segments ()
     868              :   {
     869          440 :     return segments;
     870              :   }
     871              : };
     872              : 
     873              : } // namespace HIR
     874              : } // namespace Rust
     875              : 
     876              : #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.