From 71c9ad65528c52f721dd83fdc1d71a9907e3f336 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Thu, 10 Jul 2025 16:52:44 +0200 Subject: [PATCH 1/2] Add TypeParamRef handling in isSingletonBounded --- .../src/dotty/tools/dotc/core/Types.scala | 5 +- tests/pos/i22922.scala | 57 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i22922.scala diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 61b3b958fca3..39bcddbe5bc9 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -345,6 +345,8 @@ object Types extends TypeUtils { */ def isSingletonBounded(frozen: Boolean)(using Context): Boolean = this.dealias.normalized match case tp: SingletonType => tp.isStable + case tp: TypeParamRef => + ctx.typerState.constraint.bounds(tp).hi.isSingletonBounded(frozen) case tp: TypeRef => tp.name == tpnme.Singleton && tp.symbol == defn.SingletonClass || tp.superType.isSingletonBounded(frozen) @@ -352,7 +354,8 @@ object Types extends TypeUtils { if frozen then tp frozen_<:< defn.SingletonType else tp <:< defn.SingletonType case tp: HKTypeLambda => false case tp: TypeProxy => tp.superType.isSingletonBounded(frozen) - case AndType(tpL, tpR) => tpL.isSingletonBounded(frozen) || tpR.isSingletonBounded(frozen) + case tp: AndType => tp.tp1.isSingletonBounded(frozen) || tp.tp2.isSingletonBounded(frozen) + case tp: OrType => tp.tp1.isSingletonBounded(frozen) && tp.tp2.isSingletonBounded(frozen) case _ => false /** Is this type of kind `AnyKind`? */ diff --git a/tests/pos/i22922.scala b/tests/pos/i22922.scala new file mode 100644 index 000000000000..a65c99d6bd46 --- /dev/null +++ b/tests/pos/i22922.scala @@ -0,0 +1,57 @@ +abstract class Computation[+A, -U] +type !![+A, -U] = Computation[A, U] +type Const[C] = [_] =>> C + +final class EffectImpl[Fx]: + sealed trait ThisInterpreter extends Interpreter.Unsealed: + final override type Elim = Fx + abstract class Stateless[F[+_], G[+_], Fx] + extends Interpreter.Stateless[F, G, Fx] + with ThisInterpreter + +trait Effect: + val impl: EffectImpl[this.type] = ??? + +trait SourceEffect[O] extends Effect: + abstract class Stateless[U] extends StatelessReturn[Unit, U] + abstract class StatelessReturn[R, U] extends impl.Stateless[Const[Unit], Const[R], U] + +sealed trait Handler[From[+_], To[+_], Elim, Intro]: + final def handle[V] = new HandleSyntax[V] + final class HandleSyntax[V]: + def apply[A, W](comp: From[A] !! W)(using CanPartiallyHandle[V, W, Elim]): To[A] !! (V & Intro) = ??? + +sealed trait CanPartiallyHandle[U, V, W] // missing in StreamImpl.map +object CanPartiallyHandle: + given [U, V, W](using (W & U) <:< V): CanPartiallyHandle[U, V, W] = ??? + +sealed trait Interpreter: + type From[+A] + type To[+A] + type Elim + type Intro + + final def toHandler: Handler[From, To, Elim, Intro] = ??? +object Interpreter: + trait Unsealed extends Interpreter + abstract class Stateless[F[+_], G[+_], Fx] extends Interpreter: + final override type From[+A] = F[A] + final override type To[+A] = G[A] + final override type Intro = Fx + +object Syntax: + extension [U](comp: Unit !! U) + def asStream[A, V](fx: SourceEffect[A])(using (fx.type & V) =:= U): Stream[A, V] = ??? + +sealed abstract class Stream[+A, -U]: + def map[B](f: A => B): Stream[B, U] + +import Syntax.* +final case class StreamImpl[A, U](Fx: SourceEffect[A])(val compute: Unit !! (U & Fx.type)) + extends Stream[A, U]: + type Fx = Fx.type + override def map[B](f: A => B): Stream[B, U] = + case object Fx2 extends SourceEffect[B] + new Fx.Stateless[Fx2.type] {}.toHandler + .handle(compute) + .asStream(Fx2) // error From f14fa1050d1a4a87b394609af5e474d71e348e62 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Fri, 11 Jul 2025 13:11:41 +0200 Subject: [PATCH 2/2] Fix logic in isSingletonBounded for OrType case --- compiler/src/dotty/tools/dotc/core/Types.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 39bcddbe5bc9..e18785e3aace 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -355,7 +355,6 @@ object Types extends TypeUtils { case tp: HKTypeLambda => false case tp: TypeProxy => tp.superType.isSingletonBounded(frozen) case tp: AndType => tp.tp1.isSingletonBounded(frozen) || tp.tp2.isSingletonBounded(frozen) - case tp: OrType => tp.tp1.isSingletonBounded(frozen) && tp.tp2.isSingletonBounded(frozen) case _ => false /** Is this type of kind `AnyKind`? */