@@ -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