Infer return types of literals rather than requiring explicit ascription
illicitonion opened this issue · comments
The parser should hopefully not require type ascription in the following cases where it currently does. Both because it looks messy, and because @ShaneDelmore tells me that requiring ascriptions may subvert some optimisations.
object Lib {
val Name = "Friend"
def Message = "Hello"
val HowMany = 2
def Several = 3
val Interpolated = s"${Message} ${Name}"
def Interpolated2 = s"${Message} ${Name}"
val Correct = true
def Incorrect = false
}
Currently these all produce errors:
src/examples/pure_scala/Lib.scala:4: error: No type found at src/examples/pure_scala/Lib.scala@3:2..3:21 for definition: val def <examples/pure_scala/Lib.Name.> = "Friend"
val Name = "Friend"
^
src/examples/pure_scala/Lib.scala:6: error: No type found at src/examples/pure_scala/Lib.scala@5:2..5:23 for definition: def <examples/pure_scala/Lib.Message().> = "Hello"
def Message = "Hello"
^
src/examples/pure_scala/Lib.scala:8: error: No type found at src/examples/pure_scala/Lib.scala@7:2..7:17 for definition: val def <examples/pure_scala/Lib.HowMany.> = 2
val HowMany = 2
^
src/examples/pure_scala/Lib.scala:10: error: No type found at src/examples/pure_scala/Lib.scala@9:2..9:17 for definition: def <examples/pure_scala/Lib.Several().> = 3
def Several = 3
^
src/examples/pure_scala/Lib.scala:12: error: No type found at src/examples/pure_scala/Lib.scala@11:2..11:42 for definition: val def <examples/pure_scala/Lib.Interpolated.> = s"$Message ${Name}"
val Interpolated = s"${Message} ${Name}"
^
src/examples/pure_scala/Lib.scala:14: error: No type found at src/examples/pure_scala/Lib.scala@13:2..13:43 for definition: def <examples/pure_scala/Lib.Interpolated2().> = s"$Message ${Name}"
def Interpolated2 = s"${Message} ${Name}"
^
src/examples/pure_scala/Lib.scala:16: error: No type found at src/examples/pure_scala/Lib.scala@15:2..15:20 for definition: val def <examples/pure_scala/Lib.Correct.> = true
val Correct = true
^
src/examples/pure_scala/Lib.scala:18: error: No type found at src/examples/pure_scala/Lib.scala@17:2..17:23 for definition: def <examples/pure_scala/Lib.Incorrect().> = false
def Incorrect = false
^
8 errors found
The optimisation thing is specifically because final val x = 1
is treated as a compiler constant, where final val x: Int = 1
is not. See https://scala-lang.org/files/archive/spec/2.12/04-basic-declarations-and-definitions.html#value-declarations-and-definitions
So Rsc can already infer for final val
literals -- but not for val
s, even in object
. Since object
s aren't extended, we can have RscCompat
add final
to these "constants" -- maybe.
Incredibly, adding final
would possibly be bad since scalac
does not treat these val
s in object
s as final
: https://stackoverflow.com/questions/12309114/why-is-a-val-inside-an-object-not-automatically-final
As far as I know, the types of all literals are (or are effectively) final, right? i.e. nothing extends String
. Given that, even if the field itself isn't final, the type of the field is, so we should be able to say "in this object
or class
this field is a String
, so no subclass even if it existed could change the type"?
Yes, I believe we can do what you're describing, at least for objects which don't extend anything. Though in this case it wouldn't be helping with the "subvert optimizations" since the compiler isn't making optimizations.