Skip to content

Missing type parameter inference for stable identifier patterns. #785

Open
@scabug

Description

@scabug

This is both a report of a defect in the specification and a
minor enhancement request for the implementation.

GADT-style dependent case analysis works for objects:

scala> trait T[X]
defined trait T

scala> object O extends T[int]
defined module O

scala> def f[X] : T[X] => X = { case O => 42 }
f: [X](T[X]) => X

O is syntactically a stable identifier pattern (8.1.4), but
dependent case analysis isn't defined for them in section 8.3 of
the specification. Their treatment seems straightforwardly
analogous to the treatment of constructor patterns, though: {
case O => 42 } just gets translated to { case _ : O.type => 42 }.
This description is currently missing from the specification.

Moreover, it seems that with the current implementation, the
above rule only works for objects, not for other stable
identifiers.

scala> val V = new T[int] {}
V: java.lang.Object with T[int] = $$anon$$1@23194cf5

scala> def g[X] : T[X] => X = { case V => 42 }
<console>:6: error: type mismatch;
 found   : Int(42)
 required: X
       def g[X] : T[X] => X = { case V => 42 }

Still, manual translation to a type pattern works all right:

scala> def g[X] : T[X] => X = { case _ : V.type => 42 }
g: [X](T[X]) => X

scala> g(V)
res1: int = 42

This seems inconsistent. I very much think all stable identifiers
should be treated uniformly. My immediate motivation for this is
that it makes writing a typecase somewhat neater. Given:

val IntC = classOf[Int]
val StringC = classOf[String]

Currently one has to write:

def g[X] : Class[X] => X = { 
   case _ : IntC.type => 42
   case _ : StringC.type => "forty-two" 
}

Instead of the prettier:

def g[X] : Class[X] => X = { 
   case IntC => 42
   case StringC => "forty-two" 
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions