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