Skip to content

Commit

Permalink
Merge pull request scala#12925 from dotty-staging/fix-12909
Browse files Browse the repository at this point in the history
Widen unions before finding members
  • Loading branch information
smarter authored Jun 25, 2021
2 parents cd626da + a0e4b8a commit b3ade17
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 7 deletions.
5 changes: 4 additions & 1 deletion compiler/src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2049,7 +2049,10 @@ object SymDenotations {

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

final def findMemberNoShadowingBasedOnFlags(name: Name, pre: Type,
required: FlagSet = EmptyFlags, excluded: FlagSet = EmptyFlags)(using Context): Denotation =
Expand Down
23 changes: 17 additions & 6 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1282,13 +1282,10 @@ object Types {
case tp =>
tp.widenUnionWithoutNull

/** Overridden in OrType */
def widenUnionWithoutNull(using Context): Type = widen match
case tp @ OrType(lhs, rhs) if tp.isSoft =>
TypeComparer.lub(lhs.widenUnionWithoutNull, rhs.widenUnionWithoutNull, canConstrain = true) match
case union: OrType => union.join
case res => res
case tp: AndOrType =>
tp.derivedAndOrType(tp.tp1.widenUnionWithoutNull, tp.tp2.widenUnionWithoutNull)
case tp: AndType =>
tp.derivedAndType(tp.tp1.widenUnionWithoutNull, tp.tp2.widenUnionWithoutNull)
case tp: RefinedType =>
tp.derivedRefinedType(tp.parent.widenUnion, tp.refinedName, tp.refinedInfo)
case tp: RecType =>
Expand Down Expand Up @@ -3198,6 +3195,20 @@ object Types {
myJoin
}

private var myUnion: Type = _
private var myUnionPeriod: Period = Nowhere

override def widenUnionWithoutNull(using Context): Type =
if myUnionPeriod != ctx.period then
myUnion =
if isSoft then
TypeComparer.lub(tp1.widenUnionWithoutNull, tp2.widenUnionWithoutNull, canConstrain = true) match
case union: OrType => union.join
case res => res
else derivedOrType(tp1.widenUnionWithoutNull, tp2.widenUnionWithoutNull)
if !isProvisional then myUnionPeriod = ctx.period
myUnion

private var atomsRunId: RunId = NoRunId
private var myAtoms: Atoms = _
private var myWidened: Type = _
Expand Down
42 changes: 42 additions & 0 deletions tests/pos/i12909.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package example

final case class Writer[W, A](run: (W, A)) {
def map[B](f: A => B): Writer[W, B] = ???

def flatMap[B](f: A => Writer[W, B]): Writer[W, B] = ???
}

object Main {
implicit class WriterOps[A](a: A) {
def set[W](w: W): Writer[W, A] = ???
}

def x1[A]: Writer[Vector[String], Option[A]] = ???

val failure = for {
a1 <- {
Option(1) match {
case Some(x) =>
x1[Boolean]
case _ =>
Option.empty[Boolean].set(Vector.empty[String])
}
}
a2 <- x1[String]
} yield ()

val success = for {
a1 <- {
val temp = Option(1) match {
case Some(x) =>
x1[Boolean]
case _ =>
Option.empty[Boolean].set(Vector.empty[String])
}
// why ???
temp
}
a2 <- x1[String]
} yield ()

}

0 comments on commit b3ade17

Please sign in to comment.