Skip to content
This repository was archived by the owner on Sep 1, 2020. It is now read-only.

Commit 0c0cd8a

Browse files
committed
Address the review:
- Remove mutable state by introducing `DeclaredSingletonType` - Update the spec
1 parent 0c521ca commit 0c0cd8a

File tree

6 files changed

+39
-29
lines changed

6 files changed

+39
-29
lines changed

spec/03-types.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,13 @@ forms.
103103

104104
```ebnf
105105
SimpleType ::= Path ‘.’ type
106+
| Literal [‘.’ type]
106107
```
107108

108-
A singleton type is of the form $p.$`type`, where $p$ is a
109-
path pointing to a value expected to [conform](06-expressions.html#expression-typing)
110-
to `scala.AnyRef`. The type denotes the set of values
111-
consisting of `null` and the value denoted by $p$.
109+
A singleton type is of the form $p.$`type`, where $p$ is a path,
110+
or $42$, with `.type` being optional for literals.
111+
The type denotes the set of values consisting of `null` and the
112+
value denoted by $p$.
112113

113114
A _stable type_ is either a singleton type or a type which is
114115
declared to be a subtype of trait `scala.Singleton`.

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5100,8 +5100,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
51005100
typed(tree.ref, MonoQualifierModes | mode.onlyTypePat, AnyClass.tpe)
51015101
}
51025102
tree setType {
5103-
if (tree.isLiteral) refTyped.tpe.resultType.asDeclaredSingleton
5104-
else refTyped.tpe.resultType
5103+
refTyped.tpe.resultType.asDeclaredSingleton.getOrElse(refTyped.tpe.resultType)
51055104
}
51065105
if (!refTyped.isErrorTyped)
51075106
tree setType refTyped.tpe.resultType

src/reflect/scala/reflect/internal/Types.scala

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -258,11 +258,8 @@ trait Types
258258

259259
/** The base class for all types */
260260
abstract class Type extends TypeApiImpl with Annotatable[Type] {
261-
var isDeclaredSingleton: Boolean = false
262-
def asDeclaredSingleton: this.type = {
263-
isDeclaredSingleton = true
264-
this
265-
}
261+
val isDeclaredSingleton: Boolean = false
262+
def asDeclaredSingleton: Option[DeclaredSingletonType] = None
266263

267264
/** Types for which asSeenFrom always is the identity, no matter what
268265
* prefix or owner.
@@ -1817,15 +1814,24 @@ trait Types
18171814
class PackageClassInfoType(decls: Scope, clazz: Symbol)
18181815
extends ClassInfoType(List(), decls, clazz)
18191816

1817+
final case class DeclaredSingletonType(value: Constant) extends SingletonType with SingletonTypeApi {
1818+
override val isDeclaredSingleton = true
1819+
override def asDeclaredSingleton = Some(this)
1820+
override def underlying: Type = value.tpe
1821+
override def isTrivial: Boolean = true
1822+
override def deconst = underlying
1823+
override def safeToString: String = value.escapedStringValue + ".type"
1824+
override def kind = "DeclaredSingletonType"
1825+
}
1826+
18201827
/** A class representing a constant type.
18211828
*/
18221829
abstract case class ConstantType(value: Constant) extends SingletonType with ConstantTypeApi {
1830+
override def asDeclaredSingleton = Some(DeclaredSingletonType(value))
18231831
override def underlying: Type = value.tpe
18241832
assert(underlying.typeSymbol != UnitClass)
18251833
override def isTrivial: Boolean = true
1826-
override def deconst: Type =
1827-
if (isDeclaredSingleton) this
1828-
else underlying
1834+
override def deconst: Type = underlying
18291835
override def safeToString: String = value.escapedStringValue + ".type"
18301836
override def kind = "ConstantType"
18311837
}

src/reflect/scala/reflect/runtime/JavaUniverseForce.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
143143
this.baseClassesCycleMonitor
144144
this.RefinedType
145145
this.ClassInfoType
146+
this.DeclaredSingletonType
146147
this.ConstantType
147148
this.TypeRef
148149
this.MethodType

test/files/run/42.type.check

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
2
21
(2,0,1)
32
got 1
43
got PANDA!

test/files/run/42.type.scala

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ object Test {
1616

1717
type Null = null.type
1818

19-
var x: 3.type = 3
19+
//var x: 3.type = 3
2020
/*
2121
scala> x = 42
2222
<console>:8: error: type mismatch;
@@ -46,7 +46,7 @@ object Test {
4646

4747
implicit object One extends Succ[1.type] {
4848
type Out = 2.type
49-
def apply(x: 1.type) = 2
49+
def apply(x: 1.type): 2 = 2
5050
}
5151

5252
def f[T](x: T)(implicit succ: Succ[T]) = succ(x)
@@ -57,28 +57,32 @@ object Test {
5757
}
5858

5959
def main(args: Array[String]): Unit = {
60-
println(f(1))
60+
//println(f(1))
6161
// println(f(5))
6262
println((g(1), g(5), g(7)))
6363
noisyIdentity(1)
6464
noisyIdentity("PANDA!")
6565
}
6666

67-
// Inlining functions with singleton result type
67+
// vars don't play well with singleton types:
68+
/*
69+
scala> var test: 3.type = 3
70+
<console>:7: error: assignment to non variable
71+
var test: 3.type = 3
72+
^
73+
*/
74+
75+
// No inlining of functions with singleton result type anymore, but then this:
6876
/*
69-
scala> def ok(): 7.type = {
77+
scala> def test(): 7.type = {
7078
| println("PANDA!")
7179
| 7
7280
| }
73-
ok: ()7.type
74-
75-
scala> ok()
76-
res0: 7.type = 7
77-
78-
// Expected:
79-
scala> ok()
80-
PANDA!
81-
res0: 7.type = 7
81+
<console>:7: error: type mismatch;
82+
found : Int
83+
required: 7.type
84+
def test(): 7.type = {
85+
^
8286
*/
8387

8488
// Parser problem:

0 commit comments

Comments
 (0)