@@ -2309,9 +2309,9 @@ object Types {
2309
2309
}
2310
2310
2311
2311
/** 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
2315
2315
*/
2316
2316
abstract case class RefinedType (parent : Type , refinedName : Name , refinedInfo : Type ) extends RefinedOrRecType {
2317
2317
@@ -2370,6 +2370,31 @@ object Types {
2370
2370
}
2371
2371
}
2372
2372
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
+ */
2373
2398
class RecType (parentExp : RecType => Type ) extends RefinedOrRecType with BindingType {
2374
2399
2375
2400
// See discussion in findMember#goRec why these vars are needed
@@ -2438,7 +2463,7 @@ object Types {
2438
2463
* 1. Nested Rec types on the type's spine are merged with the outer one.
2439
2464
* 2. Any refinement of the form `type T = z.T` on the spine of the type
2440
2465
* 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
2442
2467
* try to follow these references.
2443
2468
* TODO: Figure out how to guarantee absence of cycles
2444
2469
* of length > 1
@@ -2459,6 +2484,8 @@ object Types {
2459
2484
}
2460
2485
unique(rt.derivedRecType(normalize(rt.parent))).checkInst
2461
2486
}
2487
+
2488
+ /** Create a `RecType`, but only if the type generated by `parentExp` is indeed recursive. */
2462
2489
def closeOver (parentExp : RecType => Type )(implicit ctx : Context ) = {
2463
2490
val rt = this (parentExp)
2464
2491
if (rt.isReferredToBy(rt.parent)) rt else rt.parent
0 commit comments