Skip to content

Commit

Permalink
Reject splices and quotes in annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
mbovel committed Nov 25, 2024
1 parent 924ea08 commit fcbb372
Show file tree
Hide file tree
Showing 14 changed files with 135 additions and 110 deletions.
2 changes: 0 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/Checking.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1454,8 +1454,6 @@ trait Checking {
| Block
| SeqLiteral
| Inlined
| Quote
| Splice
| Hole
| Annotated
]
Expand Down
75 changes: 37 additions & 38 deletions tests/bench/inductive-implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ package shapeless {
import shapeless.*

object Test extends App {
import Selector.given
val sel = Selector[L, Boolean]

type L =
Expand Down Expand Up @@ -175,44 +174,44 @@ object Test extends App {
Int ::
Int ::
//
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
//
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
//
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
//
Int ::
Int ::
Int ::
Int ::
Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
////
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
////
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
// Int ::
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/i7052.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import scala.quoted.*
class Test {
def foo(str: String)(using Quotes) = '{
@deprecated(str, "") // error
@deprecated(str, "") // error: expression cannot be used inside an annotation argument
def bar = ???
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import scala.quoted.*
class Test {
def foo(str: Expr[String])(using Quotes) = '{
@deprecated($str, "")
@deprecated($str, "") // error: expression cannot be used inside an annotation argument
def bar = ???
}
}
3 changes: 0 additions & 3 deletions tests/neg-macros/i7121.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ class annot1[T](x: Expr[T]) extends scala.annotation.Annotation
class annot2[T: Type](x: T) extends scala.annotation.Annotation

class Test()(implicit qtx: Quotes) {
@annot1('{4}) // error
def foo(str: String) = ()

@annot2(4)(using Type.of[Int]) // error
def foo2(str: String) = ()

Expand Down
10 changes: 10 additions & 0 deletions tests/neg-macros/i7121b.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import scala.quoted.*

class annot1[T](x: Expr[T]) extends scala.annotation.Annotation
class annot2[T: Type](x: T) extends scala.annotation.Annotation

class Test()(implicit qtx: Quotes) {
@annot1('{4}) // error: expression cannot be used inside an annotation argument
def foo(str: String) = ()

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ inline def quote[T]: Quoted[T] = ${ quoteImpl[T] }

def quoteImpl[T: Type](using Quotes): Expr[Quoted[T]] = {
val value: Expr[Int] = '{ 42 }
'{ new Quoted[T @Annot($value)] }
'{ new Quoted[T @Annot($value)] } // error: expression cannot be used inside an annotation argument
}
108 changes: 60 additions & 48 deletions tests/neg/annot-invalid.check
Original file line number Diff line number Diff line change
@@ -1,72 +1,84 @@
-- Error: tests/neg/annot-invalid.scala:4:21 ---------------------------------------------------------------------------
4 | val x1: Int @annot(new Object {}) = 0 // error
-- Error: tests/neg/annot-invalid.scala:9:21 ---------------------------------------------------------------------------
9 | val x1: Int @annot(new Object {}) = 0 // error
| ^^^^^^^^^^^^^
| Implementation restriction: expression cannot be used inside an annotation argument.
| Tree: final class $anon() extends Object() {}
| Type: Object {...}
-- Error: tests/neg/annot-invalid.scala:5:28 ---------------------------------------------------------------------------
5 | val x2: Int @annot({class C}) = 0 // error
| ^^^^^^^
| Implementation restriction: expression cannot be used inside an annotation argument.
| Tree: class C() extends Object() {}
| Type: C
-- Error: tests/neg/annot-invalid.scala:6:27 ---------------------------------------------------------------------------
6 | val x16: Int @annot({val y: Int = 2}) = 0 // error
| ^^^^^^^^^^^^^^
| Implementation restriction: expression cannot be used inside an annotation argument.
| Tree: val y: Int = 2
| Type: (y : Int)
-- Error: tests/neg/annot-invalid.scala:7:27 ---------------------------------------------------------------------------
7 | val x17: Int @annot({def f = 2}) = 0 // error
| ^^^^^^^^^
| Implementation restriction: expression cannot be used inside an annotation argument.
| Tree: def f: Int = 2
| Type: (f : => Int)
-- Error: tests/neg/annot-invalid.scala:8:31 ---------------------------------------------------------------------------
8 | val x18: Int @annot((x: Int) => x) = 0 // error
| ^^^^^^^^^^^^^
| Implementation restriction: expression cannot be used inside an annotation argument.
| Tree: closure($anonfun)
| Type: Int => Int
-- [E006] Not Found Error: tests/neg/annot-invalid.scala:9:22 ----------------------------------------------------------
9 | val x19: Int @annot(O.g) = 0 // error
| ^
| Not found: O
|
| longer explanation available when compiling with `-explain`
-- Error: tests/neg/annot-invalid.scala:11:9 ---------------------------------------------------------------------------
11 | @annot(new Object {}) val y1: Int = 0 // error
-- Error: tests/neg/annot-invalid.scala:10:28 --------------------------------------------------------------------------
10 | val x2: Int @annot({class C}) = 0 // error
| ^^^^^^^
| Implementation restriction: expression cannot be used inside an annotation argument.
| Tree: class C() extends Object() {}
| Type: C
-- Error: tests/neg/annot-invalid.scala:11:26 --------------------------------------------------------------------------
11 | val x3: Int @annot({val y: Int = 2}) = 0 // error
| ^^^^^^^^^^^^^^
| Implementation restriction: expression cannot be used inside an annotation argument.
| Tree: val y: Int = 2
| Type: (y : Int)
-- Error: tests/neg/annot-invalid.scala:12:26 --------------------------------------------------------------------------
12 | val x4: Int @annot({def f = 2}) = 0 // error
| ^^^^^^^^^
| Implementation restriction: expression cannot be used inside an annotation argument.
| Tree: def f: Int = 2
| Type: (f : => Int)
-- Error: tests/neg/annot-invalid.scala:13:30 --------------------------------------------------------------------------
13 | val x5: Int @annot((x: Int) => x) = 0 // error
| ^^^^^^^^^^^^^
| Implementation restriction: expression cannot be used inside an annotation argument.
| Tree: closure($anonfun)
| Type: Int => Int
-- Error: tests/neg/annot-invalid.scala:14:21 --------------------------------------------------------------------------
14 | val x6: Int @annot(O.g) = 0 // error
| ^^^
| Implementation restriction: expression cannot be used inside an annotation argument.
| Tree: closure($anonfun)
| Type: Int => Int
-- Error: tests/neg/annot-invalid.scala:16:25 --------------------------------------------------------------------------
16 | val x7: Int @annot('{4}) = 0 // error
| ^
| Implementation restriction: expression cannot be used inside an annotation argument.
| Tree: '{4}
| Type: (scala.quoted.Quotes) ?=> scala.quoted.Expr[Int]
-- Error: tests/neg/annot-invalid.scala:18:9 ---------------------------------------------------------------------------
18 | @annot(new Object {}) val y1: Int = 0 // error
| ^^^^^^^^^^^^^
| Implementation restriction: expression cannot be used inside an annotation argument.
| Tree: final class $anon() extends Object() {}
| Type: Object {...}
-- Error: tests/neg/annot-invalid.scala:12:16 --------------------------------------------------------------------------
12 | @annot({class C}) val y2: Int = 0 // error
-- Error: tests/neg/annot-invalid.scala:19:16 --------------------------------------------------------------------------
19 | @annot({class C}) val y2: Int = 0 // error
| ^^^^^^^
| Implementation restriction: expression cannot be used inside an annotation argument.
| Tree: class C() extends Object() {}
| Type: C
-- Error: tests/neg/annot-invalid.scala:13:14 --------------------------------------------------------------------------
13 | @annot({val y: Int = 2}) val y16: Int = 0 // error
-- Error: tests/neg/annot-invalid.scala:20:14 --------------------------------------------------------------------------
20 | @annot({val y: Int = 2}) val y3: Int = 0 // error
| ^^^^^^^^^^^^^^
| Implementation restriction: expression cannot be used inside an annotation argument.
| Tree: val y: Int = 2
| Type: (y : Int)
-- Error: tests/neg/annot-invalid.scala:14:14 --------------------------------------------------------------------------
14 | @annot({def f = 2}) val y17: Int = 0 // error
-- Error: tests/neg/annot-invalid.scala:21:14 --------------------------------------------------------------------------
21 | @annot({def f = 2}) val y4: Int = 0 // error
| ^^^^^^^^^
| Implementation restriction: expression cannot be used inside an annotation argument.
| Tree: def f: Int = 2
| Type: (f : => Int)
-- Error: tests/neg/annot-invalid.scala:15:18 --------------------------------------------------------------------------
15 | @annot((x: Int) => x) val y18: Int = 0 // error
-- Error: tests/neg/annot-invalid.scala:22:18 --------------------------------------------------------------------------
22 | @annot((x: Int) => x) val y5: Int = 0 // error
| ^^^^^^^^^^^^^
| Implementation restriction: expression cannot be used inside an annotation argument.
| Tree: closure($anonfun)
| Type: Int => Int
-- [E006] Not Found Error: tests/neg/annot-invalid.scala:16:9 ----------------------------------------------------------
16 | @annot(O.g) val y19: Int = 0 // error
| ^
| Not found: O
|
| longer explanation available when compiling with `-explain`
-- Error: tests/neg/annot-invalid.scala:23:9 ---------------------------------------------------------------------------
23 | @annot(O.g) val y6: Int = 0 // error
| ^^^
| Implementation restriction: expression cannot be used inside an annotation argument.
| Tree: closure($anonfun)
| Type: Int => Int
-- Error: tests/neg/annot-invalid.scala:25:13 --------------------------------------------------------------------------
25 | @annot('{4}) val y7: Int = 0 // error
| ^
| Implementation restriction: expression cannot be used inside an annotation argument.
| Tree: '{4}
| Type: (scala.quoted.Quotes) ?=> scala.quoted.Expr[Int]
25 changes: 17 additions & 8 deletions tests/neg/annot-invalid.scala
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
import scala.quoted.Quotes

class annot[T](arg: T) extends scala.annotation.Annotation

def main =
object O:
def g(x: Int): Int = x

val x1: Int @annot(new Object {}) = 0 // error
val x2: Int @annot({class C}) = 0 // error
val x16: Int @annot({val y: Int = 2}) = 0 // error
val x17: Int @annot({def f = 2}) = 0 // error
val x18: Int @annot((x: Int) => x) = 0 // error
val x19: Int @annot(O.g) = 0 // error
val x3: Int @annot({val y: Int = 2}) = 0 // error
val x4: Int @annot({def f = 2}) = 0 // error
val x5: Int @annot((x: Int) => x) = 0 // error
val x6: Int @annot(O.g) = 0 // error
def withQuotes(using Quotes) =
val x7: Int @annot('{4}) = 0 // error

@annot(new Object {}) val y1: Int = 0 // error
@annot({class C}) val y2: Int = 0 // error
@annot({val y: Int = 2}) val y16: Int = 0 // error
@annot({def f = 2}) val y17: Int = 0 // error
@annot((x: Int) => x) val y18: Int = 0 // error
@annot(O.g) val y19: Int = 0 // error
@annot({val y: Int = 2}) val y3: Int = 0 // error
@annot({def f = 2}) val y4: Int = 0 // error
@annot((x: Int) => x) val y5: Int = 0 // error
@annot(O.g) val y6: Int = 0 // error
def withQuotes2(using Quotes) =
@annot('{4}) val y7: Int = 0 // error

()
8 changes: 4 additions & 4 deletions tests/neg/i15054.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import scala.annotation.Annotation

class AnAnnotation(function: Int => String) extends Annotation

@AnAnnotation(_.toString) // error: not a valid annotation
@AnAnnotation(_.toString) // error: expression cannot be used inside an annotation argument
val a = 1
@AnAnnotation(_.toString.length.toString) // error: not a valid annotation
@AnAnnotation(_.toString.length.toString) // error: expression cannot be used inside an annotation argument
val b = 2

def test =
@AnAnnotation(_.toString) // error: not a valid annotation
@AnAnnotation(_.toString) // error: expression cannot be used inside an annotation argument
val a = 1
@AnAnnotation(_.toString.length.toString) // error: not a valid annotation
@AnAnnotation(_.toString.length.toString) // error: expression cannot be used inside an annotation argument
val b = 2
a + b
2 changes: 1 addition & 1 deletion tests/neg/i7740a.scala
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
class A(a: Any) extends annotation.StaticAnnotation
@A({val x = 0}) trait B // error: not a valid annotation
@A({val x = 0}) trait B // error: expression cannot be used inside an annotation argument
2 changes: 1 addition & 1 deletion tests/neg/i7740b.scala
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
class A(a: Any) extends annotation.StaticAnnotation
@A({def x = 0}) trait B // error: not a valid annotation
@A({def x = 0}) trait B // error: expression cannot be used inside an annotation argument
2 changes: 1 addition & 1 deletion tests/neg/i9314.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
final class fooAnnot[T](member: T) extends scala.annotation.StaticAnnotation // must have type parameter

@fooAnnot(new RecAnnotated {}) // error: not a valid annotation
@fooAnnot(new RecAnnotated {}) // error: expression cannot be used inside an annotation argument
trait RecAnnotated
2 changes: 1 addition & 1 deletion tests/neg/t7426.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
class foo(x: Any) extends annotation.StaticAnnotation

@foo(new AnyRef { }) trait A // error: not a valid annotation
@foo(new AnyRef { }) trait A // error: expression cannot be used inside an annotation argument

0 comments on commit fcbb372

Please sign in to comment.