Skip to content

Matching on Option[Option[T]] where T is abstract and obtained from inline def in super trait emits exhaustivity warning #16435

@martingd

Description

@martingd

Compiler version

Scala 3.2.1

Minimized code

trait Base:
    type Value
    inline def oov: Option[Option[Value]] = None
    def get: Option[Value]

trait X extends Base:
    override def get: Option[Value] =
        oov match
            case Some(ov) => ov
            case None => None

Output

The compiler emits the following warning:

[warn] -- [E029] Pattern Match Exhaustivity Warning: /path/to/Test.scala:8:8 
[warn] 8 |        oov match
[warn]   |        ^^^
[warn]   |        match may not be exhaustive.
[warn]   |
[warn]   |        It would fail on pattern case: Some(_)
[warn]   |
[warn]   | longer explanation available when compiling with `-explain`
[warn] one warning found

Expectation

The code should compile.

Workarounds

We have found three ways to make the code compile without this warning and one that gives a new unexpected error:

Extract oov to local value

trait Base:
    type Value
    inline def oov: Option[Option[Value]] = None
    def get: Option[Value]

trait X extends Base:
    override def get: Option[Value] =
        val local_oov = oov
        local_oov match
            case Some(ov) => ov
            case None => None

Remove inline

Without the inline modifier, the code compiles:

trait Base:
    type Value
    def oov: Option[Option[Value]] = None
    def get: Option[Value]

trait X extends Base:
    override def get: Option[Value] =
        oov match
            case Some(ov) => ov
            case None => None

Make type Value concrete

trait Base:
    type Value
    inline def oov: Option[Option[Value]] = None
    def get: Option[Value]

trait X extends Base:
    override type Value = Int
    override def get: Option[Value] =
        oov match
            case Some(ov) => ov
            case None => None

Adding transparent to inline results in new error

This code

trait Base:
    type Value
    transparent inline def oov: Option[Option[Value]] = None
    def get: Option[Value]

trait X extends Base:
    override def get: Option[Value] =
        oov match
            case Some(ov) => ov
            case None => None

causes the compiler to emit this error:

[error] -- [E007] Type Mismatch Error: /path/to/Test.scala:9:29 
[error] 9 |            case Some(ov) => ov
[error]   |                             ^^
[error]   |                             Found:    (ov : Any)
[error]   |                             Required: Option[X.this.Value]

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions