Skip to content

Commit

Permalink
Update check-files and error annotations
Browse files Browse the repository at this point in the history
The diff in neg/10349.scala is quite interesting.
With a few intermediate values:
```scala
type First[X] = X match
 case Map[_, v] => First[Option[v]]

def first[X](x: X): First[X] = x match
 case x: Map[k, v] =>
 val hdOpt: Option[v] = x.values.headOption
 first(hdOpt): First[Option[v]] // error only before changes
```
This now type-checks but will fail at runtime because of the in-exhaustivity of the match expression.
Perhaps we should add some additional condition in `isMatchTypeShaped` to account for this, or at least emit a warning ?
  • Loading branch information
EugeneFlesselle committed Mar 16, 2024
1 parent 69e14db commit 646fea8
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 98 deletions.
61 changes: 4 additions & 57 deletions tests/neg-macros/toexproftuple.scala
Original file line number Diff line number Diff line change
@@ -1,63 +1,10 @@
import scala.quoted._, scala.deriving.* // error
// ^
// Match type reduction failed since selector ((2 : Int), quoted.Expr[(3 : Int)])
// matches none of the cases
//
// case quoted.Expr[x] *: t => x *: scala.Tuple.InverseMap[t, quoted.Expr]
// case EmptyTuple => EmptyTuple

inline def mcr: Any = ${mcrImpl} // error
// ^
// Match type reduction failed since selector ((2 : Int), quoted.Expr[(3 : Int)])
// matches none of the cases
//
// case quoted.Expr[x] *: t => x *: scala.Tuple.InverseMap[t, quoted.Expr]
// case EmptyTuple => EmptyTuple

