Skip to content

Commit

Permalink
Hardening of sigName for ill-formed valueclasses
Browse files Browse the repository at this point in the history
Need to survive even if a value class does not have an
underlying type. Also: better diagnostics if sigName
goes wrong.
  • Loading branch information
odersky committed Oct 22, 2015
1 parent 1eb26f5 commit 54f5899
Showing 1 changed file with 43 additions and 33 deletions.
76 changes: 43 additions & 33 deletions src/dotty/tools/dotc/core/TypeErasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -401,10 +401,10 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
private def eraseDerivedValueClassRef(tref: TypeRef)(implicit ctx: Context): Type = {
val cls = tref.symbol.asClass
val underlying = underlyingOfValueClass(cls)
ErasedValueType(cls, valueErasure(underlying))
if (underlying.exists) ErasedValueType(cls, valueErasure(underlying))
else NoType
}


private def eraseNormalClassRef(tref: TypeRef)(implicit ctx: Context): Type = {
val cls = tref.symbol.asClass
(if (cls.owner is Package) normalizeClass(cls) else cls).typeRef
Expand Down Expand Up @@ -439,36 +439,46 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
/** The name of the type as it is used in `Signature`s.
* Need to ensure correspondence with erasure!
*/
private def sigName(tp: Type)(implicit ctx: Context): TypeName = tp match {
case ErasedValueType(_, underlying) =>
sigName(underlying)
case tp: TypeRef =>
if (!tp.denot.exists) throw new MissingType(tp.prefix, tp.name)
val sym = tp.symbol
if (!sym.isClass) {
val info = tp.info
if (!info.exists) assert(false, "undefined: $tp with symbol $sym")
sigName(info)
}
else if (isDerivedValueClass(sym)) sigName(eraseDerivedValueClassRef(tp))
else normalizeClass(sym.asClass).fullName.asTypeName
case defn.ArrayType(elem) =>
sigName(this(tp))
case JavaArrayType(elem) =>
sigName(elem) ++ "[]"
case tp: TermRef =>
sigName(tp.widen)
case ExprType(rt) =>
sigName(defn.FunctionType(Nil, rt))
case tp: TypeProxy =>
sigName(tp.underlying)
case ErrorType | WildcardType =>
tpnme.WILDCARD
case tp: WildcardType =>
sigName(tp.optBounds)
case _ =>
val erased = this(tp)
assert(erased ne tp, tp)
sigName(erased)
private def sigName(tp: Type)(implicit ctx: Context): TypeName = try {
tp match {
case ErasedValueType(_, underlying) =>
sigName(underlying)
case tp: TypeRef =>
if (!tp.denot.exists) throw new MissingType(tp.prefix, tp.name)
val sym = tp.symbol
var edvc: Type = null
def dvcErasure: Type = {
if (edvc == null) edvc = eraseDerivedValueClassRef(tp)
edvc
}
if (!sym.isClass) {
val info = tp.info
if (!info.exists) assert(false, "undefined: $tp with symbol $sym")
sigName(info)
} else if (isDerivedValueClass(sym) && dvcErasure.exists) sigName(dvcErasure)
else normalizeClass(sym.asClass).fullName.asTypeName
case defn.ArrayType(elem) =>
sigName(this(tp))
case JavaArrayType(elem) =>
sigName(elem) ++ "[]"
case tp: TermRef =>
sigName(tp.widen)
case ExprType(rt) =>
sigName(defn.FunctionType(Nil, rt))
case tp: TypeProxy =>
sigName(tp.underlying)
case ErrorType | WildcardType =>
tpnme.WILDCARD
case tp: WildcardType =>
sigName(tp.optBounds)
case _ =>
val erased = this(tp)
assert(erased ne tp, tp)
sigName(erased)
}
} catch {
case ex: AssertionError =>
println(s"no sig for $tp")
throw ex
}
}

0 comments on commit 54f5899

Please sign in to comment.