diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 9e7e4b3f4f8c..055d5d9c39bf 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)