@@ -604,17 +604,6 @@ object Checking {
604604 checkNoConflict(Lazy , ParamAccessor , em " parameter may not be `lazy` " )
605605 }
606606
607- /** Check that the type `tp` is well-formed. Currently this only means
608- * checking that annotated types have valid annotation arguments.
609- */
610- def checkWellFormedType (tp : Type )(using Context ) =
611- tp.foreachPart:
612- case AnnotatedType (underlying, annot) =>
613- // Not checking `checkAnnotClass` because `Transform.toTypeTree` creates
614- // `Annotated` whose trees are not annotation instantiations.
615- checkAnnotArgs(annot.tree)
616- case _ => ()
617-
618607 /** Check for illegal or redundant modifiers on modules. This is done separately
619608 * from checkWellformed, since the original module modifiers don't surivive desugaring
620609 */
@@ -925,73 +914,6 @@ object Checking {
925914 annot
926915 case _ => annot
927916 end checkNamedArgumentForJavaAnnotation
928-
929- /** Check arguments of annotations */
930- private def checkAnnotArgs (tree : Tree )(using Context ): Tree =
931- val cls = Annotations .annotClass(tree)
932- tree match
933- case Apply (tycon, arg :: Nil ) if cls == defn.TargetNameAnnot =>
934- arg match
935- case Literal (Constant (" " )) =>
936- report.error(em " target name cannot be empty " , arg.srcPos)
937- case Literal (_) => // ok
938- case _ =>
939- report.error(em " @ ${cls.name} needs a string literal as argument " , arg.srcPos)
940- case _ =>
941- if cls.isRetainsLike then () // Do not check @retain annotations
942- else if cls == defn.ThrowsAnnot then
943- // Do not check @throws annotations.
944- // TODO(mbovel): in tests/run/t6380.scala, an annotation tree is
945- // `new throws[Exception](throws.<init>[Exception])`. What is this?
946- ()
947- else
948- tpd.allTermArguments(tree).foreach(checkAnnotArg)
949- tree
950-
951- private def checkAnnotArg (tree : Tree )(using Context ): Unit =
952- def isTupleModule (sym : Symbol ): Boolean =
953- ctx.definitions.isTupleClass(sym.companionClass)
954-
955- def isFunctionAllowed (t : Tree ): Boolean =
956- t match
957- case Select (qual, nme.apply) =>
958- qual.symbol == defn.ArrayModule
959- || qual.symbol == defn.ClassTagModule // class tags are used as arguments to Array.apply
960- || qual.symbol == defn.SymbolModule // used in Akka
961- || qual.symbol == defn.JSSymbolModule // used in Scala.js
962- || isTupleModule(qual.symbol)
963- case Select (New (clazz), nme.CONSTRUCTOR ) => clazz.symbol.isAnnotation
964- case Apply (fun, _) => isFunctionAllowed(fun)
965- case TypeApply (fun, _) => isFunctionAllowed(fun)
966- case _ => false
967-
968- def valid (t : Tree ): Boolean =
969- t.tpe.isEffectivelySingleton
970- || (
971- t match
972- case Literal (_) => true
973- // `_` is used as placeholder for unspecified arguments of Java
974- // annotations. Example: tests/run/java-ann-super-class
975- case Ident (nme.WILDCARD ) => true
976- case Apply (fun, args) => isFunctionAllowed(fun) && args.forall(valid)
977- case TypeApply (fun, args) => isFunctionAllowed(fun)
978- // Support for `x.isInstanceOf[T]`. Probably not needed.
979- // case TypeApply(meth @ Select(arg, _), _) if meth.symbol == defn.Any_asInstanceOf => valid(arg)
980- case SeqLiteral (elems, _) => elems.forall(valid)
981- case Typed (expr, _) => valid(expr)
982- case NamedArg (_, arg) => valid(arg)
983- case Splice (_) => true
984- case Hole (_, _, _, _) => true
985- case _ => false
986- )
987-
988- if ! valid(tree) then
989- report.error(
990- i """ Implementation restriction: not a valid annotation argument.
991- | Argument: $tree
992- | Type: ${tree.tpe}""" ,
993- tree.srcPos
994- )
995917}
996918
997919trait Checking {
@@ -1463,7 +1385,13 @@ trait Checking {
14631385 report.error(em " $what can only be used in an inline method " , pos)
14641386
14651387 def checkAnnot (tree : Tree )(using Context ): Tree =
1466- Checking .checkAnnotArgs(checkAnnotClass(tree))
1388+ tree match
1389+ case Ident (tpnme.BOUNDTYPE_ANNOT ) =>
1390+ // `FirstTransform.toTypeTree` creates `Annotated` nodes whose `annot` are
1391+ // `Ident`s, not annotation instances. See `tests/pos/annot-boundtype.scala`.
1392+ tree
1393+ case _ =>
1394+ checkAnnotArgs(checkAnnotClass(tree))
14671395
14681396 /** Check that the class corresponding to this tree is either a Scala or Java annotation.
14691397 *
@@ -1481,6 +1409,73 @@ trait Checking {
14811409 else if ! cls.derivesFrom(defn.AnnotationClass ) then
14821410 errorTree(tree, em " $cls is not a valid Scala annotation: it does not extend `scala.annotation.Annotation` " )
14831411 else tree
1412+
1413+ /** Check arguments of annotations */
1414+ private def checkAnnotArgs (tree : Tree )(using Context ): Tree =
1415+ val cls = Annotations .annotClass(tree)
1416+ tree match
1417+ case Apply (tycon, arg :: Nil ) if cls == defn.TargetNameAnnot =>
1418+ arg match
1419+ case Literal (Constant (" " )) =>
1420+ report.error(em " target name cannot be empty " , arg.srcPos)
1421+ case Literal (_) => // ok
1422+ case _ =>
1423+ report.error(em " @ ${cls.name} needs a string literal as argument " , arg.srcPos)
1424+ 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 isTupleModule (sym : Symbol ): Boolean =
1437+ ctx.definitions.isTupleClass(sym.companionClass)
1438+
1439+ def isFunctionAllowed (t : Tree ): Boolean =
1440+ t match
1441+ case Select (qual, nme.apply) =>
1442+ qual.symbol == defn.ArrayModule
1443+ || qual.symbol == defn.ClassTagModule // class tags are used as arguments to Array.apply
1444+ || qual.symbol == defn.SymbolModule // used in Akka
1445+ || qual.symbol == defn.JSSymbolModule // used in Scala.js
1446+ || isTupleModule(qual.symbol)
1447+ case Select (New (clazz), nme.CONSTRUCTOR ) => clazz.symbol.isAnnotation
1448+ case Apply (fun, _) => isFunctionAllowed(fun)
1449+ case TypeApply (fun, _) => isFunctionAllowed(fun)
1450+ case _ => false
1451+
1452+ def valid (t : Tree ): Boolean =
1453+ t.tpe.isEffectivelySingleton
1454+ || (
1455+ t match
1456+ case Literal (_) => true
1457+ // `_` is used as placeholder for unspecified arguments of Java
1458+ // annotations. Example: tests/run/java-ann-super-class
1459+ case Ident (nme.WILDCARD ) => true
1460+ case Apply (fun, args) => isFunctionAllowed(fun) && args.forall(valid)
1461+ case TypeApply (fun, args) => isFunctionAllowed(fun)
1462+ // Support for `x.isInstanceOf[T]`. Probably not needed.
1463+ // case TypeApply(meth @ Select(arg, _), _) if meth.symbol == defn.Any_asInstanceOf => valid(arg)
1464+ case SeqLiteral (elems, _) => elems.forall(valid)
1465+ case Typed (expr, _) => valid(expr)
1466+ case NamedArg (_, arg) => valid(arg)
1467+ case Splice (_) => true
1468+ case Hole (_, _, _, _) => true
1469+ case _ => false
1470+ )
1471+
1472+ if ! valid(tree) then
1473+ report.error(
1474+ i """ Implementation restriction: not a valid annotation argument.
1475+ | Argument: $tree
1476+ | Type: ${tree.tpe}""" ,
1477+ tree.srcPos
1478+ )
14841479
14851480 /** 1. Check that all case classes that extend `scala.reflect.Enum` are `enum` cases
14861481 * 2. Check that parameterised `enum` cases do not extend java.lang.Enum.
0 commit comments