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: 2026-02-28 14:20:25 Functions: 44.6 % 65 29
Legend: Lines:     hit not hit

            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         4306 :   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         3665 : template <typename VARIANCE> class VarianceVisitorCtx
      60              : {
      61              : public:
      62         3068 :   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         6093 :   VisitorBase (VarianceVisitorCtx<VARIANCE> &ctx, VARIANCE variance)
      95         6093 :     : ctx (ctx), variance (variance)
      96              :   {}
      97              : 
      98          206 :   void visit (BoolType &type) override {}
      99           47 :   void visit (CharType &type) override {}
     100         2006 :   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         4510 : 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         3068 : class GenericTyVisitorCtx : VarianceVisitorCtx<Term>
     237              : {
     238              :   using Visitor = VisitorBase<Term>;
     239              : 
     240              : public:
     241         3068 :   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.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.