1+ //! Data structures for refinement types.
2+ //!
3+ //! Thrust is a refinement type system, and so its analysis is about giving refinement types to
4+ //! variables and terms. This module defines the data structures for representing refinement
5+ //! types. The central data structure is [`RefinedType`], which is just [`Type`] plus [`Refinement`].
6+ //!
7+ //! Note that there are two notions of "variables" in this module. First is a type variable which is
8+ //! a polymorphic type parameter which is represented by [`TypeParamIdx`], and forms one of valid type as [`ParamType`].
9+ //! `T` in `struct S<T> { f: T }` is a type variable. See [`params`] module for the handling of type parameters.
10+ //! Second is a logical variable which is a variable that can appear in logical predicates.
11+ //! `x` and `y` in `{ x: int | x > y }` are logical variables.
12+ //! The actual representation of logical variables varies by context and so it is often parameterized
13+ //! as a type parameter in this module (`T` in `Type<T>`). In [`FunctionType`], logical variables are
14+ //! function parameters (`Type<FunctionParamIdx`), and during the actual analysis, logical variables are
15+ //! program variables bound in the environment (`Type<Var>`, see [`crate::refine::Var`]).
16+ //! We have [`RefinedTypeVar<T>`] to denote logical variables in refinement predicates, which
17+ //! accepts existential variables and a variable bound in the refinement type (`x` in `{ x: T | phi
18+ //! }`) in addition to variables `T` from the outer scope. This module also contains [`Closed`] which is
19+ //! used to denote a closed type, so `Type<Closed>` ensures no logical variables from the outer scope
20+ //! appear in that type.
21+ //!
22+ //! We have distinct types for each variant of [`Type`], such as [`FunctionType`] and
23+ //! [`PointerType`]. [`Type`], [`RefinedType`] and these variant types share some common operations:
24+ //!
25+ //! - `subst_var`: Substitutes logical variables with logical terms.
26+ //! - `map_var`: Maps logical variables to other logical variables.
27+ //! - `free_ty_params`: Collects free type parameters [`TypeParamIdx`] in the type.
28+ //! - `subst_ty_params`: Substitutes type parameters with other types. Since this replaces
29+ //! type parameters with refinement types, [`Type`] does not implement this, and
30+ //! [`RefinedType::subst_ty_params`] handles the substitution logic instead.
31+ //! - `strip_refinement`: Strips the refinements recursively and returns a [`Closed`] type.
32+ //!
33+ //! This module also implements several logics for manipulating refinement types and is extensively used in
34+ //! upstream logic in the [`crate::refine`] and [`crate::analyze`] modules.
35+ //!
36+ //! - [`template`]: Generates "template" refinement types with unknown predicates to be inferred.
37+ //! - [`subtyping`]: Generates CHC constraints [`crate::chc`] from subtyping relations between types.
38+ //! - [`clause_builder`]: Helper to build [`crate::chc::Clause`] from the refinement types.
39+
140use std:: collections:: { HashMap , HashSet } ;
241
342use pretty:: { termcolor, Pretty } ;
@@ -19,6 +58,11 @@ mod params;
1958pub use params:: { TypeParamIdx , TypeParamSubst , TypeParams } ;
2059
2160rustc_index:: newtype_index! {
61+ /// An index representing function parameter.
62+ ///
63+ /// We manage function parameters using indices that are unique in a function.
64+ /// [`FunctionType`] contains `IndexVec<FunctionParamIdx, RefinedType<FunctionParamIdx>>`
65+ /// that manages the indices and types of the function parameters.
2266 #[ orderable]
2367 #[ debug_format = "${}" ]
2468 pub struct FunctionParamIdx { }
3983 }
4084}
4185
86+ /// A function type.
87+ ///
88+ /// In Thrust, function types are closed. Because of that, function types, thus its parameters and
89+ /// return type only refer to the parameters of the function itself using [`FunctionParamIdx`] and
90+ /// do not accept other type of variables from the environment.
4291#[ derive( Debug , Clone ) ]
4392pub struct FunctionType {
4493 pub params : IndexVec < FunctionParamIdx , RefinedType < FunctionParamIdx > > ,
@@ -74,6 +123,8 @@ impl FunctionType {
74123 }
75124 }
76125
126+ /// Because function types are always closed in Thrust, we can convert this into
127+ /// [`Type<Closed>`].
77128 pub fn into_closed_ty ( self ) -> Type < Closed > {
78129 Type :: Function ( self )
79130 }
@@ -104,6 +155,7 @@ impl FunctionType {
104155 }
105156}
106157
158+ /// The kind of a reference, which is either mutable or immutable.
107159#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
108160pub enum RefKind {
109161 Mut ,
@@ -128,6 +180,7 @@ where
128180 }
129181}
130182
183+ /// The kind of a pointer, which is either a reference or an owned pointer.
131184#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
132185pub enum PointerKind {
133186 Ref ( RefKind ) ,
@@ -167,6 +220,7 @@ impl PointerKind {
167220 }
168221}
169222
223+ /// A pointer type.
170224#[ derive( Debug , Clone ) ]
171225pub struct PointerType < T > {
172226 pub kind : PointerKind ,
@@ -275,6 +329,11 @@ impl<T> PointerType<T> {
275329 }
276330}
277331
332+ /// A tuple type.
333+ ///
334+ /// Note that the current implementation uses tuples to represent structs. See
335+ /// implementation in `crate::refine::template` module for details.
336+ /// It is our TODO to improve the struct representation.
278337#[ derive( Debug , Clone ) ]
279338pub struct TupleType < T > {
280339 pub elems : Vec < RefinedType < T > > ,
@@ -374,13 +433,15 @@ impl<T> TupleType<T> {
374433 }
375434}
376435
436+ /// A definition of an enum variant, found in [`EnumDatatypeDef`].
377437#[ derive( Debug , Clone ) ]
378438pub struct EnumVariantDef {
379439 pub name : chc:: DatatypeSymbol ,
380440 pub discr : u32 ,
381441 pub field_tys : Vec < Type < Closed > > ,
382442}
383443
444+ /// A definition of an enum datatype.
384445#[ derive( Debug , Clone ) ]
385446pub struct EnumDatatypeDef {
386447 pub name : chc:: DatatypeSymbol ,
@@ -394,6 +455,9 @@ impl EnumDatatypeDef {
394455 }
395456}
396457
458+ /// An enum type.
459+ ///
460+ /// An enum type includes its type arguments and the argument types can refer to outer variables `T`.
397461#[ derive( Debug , Clone ) ]
398462pub struct EnumType < T > {
399463 pub symbol : chc:: DatatypeSymbol ,
@@ -495,6 +559,7 @@ impl<T> EnumType<T> {
495559 }
496560}
497561
562+ /// A type parameter.
498563#[ derive( Debug , Clone ) ]
499564pub struct ParamType {
500565 pub idx : TypeParamIdx ,
@@ -523,6 +588,7 @@ impl ParamType {
523588 }
524589}
525590
591+ /// An underlying type of a refinement type.
526592#[ derive( Debug , Clone ) ]
527593pub enum Type < T > {
528594 Int ,
@@ -803,6 +869,10 @@ impl Type<Closed> {
803869 }
804870}
805871
872+ /// A marker type for closed types.
873+ ///
874+ /// Because the value of `Closed` can never exist, `Type<Closed>` ensures that no
875+ /// logical variables from outer scope appear in the type.
806876#[ derive( Debug , Clone , Copy , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
807877pub enum Closed { }
808878
@@ -822,6 +892,11 @@ where
822892}
823893
824894rustc_index:: newtype_index! {
895+ /// An index representing existential variables.
896+ ///
897+ /// We manage existential variables using indices that are unique in a [`Formula`].
898+ /// [`Formula`] contains `IndexVec<ExistentialVarIdx, chc::Sort>` that manages the indices
899+ /// and sorts of the existential variables.
825900 #[ orderable]
826901 #[ debug_format = "e{}" ]
827902 pub struct ExistentialVarIdx { }
@@ -846,6 +921,15 @@ pub trait ShiftExistential {
846921 fn shift_existential ( self , offset : usize ) -> Self ;
847922}
848923
924+ /// A logical variable in a refinement predicate.
925+ ///
926+ /// Given a refinement type `{ v: T | ∃e. φ }`, there are three cases of logical variables
927+ /// occurring in the predicate `φ`:
928+ ///
929+ /// - `RefinedTypeVar::Value`: a variable `v` representing the value of the type
930+ /// - `RefinedTypeVar::Existential`: an existential variable `e`
931+ /// - `RefinedTypeVar::Free`: a variable from the outer scope, such as function parameters or
932+ /// variables bound in the environment
849933#[ derive( Clone , Copy , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
850934pub enum RefinedTypeVar < FV > {
851935 Value ,
@@ -908,6 +992,9 @@ impl<T> ShiftExistential for RefinedTypeVar<T> {
908992 }
909993}
910994
995+ /// A formula, potentially equipped with an existential quantifier.
996+ ///
997+ /// Note: This is not to be confused with [`crate::chc::Formula`] in the [`crate::chc`] module, which is a different notion.
911998#[ derive( Debug , Clone ) ]
912999pub struct Formula < V > {
9131000 pub existentials : IndexVec < ExistentialVarIdx , chc:: Sort > ,
@@ -1051,6 +1138,10 @@ where
10511138 }
10521139}
10531140
1141+ /// A refinement predicate in a refinement type.
1142+ ///
1143+ /// This is a [`Formula`], but gives an explicit representation of the kinds of variables that appear in
1144+ /// the refinement predicates. See [`RefinedTypeVar`] for details.
10541145pub type Refinement < FV = Closed > = Formula < RefinedTypeVar < FV > > ;
10551146
10561147impl < FV > Refinement < FV > {
@@ -1105,6 +1196,10 @@ impl<FV> Refinement<FV> {
11051196 }
11061197}
11071198
1199+ /// A helper type to map logical variables in a refinement at once.
1200+ ///
1201+ /// This is essentially just calling `Refinement::map_var`, but provides a convenient interface to
1202+ /// construct the mapping of the variables.
11081203#[ derive( Debug , Clone ) ]
11091204pub struct Instantiator < T > {
11101205 value_var : Option < T > ,
@@ -1140,6 +1235,7 @@ impl<T> Instantiator<T> {
11401235 }
11411236}
11421237
1238+ /// A refinement type.
11431239#[ derive( Debug , Clone ) ]
11441240pub struct RefinedType < FV = Closed > {
11451241 pub ty : Type < FV > ,
0 commit comments