Skip to content

Commit 739f8ea

Browse files
committed
Make it a syntactic criterion whether a literal is a legal type
Introduce a new non-terminal "SimpleLiteral". Only SimpleLiterals can be types.
1 parent e850a99 commit 739f8ea

File tree

6 files changed

+11
-9
lines changed

6 files changed

+11
-9
lines changed

docs/SyntaxSummary.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,12 @@ grammar.
7575

7676
{\small
7777
\begin{lstlisting}
78-
Literal ::= [`-'] integerLiteral
78+
SimpleLiteral ::= [`-'] integerLiteral
7979
| [`-'] floatingPointLiteral
8080
| booleanLiteral
8181
| characterLiteral
8282
| stringLiteral
83+
Literal ::= SimpleLiteral
8384
| processedStringLiteral
8485
| symbolLiteral
8586
| `null'
@@ -108,7 +109,7 @@ grammar.
108109
| Path `.' `type' SingletonTypeTree(p)
109110
| `(' ArgTypes ')' Tuple(ts)
110111
| Refinement RefinedTypeTree(EmptyTree, refinement)
111-
| Literal SingletonTypeTree(l)
112+
| SimpleLiteral SingletonTypeTree(l)
112113
ArgType ::= Type
113114
| `_' TypeBounds
114115
ArgTypes ::= ArgType {`,' ArgType}

src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ object Parsers {
117117

118118
def isIdent = in.token == IDENTIFIER || in.token == BACKQUOTED_IDENT
119119
def isIdent(name: Name) = in.token == IDENTIFIER && in.name == name
120+
def isSimpleLiteral = simpleLiteralTokens contains in.token
120121
def isLiteral = literalTokens contains in.token
121122
def isNumericLit = numericLitTokens contains in.token
122123
def isModifier = modifierTokens contains in.token
@@ -716,7 +717,7 @@ object Parsers {
716717
atPos(in.offset) { makeTupleOrParens(inParens(argTypes())) }
717718
else if (in.token == LBRACE)
718719
atPos(in.offset) { RefinedTypeTree(EmptyTree, refinement()) }
719-
else if (isLiteral) { SingletonTypeTree(literal()) }
720+
else if (isSimpleLiteral) { SingletonTypeTree(literal()) }
720721
else path(thisOK = false, handleSingletonType) match {
721722
case r @ SingletonTypeTree(_) => r
722723
case r => convertToTypeId(r)

src/dotty/tools/dotc/parsing/Tokens.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,8 @@ object Tokens extends TokensCommon {
195195

196196
final val allTokens = tokenRange(minToken, maxToken)
197197

198-
final val literalTokens = tokenRange(CHARLIT, SYMBOLLIT) | BitSet(TRUE, FALSE, NULL)
198+
final val simpleLiteralTokens = tokenRange(CHARLIT, STRINGLIT) | BitSet(TRUE, FALSE)
199+
final val literalTokens = simpleLiteralTokens | BitSet(INTERPOLATIONID, SYMBOLLIT, NULL)
199200

200201
final val atomicExprTokens = literalTokens | identifierTokens | BitSet(
201202
USCORE, NULL, THIS, SUPER, TRUE, FALSE, RETURN, XMLSTART)

src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -782,10 +782,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
782782

783783
def typedSingletonTypeTree(tree: untpd.SingletonTypeTree)(implicit ctx: Context): SingletonTypeTree = track("typedSingletonTypeTree") {
784784
val ref1 = typedExpr(tree.ref)
785-
val illegal = Set[Symbol](defn.NullClass, defn.SymbolClass)
786-
val refSym = ref1.tpe.widen.typeSymbol
787-
if (illegal contains refSym) ctx.error(i"$refSym is not a legal singleton constant type", tree.pos)
788-
else checkStable(ref1.tpe, tree.pos)
785+
checkStable(ref1.tpe, tree.pos)
789786
assignType(cpy.SingletonTypeTree(tree)(ref1), ref1)
790787
}
791788

test/dotc/tests.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ class tests extends CompilerTest {
146146
@Test def neg_instantiateAbstract = compileFile(negDir, "instantiateAbstract", xerrors = 8)
147147
@Test def neg_selfInheritance = compileFile(negDir, "selfInheritance", xerrors = 6)
148148
@Test def neg_selfreq = compileFile(negDir, "selfreq", xerrors = 4)
149-
@Test def neg_singletons = compileFile(negDir, "singletons", xerrors = 4)
149+
@Test def neg_singletons = compileFile(negDir, "singletons", xerrors = 5)
150150
@Test def neg_shadowedImplicits = compileFile(negDir, "arrayclone-new", xerrors = 2)
151151
@Test def neg_traitParamsTyper = compileFile(negDir, "traitParamsTyper", xerrors = 5)
152152
@Test def neg_traitParamsMixin = compileFile(negDir, "traitParamsMixin", xerrors = 2)

tests/neg/singletons.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ object Test {
66
val n: null = null // error: Null is not a legal singleton type
77

88
val sym: 'sym = 'sym // error: Symbol is a legal singleton type
9+
10+
val foo: s"abc" = "abc" // error: not a legal singleton type
911
}

0 commit comments

Comments
 (0)