improvement-proposals icon indicating copy to clipboard operation
improvement-proposals copied to clipboard

Match types amendment: extractors follow aliases and singletons

Open smarter opened this issue 1 year ago • 3 comments
trafficstars

The existing spec uses as a legal example:

class Base {
  type Y
}

type YExtractor[t] = Base { type Y = t }

And we are allowed to define:

type ExtractY[B <: Base] = B match
  case YExtractor[t] => t

However, with the existing spec, extraction does not always work as one might expect:

class Sub1 extends Base:
  type Y = Alias
  type Alias = Int
class Sub2[T] extends Base:
  type Y = T
class Sub3 extends Base:
  val elem: Sub1 = new Sub1
  type Y = elem.Y

ExtractY[Base { type Y = Int }] // OK
ExtractY[Sub1] // error
ExtractY[Sub2[Int]] // error
ExtractY[Sub3] // error

What's going on here is that when extracting a type Y from a non-stable prefix X, the spec mandates that we generate a skolem q and use that as a prefix to lookup the underlying type of Y. Extraction only succeeds if the underlying type does not refer to q. For example, for ExtractY[Sub1] we have q.Y with underlying type q.Alias which is rejected since it refers to q.

We amend the spec to follow aliases and singleton types in the extracted type, so that q.Alias can be dealiased to Int which is then accepted as a valid extracted type.

More motivating examples can be found in the implementation at https://github.com/scala/scala3/pull/20161.

smarter avatar Apr 11 '24 12:04 smarter

I'm in favor of promoting this fix; amendments seem better to do sooner than later and it increases the power of match types, so I recommend voting yes to this at our next meeting.

bjornregnell avatar Apr 21 '24 12:04 bjornregnell

I'm also in favor. Now that we have a spec, we can reason well about such changes. From my perspective, as long as it's sound and doesn't cause performance issues, any change that expands the match type capability is a welcome addition.

soronpo avatar Apr 21 '24 14:04 soronpo

I agree with Bjoern and Oron. It's a logical generalization, and elsewhere in the compiler we implement similar behavior.

odersky avatar Apr 21 '24 14:04 odersky