aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-08-24 13:12:02 +0200
committerMartin Odersky <odersky@gmail.com>2015-08-24 13:12:02 +0200
commit739f8ea2c3b39f81f54bfea4b618770d7aa1a1c6 (patch)
tree926b1416edd0be6ffbbb14260259f6d1fe9fe1a9
parente850a99f16004a702b5fa63736ac215fc388051b (diff)
downloaddotty-739f8ea2c3b39f81f54bfea4b618770d7aa1a1c6.tar.gz
dotty-739f8ea2c3b39f81f54bfea4b618770d7aa1a1c6.tar.bz2
dotty-739f8ea2c3b39f81f54bfea4b618770d7aa1a1c6.zip
Make it a syntactic criterion whether a literal is a legal type
Introduce a new non-terminal "SimpleLiteral". Only SimpleLiterals can be types.
-rw-r--r--docs/SyntaxSummary.txt5
-rw-r--r--src/dotty/tools/dotc/parsing/Parsers.scala3
-rw-r--r--src/dotty/tools/dotc/parsing/Tokens.scala3
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala5
-rw-r--r--test/dotc/tests.scala2
-rw-r--r--tests/neg/singletons.scala2
6 files changed, 11 insertions, 9 deletions
diff --git a/docs/SyntaxSummary.txt b/docs/SyntaxSummary.txt
index 52e880a34..764275f92 100644
--- a/docs/SyntaxSummary.txt
+++ b/docs/SyntaxSummary.txt
@@ -75,11 +75,12 @@ grammar.
{\small
\begin{lstlisting}
- Literal ::= [`-'] integerLiteral
+ SimpleLiteral ::= [`-'] integerLiteral
| [`-'] floatingPointLiteral
| booleanLiteral
| characterLiteral
| stringLiteral
+ Literal ::= SimpleLiteral
| processedStringLiteral
| symbolLiteral
| `null'
@@ -108,7 +109,7 @@ grammar.
| Path `.' `type' SingletonTypeTree(p)
| `(' ArgTypes ')' Tuple(ts)
| Refinement RefinedTypeTree(EmptyTree, refinement)
- | Literal SingletonTypeTree(l)
+ | SimpleLiteral SingletonTypeTree(l)
ArgType ::= Type
| `_' TypeBounds
ArgTypes ::= ArgType {`,' ArgType}
diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala
index 51ea09eac..69d7e5233 100644
--- a/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -117,6 +117,7 @@ object Parsers {
def isIdent = in.token == IDENTIFIER || in.token == BACKQUOTED_IDENT
def isIdent(name: Name) = in.token == IDENTIFIER && in.name == name
+ def isSimpleLiteral = simpleLiteralTokens contains in.token
def isLiteral = literalTokens contains in.token
def isNumericLit = numericLitTokens contains in.token
def isModifier = modifierTokens contains in.token
@@ -716,7 +717,7 @@ object Parsers {
atPos(in.offset) { makeTupleOrParens(inParens(argTypes())) }
else if (in.token == LBRACE)
atPos(in.offset) { RefinedTypeTree(EmptyTree, refinement()) }
- else if (isLiteral) { SingletonTypeTree(literal()) }
+ else if (isSimpleLiteral) { SingletonTypeTree(literal()) }
else path(thisOK = false, handleSingletonType) match {
case r @ SingletonTypeTree(_) => r
case r => convertToTypeId(r)
diff --git a/src/dotty/tools/dotc/parsing/Tokens.scala b/src/dotty/tools/dotc/parsing/Tokens.scala
index 226a3710d..190226635 100644
--- a/src/dotty/tools/dotc/parsing/Tokens.scala
+++ b/src/dotty/tools/dotc/parsing/Tokens.scala
@@ -195,7 +195,8 @@ object Tokens extends TokensCommon {
final val allTokens = tokenRange(minToken, maxToken)
- final val literalTokens = tokenRange(CHARLIT, SYMBOLLIT) | BitSet(TRUE, FALSE, NULL)
+ final val simpleLiteralTokens = tokenRange(CHARLIT, STRINGLIT) | BitSet(TRUE, FALSE)
+ final val literalTokens = simpleLiteralTokens | BitSet(INTERPOLATIONID, SYMBOLLIT, NULL)
final val atomicExprTokens = literalTokens | identifierTokens | BitSet(
USCORE, NULL, THIS, SUPER, TRUE, FALSE, RETURN, XMLSTART)
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 4441adcfb..33ec156a1 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -782,10 +782,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def typedSingletonTypeTree(tree: untpd.SingletonTypeTree)(implicit ctx: Context): SingletonTypeTree = track("typedSingletonTypeTree") {
val ref1 = typedExpr(tree.ref)
- val illegal = Set[Symbol](defn.NullClass, defn.SymbolClass)
- val refSym = ref1.tpe.widen.typeSymbol
- if (illegal contains refSym) ctx.error(i"$refSym is not a legal singleton constant type", tree.pos)
- else checkStable(ref1.tpe, tree.pos)
+ checkStable(ref1.tpe, tree.pos)
assignType(cpy.SingletonTypeTree(tree)(ref1), ref1)
}
diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala
index 8f8b1d04a..b5af92d64 100644
--- a/test/dotc/tests.scala
+++ b/test/dotc/tests.scala
@@ -146,7 +146,7 @@ class tests extends CompilerTest {
@Test def neg_instantiateAbstract = compileFile(negDir, "instantiateAbstract", xerrors = 8)
@Test def neg_selfInheritance = compileFile(negDir, "selfInheritance", xerrors = 6)
@Test def neg_selfreq = compileFile(negDir, "selfreq", xerrors = 4)
- @Test def neg_singletons = compileFile(negDir, "singletons", xerrors = 4)
+ @Test def neg_singletons = compileFile(negDir, "singletons", xerrors = 5)
@Test def neg_shadowedImplicits = compileFile(negDir, "arrayclone-new", xerrors = 2)
@Test def neg_traitParamsTyper = compileFile(negDir, "traitParamsTyper", xerrors = 5)
@Test def neg_traitParamsMixin = compileFile(negDir, "traitParamsMixin", xerrors = 2)
diff --git a/tests/neg/singletons.scala b/tests/neg/singletons.scala
index e4c6db060..5dff13096 100644
--- a/tests/neg/singletons.scala
+++ b/tests/neg/singletons.scala
@@ -6,4 +6,6 @@ object Test {
val n: null = null // error: Null is not a legal singleton type
val sym: 'sym = 'sym // error: Symbol is a legal singleton type
+
+ val foo: s"abc" = "abc" // error: not a legal singleton type
}