File tree 6 files changed +58
-10
lines changed
compiler/src/dotty/tools/dotc
6 files changed +58
-10
lines changed Original file line number Diff line number Diff line change @@ -38,6 +38,10 @@ object Annotations {
38
38
39
39
def sameAnnotation (that : Annotation )(implicit ctx : Context ): Boolean =
40
40
symbol == that.symbol && tree.sameTree(that.tree)
41
+
42
+ def stringArg (index : Int )(implicit ctx : Context ) = argumentConstant(index) map (_.stringValue)
43
+ def intArg (index : Int )(implicit ctx : Context ) = argumentConstant(index) map (_.intValue)
44
+ def booleanArg (index : Int )(implicit ctx : Context ) = argumentConstant(index) map (_.booleanValue)
41
45
}
42
46
43
47
case class ConcreteAnnotation (t : Tree ) extends Annotation {
Original file line number Diff line number Diff line change @@ -855,6 +855,8 @@ class Definitions {
855
855
def TransientParamAnnot (implicit ctx : Context ): ClassSymbol = TransientParamAnnotType .symbol.asClass
856
856
lazy val SwitchAnnotType : TypeRef = ctx.requiredClassRef(" scala.annotation.switch" )
857
857
def SwitchAnnot (implicit ctx : Context ): ClassSymbol = SwitchAnnotType .symbol.asClass
858
+ lazy val CompileTimeOnlyAnnotType : TypeRef = ctx.requiredClassRef(" scala.annotation.compileTimeOnly" )
859
+ def CompileTimeOnlyAnnot (implicit ctx : Context ): ClassSymbol = CompileTimeOnlyAnnotType .symbol.asClass
858
860
lazy val ThrowsAnnotType : TypeRef = ctx.requiredClassRef(" scala.throws" )
859
861
def ThrowsAnnot (implicit ctx : Context ): ClassSymbol = ThrowsAnnotType .symbol.asClass
860
862
lazy val TransientAnnotType : TypeRef = ctx.requiredClassRef(" scala.transient" )
Original file line number Diff line number Diff line change @@ -837,6 +837,17 @@ object SymDenotations {
837
837
this .exists && (test(symbol) || allOverriddenSymbols.exists(test))
838
838
}
839
839
840
+ /** Should reference to the symbol disappear after typer?
841
+ *
842
+ * Used in inlining and macros to enforce invariants.
843
+ */
844
+ def isCompileTimeOnly (implicit ctx : Context ): Boolean =
845
+ hasAnnotation(defn.CompileTimeOnlyAnnot )
846
+
847
+ /** Get the message associated with @compileTimeOnly annotation */
848
+ def compileTimeOnlyMessage (implicit ctx : Context ): Option [String ] =
849
+ getAnnotation(defn.CompileTimeOnlyAnnot ) flatMap (_ stringArg 0 )
850
+
840
851
// ------ access to related symbols ---------------------------------
841
852
842
853
/* Modules and module classes are represented as follows:
Original file line number Diff line number Diff line change @@ -833,16 +833,15 @@ object RefChecks {
833
833
case _ =>
834
834
}
835
835
}
836
- /* (Not enabled yet)
837
- * See an explanation of compileTimeOnly in its scaladoc at scala.annotation.compileTimeOnly.
838
- *
839
- if (sym.isCompileTimeOnly) {
840
- def defaultMsg =
841
- sm"""Reference to ${sym.fullLocationString} should not have survived past type checking,
842
- |it should have been processed and eliminated during expansion of an enclosing macro."""
843
- // The getOrElse part should never happen, it's just here as a backstop.
844
- ctx.error(sym.compileTimeOnlyMessage getOrElse defaultMsg, pos)
845
- }*/
836
+
837
+ if (sym.isCompileTimeOnly && ! sym.owner.isInlineMethod) {
838
+ def defaultMsg : String =
839
+ em """ Reference to ${sym.show} should not have survived past type checking,
840
+ |it should have been processed and eliminated during expansion of an enclosing macro. """
841
+ // The getOrElse part should never happen, it's just here as a backstop.
842
+ val msg = sym.compileTimeOnlyMessage.getOrElse(defaultMsg)
843
+ ctx.error(msg, pos)
844
+ }
846
845
}
847
846
848
847
/** Check that a deprecated val or def does not override a
Original file line number Diff line number Diff line change
1
+ import scala .annotation .compileTimeOnly
2
+
3
+ sealed trait Nat
4
+ case class S (n : Nat ) extends Nat
5
+ case object Z extends Nat
6
+
7
+ inline def pred (n : Nat ) = inline n match {
8
+ case S (m) => m
9
+ case Z =>
10
+ @ compileTimeOnly(" n cannot be Z" ) val res = ???
11
+ res
12
+ }
13
+
14
+ class Test {
15
+ pred(Z ) // error
16
+ }
Original file line number Diff line number Diff line change
1
+ import scala .annotation .compileTimeOnly
2
+
3
+ sealed trait Nat
4
+ case class S (n : Nat ) extends Nat
5
+ case object Z extends Nat
6
+
7
+ inline def pred (n : Nat ) = inline n match {
8
+ case S (m) => m
9
+ case Z =>
10
+ @ compileTimeOnly(" n cannot be Z" ) val res = ???
11
+ res
12
+ }
13
+
14
+ class Test {
15
+ pred(S (Z ))
16
+ }
You can’t perform that action at this time.
0 commit comments