From 289aced4a9a3f3ce4e351b3065a7f1ca4e5a37db Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Thu, 10 May 2012 20:04:43 +0200 Subject: more defensive bridging to extractor: consider boolean --- src/compiler/scala/tools/nsc/transform/Erasure.scala | 18 ++++++++++++------ 1 file 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) -- cgit v1.2.3