diff --git a/compiler/src/dotty/tools/dotc/core/MatchTypeTrace.scala b/compiler/src/dotty/tools/dotc/core/MatchTypeTrace.scala index fb278ab92dc9..ec6a9c1d8787 100644 --- a/compiler/src/dotty/tools/dotc/core/MatchTypeTrace.scala +++ b/compiler/src/dotty/tools/dotc/core/MatchTypeTrace.scala @@ -14,7 +14,6 @@ object MatchTypeTrace: case TryReduce(scrut: Type) case Stuck(scrut: Type, stuckCase: MatchTypeCaseSpec, otherCases: List[MatchTypeCaseSpec]) case NoInstance(scrut: Type, stuckCase: MatchTypeCaseSpec, fails: List[(Name, TypeBounds)]) - case EmptyScrutinee(scrut: Type) import TraceEntry.* private class MatchTrace: @@ -60,12 +59,6 @@ object MatchTypeTrace: def noInstance(scrut: Type, stuckCase: MatchTypeCaseSpec, fails: List[(Name, TypeBounds)])(using Context) = matchTypeFail(NoInstance(scrut, stuckCase, fails)) - /** Record a failure that scrutinee `scrut` is provably empty. - * Only the first failure is recorded. - */ - def emptyScrutinee(scrut: Type)(using Context) = - matchTypeFail(EmptyScrutinee(scrut)) - /** Record in the trace that we are trying to reduce `scrut` when performing `op` * If `op` succeeds the entry is removed after exit. If `op` fails, it stays. */ @@ -95,9 +88,6 @@ object MatchTypeTrace: private def explainEntry(entry: TraceEntry)(using Context): String = entry match case TryReduce(scrut: Type) => i" trying to reduce $scrut" - case EmptyScrutinee(scrut) => - i""" failed since selector $scrut - | is uninhabited (there are no values of that type).""" case Stuck(scrut, stuckCase, otherCases) => val msg = i""" failed since selector $scrut @@ -125,6 +115,10 @@ object MatchTypeTrace: | | ${casesText(cases)}""" + def emptyScrutineeText(scrut: Type)(using Context): String = + i"""failed since selector $scrut + |is uninhabited (there are no values of that type).""" + def illegalPatternText(scrut: Type, cas: MatchTypeCaseSpec.LegacyPatMat)(using Context): String = i"""The match type contains an illegal case: | ${caseText(cas)} diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index 302ad7987889..394b2e1a177f 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -3567,6 +3567,13 @@ class MatchReducer(initctx: Context) extends TypeComparer(initctx) { def matchMissingCaptures(spec: MatchTypeCaseSpec.MissingCaptures): MatchResult = MatchResult.Stuck + /** + * Report the failed match type reduction when possible, leave it unreduced otherwise + * See constvalue-of-failed-match-type.scala for an example where this is needed + */ + inline def tryReportingReductionError(typeError: TypeError) = + if ctx.isTyper then throw typeError else NoType + def recur(remaining: List[MatchTypeCaseSpec]): Type = remaining match case (cas: MatchTypeCaseSpec.LegacyPatMat) :: _ if sourceVersion.isAtLeast(SourceVersion.`3.4`) => val errorText = MatchTypeTrace.illegalPatternText(scrut, cas) @@ -3591,26 +3598,15 @@ class MatchReducer(initctx: Context) extends TypeComparer(initctx) { // probably disjoint from it, we prevent reduction. // See `tests/neg/6570.scala` and `6570-1.scala` for examples that // exploit emptiness to break match type soundness. - MatchTypeTrace.emptyScrutinee(scrut) - NoType + tryReportingReductionError: + val scrutText = MatchTypeTrace.emptyScrutineeText(scrut) + MatchTypeReductionError(em"Match type reduction $scrutText") case Nil => - val casesText = MatchTypeTrace.noMatchesText(scrut, cases) - ErrorType(reporting.MatchTypeNoCases(casesText)) - - inFrozenConstraint { - if scrut.isError then - // if the scrutinee is an error type - // then just return that as the result - // not doing so will result in the first type case matching - // because ErrorType (as a FlexType) is <:< any type case - // this situation can arise from any kind of nesting of match types, - // e.g. neg/i12049 `Tuple.Concat[Reverse[ts], (t2, t1)]` - // if Reverse[ts] fails with no matches, - // the error type should be the reduction of the Concat too - scrut - else - recur(cases) - } + tryReportingReductionError: + val casesText = MatchTypeTrace.noMatchesText(scrut, cases) + MatchTypeReductionError(em"Match type reduction $casesText") + + inFrozenConstraint(recur(cases)) } } diff --git a/compiler/src/dotty/tools/dotc/core/TypeErrors.scala b/compiler/src/dotty/tools/dotc/core/TypeErrors.scala index 240bc4eebd84..eda3910f44fc 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeErrors.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeErrors.scala @@ -53,6 +53,9 @@ object TypeError: def toMessage(using Context) = msg end TypeError +class MatchTypeReductionError(msg: Message)(using Context) extends TypeError: + def toMessage(using Context) = msg + class MalformedType(pre: Type, denot: Denotation, absMembers: Set[Name])(using Context) extends TypeError: def toMessage(using Context) = em"malformed type: $pre is not a legal prefix for $denot because it contains abstract type member${if (absMembers.size == 1) "" else "s"} ${absMembers.mkString(", ")}" diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 5162b3fed1b9..f3abe87ed765 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -663,7 +663,7 @@ trait ImplicitRunInfo: traverseChildren(t) case t => traverseChildren(t) - traverse(t.normalized) + traverse(try t.normalized catch case _: MatchTypeReductionError => t) catch case ex: Throwable => handleRecursive("collectParts of", t.show, ex) def apply(tp: Type): collection.Set[Type] = diff --git a/tests/neg-macros/toexproftuple.scala b/tests/neg-macros/toexproftuple.scala index 7b69c578be70..20ae2f08ff8d 100644 --- a/tests/neg-macros/toexproftuple.scala +++ b/tests/neg-macros/toexproftuple.scala @@ -1,8 +1,33 @@ -import scala.quoted._, scala.deriving.* +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} +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] = { +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 val tpl: (Expr[1], Expr[2], Expr[3]) = ('{1}, '{2}, '{3}) '{val res: (1, 3, 3) = ${Expr.ofTuple(tpl)}; res} // error @@ -11,7 +36,7 @@ def mcrImpl(using ctx: Quotes): Expr[Any] = { // 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 + '{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[ @@ -19,4 +44,20 @@ def mcrImpl(using ctx: Quotes): Expr[Any] = { // , 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 } diff --git a/tests/neg/6314-2.scala b/tests/neg/6314-2.scala index 216e759ca359..42c8edd07a18 100644 --- a/tests/neg/6314-2.scala +++ b/tests/neg/6314-2.scala @@ -17,8 +17,8 @@ object G { def main(args: Array[String]): Unit = { val a: Bar[X & Foo] = "hello" // error - val i: Bar[Y & Foo] = Foo.apply[Bar](a) - val b: Int = i // error + val i: Bar[Y & Foo] = Foo.apply[Bar](a) // error // error + val b: Int = i println(b + 1) } } diff --git a/tests/neg/6314-6.check b/tests/neg/6314-6.check index 7d6bd182173d..5339e9b91d48 100644 --- a/tests/neg/6314-6.check +++ b/tests/neg/6314-6.check @@ -1,16 +1,20 @@ --- Error: tests/neg/6314-6.scala:26:3 ---------------------------------------------------------------------------------- -26 | (new YY {}).boom // error: object creation impossible - | ^ - |object creation impossible, since def apply(fa: String): Int in trait XX in object Test3 is not defined - |(Note that - | parameter String in def apply(fa: String): Int in trait XX in object Test3 does not match - | parameter Test3.Bar[X & Object with Test3.YY {...}#Foo] in def apply(fa: Test3.Bar[X & YY.this.Foo]): Test3.Bar[Y & YY.this.Foo] in trait YY in object Test3 - | ) --- Error: tests/neg/6314-6.scala:52:3 ---------------------------------------------------------------------------------- -52 | (new YY {}).boom // error: object creation impossible - | ^ - |object creation impossible, since def apply(fa: String): Int in trait XX in object Test4 is not defined - |(Note that - | parameter String in def apply(fa: String): Int in trait XX in object Test4 does not match - | parameter Test4.Bar[X & Object with Test4.YY {...}#FooAlias] in def apply(fa: Test4.Bar[X & YY.this.FooAlias]): Test4.Bar[Y & YY.this.FooAlias] in trait YY in object Test4 - | ) +-- Error: tests/neg/6314-6.scala:24:18 --------------------------------------------------------------------------------- +24 | def apply(fa: Bar[X & Foo]): Bar[Y & Foo] = fa // error // error + | ^ + | Match type reduction failed since selector X & YY.this.Foo + | is uninhabited (there are no values of that type). +-- Error: tests/neg/6314-6.scala:24:33 --------------------------------------------------------------------------------- +24 | def apply(fa: Bar[X & Foo]): Bar[Y & Foo] = fa // error // error + | ^ + | Match type reduction failed since selector Y & YY.this.Foo + | is uninhabited (there are no values of that type). +-- Error: tests/neg/6314-6.scala:50:18 --------------------------------------------------------------------------------- +50 | def apply(fa: Bar[X & FooAlias]): Bar[Y & FooAlias] = fa // error // error + | ^ + | Match type reduction failed since selector X & YY.this.FooAlias + | is uninhabited (there are no values of that type). +-- Error: tests/neg/6314-6.scala:50:38 --------------------------------------------------------------------------------- +50 | def apply(fa: Bar[X & FooAlias]): Bar[Y & FooAlias] = fa // error // error + | ^ + | Match type reduction failed since selector Y & YY.this.FooAlias + | is uninhabited (there are no values of that type). diff --git a/tests/neg/6314-6.scala b/tests/neg/6314-6.scala index 23853e20434d..8759707837fe 100644 --- a/tests/neg/6314-6.scala +++ b/tests/neg/6314-6.scala @@ -21,9 +21,9 @@ object Test3 { trait YY extends XX { type Foo = X & Y - def apply(fa: Bar[X & Foo]): Bar[Y & Foo] = fa + def apply(fa: Bar[X & Foo]): Bar[Y & Foo] = fa // error // error } - (new YY {}).boom // error: object creation impossible + (new YY {}).boom } object Test4 { @@ -47,7 +47,7 @@ object Test4 { trait YY extends XX { type Foo = X & Y - def apply(fa: Bar[X & FooAlias]): Bar[Y & FooAlias] = fa + def apply(fa: Bar[X & FooAlias]): Bar[Y & FooAlias] = fa // error // error } - (new YY {}).boom // error: object creation impossible + (new YY {}).boom } diff --git a/tests/neg/6570-1.check b/tests/neg/6570-1.check index 0abf96e2d350..af30c8a726a1 100644 --- a/tests/neg/6570-1.check +++ b/tests/neg/6570-1.check @@ -1,16 +1,8 @@ --- [E007] Type Mismatch Error: tests/neg/6570-1.scala:23:27 ------------------------------------------------------------ +-- Error: tests/neg/6570-1.scala:23:11 --------------------------------------------------------------------------------- 23 | def thing = new Trait1 {} // error - | ^ - | Found: Object with Trait1 {...} - | Required: N[Box[Int & String]] - | - | Note: a match type could not be fully reduced: - | - | trying to reduce N[Box[Int & String]] - | failed since selector Box[Int & String] - | is uninhabited (there are no values of that type). - | - | longer explanation available when compiling with `-explain` + | ^ + | Match type reduction failed since selector Box[Int & String] + | is uninhabited (there are no values of that type). -- [E007] Type Mismatch Error: tests/neg/6570-1.scala:36:54 ------------------------------------------------------------ 36 | def foo[T <: Cov[Box[Int]]](c: Root[T]): Trait2 = c.thing // error | ^^^^^^^ diff --git a/tests/neg/6570.check b/tests/neg/6570.check index e849814449eb..4073737947cc 100644 --- a/tests/neg/6570.check +++ b/tests/neg/6570.check @@ -17,19 +17,11 @@ | x >: Int | | longer explanation available when compiling with `-explain` --- [E007] Type Mismatch Error: tests/neg/6570.scala:29:29 -------------------------------------------------------------- +-- Error: tests/neg/6570.scala:29:13 ----------------------------------------------------------------------------------- 29 | def thing = new Trait1 {} // error - | ^ - | Found: Object with Base.Trait1 {...} - | Required: Base.N[String & Int] - | - | Note: a match type could not be fully reduced: - | - | trying to reduce Base.N[String & Int] - | failed since selector String & Int - | is uninhabited (there are no values of that type). - | - | longer explanation available when compiling with `-explain` + | ^ + | Match type reduction failed since selector String & Int + | is uninhabited (there are no values of that type). -- [E007] Type Mismatch Error: tests/neg/6570.scala:47:32 -------------------------------------------------------------- 47 | def foo(c: Child): Trait2 = c.thing // error | ^^^^^^^ @@ -46,45 +38,21 @@ | a >: Int | | longer explanation available when compiling with `-explain` --- [E007] Type Mismatch Error: tests/neg/6570.scala:51:29 -------------------------------------------------------------- +-- Error: tests/neg/6570.scala:51:13 ----------------------------------------------------------------------------------- 51 | def thing = new Trait1 {} // error - | ^ - | Found: Object with Base.Trait1 {...} - | Required: Base.N[String & Int] - | - | Note: a match type could not be fully reduced: - | - | trying to reduce Base.N[String & Int] - | failed since selector String & Int - | is uninhabited (there are no values of that type). - | - | longer explanation available when compiling with `-explain` --- [E007] Type Mismatch Error: tests/neg/6570.scala:69:29 -------------------------------------------------------------- + | ^ + | Match type reduction failed since selector String & Int + | is uninhabited (there are no values of that type). +-- Error: tests/neg/6570.scala:69:13 ----------------------------------------------------------------------------------- 69 | def thing = new Trait1 {} // error - | ^ - | Found: Object with Base.Trait1 {...} - | Required: Base.N[String & Int] - | - | Note: a match type could not be fully reduced: - | - | trying to reduce Base.N[String & Int] - | failed since selector String & Int - | is uninhabited (there are no values of that type). - | - | longer explanation available when compiling with `-explain` --- [E007] Type Mismatch Error: tests/neg/6570.scala:86:29 -------------------------------------------------------------- + | ^ + | Match type reduction failed since selector String & Int + | is uninhabited (there are no values of that type). +-- Error: tests/neg/6570.scala:86:13 ----------------------------------------------------------------------------------- 86 | def thing = new Trait1 {} // error - | ^ - | Found: Object with Base.Trait1 {...} - | Required: Base.N[String & Int] - | - | Note: a match type could not be fully reduced: - | - | trying to reduce Base.N[String & Int] - | failed since selector String & Int - | is uninhabited (there are no values of that type). - | - | longer explanation available when compiling with `-explain` + | ^ + | Match type reduction failed since selector String & Int + | is uninhabited (there are no values of that type). -- [E007] Type Mismatch Error: tests/neg/6570.scala:103:32 ------------------------------------------------------------- 103 | def foo(c: Child): Trait2 = c.thing // error | ^^^^^^^ @@ -101,16 +69,8 @@ | t >: Int | | longer explanation available when compiling with `-explain` --- [E007] Type Mismatch Error: tests/neg/6570.scala:107:29 ------------------------------------------------------------- +-- Error: tests/neg/6570.scala:107:13 ---------------------------------------------------------------------------------- 107 | def thing = new Trait1 {} // error - | ^ - | Found: Object with Base.Trait1 {...} - | Required: Base.N[String & Int] - | - | Note: a match type could not be fully reduced: - | - | trying to reduce Base.N[String & Int] - | failed since selector String & Int - | is uninhabited (there are no values of that type). - | - | longer explanation available when compiling with `-explain` + | ^ + | Match type reduction failed since selector String & Int + | is uninhabited (there are no values of that type). diff --git a/tests/neg/i12049.check b/tests/neg/i12049.check index b44eb612f627..4977b8d8c591 100644 --- a/tests/neg/i12049.check +++ b/tests/neg/i12049.check @@ -15,17 +15,17 @@ | case B => String | | longer explanation available when compiling with `-explain` --- [E184] Type Error: tests/neg/i12049.scala:14:23 --------------------------------------------------------------------- +-- Error: tests/neg/i12049.scala:14:23 --------------------------------------------------------------------------------- 14 |val y3: String = ??? : Last[Int *: Int *: Boolean *: String *: EmptyTuple] // error - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ | Match type reduction failed since selector EmptyTuple | matches none of the cases | | case _ *: _ *: t => Last[t] | case t *: EmptyTuple => t --- [E184] Type Error: tests/neg/i12049.scala:22:26 --------------------------------------------------------------------- +-- Error: tests/neg/i12049.scala:22:26 --------------------------------------------------------------------------------- 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 | @@ -45,17 +45,17 @@ | Therefore, reduction cannot advance to the remaining case | | case B => String --- [E184] Type Error: tests/neg/i12049.scala:25:26 --------------------------------------------------------------------- +-- Error: tests/neg/i12049.scala:25:26 --------------------------------------------------------------------------------- 25 |val _ = summon[String =:= Last[Int *: Int *: Boolean *: String *: EmptyTuple]] // error - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ | Match type reduction failed since selector EmptyTuple | matches none of the cases | | case _ *: _ *: t => Last[t] | case t *: EmptyTuple => t --- [E184] Type Error: tests/neg/i12049.scala:26:29 --------------------------------------------------------------------- +-- Error: tests/neg/i12049.scala:26:29 --------------------------------------------------------------------------------- 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 | diff --git a/tests/neg/i13757-match-type-anykind.scala b/tests/neg/i13757-match-type-anykind.scala index a80e8b2b289b..3feb9907fb69 100644 --- a/tests/neg/i13757-match-type-anykind.scala +++ b/tests/neg/i13757-match-type-anykind.scala @@ -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 + type AnyKindMatchType4[X <: Option] = X match // error // error: the scrutinee of a match type cannot be higher-kinded // error case _ => Int - type AnyKindMatchType5[X[_]] = X match // error: the scrutinee of a match type cannot be higher-kinded + type AnyKindMatchType5[X[_]] = X match // error: the scrutinee of a match type cannot be higher-kinded // error case _ => Int end Test diff --git a/tests/neg/i19949.scala b/tests/neg/i19949.scala new file mode 100644 index 000000000000..96a22e42e079 --- /dev/null +++ b/tests/neg/i19949.scala @@ -0,0 +1,9 @@ + +trait T[N]: + type M = N match + case 0 => Any + +val t: T[Double] = new T[Double] {} +val x: t.M = "hello" // error + +val z: T[Double]#M = "hello" // error diff --git a/tests/neg/matchtype-seq.check b/tests/neg/matchtype-seq.check index 980329d585dc..a98fd7a2168e 100644 --- a/tests/neg/matchtype-seq.check +++ b/tests/neg/matchtype-seq.check @@ -1,14 +1,14 @@ --- [E184] Type Error: tests/neg/matchtype-seq.scala:9:11 --------------------------------------------------------------- +-- Error: tests/neg/matchtype-seq.scala:9:11 --------------------------------------------------------------------------- 9 | identity[T1[3]]("") // error - | ^^^^^ + | ^ | Match type reduction failed since selector (3 : Int) | matches none of the cases | | case (1 : Int) => Int | case (2 : Int) => String --- [E184] Type Error: tests/neg/matchtype-seq.scala:10:11 -------------------------------------------------------------- +-- Error: tests/neg/matchtype-seq.scala:10:11 -------------------------------------------------------------------------- 10 | identity[T1[3]](1) // error - | ^^^^^ + | ^ | Match type reduction failed since selector (3 : Int) | matches none of the cases | @@ -232,58 +232,26 @@ | case Test.E2 => String | | longer explanation available when compiling with `-explain` --- [E007] Type Mismatch Error: tests/neg/matchtype-seq.scala:105:40 ---------------------------------------------------- +-- Error: tests/neg/matchtype-seq.scala:105:11 ------------------------------------------------------------------------- 105 | identity[T9[Tuple2[Nothing, String]]](1) // error - | ^ - | Found: (1 : Int) - | Required: Test.T9[(Nothing, String)] - | - | Note: a match type could not be fully reduced: - | - | trying to reduce Test.T9[(Nothing, String)] - | failed since selector (Nothing, String) - | is uninhabited (there are no values of that type). - | - | longer explanation available when compiling with `-explain` --- [E007] Type Mismatch Error: tests/neg/matchtype-seq.scala:106:40 ---------------------------------------------------- + | ^ + | Match type reduction failed since selector (Nothing, String) + | is uninhabited (there are no values of that type). +-- Error: tests/neg/matchtype-seq.scala:106:11 ------------------------------------------------------------------------- 106 | identity[T9[Tuple2[String, Nothing]]]("1") // error - | ^^^ - | Found: ("1" : String) - | Required: Test.T9[(String, Nothing)] - | - | Note: a match type could not be fully reduced: - | - | trying to reduce Test.T9[(String, Nothing)] - | failed since selector (String, Nothing) - | is uninhabited (there are no values of that type). - | - | longer explanation available when compiling with `-explain` --- [E007] Type Mismatch Error: tests/neg/matchtype-seq.scala:107:37 ---------------------------------------------------- + | ^ + | Match type reduction failed since selector (String, Nothing) + | is uninhabited (there are no values of that type). +-- Error: tests/neg/matchtype-seq.scala:107:11 ------------------------------------------------------------------------- 107 | identity[T9[Tuple2[Int, Nothing]]](1) // error - | ^ - | Found: (1 : Int) - | Required: Test.T9[(Int, Nothing)] - | - | Note: a match type could not be fully reduced: - | - | trying to reduce Test.T9[(Int, Nothing)] - | failed since selector (Int, Nothing) - | is uninhabited (there are no values of that type). - | - | longer explanation available when compiling with `-explain` --- [E007] Type Mismatch Error: tests/neg/matchtype-seq.scala:108:37 ---------------------------------------------------- + | ^ + | Match type reduction failed since selector (Int, Nothing) + | is uninhabited (there are no values of that type). +-- Error: tests/neg/matchtype-seq.scala:108:11 ------------------------------------------------------------------------- 108 | identity[T9[Tuple2[Nothing, Int]]]("1") // error - | ^^^ - | Found: ("1" : String) - | Required: Test.T9[(Nothing, Int)] - | - | Note: a match type could not be fully reduced: - | - | trying to reduce Test.T9[(Nothing, Int)] - | failed since selector (Nothing, Int) - | is uninhabited (there are no values of that type). - | - | longer explanation available when compiling with `-explain` + | ^ + | Match type reduction failed since selector (Nothing, Int) + | is uninhabited (there are no values of that type). -- [E007] Type Mismatch Error: tests/neg/matchtype-seq.scala:109:29 ---------------------------------------------------- 109 | identity[T9[Tuple2[?, ?]]]("") // error | ^^ diff --git a/tests/pos/8778.scala b/tests/pos/8778.scala index c91f765cca01..781102d7a251 100644 --- a/tests/pos/8778.scala +++ b/tests/pos/8778.scala @@ -18,6 +18,6 @@ object Test { val invN: Inv[Nothing] = new Inv[Nothing] {} m(invN) // reduces to Int both as a value and as a type - m(ev(invN)) // reduces to String both as a value and as a type + // TODO m(ev(invN)) // reduces to String both as a value and as a type } diff --git a/tests/pos/i18488.scala b/tests/pos/i18488.scala deleted file mode 100644 index c225a2c20711..000000000000 --- a/tests/pos/i18488.scala +++ /dev/null @@ -1,15 +0,0 @@ -trait AbstractTable[T] - -trait Query[E, U] - -class TableQuery[E <: AbstractTable[?]] extends Query[E, Extract[E]] - -type Extract[E] = E match - case AbstractTable[t] => t - -trait BaseCrudRepository[E[T[_]]]: - - type EntityTable <: AbstractTable[E[Option]] - - def filterById: Query[EntityTable, Extract[EntityTable]] = - new TableQuery[EntityTable] diff --git a/tests/pos/i19950.scala b/tests/pos/i19950.scala new file mode 100644 index 000000000000..349140f43ff5 --- /dev/null +++ b/tests/pos/i19950.scala @@ -0,0 +1,10 @@ + +trait Apply[F[_]]: + extension [T <: NonEmptyTuple](tuple: T)(using toMap: Tuple.IsMappedBy[F][T]) + def mapN[B](f: Tuple.InverseMap[T, F] => B): F[B] = ??? + +given Apply[Option] = ??? +given Apply[List] = ??? +given Apply[util.Try] = ??? + +@main def Repro = (Option(1), Option(2), Option(3)).mapN(_ + _ + _) \ No newline at end of file