Skip to content

Commit 84d83e3

Browse files
committed
Do not lift annotation arguments
1 parent fcbb372 commit 84d83e3

File tree

6 files changed

+37
-37
lines changed

6 files changed

+37
-37
lines changed

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,18 +142,17 @@ trait TreeInfo[T <: Untyped] { self: Trees.Instance[T] =>
142142

143143
/** All term arguments of an application in a single flattened list */
144144
def allTermArguments(tree: Tree): List[Tree] = unsplice(tree) match {
145-
case Apply(fn, args) => allTermArguments(fn) ::: args
145+
case Apply(fn, args) => allTermArguments(fn) ::: args.map(stripNamedArg)
146146
case TypeApply(fn, args) => allTermArguments(fn)
147-
// TOOD(mbovel): is it really safe to skip all blocks here and in `allArguments`?
148-
case Block(_, expr) => allTermArguments(expr)
147+
case Block(Nil, expr) => allTermArguments(expr)
149148
case _ => Nil
150149
}
151150

152151
/** All type and term arguments of an application in a single flattened list */
153152
def allArguments(tree: Tree): List[Tree] = unsplice(tree) match {
154-
case Apply(fn, args) => allArguments(fn) ::: args
155-
case TypeApply(fn, args) => allArguments(fn) ::: args
156-
case Block(_, expr) => allArguments(expr)
153+
case Apply(fn, args) => allArguments(fn) ::: args.map(stripNamedArg)
154+
case TypeApply(fn, args) => allArguments(fn) ::: args.map(stripNamedArg)
155+
case Block(Nil, expr) => allArguments(expr)
157156
case _ => Nil
158157
}
159158

compiler/src/dotty/tools/dotc/cc/CaptureOps.scala

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -171,13 +171,14 @@ extension (tree: Tree)
171171
refs
172172

173173
/** The arguments of a @retains, @retainsCap or @retainsByName annotation */
174-
def retainedElems(using Context): List[Tree] = tree match
175-
case Apply(_, Typed(SeqLiteral(elems, _), _) :: Nil) =>
176-
elems
177-
case _ =>
178-
if tree.symbol.maybeOwner == defn.RetainsCapAnnot
179-
then ref(defn.captureRoot.termRef) :: Nil
180-
else Nil
174+
def retainedElems(using Context): List[Tree] =
175+
tpd.allTermArguments(tree) match
176+
case List(Typed(SeqLiteral(elems, _), _)) =>
177+
elems
178+
case _ =>
179+
if tree.symbol.maybeOwner == defn.RetainsCapAnnot
180+
then ref(defn.captureRoot.termRef) :: Nil
181+
else Nil
181182

182183
extension (tp: Type)
183184

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1121,7 +1121,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
11211121
def recur(t: untpd.Tree): Text = t match
11221122
case Apply(fn, Nil) => recur(fn)
11231123
case Apply(fn, args) =>
1124-
val explicitArgs = args.filterNot(_.symbol.name.is(DefaultGetterName))
1124+
val explicitArgs = args.filterNot(untpd.stripNamedArg(_).symbol.name.is(DefaultGetterName))
11251125
recur(fn) ~ "(" ~ toTextGlobal(explicitArgs, ", ") ~ ")"
11261126
case TypeApply(fn, args) => recur(fn) ~ "[" ~ toTextGlobal(args, ", ") ~ "]"
11271127
case Select(qual, nme.CONSTRUCTOR) => recur(qual)

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ trait Applications extends Compatibility {
513513
case tp => args.size
514514
}
515515

516-
!isJavaAnnotConstr(methRef.symbol) &&
516+
!isAnnotConstr(methRef.symbol) &&
517517
args.size < requiredArgNum(funType)
518518
}
519519

@@ -662,6 +662,11 @@ trait Applications extends Compatibility {
662662
def isJavaAnnotConstr(sym: Symbol): Boolean =
663663
sym.is(JavaDefined) && sym.isConstructor && sym.owner.is(JavaAnnotation)
664664

665+
666+
/** Is `sym` a constructor of an annotation? */
667+
def isAnnotConstr(sym: Symbol): Boolean =
668+
sym.isConstructor && sym.owner.isAnnotation
669+
665670
/** Match re-ordered arguments against formal parameters
666671
* @param n The position of the first parameter in formals in `methType`.
667672
*/
@@ -951,7 +956,7 @@ trait Applications extends Compatibility {
951956
val app1 =
952957
if !success then app0.withType(UnspecifiedErrorType)
953958
else {
954-
if isJavaAnnotConstr(methRef.symbol) then
959+
if isAnnotConstr(methRef.symbol) then
955960
// #19951 Make sure all arguments are NamedArgs for Java annotations
956961
if typedArgs.exists(!_.isInstanceOf[NamedArg]) then
957962
typedArgs = typedArgs.lazyZip(methType.asInstanceOf[MethodType].paramNames).map {

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

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,26 +1415,21 @@ trait Checking {
14151415
/** Check arguments of annotations */
14161416
private def checkAnnotTree(tree: Tree)(using Context): Tree =
14171417
val cls = Annotations.annotClass(tree)
1418-
tree match
1419-
case Apply(tycon, arg :: Nil) if cls == defn.TargetNameAnnot =>
1420-
arg match
1421-
case Literal(Constant("")) =>
1422-
report.error(em"target name cannot be empty", arg.srcPos)
1423-
case Literal(_) => // ok
1424-
case _ =>
1425-
report.error(em"@${cls.name} needs a string literal as argument", arg.srcPos)
1426-
tree
1427-
case _ =>
1428-
tree.find(!isValidAnnotSubtree(_)) match
1429-
case None => tree
1430-
case Some(invalidSubTree) =>
1431-
errorTree(
1432-
EmptyTree,
1433-
em"""Implementation restriction: expression cannot be used inside an annotation argument.
1434-
|Tree: ${invalidSubTree}
1435-
|Type: ${invalidSubTree.tpe}""",
1436-
invalidSubTree.srcPos
1437-
)
1418+
if cls == defn.TargetNameAnnot then
1419+
allArguments(tree) match
1420+
case List(Literal(Constant(name: String))) if !name.isEmpty => tree
1421+
case _ => errorTree(tree, em"@${cls.name} needs a non-empty string literal as argument")
1422+
else
1423+
tree.find(!isValidAnnotSubtree(_)) match
1424+
case None => tree
1425+
case Some(invalidSubTree) =>
1426+
errorTree(
1427+
EmptyTree,
1428+
em"""Implementation restriction: expression cannot be used inside an annotation argument.
1429+
|Tree: ${invalidSubTree}
1430+
|Type: ${invalidSubTree.tpe}""",
1431+
invalidSubTree.srcPos
1432+
)
14381433

14391434
/** Returns `true` if this tree can appear inside an annotation argument. */
14401435
private def isValidAnnotSubtree(subTree: Tree) =

tests/neg/annot-printing.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
5 |def x: Int @nowarn @main @Foo @Bar("hello") = "abc" // error
33
| ^^^^^
44
| Found: ("abc" : String)
5-
| Required: Int @nowarn() @main @Foo @Bar("hello")
5+
| Required: Int @nowarn() @main @Foo @Bar(s = "hello")
66
|
77
| longer explanation available when compiling with `-explain`

0 commit comments

Comments
 (0)