Skip to content

Commit 395d1c3

Browse files
committed
improve error reporting
1 parent 731a82b commit 395d1c3

File tree

9 files changed

+78
-40
lines changed

9 files changed

+78
-40
lines changed

src/compiler/scala/tools/nsc/tasty/TreeUnpickler.scala

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ class TreeUnpickler[Tasty <: TastyUniverse](
124124
override def complete(sym: Symbol): Unit = throw new UnsupportedOperationException("complete")
125125
}
126126

127+
final class ErrorCompleter(msg: Symbol => String) extends TastyLazyType {
128+
override def complete(sym: Symbol): Unit = {
129+
throw new symbolTable.TypeError(msg(sym))
130+
}
131+
}
132+
127133
class TreeReader(val reader: TastyReader) {
128134
import reader._
129135

@@ -854,10 +860,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
854860
val unsupported = completer.tastyFlagSet &~ supported
855861
assertTasty(!unsupported, s"unsupported Scala 3 flags on $sym: ${show(unsupported)}")
856862
if (completer.tastyFlagSet.is(Inline)) {
857-
sym.addAnnotation(
858-
defn.CompileTimeOnlyAttr,
859-
Literal(Constant(s"Unsupported Scala 3 inline $sym"))
860-
)
863+
attachCompiletimeOnly(sym, s"Unsupported Scala 3 inline $sym")
861864
}
862865
if (completer.tastyFlagSet.is(Extension)) ctx.log(s"$name is a Scala 3 extension method.")
863866
val typeParams = {
@@ -900,6 +903,9 @@ class TreeUnpickler[Tasty <: TastyUniverse](
900903
}
901904
// TODO check for cycles
902905
sym.info = rhs.tpe match {
906+
case bounds @ TypeBounds(lo: PolyType, hi: PolyType) if !(mergeableParams(lo,hi)) =>
907+
new ErrorCompleter(owner =>
908+
s"$owner has diverging type lambdas as bounds:$bounds")
903909
case tpe: TypeBounds => normaliseBounds(tpe)
904910
case tpe => tpe
905911
}

src/compiler/scala/tools/nsc/tasty/bridge/TypeOps.scala

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,20 @@ trait TypeOps extends TastyKernel { self: TastyUniverse =>
2525
def mergeableParams(t: Type, u: Type): Boolean =
2626
t.typeParams.size == u.typeParams.size
2727

28+
def attachCompiletimeOnly(owner: Symbol, msg: String): Unit = {
29+
owner.addAnnotation(defn.CompileTimeOnlyAttr, Literal(Constant(msg)))
30+
}
31+
32+
def attachCompiletimeOnly(msg: Symbol => String)(implicit ctx: Context): Unit = {
33+
findOwner(owner => attachCompiletimeOnly(owner, msg(owner)))
34+
}
35+
36+
def findOwner[U](op: Symbol => U)(implicit ctx: Context): Unit = {
37+
for (owner <- ctx.owner.ownerChain.find(sym => !sym.is(Param))) {
38+
op(owner)
39+
}
40+
}
41+
2842
def normaliseBounds(bounds: TypeBounds)(implicit ctx: Context): Type = {
2943
val TypeBounds(lo, hi) = bounds
3044
if (lo.isHigherKinded && hi.isHigherKinded) {
@@ -37,11 +51,9 @@ trait TypeOps extends TastyKernel { self: TastyUniverse =>
3751
}
3852
mkPolyType(hi.typeParams, TypeBounds.bounded(nuLo, hi.resultType.upperBound))
3953
}
40-
else {
41-
bounds match {
42-
case TypeBounds(LambdaEncoding(lo), LambdaEncoding(hi)) => TypeBounds.bounded(lo,hi)
43-
case _ => bounds
44-
}
54+
else bounds match {
55+
case TypeBounds(LambdaEncoding(lo), LambdaEncoding(hi)) => TypeBounds.bounded(lo,hi)
56+
case _ => bounds
4557
}
4658
}
4759
else if (hi.isHigherKinded)
@@ -56,13 +68,9 @@ trait TypeOps extends TastyKernel { self: TastyUniverse =>
5668

5769
def typeRefUncurried(tycon: Type, args: List[Type]): Type = {
5870
if (tycon.isInstanceOf[TypeRef] && tycon.typeArgs.nonEmpty) {
59-
for (owner <- ctx.owner.ownerChain.find(sym => !sym.is(Param))) {
60-
owner.addAnnotation(
61-
defn.CompileTimeOnlyAttr,
62-
Literal(Constant(
63-
s"Unsupported Scala 3 curried type application $tycon[${args.mkString(",")}] in signature of $owner")))
64-
}
65-
defn.AnyTpe
71+
attachCompiletimeOnly(owner =>
72+
s"Unsupported Scala 3 curried type application $tycon[${args.mkString(",")}] in signature of $owner")
73+
errorType
6674
}
6775
else {
6876
mkAppliedType(tycon, args)
@@ -126,7 +134,7 @@ trait TypeOps extends TastyKernel { self: TastyUniverse =>
126134
AndType
127135
}
128136
else {
129-
errorTasty(s"Union types are not currently supported, [found within ${ctx.classRoot}]")
137+
attachCompiletimeOnly(owner => s"Scala 3 union types are not supported for $owner")
130138
errorType
131139
}
132140
}

test/tasty/neg/src-2/TestHKNest.check

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
TestHKNest_fail.scala:7: error: Unsupported Scala 3 curried type application F[T][U] in signature of method foo
2-
def test13 = assert(new HKClass_13[HKLam].foo[Int,String](("",0)) == "(,0)") // error: unsupported curried type application
3-
^
4-
1 error
1+
TestHKNest_fail.scala:6: error: type F has diverging type lambdas as bounds: >: [X]tastytest.HKNest.Arg1[X] <: [Y, Z]tastytest.HKNest.QuxArg[Y]
2+
def test14 = new HKClass_14[Quuux].foo(new Quuux[QuxArg]) // error: diverging lamdba type bounds
3+
^
4+
TestHKNest_fail.scala:7: error: type F has diverging type lambdas as bounds: >: [X]tastytest.HKNest.Arg1[X] <: [Y, Z]tastytest.HKNest.QuxArg[Y]
5+
def test15 = new HKClass_14[Quuuux].foo(new Quuuux[DummyQuxArg]) // error: diverging lamdba type bounds
6+
^
7+
2 errors
Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
1-
TestHKNest2_fail.scala:7: error: no type parameters for method foo: (x: tastytest.HKNest.Quuux[F])String exist so that it can be applied to arguments (tastytest.HKNest.Quuux[tastytest.HKNest.QuxArg])
2-
--- because ---
3-
argument expression's type is not compatible with formal parameter type;
4-
found : tastytest.HKNest.Quuux[tastytest.HKNest.QuxArg]
5-
required: tastytest.HKNest.Quuux[?F]
6-
7-
def test14 = new HKClass_14[Quuux].foo(new Quuux[QuxArg])
8-
^
9-
TestHKNest2_fail.scala:7: error: type mismatch;
10-
found : tastytest.HKNest.Quuux[tastytest.HKNest.QuxArg]
11-
required: tastytest.HKNest.Quuux[F]
12-
def test14 = new HKClass_14[Quuux].foo(new Quuux[QuxArg])
13-
^
1+
TestHKNest2_fail.scala:6: error: Scala 3 union types are not supported for method foo
2+
def test16 = new HKClass_15().foo(List(1,2,3)) // error: Union type not supported
3+
^
4+
TestHKNest2_fail.scala:7: error: Scala 3 union types are not supported for method foo
5+
def test17 = new HKClass_15().foo(Option(1)) // error: Union type not supported
6+
^
147
2 errors

test/tasty/neg/src-2/TestHKNest2_fail.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package tastytest
33
import HKNest._
44

55
object TestHKNest2 {
6-
7-
def test14 = new HKClass_14[Quuux].foo(new Quuux[QuxArg])
8-
6+
def test16 = new HKClass_15().foo(List(1,2,3)) // error: Union type not supported
7+
def test17 = new HKClass_15().foo(Option(1)) // error: Union type not supported
98
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
TestHKNest3_fail.scala:6: error: Unsupported Scala 3 curried type application F[T][U] in signature of method foo
2+
def test13 = new HKClass_13[HKLam].foo[Int,String](("",0)) // error: unsupported curried type application
3+
^
4+
TestHKNest3_fail.scala:7: error: Unsupported Scala 3 curried type application F[T][U] in signature of method foo
5+
def test16 = new HKClass_16[List].foo[HKLam,Int,String](("",0) :: Nil)
6+
^
7+
2 errors
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package tastytest
2+
3+
import HKNest._
4+
5+
object TestHKNest {
6+
def test13 = new HKClass_13[HKLam].foo[Int,String](("",0)) // error: unsupported curried type application
7+
def test16 = new HKClass_16[List].foo[HKLam,Int,String](("",0) :: Nil)
8+
}

test/tasty/neg/src-2/TestHKNest_fail.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package tastytest
33
import HKNest._
44

55
object TestHKNest {
6-
7-
def test13 = assert(new HKClass_13[HKLam].foo[Int,String](("",0)) == "(,0)") // error: unsupported curried type application
8-
6+
def test14 = new HKClass_14[Quuux].foo(new Quuux[QuxArg]) // error: diverging lamdba type bounds
7+
def test15 = new HKClass_14[Quuuux].foo(new Quuuux[DummyQuxArg]) // error: diverging lamdba type bounds
98
}

test/tasty/neg/src-3/HKNest.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,32 @@ object HKNest {
1010
def foo[F >: [X] =>> Arg1[X] <: [Y,Z] =>> QuxArg[Y]](x: M[F]): String = x.toString()
1111
}
1212

13+
class HKClass_15 {
14+
def foo[F[X] <: List[X] | Option[X], A](fa: F[A]): String = fa.toString()
15+
}
16+
17+
class HKClass_16[M[_]] {
18+
def foo[F <: [T] =>> [U] =>> (U, T),T,U](x: M[F[T][U]]): String = x.toString()
19+
}
20+
1321
def test13 = new HKClass_13[HKLam].foo[Int,String](("",0))
22+
def test16 = new HKClass_16[List].foo[HKLam,Int,String](("",0) :: Nil)
1423

1524
// def test14 = new HKClass_14[Quuux].foo(new Quuux[QuxArg])
1625

1726
type HKLam = [T] =>> [U] =>> (U, T)
1827

28+
type DummyQuxArg[Y,Z] = QuxArg[Y]
29+
1930
sealed trait QuxArg[T]
2031
class Arg1[T]() extends QuxArg[T]
2132

2233
class Quuux[F[X] >: Arg1[X] <: QuxArg[X]] {
2334
override def toString(): String = "Quuux"
2435
}
2536

37+
class Quuuux[F[Y,Z] >: Arg1[Y] <: QuxArg[Y]] {
38+
override def toString(): String = "Quuux"
39+
}
40+
2641
}

0 commit comments

Comments
 (0)