Skip to content

Unexpected union of skolems as Singleton type argument #23489

Open
@mbovel

Description

@mbovel
import scala.language.experimental.modularity

class Box1[T <: Singleton](val x: T)
class Box2[T : Singleton](val x: T)
def id(x: Int): x.type = x
def readInt(): Int = ???

def Test = ()
  val x /*: Box1[(?1 : Int) | (?2 : Int)]*/ = Box1(id(readInt()))

  val y = Box2(id(readInt())) // error: Failed to synthesize an instance of type
                              // Singleton{type Self = (?1 : Int) | (?2 : Int)}:
                              // (?1 : Int) | (?2 : Int) is not a singleton
sbt:scala3> scalac -Xprint-types -Xprint:typer tests/pos/singleton-skolem.scala
...
    val x: Box1[(<?3:Int> : Int) | (<?4:Int> : Int)] =
      <
        <<<new Box1:Box1>:([T <: Singleton](x: T): Box1[T])>[
          (<?3:Int> : Int) | (<?4:Int> : Int)]:
          ((x: (<?3:Int> : Int) | (<?4:Int> : Int)):
            Box1[(<?3:Int> : Int) | (<?4:Int> : Int)])
        >
      (<<id:((x: Int): x.type)>(<<readInt:((): Int)>():Int>):(<?4:Int> : Int)>):
        Box1[(<?3:Int> : Int) | (<?4:Int> : Int)]>
...

id(readInt()) gets a skolem type (?4: Int) as expected.

But then the type argument of Box1 is inferred to be (?3: Int) | (?4: Int). I don't understand where (?3: Int) | comes from. I would expect it to just be (?4: Int)

Compiler version: 8598403.

Same behavior since 3.0:

class Box1[T <: Singleton](val x: T)
def id(x: Int): x.type = x
def readInt(): Int = ???

def Test = ()
  val x /*: Box1[(?1 : Int) | (?2 : Int)]*/ = Box1(id(readInt()))
$ scala compile -S 3.0 --server=false -Xprint:typer tests/pos/singleton-skolem.scala
...
    val x: Box1[(?1 : Int) | (?2 : Int)] = new Box1[((?1 : Int) | (?2 : Int))](id(readInt()))
...

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions