Skip to content

Commit

Permalink
Merge pull request scala#4919 from abeln/refined-type-comment
Browse files Browse the repository at this point in the history
Improve documentation on refinement/recursive types
  • Loading branch information
Blaisorblade authored Aug 10, 2018
2 parents dbc8d80 + ab8e431 commit 9b7721c
Showing 1 changed file with 31 additions and 4 deletions.
35 changes: 31 additions & 4 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2309,9 +2309,9 @@ object Types {
}

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

Expand Down Expand Up @@ -2370,6 +2370,31 @@ object Types {
}
}

/** A recursive type. Instances should be constructed via the companion object.
*
* @param parentExp A function that, given a recursive type R, produces a type
* that can refer to R via a `RecThis(R)` node. This is used to
* "tie the knot".
*
* For example, in
* class C { type T1; type T2 }
* type C2 = C { type T1; type T2 = T1 }
*
* The type of `C2` is a recursive type `{(x) => C{T1; T2 = x.T1}}`, written as
*
* RecType(
* RefinedType(
* RefinedType(
* TypeRef(...,class C),
* T1,
* TypeBounds(...)),
* T2,
* TypeBounds(
* TypeRef(RecThis(...),T1),
* TypeRef(RecThis(...),T1))))
*
* Where `RecThis(...)` points back to the enclosing `RecType`.
*/
class RecType(parentExp: RecType => Type) extends RefinedOrRecType with BindingType {

// See discussion in findMember#goRec why these vars are needed
Expand Down Expand Up @@ -2438,7 +2463,7 @@ object Types {
* 1. Nested Rec types on the type's spine are merged with the outer one.
* 2. Any refinement of the form `type T = z.T` on the spine of the type
* where `z` refers to the created rec-type is replaced by
* `type T`. This avoids infinite recursons later when we
* `type T`. This avoids infinite recursions later when we
* try to follow these references.
* TODO: Figure out how to guarantee absence of cycles
* of length > 1
Expand All @@ -2459,6 +2484,8 @@ object Types {
}
unique(rt.derivedRecType(normalize(rt.parent))).checkInst
}

/** Create a `RecType`, but only if the type generated by `parentExp` is indeed recursive. */
def closeOver(parentExp: RecType => Type)(implicit ctx: Context) = {
val rt = this(parentExp)
if (rt.isReferredToBy(rt.parent)) rt else rt.parent
Expand Down

0 comments on commit 9b7721c

Please sign in to comment.