Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always use baseType when constraining patternTp with scrutineeTp #20032

Merged
merged 1 commit into from
Apr 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ trait PatternTypeConstrainer { self: TypeComparer =>
*
* This function expects to receive two types (scrutinee and pattern), both
* of which have class symbols, one of which is derived from another. If the
* type "being derived from" is an applied type, it will 1) "upcast" the
* deriving type to an applied type with the same constructor and 2) infer
* type "being derived from" is an applied type, it will 1) "upcast" both
* types to an applied type with the same constructor and 2) infer
* constraints for the applied types' arguments that follow from both
* types being inhabited by one value (the scrutinee).
*
Expand Down Expand Up @@ -252,11 +252,9 @@ trait PatternTypeConstrainer { self: TypeComparer =>
val scrutineeCls = scrutineeTp.classSymbol

// NOTE: we already know that there is a derives-from relationship in either direction
val upcastPattern =
patternCls.derivesFrom(scrutineeCls)

val pt = if upcastPattern then patternTp.baseType(scrutineeCls) else patternTp
val tp = if !upcastPattern then scrutineeTp.baseType(patternCls) else scrutineeTp
val base = if patternCls.derivesFrom(scrutineeCls) then scrutineeCls else patternCls
val pt = patternTp.baseType(base)
val tp = scrutineeTp.baseType(base)

val assumeInvariantRefinement =
migrateTo3 || forceInvariantRefinement || refinementIsInvariant(patternTp)
Expand Down
29 changes: 29 additions & 0 deletions tests/pos/i19706.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

import scala.compiletime.ops.string.{Length, Matches, Substring}

def emptyContext(): Unit =
summon[Decoded["Tuple(0, EmptyTuple)"] =:= 0 *: EmptyTuple]

type Decoded[S <: String] = Matches[S, "Tuple(.+, .+)"] match
case true => Parsed[Substring[S, 6, 19], 0, ""] match
case (h, t) => Decoded["0"] *: EmptyTuple
case false => 0

type Parsed[S <: String, I <: Int, A <: String] <: (String, String) = Matches[S, "other"] match
case true => I match
case 1 => ("", "")
case _ => Parsed[Substring[S, 1, Length[S]], I, ""]
case false => ("0", "EmptyTuple")


object Minimization:

type Cond[B <: Boolean] <: Tuple2[String, String] = B match
case true => ("", "")
case false => ("a", "b")

type Decoded[B <: Boolean] = Cond[B] match
case (h1, _) => Int

val _: Decoded[false] = 1

Loading