Skip to content

Commit 17e6a6a

Browse files
authored
Backport "Better types for class type parameters" (#16046)
Backports #15951
2 parents ccb53a9 + 68325f6 commit 17e6a6a

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -1120,7 +1120,12 @@ object Denotations {
11201120
then this
11211121
else if symbol.isAllOf(ClassTypeParam) then
11221122
val arg = symbol.typeRef.argForParam(pre, widenAbstract = true)
1123-
if arg.exists then derivedSingleDenotation(symbol, arg.bounds, pre)
1123+
if arg.exists then
1124+
val newBounds =
1125+
if symbol.isCompleted && !symbol.info.containsLazyRefs
1126+
then symbol.info.bounds & arg.bounds
1127+
else arg.bounds
1128+
derivedSingleDenotation(symbol, newBounds, pre)
11241129
else derived(symbol.info)
11251130
else derived(symbol.info)
11261131
}

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

+8
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,14 @@ object Types {
442442
final def containsWildcardTypes(using Context) =
443443
existsPart(_.isInstanceOf[WildcardType], StopAt.Static, forceLazy = false)
444444

445+
/** Does this type contain LazyRef types? */
446+
final def containsLazyRefs(using Context) =
447+
val acc = new TypeAccumulator[Boolean]:
448+
def apply(x: Boolean, tp: Type): Boolean = tp match
449+
case _: LazyRef => true
450+
case _ => x || foldOver(x, tp)
451+
acc(false, this)
452+
445453
// ----- Higher-order combinators -----------------------------------
446454

447455
/** Returns true if there is a part of this type that satisfies predicate `p`.

tests/pos/i15940.scala

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
object Ops:
2+
implicit class EitherSeqOps[E, T](private val seq: Seq[Either[E, T]]) extends AnyVal:
3+
def sequence: Either[::[E], Seq[T]] = ???
4+
5+
trait BuildException
6+
case class CompositeBuildException(ex: ::[BuildException]) extends BuildException
7+
8+
trait ActionableDiagnostic
9+
trait ActionableHandler[A <: ActionableDiagnostic]:
10+
def exec: Either[BuildException, Seq[A]]
11+
12+
import Ops._
13+
14+
val test: Either[BuildException, Seq[ActionableDiagnostic]] =
15+
// Can be replaced with Seq[Either[BuildException, Seq[ _ <: ActionableDiagnostic]]] , but current version matches better type of missing implicit
16+
Seq.empty[ActionableHandler[_]].map(_.exec)
17+
.sequence
18+
.left.map(_.head)
19+
.map(_.flatten) // error

0 commit comments

Comments
 (0)