From ef2ffb8c0fcb8fd9dfac937ea002021427567801 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Mon, 15 May 2023 16:23:27 -0700 Subject: [PATCH] Accommodate quasi-constant annotation value --- compiler/src/dotty/tools/dotc/core/Annotations.scala | 8 +++++++- compiler/src/dotty/tools/dotc/transform/Erasure.scala | 8 ++++---- tests/neg/no-unit.check | 4 ++++ tests/neg/no-unit.scala | 1 + 4 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 tests/neg/no-unit.check create mode 100644 tests/neg/no-unit.scala diff --git a/compiler/src/dotty/tools/dotc/core/Annotations.scala b/compiler/src/dotty/tools/dotc/core/Annotations.scala index 1615679a036e..d075d42e619f 100644 --- a/compiler/src/dotty/tools/dotc/core/Annotations.scala +++ b/compiler/src/dotty/tools/dotc/core/Annotations.scala @@ -2,7 +2,7 @@ package dotty.tools package dotc package core -import Symbols.*, Types.*, Contexts.*, Constants.*, Phases.* +import StdNames.*, Symbols.*, Types.*, Contexts.*, Constants.*, Phases.* import ast.tpd, tpd.* import util.Spans.Span import printing.{Showable, Printer} @@ -43,6 +43,12 @@ object Annotations { def argumentConstantString(i: Int)(using Context): Option[String] = for (case Constant(s: String) <- argumentConstant(i)) yield s + def argumentAdaptedConstantString(i: Int)(using Context): Option[String] = + argument(i) match + case Some(Literal(Constant(s: String))) => Some(s) + case Some(TypeApply(Select(Literal(Constant(s: String)), nme.asInstanceOf_), _)) => Some(s) + case _ => None + /** The tree evaluation is in progress. */ def isEvaluating: Boolean = false diff --git a/compiler/src/dotty/tools/dotc/transform/Erasure.scala b/compiler/src/dotty/tools/dotc/transform/Erasure.scala index 25239aee59cf..a265059fd2bd 100644 --- a/compiler/src/dotty/tools/dotc/transform/Erasure.scala +++ b/compiler/src/dotty/tools/dotc/transform/Erasure.scala @@ -551,7 +551,7 @@ object Erasure { } /** Check that Java statics and packages can only be used in selections. - */ + */ private def checkNotErased(tree: Tree)(using Context): tree.type = if !ctx.mode.is(Mode.Type) then if isErased(tree) then @@ -565,15 +565,15 @@ object Erasure { report.error(msg, tree.srcPos) tree.symbol.getAnnotation(defn.CompileTimeOnlyAnnot) match case Some(annot) => - val message = annot.argumentConstant(0) match - case Some(c) => + val message = annot.argumentConstantString(0).orElse(annot.argumentAdaptedConstantString(0)) match + case Some(msg) => val addendum = tree match case tree: RefTree if tree.symbol == defn.Compiletime_deferred && tree.name != nme.deferred => i".\nNote that `deferred` can only be used under its own name when implementing a given in a trait; `${tree.name}` is not accepted." case _ => "" - (c.stringValue ++ addendum).toMessage + (msg + addendum).toMessage case _ => em"""Reference to ${tree.symbol.showLocated} should not have survived, |it should have been processed and eliminated during expansion of an enclosing macro or term erasure.""" diff --git a/tests/neg/no-unit.check b/tests/neg/no-unit.check new file mode 100644 index 000000000000..faee70accb2a --- /dev/null +++ b/tests/neg/no-unit.check @@ -0,0 +1,4 @@ +-- Error: tests/neg/no-unit.scala:1:8 ---------------------------------------------------------------------------------- +1 |val u = Unit // error + | ^^^^ + | `Unit` companion object is not allowed in source; instead, use `()` for the unit value diff --git a/tests/neg/no-unit.scala b/tests/neg/no-unit.scala new file mode 100644 index 000000000000..2cb5c84e5b7a --- /dev/null +++ b/tests/neg/no-unit.scala @@ -0,0 +1 @@ +val u = Unit // error