Skip to content

Commit 5429b1f

Browse files
authored
Fix #22922: Add TypeParamRef handling in isSingletonBounded (#23501)
Fix #22922 #20061 removed `isSingleton`, and `TypeParamRef` is not handled correctly by `isSingletonBounded`.
2 parents 26d1794 + f14fa10 commit 5429b1f

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,14 +345,16 @@ object Types extends TypeUtils {
345345
*/
346346
def isSingletonBounded(frozen: Boolean)(using Context): Boolean = this.dealias.normalized match
347347
case tp: SingletonType => tp.isStable
348+
case tp: TypeParamRef =>
349+
ctx.typerState.constraint.bounds(tp).hi.isSingletonBounded(frozen)
348350
case tp: TypeRef =>
349351
tp.name == tpnme.Singleton && tp.symbol == defn.SingletonClass
350352
|| tp.superType.isSingletonBounded(frozen)
351353
case tp: TypeVar if !tp.isInstantiated =>
352354
if frozen then tp frozen_<:< defn.SingletonType else tp <:< defn.SingletonType
353355
case tp: HKTypeLambda => false
354356
case tp: TypeProxy => tp.superType.isSingletonBounded(frozen)
355-
case AndType(tpL, tpR) => tpL.isSingletonBounded(frozen) || tpR.isSingletonBounded(frozen)
357+
case tp: AndType => tp.tp1.isSingletonBounded(frozen) || tp.tp2.isSingletonBounded(frozen)
356358
case _ => false
357359

358360
/** Is this type of kind `AnyKind`? */

tests/pos/i22922.scala

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
abstract class Computation[+A, -U]
2+
type !![+A, -U] = Computation[A, U]
3+
type Const[C] = [_] =>> C
4+
5+
final class EffectImpl[Fx]:
6+
sealed trait ThisInterpreter extends Interpreter.Unsealed:
7+
final override type Elim = Fx
8+
abstract class Stateless[F[+_], G[+_], Fx]
9+
extends Interpreter.Stateless[F, G, Fx]
10+
with ThisInterpreter
11+
12+
trait Effect:
13+
val impl: EffectImpl[this.type] = ???
14+
15+
trait SourceEffect[O] extends Effect:
16+
abstract class Stateless[U] extends StatelessReturn[Unit, U]
17+
abstract class StatelessReturn[R, U] extends impl.Stateless[Const[Unit], Const[R], U]
18+
19+
sealed trait Handler[From[+_], To[+_], Elim, Intro]:
20+
final def handle[V] = new HandleSyntax[V]
21+
final class HandleSyntax[V]:
22+
def apply[A, W](comp: From[A] !! W)(using CanPartiallyHandle[V, W, Elim]): To[A] !! (V & Intro) = ???
23+
24+
sealed trait CanPartiallyHandle[U, V, W] // missing in StreamImpl.map
25+
object CanPartiallyHandle:
26+
given [U, V, W](using (W & U) <:< V): CanPartiallyHandle[U, V, W] = ???
27+
28+
sealed trait Interpreter:
29+
type From[+A]
30+
type To[+A]
31+
type Elim
32+
type Intro
33+
34+
final def toHandler: Handler[From, To, Elim, Intro] = ???
35+
object Interpreter:
36+
trait Unsealed extends Interpreter
37+
abstract class Stateless[F[+_], G[+_], Fx] extends Interpreter:
38+
final override type From[+A] = F[A]
39+
final override type To[+A] = G[A]
40+
final override type Intro = Fx
41+
42+
object Syntax:
43+
extension [U](comp: Unit !! U)
44+
def asStream[A, V](fx: SourceEffect[A])(using (fx.type & V) =:= U): Stream[A, V] = ???
45+
46+
sealed abstract class Stream[+A, -U]:
47+
def map[B](f: A => B): Stream[B, U]
48+
49+
import Syntax.*
50+
final case class StreamImpl[A, U](Fx: SourceEffect[A])(val compute: Unit !! (U & Fx.type))
51+
extends Stream[A, U]:
52+
type Fx = Fx.type
53+
override def map[B](f: A => B): Stream[B, U] =
54+
case object Fx2 extends SourceEffect[B]
55+
new Fx.Stateless[Fx2.type] {}.toHandler
56+
.handle(compute)
57+
.asStream(Fx2) // error

0 commit comments

Comments
 (0)