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