File tree Expand file tree Collapse file tree 6 files changed +58
-10
lines changed
compiler/src/dotty/tools/dotc Expand file tree Collapse file tree 6 files changed +58
-10
lines changed Original file line number Diff line number Diff line change @@ -38,6 +38,10 @@ object Annotations {
3838
3939 def sameAnnotation (that : Annotation )(implicit ctx : Context ): Boolean =
4040 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)
4145 }
4246
4347 case class ConcreteAnnotation (t : Tree ) extends Annotation {
Original file line number Diff line number Diff line change @@ -855,6 +855,8 @@ class Definitions {
855855 def TransientParamAnnot (implicit ctx : Context ): ClassSymbol = TransientParamAnnotType .symbol.asClass
856856 lazy val SwitchAnnotType : TypeRef = ctx.requiredClassRef(" scala.annotation.switch" )
857857 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
858860 lazy val ThrowsAnnotType : TypeRef = ctx.requiredClassRef(" scala.throws" )
859861 def ThrowsAnnot (implicit ctx : Context ): ClassSymbol = ThrowsAnnotType .symbol.asClass
860862 lazy val TransientAnnotType : TypeRef = ctx.requiredClassRef(" scala.transient" )
Original file line number Diff line number Diff line change @@ -837,6 +837,17 @@ object SymDenotations {
837837 this .exists && (test(symbol) || allOverriddenSymbols.exists(test))
838838 }
839839
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+
840851 // ------ access to related symbols ---------------------------------
841852
842853 /* Modules and module classes are represented as follows:
Original file line number Diff line number Diff line change @@ -833,16 +833,15 @@ object RefChecks {
833833 case _ =>
834834 }
835835 }
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+ }
846845 }
847846
848847 /** 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