Skip to content

Commit 7536871

Browse files
mbovelKacperFKorban
andcommitted
Fix best-effort error
Throw away erroneous trees to avoid unpickling issues in best-effort mode. Co-Authored-By: Kacper Korban <[email protected]>
1 parent dbcf30f commit 7536871

File tree

2 files changed

+35
-36
lines changed

2 files changed

+35
-36
lines changed

compiler/src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,41 +1421,40 @@ trait Checking {
14211421
case Literal(_) => // ok
14221422
case _ =>
14231423
report.error(em"@${cls.name} needs a string literal as argument", arg.srcPos)
1424+
tree
14241425
case _ =>
1425-
if cls.isRetainsLike then () // Do not check @retain annotations
1426-
else if cls == defn.ThrowsAnnot then
1427-
// Do not check @throws annotations.
1428-
// TODO(mbovel): in tests/run/t6380.scala, an annotation tree is
1429-
// `new throws[Exception](throws.<init>[Exception])`. What is this?
1430-
()
1431-
else
1432-
tpd.allTermArguments(tree).foreach(checkAnnotArg)
1433-
tree
1434-
1435-
private def checkAnnotArg(tree: Tree)(using Context): Unit =
1436-
def valid(t: Tree): Boolean =
1437-
t match
1438-
case _ if t.tpe.isEffectivelySingleton => true
1439-
case Literal(_) => true
1440-
// `_` is used as placeholder for unspecified arguments of Java
1441-
// annotations. Example: tests/run/java-ann-super-class
1442-
case Ident(nme.WILDCARD) => true
1443-
case Apply(fun, args) => valid(fun) && args.forall(valid)
1444-
case TypeApply(fun, args) => valid(fun)
1445-
case SeqLiteral(elems, _) => elems.forall(valid)
1446-
case Typed(expr, _) => valid(expr)
1447-
case NamedArg(_, arg) => valid(arg)
1448-
case Splice(_) => true
1449-
case Hole(_, _, _, _) => true
1450-
case _ => false
1451-
if !valid(tree) then
1452-
report.error(
1453-
i"""Implementation restriction: not a valid annotation argument.
1454-
|Argument: $tree
1455-
|Type: ${tree.tpe}""",
1456-
tree.srcPos
1457-
)
1458-
1426+
tpd.allTermArguments(tree).foldLeft(tree: Tree)((acc: Tree, arg: Tree) =>
1427+
if validAnnotArg(arg) then acc
1428+
else errorTree(
1429+
EmptyTree,
1430+
em"""Implementation restriction: not a valid annotation argument.
1431+
|Argument: $tree
1432+
|Type: ${tree.tpe}""",
1433+
arg.srcPos)
1434+
)
1435+
1436+
private def validAnnotArg(t: Tree)(using Context): Boolean =
1437+
t match
1438+
case _ if t.tpe.isEffectivelySingleton => true
1439+
case Literal(_) => true
1440+
// `Ident(nme.WILDCARD)` is used as placeholder for unspecified
1441+
// arguments of Java annotations.
1442+
// Example: tests/run/java-ann-super-class.
1443+
case Ident(nme.WILDCARD) => true
1444+
case Apply(fun, args) => validAnnotArg(fun) && args.forall(validAnnotArg)
1445+
case TypeApply(fun, args) => validAnnotArg(fun)
1446+
case SeqLiteral(elems, _) => elems.forall(validAnnotArg)
1447+
case Typed(expr, _) => validAnnotArg(expr)
1448+
// TODO(mbovel): should probably be handled by `tpd.allTermArguments` instead.
1449+
case NamedArg(_, arg) => validAnnotArg(arg)
1450+
// TODO(mbovel): we should probably not allow `Splice` and `Hole`.
1451+
// How to encode them as types?
1452+
// When removing those cases, tests/pos-macros/i7519b.scala and
1453+
// tests/pos-macros/i7052.scala fail.
1454+
case Splice(_) => true
1455+
case Hole(_, _, _, _) => true
1456+
case _ => false
1457+
14591458
/** 1. Check that all case classes that extend `scala.reflect.Enum` are `enum` cases
14601459
* 2. Check that parameterised `enum` cases do not extend java.lang.Enum.
14611460
* 3. Check that only a static `enum` base class can extend java.lang.Enum.

tests/neg/annot-invalid.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ class annot[T](arg: T) extends scala.annotation.Annotation
33
def main =
44
val x1: Int @annot(new Object {}) = 0 // error
55
val x2: Int @annot({val x = 1}) = 0 // error
6-
val x4: Int @annot((x: Int) => x) = 0 // error
6+
val x3: Int @annot((x: Int) => x) = 0 // error
77

88
@annot(new Object {}) val y1: Int = 0 // error
99
@annot({val x = 1}) val y2: Int = 0 // error
10-
@annot((x: Int) => x) val y4: Int = 0 // error
10+
@annot((x: Int) => x) val y3: Int = 0 // error
1111

1212
()

0 commit comments

Comments
 (0)