Skip to content

Commit

Permalink
Better error for Java annotation nested in a Scala ConstantAnnotation
Browse files Browse the repository at this point in the history
  • Loading branch information
lrytz committed Dec 11, 2020
1 parent ebb5ab1 commit 56d2c42
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 36 deletions.
4 changes: 2 additions & 2 deletions src/compiler/scala/tools/nsc/typechecker/Typers.scala
Expand Up @@ -3858,7 +3858,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
* Convert an annotation constructor call into an AnnotationInfo.
*/
@nowarn("cat=lint-nonlocal-return")
def typedAnnotation(ann: Tree, annotee: Option[Tree], mode: Mode = EXPRmode): AnnotationInfo = context.withinAnnotation {
def typedAnnotation(ann: Tree, annotee: Option[Tree], mode: Mode = EXPRmode): AnnotationInfo = {
var hasError: Boolean = false
var unmappable: Boolean = false
val pending = ListBuffer[AbsTypeError]()
Expand Down Expand Up @@ -4009,7 +4009,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
// begin typedAnnotation
val treeInfo.Applied(fun0, _, argss) = ann
if (fun0.isErroneous) return finish(ErroneousAnnotation)
val typedFun = typed(fun0, mode.forFunMode)
val typedFun = context.withinAnnotation(typed(fun0, mode.forFunMode))
if (typedFun.isErroneous) return finish(ErroneousAnnotation)

val Select(New(annTpt), _) = typedFun: @unchecked
Expand Down
52 changes: 37 additions & 15 deletions test/files/neg/annots-constant-neg.check
Expand Up @@ -43,54 +43,76 @@ Test.scala:38: error: annotation argument cannot be null
Test.scala:41: error: annotation argument needs to be a constant; found: java.lang.Integer.TYPE
@JAnn(value = 0, b = java.lang.Integer.TYPE) def t16 = 0 // err
^
Test.scala:45: error: annotation argument needs to be a constant; found: Test.this.nonConst
Test.scala:46: error: nested classfile annotations must be defined in java; found: inline
@JAnn(value = 0, c = Array(new inline)) def t18 = 0 // err
^
Test.scala:50: error: annotation argument needs to be a constant; found: Test.this.nonConst
@Ann(nonConst) def u3 = 0 // err
^
Test.scala:47: error: not enough arguments for constructor Ann: (value: Int, a: String, b: Class[_], c: Array[Object]): Ann.
Test.scala:52: error: not enough arguments for constructor Ann: (value: Int, a: String, b: Class[_], c: Array[Object]): Ann.
Unspecified value parameter value.
@Ann() def u4 = 0 // err
^
Test.scala:54: error: annotation argument cannot be null
Test.scala:59: error: annotation argument cannot be null
@Ann(value = 0, a = null) def u10 = 0 // err
^
Test.scala:55: error: annotation argument needs to be a constant; found: Test.this.getClass()
Test.scala:60: error: annotation argument needs to be a constant; found: Test.this.getClass()
@Ann(value = 0, b = getClass) def u11 = 0 // err
^
Test.scala:56: error: Array constants have to be specified using the `Array(...)` factory method
Test.scala:61: error: Array constants have to be specified using the `Array(...)` factory method
@Ann(value = 0, c = new Array(1)) def u12 = 0 // err
^
Test.scala:59: error: annotation argument needs to be a constant; found: java.lang.Integer.TYPE
Test.scala:64: error: annotation argument needs to be a constant; found: java.lang.Integer.TYPE
@Ann(value = 0, b = java.lang.Integer.TYPE) def u16 = 0 // err
^
Test.scala:64: error: multiple constructors for Ann1 with alternatives:
Test.scala:67: error: Java annotation SuppressWarnings is abstract; cannot be instantiated
Error occurred in an application involving default arguments.
@Ann(value = 0, c = Array(new SuppressWarnings(value = Array("")))) def t17 = 0 // err
^
Test.scala:67: error: not found: value value
Error occurred in an application involving default arguments.
@Ann(value = 0, c = Array(new SuppressWarnings(value = Array("")))) def t17 = 0 // err
^
Test.scala:69: error: nested classfile annotations must be defined in java; found: inline
@Ann(value = 0, c = Array(new inline)) def t18 = 0 // err
^
Test.scala:74: error: multiple constructors for Ann1 with alternatives:
(s: String)Ann1 <and>
(value: Int)Ann1
cannot be invoked with (x: String)
@Ann1(x = "") def v4 = 0 // err
^
Test.scala:66: error: Ann1 does not take parameters
Test.scala:76: error: Ann1 does not take parameters
@Ann1(0)(0) def v6 = 0 // err
^
Test.scala:67: error: not enough arguments for constructor Ann2: (x: Int)(y: Int): Ann2.
Test.scala:77: error: not enough arguments for constructor Ann2: (x: Int)(y: Int): Ann2.
Unspecified value parameter x.
@Ann2 def v7 = 0 // err
^
Test.scala:68: error: missing argument list for constructor Ann2 in class Ann2
Test.scala:78: error: missing argument list for constructor Ann2 in class Ann2
@Ann2(x = 0) def v8 = 0 // err
^
Test.scala:71: error: no arguments allowed for nullary constructor Ann3: (): Ann3
Test.scala:81: error: no arguments allowed for nullary constructor Ann3: (): Ann3
@Ann3(0) def v11 = 0 // err
^
Test.scala:72: error: not enough arguments for constructor Ann4: (x: Int, value: Int): Ann4.
Test.scala:82: error: not enough arguments for constructor Ann4: (x: Int, value: Int): Ann4.
Unspecified value parameter value.
@Ann4(0) def v12 = 0
^
Test.scala:78: error: no arguments allowed for nullary constructor Ann5: (): Ann5
Test.scala:88: error: no arguments allowed for nullary constructor Ann5: (): Ann5
@Ann5(0) def v18 = 0 // err
^
Test.scala:69: warning: Implementation limitation: multiple argument lists on annotations are
Test.scala:69: error: method t18 is defined twice;
the conflicting method t18 was defined at line 46:47
@Ann(value = 0, c = Array(new inline)) def t18 = 0 // err
^
Test.scala:67: error: method t17 is defined twice;
the conflicting method t17 was defined at line 44:76
@Ann(value = 0, c = Array(new SuppressWarnings(value = Array("")))) def t17 = 0 // err
^
Test.scala:79: warning: Implementation limitation: multiple argument lists on annotations are
currently not supported; ignoring arguments List(0)
@Ann2(x = 0)(y = 0) def v9 = 0 // warn
^
1 warning
28 errors
34 errors
10 changes: 10 additions & 0 deletions test/files/neg/annots-constant-neg/Test.scala
Expand Up @@ -42,6 +42,11 @@ object Test {
@JAnn(value = 0, b = classOf[Int]) def t15 = 0
@JAnn(value = 0, b = java.lang.Integer.TYPE) def t16 = 0 // err

// nested annotation is ok
@JAnn(value = 0, c = Array(new SuppressWarnings(value = Array("")))) def t17 = 0
// but the nested annotation needs to be itself a Java annotation
@JAnn(value = 0, c = Array(new inline)) def t18 = 0 // err

@Ann(1) def u1 = 0
@Ann(const) def u2 = 0
@Ann(nonConst) def u3 = 0 // err
Expand All @@ -60,6 +65,11 @@ object Test {
@Ann(value = 0, b = classOf[Int]) def u15 = 0
@Ann(value = 0, b = java.lang.Integer.TYPE) def u16 = 0 // err

// nested annotations are only allowed for Java annotations, not for Scala ConstantAnnotations
@Ann(value = 0, c = Array(new SuppressWarnings(value = Array("")))) def u17 = 0 // err
// the outer and the nested annotation need to be Java annotations
@Ann(value = 0, c = Array(new inline)) def u18 = 0 // err

@Ann1() def v1 = 0
@Ann1(0) def v2 = 0
@Ann1(value = 0) def v3 = 0
Expand Down
7 changes: 0 additions & 7 deletions test/files/neg/nested-annotation.check

This file was deleted.

12 changes: 0 additions & 12 deletions test/files/neg/nested-annotation.scala

This file was deleted.

0 comments on commit 56d2c42

Please sign in to comment.