Skip to content

Commit ab8e431

Browse files
committed
Improve documentation on refinement/recursive types
1 parent dbc8d80 commit ab8e431

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2309,9 +2309,9 @@ object Types {
23092309
}
23102310

23112311
/** A refined type parent { refinement }
2312-
* @param refinedName The name of the refinement declaration
2313-
* @param infoFn: A function that produces the info of the refinement declaration,
2314-
* given the refined type itself.
2312+
* @param parent The type being refined
2313+
* @param refinedName The name of the refinement declaration
2314+
* @param refinedInfo The info of the refinement declaration
23152315
*/
23162316
abstract case class RefinedType(parent: Type, refinedName: Name, refinedInfo: Type) extends RefinedOrRecType {
23172317

@@ -2370,6 +2370,31 @@ object Types {
23702370
}
23712371
}
23722372

2373+
/** A recursive type. Instances should be constructed via the companion object.
2374+
*
2375+
* @param parentExp A function that, given a recursive type R, produces a type
2376+
* that can refer to R via a `RecThis(R)` node. This is used to
2377+
* "tie the knot".
2378+
*
2379+
* For example, in
2380+
* class C { type T1; type T2 }
2381+
* type C2 = C { type T1; type T2 = T1 }
2382+
*
2383+
* The type of `C2` is a recursive type `{(x) => C{T1; T2 = x.T1}}`, written as
2384+
*
2385+
* RecType(
2386+
* RefinedType(
2387+
* RefinedType(
2388+
* TypeRef(...,class C),
2389+
* T1,
2390+
* TypeBounds(...)),
2391+
* T2,
2392+
* TypeBounds(
2393+
* TypeRef(RecThis(...),T1),
2394+
* TypeRef(RecThis(...),T1))))
2395+
*
2396+
* Where `RecThis(...)` points back to the enclosing `RecType`.
2397+
*/
23732398
class RecType(parentExp: RecType => Type) extends RefinedOrRecType with BindingType {
23742399

23752400
// See discussion in findMember#goRec why these vars are needed
@@ -2438,7 +2463,7 @@ object Types {
24382463
* 1. Nested Rec types on the type's spine are merged with the outer one.
24392464
* 2. Any refinement of the form `type T = z.T` on the spine of the type
24402465
* where `z` refers to the created rec-type is replaced by
2441-
* `type T`. This avoids infinite recursons later when we
2466+
* `type T`. This avoids infinite recursions later when we
24422467
* try to follow these references.
24432468
* TODO: Figure out how to guarantee absence of cycles
24442469
* of length > 1
@@ -2459,6 +2484,8 @@ object Types {
24592484
}
24602485
unique(rt.derivedRecType(normalize(rt.parent))).checkInst
24612486
}
2487+
2488+
/** Create a `RecType`, but only if the type generated by `parentExp` is indeed recursive. */
24622489
def closeOver(parentExp: RecType => Type)(implicit ctx: Context) = {
24632490
val rt = this(parentExp)
24642491
if (rt.isReferredToBy(rt.parent)) rt else rt.parent

0 commit comments

Comments
 (0)