Skip to content

Commit 54f5899

Browse files
committed
Hardening of sigName for ill-formed valueclasses
Need to survive even if a value class does not have an underlying type. Also: better diagnostics if sigName goes wrong.
1 parent 1eb26f5 commit 54f5899

File tree

1 file changed

+43
-33
lines changed

1 file changed

+43
-33
lines changed

src/dotty/tools/dotc/core/TypeErasure.scala

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -401,10 +401,10 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
401401
private def eraseDerivedValueClassRef(tref: TypeRef)(implicit ctx: Context): Type = {
402402
val cls = tref.symbol.asClass
403403
val underlying = underlyingOfValueClass(cls)
404-
ErasedValueType(cls, valueErasure(underlying))
404+
if (underlying.exists) ErasedValueType(cls, valueErasure(underlying))
405+
else NoType
405406
}
406407

407-
408408
private def eraseNormalClassRef(tref: TypeRef)(implicit ctx: Context): Type = {
409409
val cls = tref.symbol.asClass
410410
(if (cls.owner is Package) normalizeClass(cls) else cls).typeRef
@@ -439,36 +439,46 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
439439
/** The name of the type as it is used in `Signature`s.
440440
* Need to ensure correspondence with erasure!
441441
*/
442-
private def sigName(tp: Type)(implicit ctx: Context): TypeName = tp match {
443-
case ErasedValueType(_, underlying) =>
444-
sigName(underlying)
445-
case tp: TypeRef =>
446-
if (!tp.denot.exists) throw new MissingType(tp.prefix, tp.name)
447-
val sym = tp.symbol
448-
if (!sym.isClass) {
449-
val info = tp.info
450-
if (!info.exists) assert(false, "undefined: $tp with symbol $sym")
451-
sigName(info)
452-
}
453-
else if (isDerivedValueClass(sym)) sigName(eraseDerivedValueClassRef(tp))
454-
else normalizeClass(sym.asClass).fullName.asTypeName
455-
case defn.ArrayType(elem) =>
456-
sigName(this(tp))
457-
case JavaArrayType(elem) =>
458-
sigName(elem) ++ "[]"
459-
case tp: TermRef =>
460-
sigName(tp.widen)
461-
case ExprType(rt) =>
462-
sigName(defn.FunctionType(Nil, rt))
463-
case tp: TypeProxy =>
464-
sigName(tp.underlying)
465-
case ErrorType | WildcardType =>
466-
tpnme.WILDCARD
467-
case tp: WildcardType =>
468-
sigName(tp.optBounds)
469-
case _ =>
470-
val erased = this(tp)
471-
assert(erased ne tp, tp)
472-
sigName(erased)
442+
private def sigName(tp: Type)(implicit ctx: Context): TypeName = try {
443+
tp match {
444+
case ErasedValueType(_, underlying) =>
445+
sigName(underlying)
446+
case tp: TypeRef =>
447+
if (!tp.denot.exists) throw new MissingType(tp.prefix, tp.name)
448+
val sym = tp.symbol
449+
var edvc: Type = null
450+
def dvcErasure: Type = {
451+
if (edvc == null) edvc = eraseDerivedValueClassRef(tp)
452+
edvc
453+
}
454+
if (!sym.isClass) {
455+
val info = tp.info
456+
if (!info.exists) assert(false, "undefined: $tp with symbol $sym")
457+
sigName(info)
458+
} else if (isDerivedValueClass(sym) && dvcErasure.exists) sigName(dvcErasure)
459+
else normalizeClass(sym.asClass).fullName.asTypeName
460+
case defn.ArrayType(elem) =>
461+
sigName(this(tp))
462+
case JavaArrayType(elem) =>
463+
sigName(elem) ++ "[]"
464+
case tp: TermRef =>
465+
sigName(tp.widen)
466+
case ExprType(rt) =>
467+
sigName(defn.FunctionType(Nil, rt))
468+
case tp: TypeProxy =>
469+
sigName(tp.underlying)
470+
case ErrorType | WildcardType =>
471+
tpnme.WILDCARD
472+
case tp: WildcardType =>
473+
sigName(tp.optBounds)
474+
case _ =>
475+
val erased = this(tp)
476+
assert(erased ne tp, tp)
477+
sigName(erased)
478+
}
479+
} catch {
480+
case ex: AssertionError =>
481+
println(s"no sig for $tp")
482+
throw ex
473483
}
474484
}

0 commit comments

Comments
 (0)