Skip to content

Commit

Permalink
skip null check if the paramType is primitive
Browse files Browse the repository at this point in the history
  • Loading branch information
eed3si9n committed Apr 7, 2018
1 parent 9f24aa4 commit cee9f3a
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 8 deletions.
Expand Up @@ -364,7 +364,7 @@ trait MatchApproximation extends TreeAndTypeAnalysis with ScalaLogic with MatchT
case AlternativesTreeMaker(_, altss, _) => \/(altss map (alts => /\(alts map this)))
case ProductExtractorTreeMaker(testedBinder, None) => uniqueNonNullProp(binderToUniqueTree(testedBinder))
case SubstOnlyTreeMaker(_, _) => True
case NonNullTestTreeMaker(prevBinder, _) => uniqueNonNullProp(binderToUniqueTree(prevBinder))
case NonNullTestTreeMaker(prevBinder, _, _) => uniqueNonNullProp(binderToUniqueTree(prevBinder))
case GuardTreeMaker(guard) =>
guard.tpe match {
case ConstantTrue => True
Expand Down
Expand Up @@ -112,7 +112,7 @@ trait MatchTranslation {
// Statically conforms to paramType
if (tpe <:< paramType) {
// enforce all extractor patterns to be non-null
val nonNullTest = NonNullTestTreeMaker(binder, pos)
val nonNullTest = NonNullTestTreeMaker(binder, paramType, pos)
val unappBinder = nonNullTest.nextBinder
(nonNullTest :: treeMakers(unappBinder, pos), unappBinder)
}
Expand All @@ -128,7 +128,7 @@ trait MatchTranslation {
val unappBinder = typeTest.nextBinder
(typeTest :: treeMakers(unappBinder, pos), unappBinder)
} else {
val nonNullTest = NonNullTestTreeMaker(typeTest.nextBinder, pos)
val nonNullTest = NonNullTestTreeMaker(typeTest.nextBinder, paramType, pos)
val unappBinder = nonNullTest.nextBinder
(typeTest :: nonNullTest :: treeMakers(unappBinder, pos), unappBinder)
}
Expand Down
Expand Up @@ -192,16 +192,24 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging {
* Make a TreeMaker that performs null check.
* This is called prior to extractor call.
*/
case class NonNullTestTreeMaker(prevBinder: Symbol, override val pos: Position) extends FunTreeMaker {
case class NonNullTestTreeMaker(
prevBinder: Symbol,
expectedTp: Type,
override val pos: Position) extends FunTreeMaker {
import CODE._
override lazy val nextBinder = prevBinder.asTerm // just passing through
val nextBinderTp = nextBinder.info.widen

val nullCheck = REF(prevBinder) OBJ_NE NULL
lazy val localSubstitution = Substitution(Nil, Nil)

def isExpectedPrimitiveType = isPrimitiveValueType(expectedTp)

def chainBefore(next: Tree)(casegen: Casegen): Tree =
atPos(pos)(casegen.ifThenElseZero(nullCheck, next))
atPos(pos) {
if (isExpectedPrimitiveType) next
else casegen.ifThenElseZero(nullCheck, next)
}

override def toString = s"NN(${prevBinder.name})"
}
Expand Down
29 changes: 26 additions & 3 deletions test/files/run/t6288.check
Expand Up @@ -56,9 +56,9 @@
}
}
};
[224]object Case5 extends [230][312]scala.AnyRef {
[312]def <init>(): [230]Case5.type = [312]{
[312][312][312]Case5.super.<init>();
[224]object Case5 extends [230][313]scala.AnyRef {
[313]def <init>(): [230]Case5.type = [313]{
[313][313][313]Case5.super.<init>();
[230]()
};
[238]def unapply([246]z: [249]<type: [249]scala.Any>): [238]Boolean = [265]true;
Expand All @@ -83,6 +83,29 @@
[273]x
}
}
};
[320]object Case6 extends [326][417]scala.AnyRef {
[417]def <init>(): [326]Case6.type = [417]{
[417][417][417]Case6.super.<init>();
[326]()
};
[334]def unapply([342]z: [345]<type: [345]scala.Int>): [334]Option[Int] = [369][365][365]scala.Some.apply[[365]Int]([370]-1);
[377]{
[377]case <synthetic> val x1: [377]Int = [377]0;
[377]case5()[396]{
[396]<synthetic> val o7: [396]Option[Int] = [396][396]Case6.unapply([396]x1);
[396]if ([396]o7.isEmpty.unary_!)
[409][409]matchEnd4([409]())
else
[396][396]case6()
};
[377]case6(){
[377][377]matchEnd4([377]throw [377][377][377]new [377]MatchError([377]x1))
};
[377]matchEnd4(x: [NoPosition]Unit){
[377]x
}
}
}
}

6 changes: 6 additions & 0 deletions test/files/run/t6288.scala
Expand Up @@ -28,7 +28,13 @@ object Test extends DirectTest {
| case Case4() => ()
| }
|}
|object Case6 {
| def unapply(z: Int): Option[Int] = Some(-1)
|
| 0 match {
| case Case6(nr) => ()
| }
|}
|""".stripMargin.trim

override def show(): Unit = {
Expand Down

0 comments on commit cee9f3a

Please sign in to comment.