Skip to content

Commit 5ebd552

Browse files
authored
Merge pull request #1597 from dotty-staging/fix-i1540
Fix #1540: overloaded get and isDefined in option-less patmat
2 parents c5aa4ec + eca3f69 commit 5ebd552

File tree

3 files changed

+41
-9
lines changed

3 files changed

+41
-9
lines changed

src/dotty/tools/dotc/transform/PatternMatcher.scala

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -240,17 +240,21 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
240240
val isDefined = extractorMemberType(prev.tpe, nme.isDefined)
241241

242242
if ((isDefined isRef defn.BooleanClass) && getTp.exists) {
243-
val tmpSym = freshSym(prev.pos, prev.tpe, "o")
244-
val prevValue = ref(tmpSym).select("get".toTermName).ensureApplied
243+
// isDefined and get may be overloaded
244+
val getDenot = prev.tpe.member(nme.get).suchThat(_.info.isParameterless)
245+
val isDefinedDenot = prev.tpe.member(nme.isDefined).suchThat(_.info.isParameterless)
245246

246-
Block(
247-
List(ValDef(tmpSym, prev)),
248-
// must be isEmpty and get as we don't control the target of the call (prev is an extractor call)
249-
ifThenElseZero(
250-
ref(tmpSym).select(nme.isDefined),
251-
Block(List(ValDef(b.asTerm, prevValue)), next)
252-
)
247+
val tmpSym = freshSym(prev.pos, prev.tpe, "o")
248+
val prevValue = ref(tmpSym).select(getDenot.symbol).ensureApplied
249+
250+
Block(
251+
List(ValDef(tmpSym, prev)),
252+
// must be isEmpty and get as we don't control the target of the call (prev is an extractor call)
253+
ifThenElseZero(
254+
ref(tmpSym).select(isDefinedDenot.symbol),
255+
Block(List(ValDef(b.asTerm, prevValue)), next)
253256
)
257+
)
254258
} else {
255259
assert(defn.isProductSubType(prev.tpe))
256260
val nullCheck: Tree = prev.select(defn.Object_ne).appliedTo(Literal(Constant(null)))

tests/pos/i1540.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class Casey1(val a: Int) {
2+
def isDefined: Boolean = true
3+
def isDefined(x: Int): Boolean = ???
4+
def get: Int = a
5+
def get(x: Int): String = ???
6+
}
7+
object Casey1 { def unapply(a: Casey1) = a }
8+
9+
object Test {
10+
def main(args: Array[String]): Unit = {
11+
val c @ Casey1(x) = new Casey1(0)
12+
assert(x == c.get)
13+
}
14+
}

tests/pos/i1540b.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class Casey1[T](val a: T) {
2+
def isDefined: Boolean = true
3+
def isDefined(x: T): Boolean = ???
4+
def get: T = a
5+
def get(x: T): String = ???
6+
}
7+
object Casey1 { def unapply[T](a: Casey1[T]) = a }
8+
9+
object Test {
10+
def main(args: Array[String]): Unit = {
11+
val c @ Casey1(x) = new Casey1(0)
12+
assert(x == c.get)
13+
}
14+
}

0 commit comments

Comments
 (0)