Skip to content

Commit 28069b6

Browse files
authored
Merge pull request #9536 from dotty-staging/fix-annot-cycle
Fix #9492: Avoid forcing nested annotation
2 parents 9b66529 + abe1314 commit 28069b6

File tree

4 files changed

+32
-9
lines changed

4 files changed

+32
-9
lines changed

compiler/src/dotty/tools/dotc/core/Annotations.scala

-6
Original file line numberDiff line numberDiff line change
@@ -163,12 +163,6 @@ object Annotations {
163163
protected var myTree: Tree | (Context ?=> Tree) = (using ctx) => treeFn(using ctx)
164164
}
165165

166-
def deferred(atp: Type, args: List[Tree])(using Context): Annotation =
167-
deferred(atp.classSymbol)(New(atp, args))
168-
169-
def deferredResolve(atp: Type, args: List[ast.untpd.Tree])(using Context): Annotation =
170-
deferred(atp.classSymbol)(ast.untpd.resolveConstructor(atp, args))
171-
172166
/** Extractor for child annotations */
173167
object Child {
174168

compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala

+14-3
Original file line numberDiff line numberDiff line change
@@ -555,14 +555,25 @@ class ClassfileParser(
555555
Some(untpd.JavaSeqLiteral(elems, TypeTree()))
556556
}
557557
case ANNOTATION_TAG =>
558-
parseAnnotation(index, skip) map (_.tree)
558+
parseAnnotation(index, skip).map(_.untpdTree)
559559
}
560560
}
561561

562+
class ClassfileAnnotation(annotType: Type, args: List[untpd.Tree]) extends LazyAnnotation {
563+
protected var mySym: Symbol | (Context ?=> Symbol) =
564+
(using ctx: Context) => annotType.classSymbol
565+
566+
protected var myTree: Tree | (Context ?=> Tree) =
567+
(using ctx: Context) => untpd.resolveConstructor(annotType, args)
568+
569+
def untpdTree(using Context): untpd.Tree =
570+
untpd.New(untpd.TypeTree(annotType), List(args))
571+
}
572+
562573
/** Parse and return a single annotation. If it is malformed,
563574
* return None.
564575
*/
565-
def parseAnnotation(attrNameIndex: Char, skip: Boolean = false)(using Context): Option[Annotation] = try {
576+
def parseAnnotation(attrNameIndex: Char, skip: Boolean = false)(using Context): Option[ClassfileAnnotation] = try {
566577
val attrType = pool.getType(attrNameIndex)
567578
attrType match
568579
case tp: TypeRef =>
@@ -584,7 +595,7 @@ class ClassfileParser(
584595
}
585596
}
586597
if (hasError || skip) None
587-
else Some(Annotation.deferredResolve(attrType, argbuf.toList))
598+
else Some(ClassfileAnnotation(attrType, argbuf.toList))
588599
}
589600
catch {
590601
case f: FatalError => throw f // don't eat fatal errors, they mean a class was not found
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import java.lang.annotation.*;
2+
3+
@interface BaseClassAnn {
4+
Type[] value();
5+
@interface Type {
6+
Class<?> value();
7+
}
8+
}
9+
10+
@BaseClassAnn({
11+
@BaseClassAnn.Type(value=A_1.class)
12+
})
13+
abstract class BaseClass {}
14+
15+
public class A_1 extends BaseClass {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Test {
2+
def oops: A_1 = ???
3+
}

0 commit comments

Comments
 (0)