Branch data Line data Source code
1 : : #ifndef RUST_TYTY_VARIANCE_ANALYSIS_H
2 : : #define RUST_TYTY_VARIANCE_ANALYSIS_H
3 : :
4 : : #include "rust-tyty.h"
5 : :
6 : : #include <rust-bir-free-region.h>
7 : :
8 : : namespace Rust {
9 : : namespace TyTy {
10 : : namespace VarianceAnalysis {
11 : :
12 : : class Variance;
13 : : class GenericTyPerCrateCtx;
14 : :
15 : : /** Per crate context for variance analysis. */
16 : : class CrateCtx
17 : : {
18 : : public:
19 : : CrateCtx ();
20 : : ~CrateCtx ();
21 : :
22 : : /** Add type to variance analysis context. */
23 : : void add_type_constraints (ADTType &type);
24 : :
25 : : /** Solve all constraints and print debug output. */
26 : : void solve ();
27 : :
28 : : /** Get variance of a type parameters. */
29 : : std::vector<Variance> query_generic_variance (const ADTType &type);
30 : :
31 : : /** Get variance of a type body (members, fn parameters...). */
32 : : std::vector<Variance> query_type_variances (BaseType *type);
33 : :
34 : : /** Get regions mentioned in a type. */
35 : : std::vector<Region> query_type_regions (BaseType *type);
36 : : std::vector<size_t> query_field_regions (const ADTType *parent,
37 : : size_t variant_index,
38 : : size_t field_index,
39 : : const FreeRegions &parent_regions);
40 : :
41 : : private:
42 : : std::unique_ptr<GenericTyPerCrateCtx> private_ctx;
43 : : };
44 : :
45 : : std::vector<size_t>
46 : : query_field_regions (const ADTType *parent, size_t variant_index,
47 : : size_t field_index, const FreeRegions &parent_regions);
48 : :
49 : : /** Variance semilattice */
50 : : class Variance
51 : : {
52 : : enum Kind : uint8_t
53 : : {
54 : : BIVARIANT = 0, // 0b00
55 : : COVARIANT = 1, // 0b01
56 : : CONTRAVARIANT = 2, // 0b10
57 : : INVARIANT = 3, // 0b11
58 : : } kind;
59 : :
60 : : static constexpr auto TOP = BIVARIANT;
61 : : static constexpr auto BOTTOM = INVARIANT;
62 : :
63 : 1139 : constexpr Variance (Kind kind) : kind (kind) {}
64 : :
65 : : public:
66 : : constexpr Variance () : kind (TOP) {}
67 : :
68 : : constexpr bool is_bivariant () const { return kind == BIVARIANT; }
69 : : constexpr bool is_covariant () const { return kind == COVARIANT; }
70 : : constexpr bool is_contravariant () const { return kind == CONTRAVARIANT; }
71 : : constexpr bool is_invariant () const { return kind == INVARIANT; }
72 : :
73 : : static constexpr Variance bivariant () { return {BIVARIANT}; }
74 : : static constexpr Variance covariant () { return {COVARIANT}; }
75 : : static constexpr Variance contravariant () { return {CONTRAVARIANT}; }
76 : : static constexpr Variance invariant () { return {INVARIANT}; }
77 : :
78 : : WARN_UNUSED_RESULT Variance reverse () const;
79 : : static WARN_UNUSED_RESULT Variance join (Variance lhs, Variance rhs);
80 : :
81 : : void join (Variance rhs);
82 : :
83 : : /**
84 : : * Variance composition function.
85 : : *
86 : : * For `A<X>` and `B<X>` and the composition `A<B<X>>` the variance of
87 : : * `v(A<B<X>>, X)` is defined as:
88 : : * ```
89 : : * v(A<B<X>>, X) = v(A<X>, X).transform(v(B<X>, X))
90 : : * ```
91 : : */
92 : : static WARN_UNUSED_RESULT Variance transform (Variance lhs, Variance rhs);
93 : :
94 : 110 : constexpr friend bool operator== (const Variance &lhs, const Variance &rhs)
95 : : {
96 : 110 : return lhs.kind == rhs.kind;
97 : : }
98 : 110 : constexpr friend bool operator!= (const Variance &lhs, const Variance &rhs)
99 : : {
100 : 110 : return !(lhs == rhs);
101 : : }
102 : :
103 : : WARN_UNUSED_RESULT std::string as_string () const;
104 : : };
105 : :
106 : : } // namespace VarianceAnalysis
107 : :
108 : : } // namespace TyTy
109 : : } // namespace Rust
110 : :
111 : : #endif // RUST_TYTY_VARIANCE_ANALYSIS_H
|