Skip to content

Commit

Permalink
Do not widen selector type in inline matches
Browse files Browse the repository at this point in the history
Fixes #12715
  • Loading branch information
tgodzik committed Jun 22, 2021
1 parent d7d4a9f commit 019f40f
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 2 deletions.
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1465,8 +1465,8 @@ class Typer extends Namer
case _ =>
if tree.isInline then checkInInlineContext("inline match", tree.srcPos)
val sel1 = typedExpr(tree.selector)
val selType = fullyDefinedType(sel1.tpe, "pattern selector", tree.span).widen

val rawSelectorTpe = fullyDefinedType(sel1.tpe, "pattern selector", tree.span)
val selType = if (tree.isInline) rawSelectorTpe else rawSelectorTpe.widen
/** Extractor for match types hidden behind an AppliedType/MatchAlias */
object MatchTypeInDisguise {
def unapply(tp: AppliedType): Option[MatchType] = tp match {
Expand Down
41 changes: 41 additions & 0 deletions tests/pos/i12715/full.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package repro

import compiletime.{constValue, erasedValue}

sealed trait ValidateExprInt

class And[A <: ValidateExprInt, B <: ValidateExprInt] extends ValidateExprInt
class GreaterThan[T <: Int] extends ValidateExprInt

object Repro:
inline def validate[E <: ValidateExprInt](v: Int): String =
inline val failMsg = validateV[E](v)
inline if failMsg == "neverPass" then "neverPass"
else "something else"

transparent inline def validateV[E <: ValidateExprInt](v: Int): String =
inline erasedValue[E] match
case _: GreaterThan[t] =>
"GreaterThan"
case _: And[a, b] =>
inline validateV[a](v) match
case "" =>
validateV[b](v)
case other =>
other

// This one works fine:
transparent inline def validateV_fixed[E <: ValidateExprInt](v: Int): String =
inline erasedValue[E] match
case _: GreaterThan[t] =>
"GreaterThan"
case _: And[a, b] =>
inline val res = validateV[a](v)
inline res match
case "" =>
validateV[b](v)
case _ =>
res

@main def test(): Unit =
println(validate[And[GreaterThan[10], GreaterThan[12]]](5))
8 changes: 8 additions & 0 deletions tests/pos/i12715/minimized.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
transparent inline def f: String =
inline 10 match
case _ =>
inline "foo" match
case x : String => x

def test =
inline val failMsg = f

0 comments on commit 019f40f

Please sign in to comment.