diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-01-29 18:47:01 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-01-29 18:56:07 +0100 |
commit | 0679da5440869d170df8a485db03532f9f49e04f (patch) | |
tree | eb0f80eb80606335abf35fa8216377469dad2d96 /src/compiler/scala/tools/nsc/backend/icode/GenICode.scala | |
parent | eff78b852e8b866badf9b9738f896c2a31c05474 (diff) | |
download | scala-0679da5440869d170df8a485db03532f9f49e04f.tar.gz scala-0679da5440869d170df8a485db03532f9f49e04f.tar.bz2 scala-0679da5440869d170df8a485db03532f9f49e04f.zip |
[backport] SI-6301 / SI-6572 specialization regressions
Squashed commit of the following:
commit a3680be29ccd5314c5d027d473b37940eaecd530
Author: Paul Phillips <paulp@improving.org>
Date: Fri Aug 31 10:20:16 2012 -0700
Actual fix for SI-6301, specialized crasher.
This means the workaround in the previous commit is no
longer reached, but it should remain where it is as a much
needed layer of robustness/useful error reporting.
Conflicts:
src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
commit f4c45ae204ce3ff3c16b19cab266d0b6515b6e0f
Author: Paul Phillips <paulp@improving.org>
Date: Fri Aug 31 10:49:24 2012 -0700
Rewrite of GenICode adapt.
Started for debuggability, stayed for clarify/performance.
Conflicts:
src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
commit 74842f72a0af485e5def796f777f7003f969d75b
Author: Paul Phillips <paulp@improving.org>
Date: Fri Aug 31 08:45:34 2012 -0700
Workaround for SI-6301, @specialize crasher.
SpecializeTypes is generating symbols with overloaded types
which then proceed to crash in CleanUp or GenICode. Until I
or someone works out why that is, take a look in case the
overload is easily disambiguated by the argument list arity,
in which case warn and proceed.
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/icode/GenICode.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/icode/GenICode.scala | 60 |
1 files changed, 22 insertions, 38 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index fd2b11898c..44d7a1929b 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -1164,34 +1164,28 @@ abstract class GenICode extends SubComponent { resCtx } - private def adapt(from: TypeKind, to: TypeKind, ctx: Context, pos: Position): Unit = { - if (!(from <:< to) && !(from == NullReference && to == NothingReference)) { - to match { - case UNIT => - ctx.bb.emit(DROP(from), pos) - debuglog("Dropped an " + from); - - case _ => - debugassert(from != UNIT, "Can't convert from UNIT to " + to + " at: " + pos) - assert(!from.isReferenceType && !to.isReferenceType, - "type error: can't convert from " + from + " to " + to +" in unit " + unit.source + " at " + pos) - - ctx.bb.emit(CALL_PRIMITIVE(Conversion(from, to)), pos) - } - } else if (from == NothingReference) { - ctx.bb.emit(THROW(ThrowableClass)) - ctx.bb.enterIgnoreMode - } else if (from == NullReference) { - ctx.bb.emit(DROP(from)) - ctx.bb.emit(CONSTANT(Constant(null))) + private def adapt(from: TypeKind, to: TypeKind, ctx: Context, pos: Position) { + // An awful lot of bugs explode here - let's leave ourselves more clues. + // A typical example is an overloaded type assigned after typer. + log(s"GenICode#adapt($from, $to, $ctx, $pos)") + + val conforms = (from <:< to) || (from == NullReference && to == NothingReference) + def coerce(from: TypeKind, to: TypeKind) = ctx.bb.emit(CALL_PRIMITIVE(Conversion(from, to)), pos) + def checkAssertions() { + def msg = s"Can't convert from $from to $to in unit ${unit.source} at $pos" + debugassert(from != UNIT, msg) + assert(!from.isReferenceType && !to.isReferenceType, msg) } - else if (from == ThrowableReference && !(ThrowableClass.tpe <:< to.toType)) { - log("Inserted check-cast on throwable to " + to + " at " + pos) - ctx.bb.emit(CHECK_CAST(to)) + if (conforms) from match { + case NothingReference => ctx.bb.emit(THROW(ThrowableClass)) ; ctx.bb.enterIgnoreMode + case NullReference => ctx.bb.emit(Seq(DROP(from), CONSTANT(Constant(null)))) + case ThrowableReference if !(ThrowableClass.tpe <:< to.toType) => ctx.bb.emit(CHECK_CAST(to)) // downcast throwables + case BYTE | SHORT | CHAR | INT if to == LONG => coerce(INT, LONG) // widen subrange types + case _ => () } - else (from, to) match { - case (BYTE, LONG) | (SHORT, LONG) | (CHAR, LONG) | (INT, LONG) => ctx.bb.emit(CALL_PRIMITIVE(Conversion(INT, LONG))) - case _ => () + else to match { + case UNIT => ctx.bb.emit(DROP(from), pos) // value discarding + case _ => checkAssertions() ; coerce(from, to) // other primitive coercions } } @@ -1907,18 +1901,8 @@ abstract class GenICode extends SubComponent { var handlerCount = 0 - override def toString(): String = { - val buf = new StringBuilder() - buf.append("\tpackage: ").append(packg).append('\n') - buf.append("\tclazz: ").append(clazz).append('\n') - buf.append("\tmethod: ").append(method).append('\n') - buf.append("\tbb: ").append(bb).append('\n') - buf.append("\tlabels: ").append(labels).append('\n') - buf.append("\texception handlers: ").append(handlers).append('\n') - buf.append("\tcleanups: ").append(cleanups).append('\n') - buf.append("\tscope: ").append(scope).append('\n') - buf.toString() - } + override def toString = + s"package $packg { class $clazz { def $method { bb=$bb } } }" def loadException(ctx: Context, exh: ExceptionHandler, pos: Position) = { debuglog("Emitting LOAD_EXCEPTION for class: " + exh.loadExceptionClass) |