Skip to content

Commit 3a3b5e0

Browse files
committed
Refinements to realizability
- Unstable types can still be realizable (i.e. if their underlying type is concrete with no bad bounds). - SkolemTypes are unrealizable if there underlying type is.
1 parent 0c18756 commit 3a3b5e0

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,22 +66,33 @@ class CheckRealizable(implicit ctx: Context) {
6666
*/
6767
private def isLateInitialized(sym: Symbol) = sym.is(LateInitialized, butNot = Module)
6868

69+
def underlyingRealizability(tp: Type): Realizability =
70+
realizability(tp).mapError(r => new ProblemInUnderlying(tp, r))
71+
6972
/** The realizability status of given type `tp`*/
7073
def realizability(tp: Type): Realizability = tp.dealias match {
7174
case tp: TermRef =>
7275
val sym = tp.symbol
7376
if (sym.is(Stable)) realizability(tp.prefix)
7477
else {
7578
val r =
76-
if (!sym.isStable) NotStable
77-
else if (!isLateInitialized(sym)) Realizable
78-
else if (!sym.isEffectivelyFinal) new NotFinal(sym)
79-
else realizability(tp.info).mapError(r => new ProblemInUnderlying(tp.info, r))
79+
if (sym.isStable && !isLateInitialized(sym))
80+
// it's realizable because we know that the symbol has been created
81+
Realizable
82+
else if (!sym.isEffectivelyFinal)
83+
// it's potentially not realizable since it might be overridden with a member of nonrealizable type
84+
new NotFinal(sym)
85+
else
86+
// otherwise we need to look at the info to determine realizability
87+
// roughly: it's realizable if the info does not have bad bounds
88+
underlyingRealizability(tp.info)
8089
r andAlso {
8190
sym.setFlag(Stable)
8291
realizability(tp.prefix)
8392
}
8493
}
94+
case tp: SkolemType =>
95+
underlyingRealizability(tp.info)
8596
case _: SingletonType | NoPrefix =>
8697
Realizable
8798
case tp =>

0 commit comments

Comments
 (0)