def mcrImpl(using ctx: Quotes): Expr[Any] = { // error // error
//^
// Match type reduction failed since selector ((2 : Int), quoted.Expr[(3 : Int)])
// matches none of the cases
//
// case quoted.Expr[x] *: t => x *: scala.Tuple.InverseMap[t, quoted.Expr]
// case EmptyTuple => EmptyTuple

// ^
// Match type reduction failed since selector ((2 : Int), quoted.Expr[(3 : Int)])
// matches none of the cases
//
// case quoted.Expr[x] *: t => x *: scala.Tuple.InverseMap[t, quoted.Expr]
// case EmptyTuple => EmptyTuple
import scala.quoted._, scala.deriving.*

inline def mcr: Any = ${mcrImpl}
def mcrImpl(using ctx: Quotes): Expr[Any] = {
val tpl: (Expr[1], Expr[2], Expr[3]) = ('{1}, '{2}, '{3})
'{val res: (1, 3, 3) = ${Expr.ofTuple(tpl)}; res} // error
// ^^^^^^^^^^^^^^^^^
// Found: quoted.Expr[(1 : Int) *: (2 : Int) *: (3 : Int) *: EmptyTuple]
// Required: quoted.Expr[((1 : Int), (3 : Int), (3 : Int))]

val tpl2: (Expr[1], 2, Expr[3]) = ('{1}, 2, '{3})
'{val res = ${Expr.ofTuple(tpl2)}; res} // error // error // error // error
// ^
// Cannot prove that (quoted.Expr[(1 : Int)], (2 : Int), quoted.Expr[(3 : Int)]) =:= scala.Tuple.Map[
// scala.Tuple.InverseMap[
// (quoted.Expr[(1 : Int)], (2 : Int), quoted.Expr[(3 : Int)])
// , quoted.Expr]
// , quoted.Expr].

// ^
// Match type reduction failed since selector ((2 : Int), quoted.Expr[(3 : Int)])
// matches none of the cases
//
// case quoted.Expr[x] *: t => x *: scala.Tuple.InverseMap[t, quoted.Expr]
// case EmptyTuple => EmptyTuple

// ^
// Cyclic reference involving val res

// ^
// Match type reduction failed since selector ((2 : Int), quoted.Expr[(3 : Int)])
// matches none of the cases
//
// case quoted.Expr[x] *: t => x *: scala.Tuple.InverseMap[t, quoted.Expr]
// case EmptyTuple => EmptyTuple
'{val res = ${Expr.ofTuple(tpl2)}; res} // error
}
2 changes: 1 addition & 1 deletion tests/neg/10349.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ object Firsts:
case Map[_, v] => First[Option[v]]

def first[X](x: X): First[X] = x match
case x: Map[_, _] => first(x.values.headOption) // error
case x: Map[_, _] => first(x.values.headOption)

@main
def runFirsts2(): Unit =
Expand Down
3 changes: 2 additions & 1 deletion tests/neg/10747.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ type Foo[A] = A match {
case Int => String
}

type B = Foo[Boolean] // error
type B = Foo[Boolean]
val _: B = "hello" // error
88 changes: 64 additions & 24 deletions tests/neg/i12049.check
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,45 @@
| case B => String
|
| longer explanation available when compiling with `-explain`
-- Error: tests/neg/i12049.scala:14:23 ---------------------------------------------------------------------------------
-- [E007] Type Mismatch Error: tests/neg/i12049.scala:14:17 ------------------------------------------------------------
14 |val y3: String = ??? : Last[Int *: Int *: Boolean *: String *: EmptyTuple] // error
| ^
| Match type reduction failed since selector EmptyTuple
| matches none of the cases
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| Found: Last[EmptyTuple]
| Required: String
|
| case _ *: _ *: t => Last[t]
| case t *: EmptyTuple => t
-- Error: tests/neg/i12049.scala:22:26 ---------------------------------------------------------------------------------
| Note: a match type could not be fully reduced:
|
| trying to reduce Last[EmptyTuple]
| failed since selector EmptyTuple
| matches none of the cases
|
| case _ *: _ *: t => Last[t]
| case t *: EmptyTuple => t
|
| longer explanation available when compiling with `-explain`
-- [E007] Type Mismatch Error: tests/neg/i12049.scala:22:20 ------------------------------------------------------------
22 |val z3: (A, B, A) = ??? : Reverse[(A, B, A)] // error
| ^
| Match type reduction failed since selector A *: EmptyTuple.type
| matches none of the cases
| ^^^^^^^^^^^^^^^^^^^^^^^^
| Found: Tuple.Concat[Reverse[A *: EmptyTuple.type], (B, A)]
| Required: (A, B, A)
|
| Note: a match type could not be fully reduced:
|
| trying to reduce Tuple.Concat[Reverse[A *: EmptyTuple.type], (B, A)]
| trying to reduce Reverse[A *: EmptyTuple.type]
| failed since selector A *: EmptyTuple.type
| matches none of the cases
|
| case t1 *: t2 *: ts => Tuple.Concat[Reverse[ts], (t2, t1)]
| case EmptyTuple => EmptyTuple
| trying to reduce Reverse[A *: EmptyTuple.type]
| failed since selector A *: EmptyTuple.type
| matches none of the cases
|
| case t1 *: t2 *: ts => Tuple.Concat[Reverse[ts], (t2, t1)]
| case EmptyTuple => EmptyTuple
| case t1 *: t2 *: ts => Tuple.Concat[Reverse[ts], (t2, t1)]
| case EmptyTuple => EmptyTuple
|
| longer explanation available when compiling with `-explain`
-- [E172] Type Error: tests/neg/i12049.scala:24:20 ---------------------------------------------------------------------
24 |val _ = summon[M[B]] // error
| ^
Expand All @@ -45,22 +68,39 @@
| Therefore, reduction cannot advance to the remaining case
|
| case B => String
-- Error: tests/neg/i12049.scala:25:26 ---------------------------------------------------------------------------------
-- [E172] Type Error: tests/neg/i12049.scala:25:78 ---------------------------------------------------------------------
25 |val _ = summon[String =:= Last[Int *: Int *: Boolean *: String *: EmptyTuple]] // error
| ^
| Match type reduction failed since selector EmptyTuple
| matches none of the cases
| ^
| Cannot prove that String =:= Last[EmptyTuple].
|
| Note: a match type could not be fully reduced:
|
| trying to reduce Last[EmptyTuple]
| failed since selector EmptyTuple
| matches none of the cases
|
| case _ *: _ *: t => Last[t]
| case t *: EmptyTuple => t
-- Error: tests/neg/i12049.scala:26:29 ---------------------------------------------------------------------------------
| case _ *: _ *: t => Last[t]
| case t *: EmptyTuple => t
-- [E172] Type Error: tests/neg/i12049.scala:26:48 ---------------------------------------------------------------------
26 |val _ = summon[(A, B, A) =:= Reverse[(A, B, A)]] // error
| ^
| Match type reduction failed since selector A *: EmptyTuple.type
| matches none of the cases
| ^
| Cannot prove that (A, B, A) =:= Tuple.Concat[Reverse[A *: EmptyTuple.type], (B, A)].
|
| Note: a match type could not be fully reduced:
|
| trying to reduce Tuple.Concat[Reverse[A *: EmptyTuple.type], (B, A)]
| trying to reduce Reverse[A *: EmptyTuple.type]
| failed since selector A *: EmptyTuple.type
| matches none of the cases
|
| case t1 *: t2 *: ts => Tuple.Concat[Reverse[ts], (t2, t1)]
| case EmptyTuple => EmptyTuple
| trying to reduce Reverse[A *: EmptyTuple.type]
| failed since selector A *: EmptyTuple.type
| matches none of the cases
|
| case t1 *: t2 *: ts => Tuple.Concat[Reverse[ts], (t2, t1)]
| case EmptyTuple => EmptyTuple
| case t1 *: t2 *: ts => Tuple.Concat[Reverse[ts], (t2, t1)]
| case EmptyTuple => EmptyTuple
-- [E008] Not Found Error: tests/neg/i12049.scala:28:21 ----------------------------------------------------------------
28 |val _ = (??? : M[B]).length // error
| ^^^^^^^^^^^^^^^^^^^
Expand Down
4 changes: 2 additions & 2 deletions tests/neg/i13757-match-type-anykind.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ object Test:
type AnyKindMatchType3[X <: AnyKind] = X match // error: the scrutinee of a match type cannot be higher-kinded
case _ => Int

type AnyKindMatchType4[X <: Option] = X match // error // error: the scrutinee of a match type cannot be higher-kinded // error
type AnyKindMatchType4[X <: Option] = X match // error // error: the scrutinee of a match type cannot be higher-kinded
case _ => Int

type AnyKindMatchType5[X[_]] = X match // error: the scrutinee of a match type cannot be higher-kinded // error
type AnyKindMatchType5[X[_]] = X match // error: the scrutinee of a match type cannot be higher-kinded
case _ => Int
end Test
40 changes: 28 additions & 12 deletions tests/neg/matchtype-seq.check
Original file line number Diff line number Diff line change
@@ -1,19 +1,35 @@
-- Error: tests/neg/matchtype-seq.scala:9:11 ---------------------------------------------------------------------------
-- [E007] Type Mismatch Error: tests/neg/matchtype-seq.scala:9:18 ------------------------------------------------------
9 | identity[T1[3]]("") // error
| ^
| Match type reduction failed since selector (3 : Int)
| matches none of the cases
| ^^
| Found: ("" : String)
| Required: Test.T1[(3 : Int)]
|
| case (1 : Int) => Int
| case (2 : Int) => String
-- Error: tests/neg/matchtype-seq.scala:10:11 --------------------------------------------------------------------------
| Note: a match type could not be fully reduced:
|
| trying to reduce Test.T1[(3 : Int)]
| failed since selector (3 : Int)
| matches none of the cases
|
| case (1 : Int) => Int
| case (2 : Int) => String
|
| longer explanation available when compiling with `-explain`
-- [E007] Type Mismatch Error: tests/neg/matchtype-seq.scala:10:18 -----------------------------------------------------
10 | identity[T1[3]](1) // error
| ^
| Match type reduction failed since selector (3 : Int)
| matches none of the cases
| ^
| Found: (1 : Int)
| Required: Test.T1[(3 : Int)]
|
| case (1 : Int) => Int
| case (2 : Int) => String
| Note: a match type could not be fully reduced:
|
| trying to reduce Test.T1[(3 : Int)]
| failed since selector (3 : Int)
| matches none of the cases
|
| case (1 : Int) => Int
| case (2 : Int) => String
|
| longer explanation available when compiling with `-explain`
-- [E007] Type Mismatch Error: tests/neg/matchtype-seq.scala:11:20 -----------------------------------------------------
11 | identity[T1[Int]]("") // error
| ^^
Expand Down
2 changes: 1 addition & 1 deletion tests/neg/12974.scala → tests/warn/12974.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ object RecMap {
def main(args: Array[String]) =
import Record._

val foo: Any = Rec.empty.fetch("foo") // error
val foo: Any = Rec.empty.fetch("foo") // TODO
// ^
// Match type reduction failed since selector EmptyTuple.type
// matches none of the cases
Expand Down

0 comments on commit 646fea8

Please sign in to comment.