Skip to content

Commit 45e1526

Browse files
committed
Widen unions before finding members
If a prefix in a findMember is an OrType, widen it to its join before computing the selection denotation. This mimics what is done if the prefix is pulled out into a temporary variable. Fixes #12909
1 parent 2ccf681 commit 45e1526

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2049,7 +2049,10 @@ object SymDenotations {
20492049

20502050
override final def findMember(name: Name, pre: Type, required: FlagSet, excluded: FlagSet)(using Context): Denotation =
20512051
val raw = if excluded.is(Private) then nonPrivateMembersNamed(name) else membersNamed(name)
2052-
raw.filterWithFlags(required, excluded).asSeenFrom(pre).toDenot(pre)
2052+
val pre1 = pre match
2053+
case pre: OrType => pre.widenUnion
2054+
case _ => pre
2055+
raw.filterWithFlags(required, excluded).asSeenFrom(pre1).toDenot(pre1)
20532056

20542057
final def findMemberNoShadowingBasedOnFlags(name: Name, pre: Type,
20552058
required: FlagSet = EmptyFlags, excluded: FlagSet = EmptyFlags)(using Context): Denotation =

tests/pos/i12909.scala

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package example
2+
3+
final case class Writer[W, A](run: (W, A)) {
4+
def map[B](f: A => B): Writer[W, B] = ???
5+
6+
def flatMap[B](f: A => Writer[W, B]): Writer[W, B] = ???
7+
}
8+
9+
object Main {
10+
implicit class WriterOps[A](a: A) {
11+
def set[W](w: W): Writer[W, A] = ???
12+
}
13+
14+
def x1[A]: Writer[Vector[String], Option[A]] = ???
15+
16+
val failure = for {
17+
a1 <- {
18+
Option(1) match {
19+
case Some(x) =>
20+
x1[Boolean]
21+
case _ =>
22+
Option.empty[Boolean].set(Vector.empty[String])
23+
}
24+
}
25+
a2 <- x1[String]
26+
} yield ()
27+
28+
val success = for {
29+
a1 <- {
30+
val temp = Option(1) match {
31+
case Some(x) =>
32+
x1[Boolean]
33+
case _ =>
34+
Option.empty[Boolean].set(Vector.empty[String])
35+
}
36+
// why ???
37+
temp
38+
}
39+
a2 <- x1[String]
40+
} yield ()
41+
42+
}

0 commit comments

Comments
 (0)