summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2012-05-10 20:04:43 +0200
committerAdriaan Moors <adriaan.moors@epfl.ch>2012-05-10 20:04:43 +0200
commit289aced4a9a3f3ce4e351b3065a7f1ca4e5a37db (patch)
tree412b4df8c23d06e6b3650d89402e86e90dec43ae /src/compiler
parent782dad7619993d5f9ea358c41cd764ad0c692162 (diff)
downloadscala-289aced4a9a3f3ce4e351b3065a7f1ca4e5a37db.tar.gz
scala-289aced4a9a3f3ce4e351b3065a7f1ca4e5a37db.tar.bz2
scala-289aced4a9a3f3ce4e351b3065a7f1ca4e5a37db.zip
more defensive bridging to extractor: consider boolean
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala18
1 files changed, 12 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 9e7e4b3f4f..055d5d9c39 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -480,16 +480,22 @@ abstract class Erasure extends AddInterfaces
// TODO: should we do this for user-defined unapplies as well?
// does the first argument list have exactly one argument -- for user-defined unapplies we can't be sure
def maybeWrap(bridgingCall: Tree): Tree = {
- val canReturnNone = ( // can't statically know which member is going to be selected, so don't let this depend on member.isSynthetic
+ val guardExtractor = ( // can't statically know which member is going to be selected, so don't let this depend on member.isSynthetic
(member.name == nme.unapply || member.name == nme.unapplySeq)
&& !afterErasure((member.tpe <:< other.tpe))) // no static guarantees (TODO: is the subtype test ever true?)
- if (canReturnNone) {
- import CODE._
+ import CODE._
+ val _false = FALSE_typed
+ val pt = member.tpe.resultType
+ lazy val zero =
+ if (_false.tpe <:< pt) _false
+ else if (NoneModule.tpe <:< pt) REF(NoneModule)
+ else EmptyTree
+
+ if (guardExtractor && (zero ne EmptyTree)) {
val typeTest = gen.mkIsInstanceOf(REF(bridge.firstParam), member.tpe.params.head.tpe)
- IF (typeTest) THEN bridgingCall ELSE REF(NoneModule)
- }
- else bridgingCall
+ IF (typeTest) THEN bridgingCall ELSE zero
+ } else bridgingCall
}
val rhs = member.tpe match {
case MethodType(Nil, ConstantType(c)) => Literal(c)