LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-tyty-variance-analysis-private.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 78.9 % 90 71
Test Date: 2025-11-22 14:42:49 Functions: 44.6 % 65 29
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : #ifndef RUST_TYTY_VARIANCE_ANALYSIS_PRIVATE_H
       2                 :             : #define RUST_TYTY_VARIANCE_ANALYSIS_PRIVATE_H
       3                 :             : 
       4                 :             : #include "rust-tyty-variance-analysis.h"
       5                 :             : 
       6                 :             : #include "rust-tyty-visitor.h"
       7                 :             : 
       8                 :             : namespace Rust {
       9                 :             : namespace TyTy {
      10                 :             : namespace VarianceAnalysis {
      11                 :             : 
      12                 :             : using SolutionIndex = uint32_t;
      13                 :             : 
      14                 :             : /** Term descibing variance relations. */
      15                 :             : struct Term
      16                 :             : {
      17                 :             :   enum Kind : uint8_t
      18                 :             :   {
      19                 :             :     CONST,
      20                 :             :     REF,
      21                 :             :     TRANSFORM,
      22                 :             :   };
      23                 :             : 
      24                 :             :   Kind kind;
      25                 :             :   union
      26                 :             :   {
      27                 :             :     struct
      28                 :             :     {
      29                 :             :       Term *lhs;
      30                 :             :       Term *rhs;
      31                 :             :     } transform;
      32                 :             :     SolutionIndex ref;
      33                 :             :     Variance const_val;
      34                 :             :   };
      35                 :             : 
      36                 :         169 :   Term () {}
      37                 :             : 
      38                 :        4283 :   Term (Variance variance) : kind (CONST), const_val (variance) {}
      39                 :             : 
      40                 :         178 :   WARN_UNUSED_RESULT bool is_const () const { return kind == CONST; }
      41                 :             : 
      42                 :             :   static Term make_ref (SolutionIndex index);
      43                 :             : 
      44                 :             :   static Term make_transform (Term lhs, Term rhs);
      45                 :             : };
      46                 :             : 
      47                 :             : /** Variance constraint of a type parameter. */
      48                 :             : struct Constraint
      49                 :             : {
      50                 :         139 :   Constraint (SolutionIndex target_index, Term *term)
      51                 :         139 :     : target_index (target_index), term (term)
      52                 :             :   {}
      53                 :             : 
      54                 :             :   SolutionIndex target_index;
      55                 :             :   Term *term;
      56                 :             : };
      57                 :             : 
      58                 :             : /** Abstract variance visitor context. */
      59                 :        3643 : template <typename VARIANCE> class VarianceVisitorCtx
      60                 :             : {
      61                 :             : public:
      62                 :        3046 :   virtual ~VarianceVisitorCtx () = default;
      63                 :             : 
      64                 :             :   virtual void add_constraints_from_ty (BaseType *ty, VARIANCE variance) = 0;
      65                 :             :   virtual void add_constraints_from_region (const Region &region,
      66                 :             :                                             VARIANCE variance)
      67                 :             :     = 0;
      68                 :         472 :   void add_constraints_from_mutability (BaseType *type, Mutability mutability,
      69                 :             :                                         VARIANCE variance)
      70                 :             :   {
      71                 :         472 :     switch (mutability)
      72                 :             :       {
      73                 :         300 :       case Mutability::Imm:
      74                 :         300 :         return add_constraints_from_ty (type, variance);
      75                 :         172 :       case Mutability::Mut:
      76                 :         172 :         return add_constraints_from_ty (type, Variance::invariant ());
      77                 :             :       }
      78                 :             :   }
      79                 :             :   virtual void
      80                 :             :   add_constraints_from_generic_args (HirId ref, SubstitutionRef &subst,
      81                 :             :                                      VARIANCE variance, bool invariant_args)
      82                 :             :     = 0;
      83                 :             :   virtual void add_constrints_from_param (ParamType &param, VARIANCE variance)
      84                 :             :     = 0;
      85                 :             :   virtual VARIANCE contra (VARIANCE variance) = 0;
      86                 :             : };
      87                 :             : 
      88                 :             : template <typename VARIANCE> class VisitorBase final : public TyVisitor
      89                 :             : {
      90                 :             :   VarianceVisitorCtx<VARIANCE> &ctx;
      91                 :             :   VARIANCE variance;
      92                 :             : 
      93                 :             : public:
      94                 :        6070 :   VisitorBase (VarianceVisitorCtx<VARIANCE> &ctx, VARIANCE variance)
      95                 :        6070 :     : ctx (ctx), variance (variance)
      96                 :             :   {}
      97                 :             : 
      98                 :         206 :   void visit (BoolType &type) override {}
      99                 :          47 :   void visit (CharType &type) override {}
     100                 :        1983 :   void visit (IntType &type) override {}
     101                 :         592 :   void visit (UintType &type) override {}
     102                 :         188 :   void visit (FloatType &type) override {}
     103                 :         175 :   void visit (USizeType &type) override {}
     104                 :          17 :   void visit (ISizeType &type) override {}
     105                 :           8 :   void visit (StrType &type) override {}
     106                 :           0 :   void visit (NeverType &type) override {}
     107                 :             : 
     108                 :           0 :   void visit (ClosureType &type) override {}
     109                 :          11 :   void visit (FnType &type) override
     110                 :             :   {
     111                 :          23 :     for (auto &region : type.get_used_arguments ().get_regions ())
     112                 :          12 :       ctx.add_constraints_from_region (region, Variance::invariant ());
     113                 :          11 :   }
     114                 :             : 
     115                 :         253 :   void visit (ReferenceType &type) override
     116                 :             :   {
     117                 :         253 :     ctx.add_constraints_from_region (type.get_region (), variance);
     118                 :         253 :     ctx.add_constraints_from_mutability (type.get_base (), type.mutability (),
     119                 :             :                                          variance);
     120                 :         253 :   }
     121                 :          50 :   void visit (ArrayType &type) override
     122                 :             :   {
     123                 :          50 :     ctx.add_constraints_from_ty (type.get_element_type (), variance);
     124                 :          50 :   }
     125                 :         290 :   void visit (SliceType &type) override
     126                 :             :   {
     127                 :         290 :     ctx.add_constraints_from_ty (type.get_element_type (), variance);
     128                 :         290 :   }
     129                 :         219 :   void visit (PointerType &type) override
     130                 :             :   {
     131                 :         219 :     ctx.add_constraints_from_ty (type.get_base (), variance);
     132                 :         219 :     ctx.add_constraints_from_mutability (type.get_base (), type.mutability (),
     133                 :             :                                          variance);
     134                 :         219 :   }
     135                 :         148 :   void visit (TupleType &type) override
     136                 :             :   {
     137                 :         149 :     for (auto &elem : type.get_fields ())
     138                 :           1 :       ctx.add_constraints_from_ty (elem.get_tyty (), variance);
     139                 :         148 :   }
     140                 :         429 :   void visit (ADTType &type) override
     141                 :             :   {
     142                 :         429 :     ctx.add_constraints_from_generic_args (type.get_orig_ref (), type, variance,
     143                 :             :                                            false);
     144                 :         429 :   }
     145                 :           0 :   void visit (ProjectionType &type) override
     146                 :             :   {
     147                 :           0 :     ctx.add_constraints_from_generic_args (type.get_orig_ref (), type, variance,
     148                 :             :                                            true);
     149                 :           0 :   }
     150                 :        1445 :   void visit (ParamType &type) override
     151                 :             :   {
     152                 :        1445 :     ctx.add_constrints_from_param (type, variance);
     153                 :        1445 :   }
     154                 :           9 :   void visit (FnPtr &type) override
     155                 :             :   {
     156                 :           9 :     auto contra = ctx.contra (variance);
     157                 :             : 
     158                 :          16 :     for (auto &param : type.get_params ())
     159                 :             :       {
     160                 :           7 :         ctx.add_constraints_from_ty (param.get_tyty (), contra);
     161                 :             :       }
     162                 :             : 
     163                 :           9 :     ctx.add_constraints_from_ty (type.get_return_type (), variance);
     164                 :           9 :   }
     165                 :             : 
     166                 :           0 :   void visit (ErrorType &type) override {}
     167                 :             : 
     168                 :           0 :   void visit (PlaceholderType &type) override { rust_unreachable (); }
     169                 :           0 :   void visit (InferType &type) override { rust_unreachable (); }
     170                 :             : 
     171                 :           0 :   void visit (DynamicObjectType &type) override
     172                 :             :   {
     173                 :             :     // TODO
     174                 :           0 :   }
     175                 :             : 
     176                 :           0 :   void visit (OpaqueType &type) override {}
     177                 :             : 
     178                 :           0 :   void visit (TyTy::ConstParamType &) override {}
     179                 :           0 :   void visit (TyTy::ConstValueType &) override {}
     180                 :           0 :   void visit (TyTy::ConstInferType &) override {}
     181                 :           0 :   void visit (TyTy::ConstErrorType &) override {}
     182                 :             : };
     183                 :             : 
     184                 :             : /** Per crate context for generic type variance analysis. */
     185                 :        4449 : class GenericTyPerCrateCtx
     186                 :             : {
     187                 :             : public: // External API
     188                 :             :   /** Add a type to context and process its variance constraints. */
     189                 :             :   void process_type (ADTType &ty);
     190                 :             : 
     191                 :             :   /**
     192                 :             :    * Solve for all variance constraints and clear temporary data.
     193                 :             :    *
     194                 :             :    * Only keeps the results.
     195                 :             :    */
     196                 :             :   void solve ();
     197                 :             : 
     198                 :             :   /** Prints solution debug output. To be called after solve. */
     199                 :             :   void debug_print_solutions ();
     200                 :             : 
     201                 :             :   tl::optional<SolutionIndex> lookup_type_index (HirId orig_ref);
     202                 :             : 
     203                 :             : public: // Module internal API
     204                 :             :   /** Format term tree to string. */
     205                 :             :   WARN_UNUSED_RESULT std::string to_string (const Term &term) const;
     206                 :             : 
     207                 :             :   /** Formats as <type ident>`[`<param index>``]` */
     208                 :             :   WARN_UNUSED_RESULT std::string to_string (SolutionIndex index) const;
     209                 :             : 
     210                 :             :   /** Evaluate a variance relation expression (term tree). */
     211                 :             :   Variance evaluate (Term *term);
     212                 :             : 
     213                 :             :   std::vector<Variance> query_generic_variance (const ADTType &type);
     214                 :             : 
     215                 :             :   FreeRegions query_field_regions (const ADTType *parent, size_t variant_index,
     216                 :             :                                    size_t field_index,
     217                 :             :                                    const FreeRegions &parent_regions);
     218                 :             : 
     219                 :             :   std::vector<Region> query_type_regions (BaseType *base);
     220                 :             : 
     221                 :             : public: // Data used by visitors.
     222                 :             :   // This whole class is private, therfore members can be public.
     223                 :             : 
     224                 :             :   /** Current solutions. Initiated to bivariant. */
     225                 :             :   std::vector<Variance> solutions;
     226                 :             : 
     227                 :             :   /** Constrains on solutions. Iteratively applied until fixpoint. */
     228                 :             :   std::vector<Constraint> constraints;
     229                 :             : 
     230                 :             :   /** Maps TyTy::orig_ref to an index of first solution for this type. */
     231                 :             :   std::unordered_map<HirId, SolutionIndex> map_from_ty_orig_ref;
     232                 :             : };
     233                 :             : 
     234                 :             : /** Visitor context for generic type variance analysis used for processing of a
     235                 :             :  * single type. */
     236                 :        3046 : class GenericTyVisitorCtx : VarianceVisitorCtx<Term>
     237                 :             : {
     238                 :             :   using Visitor = VisitorBase<Term>;
     239                 :             : 
     240                 :             : public:
     241                 :        3046 :   explicit GenericTyVisitorCtx (GenericTyPerCrateCtx &ctx) : ctx (ctx) {}
     242                 :             :   /** Entry point: Add a type to context and process its variance constraints.
     243                 :             :    */
     244                 :             :   void process_type (ADTType &ty);
     245                 :             : 
     246                 :             : private:
     247                 :             :   /** Resolve a type from a TyTy::ref. */
     248                 :             :   SolutionIndex lookup_or_add_type (HirId hir_id);
     249                 :             : 
     250                 :             :   /** Visit an inner type and add its constraints. */
     251                 :             :   void add_constraints_from_ty (BaseType *ty, Term variance) override;
     252                 :             : 
     253                 :             :   void add_constraint (SolutionIndex index, Term term);
     254                 :             : 
     255                 :             :   void add_constraints_from_region (const Region &region, Term term) override;
     256                 :             : 
     257                 :             :   void add_constraints_from_generic_args (HirId ref, SubstitutionRef &subst,
     258                 :             :                                           Term variance,
     259                 :             :                                           bool invariant_args) override;
     260                 :             : 
     261                 :             :   void add_constrints_from_param (ParamType &type, Term variance) override;
     262                 :             : 
     263                 :             :   /** Construct a term for type in contravaraint position. */
     264                 :             :   Term contra (Term variance) override;
     265                 :             : 
     266                 :             : private:
     267                 :             :   GenericTyPerCrateCtx &ctx;
     268                 :             : 
     269                 :             : private: // Per type processing context
     270                 :             :   /** Index of the solution first **lifetime param** for the current type. */
     271                 :             :   SolutionIndex first_lifetime = 0;
     272                 :             : 
     273                 :             :   /** Index of the solution first **type param** for the current type. */
     274                 :             :   SolutionIndex first_type = 0;
     275                 :             : 
     276                 :             :   /** Maps type param names to index among type params. */
     277                 :             :   std::vector<std::string> param_names;
     278                 :             : };
     279                 :             : 
     280                 :             : /** Visitor context for basic type variance analysis. */
     281                 :             : class TyVisitorCtx : public VarianceVisitorCtx<Variance>
     282                 :             : {
     283                 :             : public:
     284                 :             :   using Visitor = VisitorBase<Variance>;
     285                 :             : 
     286                 :         592 :   TyVisitorCtx (GenericTyPerCrateCtx &ctx) : ctx (ctx) {}
     287                 :             : 
     288                 :         516 :   std::vector<Variance> collect_variances (BaseType &ty)
     289                 :             :   {
     290                 :         516 :     add_constraints_from_ty (&ty, Variance::covariant ());
     291                 :         516 :     return variances;
     292                 :             :   }
     293                 :             : 
     294                 :          76 :   std::vector<Region> collect_regions (BaseType &ty)
     295                 :             :   {
     296                 :          76 :     add_constraints_from_ty (&ty, Variance::covariant ());
     297                 :          76 :     return regions;
     298                 :             :   }
     299                 :             : 
     300                 :             :   void add_constraints_from_ty (BaseType *ty, Variance variance) override;
     301                 :             :   void add_constraints_from_region (const Region &region,
     302                 :             :                                     Variance variance) override;
     303                 :             :   void add_constraints_from_generic_args (HirId ref, SubstitutionRef &subst,
     304                 :             :                                           Variance variance,
     305                 :             :                                           bool invariant_args) override;
     306                 :           0 :   void add_constrints_from_param (ParamType &param, Variance variance) override
     307                 :           0 :   {}
     308                 :             :   Variance contra (Variance variance) override;
     309                 :             : 
     310                 :             : private:
     311                 :             :   GenericTyPerCrateCtx &ctx;
     312                 :             :   std::vector<Variance> variances;
     313                 :             :   std::vector<Region> regions;
     314                 :             : };
     315                 :             : 
     316                 :             : /** Extracts regions of a field from regions of parent ADT. */
     317                 :             : class FieldVisitorCtx : public VarianceVisitorCtx<Variance>
     318                 :             : {
     319                 :             : public:
     320                 :             :   using Visitor = VisitorBase<Variance>;
     321                 :             : 
     322                 :             :   FreeRegions collect_regions (BaseType &ty);
     323                 :             : 
     324                 :           5 :   FieldVisitorCtx (GenericTyPerCrateCtx &ctx, const SubstitutionRef &subst,
     325                 :             :                    const FreeRegions &parent_regions)
     326                 :           5 :     : ctx (ctx), subst (subst), parent_regions (parent_regions)
     327                 :             :   {}
     328                 :             : 
     329                 :             :   void add_constraints_from_ty (BaseType *ty, Variance variance) override;
     330                 :             :   void add_constraints_from_region (const Region &region,
     331                 :             :                                     Variance variance) override;
     332                 :           2 :   void add_constraints_from_generic_args (HirId ref, SubstitutionRef &subst,
     333                 :             :                                           Variance variance,
     334                 :           2 :                                           bool invariant_args) override{};
     335                 :             :   void add_constrints_from_param (ParamType &param, Variance variance) override;
     336                 :             : 
     337                 :           0 :   Variance contra (Variance variance) override
     338                 :             :   {
     339                 :           0 :     return Variance::transform (variance, Variance::contravariant ());
     340                 :             :   }
     341                 :             : 
     342                 :             : private:
     343                 :             :   GenericTyPerCrateCtx &ctx;
     344                 :             :   const SubstitutionRef &subst;
     345                 :             :   FreeRegions regions;
     346                 :             :   FreeRegions parent_regions;
     347                 :             :   std::vector<size_t> type_param_ranges;
     348                 :             : };
     349                 :             : 
     350                 :             : } // namespace VarianceAnalysis
     351                 :             : 
     352                 :             : } // namespace TyTy
     353                 :             : } // namespace Rust
     354                 :             : 
     355                 :             : #endif // RUST_TYTY_VARIANCE_ANALYSIS_PRIVATE_H
        

Generated by: LCOV version 2.1-beta

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