diff options
author | odersky <odersky@gmail.com> | 2016-10-14 22:47:55 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-10-14 22:47:55 +0200 |
commit | 5ebd55243ccc5ca637aa8c32f085a3ffb0fd93cb (patch) | |
tree | 03130cce971f54b5afd3a2404468d32f6691712b | |
parent | c5aa4ec052cae047486cffe7495d0bc02c103357 (diff) | |
parent | eca3f6997e324559aa499cced51a275fe118051f (diff) | |
download | dotty-5ebd55243ccc5ca637aa8c32f085a3ffb0fd93cb.tar.gz dotty-5ebd55243ccc5ca637aa8c32f085a3ffb0fd93cb.tar.bz2 dotty-5ebd55243ccc5ca637aa8c32f085a3ffb0fd93cb.zip |
Merge pull request #1597 from dotty-staging/fix-i1540
Fix #1540: overloaded get and isDefined in option-less patmat
-rw-r--r-- | src/dotty/tools/dotc/transform/PatternMatcher.scala | 22 | ||||
-rw-r--r-- | tests/pos/i1540.scala | 14 | ||||
-rw-r--r-- | tests/pos/i1540b.scala | 14 |
3 files changed, 41 insertions, 9 deletions
diff --git a/src/dotty/tools/dotc/transform/PatternMatcher.scala b/src/dotty/tools/dotc/transform/PatternMatcher.scala index 49c0eabec..8636d5084 100644 --- a/src/dotty/tools/dotc/transform/PatternMatcher.scala +++ b/src/dotty/tools/dotc/transform/PatternMatcher.scala @@ -240,17 +240,21 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer { val isDefined = extractorMemberType(prev.tpe, nme.isDefined) if ((isDefined isRef defn.BooleanClass) && getTp.exists) { - val tmpSym = freshSym(prev.pos, prev.tpe, "o") - val prevValue = ref(tmpSym).select("get".toTermName).ensureApplied + // isDefined and get may be overloaded + val getDenot = prev.tpe.member(nme.get).suchThat(_.info.isParameterless) + val isDefinedDenot = prev.tpe.member(nme.isDefined).suchThat(_.info.isParameterless) - Block( - List(ValDef(tmpSym, prev)), - // must be isEmpty and get as we don't control the target of the call (prev is an extractor call) - ifThenElseZero( - ref(tmpSym).select(nme.isDefined), - Block(List(ValDef(b.asTerm, prevValue)), next) - ) + val tmpSym = freshSym(prev.pos, prev.tpe, "o") + val prevValue = ref(tmpSym).select(getDenot.symbol).ensureApplied + + Block( + List(ValDef(tmpSym, prev)), + // must be isEmpty and get as we don't control the target of the call (prev is an extractor call) + ifThenElseZero( + ref(tmpSym).select(isDefinedDenot.symbol), + Block(List(ValDef(b.asTerm, prevValue)), next) ) + ) } else { assert(defn.isProductSubType(prev.tpe)) val nullCheck: Tree = prev.select(defn.Object_ne).appliedTo(Literal(Constant(null))) diff --git a/tests/pos/i1540.scala b/tests/pos/i1540.scala new file mode 100644 index 000000000..7aa24f459 --- /dev/null +++ b/tests/pos/i1540.scala @@ -0,0 +1,14 @@ +class Casey1(val a: Int) { + def isDefined: Boolean = true + def isDefined(x: Int): Boolean = ??? + def get: Int = a + def get(x: Int): String = ??? +} +object Casey1 { def unapply(a: Casey1) = a } + +object Test { + def main(args: Array[String]): Unit = { + val c @ Casey1(x) = new Casey1(0) + assert(x == c.get) + } +} diff --git a/tests/pos/i1540b.scala b/tests/pos/i1540b.scala new file mode 100644 index 000000000..2b4c5408e --- /dev/null +++ b/tests/pos/i1540b.scala @@ -0,0 +1,14 @@ +class Casey1[T](val a: T) { + def isDefined: Boolean = true + def isDefined(x: T): Boolean = ??? + def get: T = a + def get(x: T): String = ??? +} +object Casey1 { def unapply[T](a: Casey1[T]) = a } + +object Test { + def main(args: Array[String]): Unit = { + val c @ Casey1(x) = new Casey1(0) + assert(x == c.get) + } +} |