1 #ifndef RUST_TYTY_VARIANCE_ANALYSIS_PRIVATE_H
2 #define RUST_TYTY_VARIANCE_ANALYSIS_PRIVATE_H
4 #include "rust-tyty-variance-analysis.h"
6 #include "rust-tyty-visitor.h"
10 namespace VarianceAnalysis
{
12 using SolutionIndex
= uint32_t;
14 /** Term descibing variance relations. */
38 Term (Variance variance
) : kind (CONST
), const_val (variance
) {}
40 WARN_UNUSED_RESULT
bool is_const () const { return kind
== CONST
; }
42 static Term
make_ref (SolutionIndex index
);
44 static Term
make_transform (Term lhs
, Term rhs
);
47 /** Variance constraint of a type parameter. */
50 SolutionIndex target_index
;
54 /** Abstract variance visitor context. */
55 template <typename VARIANCE
> class VarianceVisitorCtx
58 virtual ~VarianceVisitorCtx () = default;
60 virtual void add_constraints_from_ty (BaseType
*ty
, VARIANCE variance
) = 0;
61 virtual void add_constraints_from_region (const Region
®ion
,
64 void add_constraints_from_mutability (BaseType
*type
, Mutability mutability
,
70 return add_constraints_from_ty (type
, variance
);
72 return add_constraints_from_ty (type
, Variance::invariant ());
76 add_constraints_from_generic_args (HirId ref
, SubstitutionRef
&subst
,
77 VARIANCE variance
, bool invariant_args
)
79 virtual void add_constrints_from_param (ParamType
¶m
, VARIANCE variance
)
81 virtual VARIANCE
contra (VARIANCE variance
) = 0;
84 template <typename VARIANCE
> class VisitorBase final
: public TyVisitor
86 VarianceVisitorCtx
<VARIANCE
> &ctx
;
90 VisitorBase (VarianceVisitorCtx
<VARIANCE
> &ctx
, VARIANCE variance
)
91 : ctx (ctx
), variance (variance
)
94 void visit (BoolType
&type
) override
{}
95 void visit (CharType
&type
) override
{}
96 void visit (IntType
&type
) override
{}
97 void visit (UintType
&type
) override
{}
98 void visit (FloatType
&type
) override
{}
99 void visit (USizeType
&type
) override
{}
100 void visit (ISizeType
&type
) override
{}
101 void visit (StrType
&type
) override
{}
102 void visit (NeverType
&type
) override
{}
104 void visit (ClosureType
&type
) override
{}
105 void visit (FnType
&type
) override
107 for (auto ®ion
: type
.get_used_arguments ().get_regions ())
108 ctx
.add_constraints_from_region (region
, Variance::invariant ());
111 void visit (ReferenceType
&type
) override
113 ctx
.add_constraints_from_region (type
.get_region (), variance
);
114 ctx
.add_constraints_from_mutability (type
.get_base (), type
.mutability (),
117 void visit (ArrayType
&type
) override
119 ctx
.add_constraints_from_ty (type
.get_element_type (), variance
);
121 void visit (SliceType
&type
) override
123 ctx
.add_constraints_from_ty (type
.get_element_type (), variance
);
125 void visit (PointerType
&type
) override
127 ctx
.add_constraints_from_ty (type
.get_base (), variance
);
128 ctx
.add_constraints_from_mutability (type
.get_base (), type
.mutability (),
131 void visit (TupleType
&type
) override
133 for (auto &elem
: type
.get_fields ())
134 ctx
.add_constraints_from_ty (elem
.get_tyty (), variance
);
136 void visit (ADTType
&type
) override
138 ctx
.add_constraints_from_generic_args (type
.get_orig_ref (), type
, variance
,
141 void visit (ProjectionType
&type
) override
143 ctx
.add_constraints_from_generic_args (type
.get_orig_ref (), type
, variance
,
146 void visit (ParamType
&type
) override
148 ctx
.add_constrints_from_param (type
, variance
);
150 void visit (FnPtr
&type
) override
152 auto contra
= ctx
.contra (variance
);
154 for (auto ¶m
: type
.get_params ())
156 ctx
.add_constraints_from_ty (param
.get_tyty (), contra
);
159 ctx
.add_constraints_from_ty (type
.get_return_type (), variance
);
162 void visit (ErrorType
&type
) override
{}
164 void visit (PlaceholderType
&type
) override
{ rust_unreachable (); }
165 void visit (InferType
&type
) override
{ rust_unreachable (); }
167 void visit (DynamicObjectType
&type
) override
173 /** Per crate context for generic type variance analysis. */
174 class GenericTyPerCrateCtx
176 public: // External API
177 /** Add a type to context and process its variance constraints. */
178 void process_type (ADTType
&ty
);
181 * Solve for all variance constraints and clear temporary data.
183 * Only keeps the results.
187 /** Prints solution debug output. To be called after solve. */
188 void debug_print_solutions ();
190 tl::optional
<SolutionIndex
> lookup_type_index (HirId orig_ref
);
192 public: // Module internal API
193 /** Format term tree to string. */
194 WARN_UNUSED_RESULT
std::string
to_string (const Term
&term
) const;
196 /** Formats as <type ident>`[`<param index>``]` */
197 WARN_UNUSED_RESULT
std::string
to_string (SolutionIndex index
) const;
199 /** Evaluate a variance relation expression (term tree). */
200 Variance
evaluate (Term
*term
);
202 std::vector
<Variance
> query_generic_variance (const ADTType
&type
);
204 std::vector
<size_t> query_field_regions (const ADTType
*parent
,
205 size_t variant_index
,
207 const FreeRegions
&parent_regions
);
209 std::vector
<Region
> query_type_regions (BaseType
*base
);
211 public: // Data used by visitors.
212 // This whole class is private, therfore members can be public.
214 /** Current solutions. Initiated to bivariant. */
215 std::vector
<Variance
> solutions
;
217 /** Constrains on solutions. Iteratively applied until fixpoint. */
218 std::vector
<Constraint
> constraints
;
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
;
224 /** Visitor context for generic type variance analysis used for processing of a
226 class GenericTyVisitorCtx
: VarianceVisitorCtx
<Term
>
228 using Visitor
= VisitorBase
<Term
>;
231 explicit GenericTyVisitorCtx (GenericTyPerCrateCtx
&ctx
) : ctx (ctx
) {}
232 /** Entry point: Add a type to context and process its variance constraints.
234 void process_type (ADTType
&ty
);
237 /** Resolve a type from a TyTy::ref. */
238 SolutionIndex
lookup_or_add_type (HirId hir_id
);
240 /** Visit an inner type and add its constraints. */
241 void add_constraints_from_ty (BaseType
*ty
, Term variance
) override
;
243 void add_constraint (SolutionIndex index
, Term term
);
245 void add_constraints_from_region (const Region
®ion
, Term term
) override
;
247 void add_constraints_from_generic_args (HirId ref
, SubstitutionRef
&subst
,
249 bool invariant_args
) override
;
251 void add_constrints_from_param (ParamType
&type
, Term variance
) override
;
253 /** Construct a term for type in contravaraint position. */
254 Term
contra (Term variance
) override
;
257 GenericTyPerCrateCtx
&ctx
;
259 private: // Per type processing context
260 /** Index of the solution first **lifetime param** for the current type. */
261 SolutionIndex first_lifetime
= 0;
263 /** Index of the solution first **type param** for the current type. */
264 SolutionIndex first_type
= 0;
266 /** Maps type param names to index among type params. */
267 std::vector
<std::string
> param_names
;
270 /** Visitor context for basic type variance analysis. */
271 class TyVisitorCtx
: public VarianceVisitorCtx
<Variance
>
274 using Visitor
= VisitorBase
<Variance
>;
276 TyVisitorCtx (GenericTyPerCrateCtx
&ctx
) : ctx (ctx
) {}
278 std::vector
<Variance
> collect_variances (BaseType
&ty
)
280 add_constraints_from_ty (&ty
, Variance::covariant ());
284 std::vector
<Region
> collect_regions (BaseType
&ty
)
286 add_constraints_from_ty (&ty
, Variance::covariant ());
290 void add_constraints_from_ty (BaseType
*ty
, Variance variance
) override
;
291 void add_constraints_from_region (const Region
®ion
,
292 Variance variance
) override
;
293 void add_constraints_from_generic_args (HirId ref
, SubstitutionRef
&subst
,
295 bool invariant_args
) override
;
296 void add_constrints_from_param (ParamType
¶m
, Variance variance
) override
298 Variance
contra (Variance variance
) override
;
301 GenericTyPerCrateCtx
&ctx
;
302 std::vector
<Variance
> variances
;
303 std::vector
<Region
> regions
;
306 /** Extracts regions of a field from regions of parent ADT. */
307 class FieldVisitorCtx
: public VarianceVisitorCtx
<Variance
>
310 using Visitor
= VisitorBase
<Variance
>;
312 std::vector
<size_t> collect_regions (BaseType
&ty
);
314 FieldVisitorCtx (GenericTyPerCrateCtx
&ctx
, const SubstitutionRef
&subst
,
315 const FreeRegions
&parent_regions
)
316 : ctx (ctx
), subst (subst
), parent_regions (parent_regions
)
319 void add_constraints_from_ty (BaseType
*ty
, Variance variance
) override
;
320 void add_constraints_from_region (const Region
®ion
,
321 Variance variance
) override
;
322 void add_constraints_from_generic_args (HirId ref
, SubstitutionRef
&subst
,
324 bool invariant_args
) override
{};
325 void add_constrints_from_param (ParamType
¶m
, Variance variance
) override
;
327 Variance
contra (Variance variance
) override
329 return Variance::transform (variance
, Variance::contravariant ());
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
;
340 } // namespace VarianceAnalysis
345 #endif // RUST_TYTY_VARIANCE_ANALYSIS_PRIVATE_H