Skip to content

Commit

Permalink
Backport "Better types for class type parameters" (#16046)
Browse files Browse the repository at this point in the history
Backports #15951
  • Loading branch information
Kordyjan authored Sep 15, 2022
2 parents ccb53a9 + 68325f6 commit 17e6a6a
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 1 deletion.
7 changes: 6 additions & 1 deletion compiler/src/dotty/tools/dotc/core/Denotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1120,7 +1120,12 @@ object Denotations {
then this
else if symbol.isAllOf(ClassTypeParam) then
val arg = symbol.typeRef.argForParam(pre, widenAbstract = true)
if arg.exists then derivedSingleDenotation(symbol, arg.bounds, pre)
if arg.exists then
val newBounds =
if symbol.isCompleted && !symbol.info.containsLazyRefs
then symbol.info.bounds & arg.bounds
else arg.bounds
derivedSingleDenotation(symbol, newBounds, pre)
else derived(symbol.info)
else derived(symbol.info)
}
Expand Down
8 changes: 8 additions & 0 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,14 @@ object Types {
final def containsWildcardTypes(using Context) =
existsPart(_.isInstanceOf[WildcardType], StopAt.Static, forceLazy = false)

/** Does this type contain LazyRef types? */
final def containsLazyRefs(using Context) =
val acc = new TypeAccumulator[Boolean]:
def apply(x: Boolean, tp: Type): Boolean = tp match
case _: LazyRef => true
case _ => x || foldOver(x, tp)
acc(false, this)

// ----- Higher-order combinators -----------------------------------

/** Returns true if there is a part of this type that satisfies predicate `p`.
Expand Down
19 changes: 19 additions & 0 deletions tests/pos/i15940.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
object Ops:
implicit class EitherSeqOps[E, T](private val seq: Seq[Either[E, T]]) extends AnyVal:
def sequence: Either[::[E], Seq[T]] = ???

trait BuildException
case class CompositeBuildException(ex: ::[BuildException]) extends BuildException

trait ActionableDiagnostic
trait ActionableHandler[A <: ActionableDiagnostic]:
def exec: Either[BuildException, Seq[A]]

import Ops._

val test: Either[BuildException, Seq[ActionableDiagnostic]] =
// Can be replaced with Seq[Either[BuildException, Seq[ _ <: ActionableDiagnostic]]] , but current version matches better type of missing implicit
Seq.empty[ActionableHandler[_]].map(_.exec)
.sequence
.left.map(_.head)
.map(_.flatten) // error

0 comments on commit 17e6a6a

Please sign in to comment.