Open
Description
Compiler version
3.1.1, 3.1.2
Example 1:
Transitivity of subtyping is violated:
val fredToFredOrWilma: "Fred" <:< ("Fred" | "Wilma") = summon
val nullToFred: Null <:< "Fred" = summon
val nullToFredOrWilma: Null <:< ("Fred" | "Wilma") = summon // errors
Output
no implicit argument of type T was found for parameter x of method summon in object Predef
where: T is a type variable with constraint <: Null <:< (("Fred" : String) | ("Wilma" : String))
Expectation
Either:
nullToFred
fails<:<
is transitive andNull <:< "Fred" <:< ("Fred" | "Wilma")
Example 2:
scala> val x: "Fred" = null
val x: "Fred" = null
scala> x
val res1: String = Fred // notice this is not `null`!
Expectation
Either:
null
is not assignable to a"Fred"
x
reports a value ofnull
Example 3:
Null is accepted for variable .type
s but not object .type
s (which are both nullable in the JVM):
scala> val foo: Int = 1
val foo: Int = 1
scala> val fooNull: foo.type = null
-- [E007] Type Mismatch Error: -------------------------------------------------
1 |val fooNull: foo.type = null
| ^^^^
| Found: Null
| Required: (foo : Int)
longer explanation available when compiling with `-explain`
1 error found
scala> val bar: String = "bar"
val bar: String = bar
scala> val barNull: bar.type = null
val barNull: bar.type = null
scala> object baz
// defined object baz
scala> val bazNull: baz.type = null
-- [E007] Type Mismatch Error: -------------------------------------------------
1 |val bazNull: baz.type = null
| ^^^^
| Found: Null
| Required: baz.type
longer explanation available when compiling with `-explain`
1 error found
Expectation
Either:
null
should not be accepted as an inhabitant ofbar.type
null
should be accepted as an inhabitant ofbaz.type
Example 4:
Unions of two singletons don't accept null, but not a union of a singleton and a non-nullable:
scala> val f: "Foo" = null
val f: "Foo" = null
scala> val g: ("Foo" | 1) = null
-- [E007] Type Mismatch Error: -------------------------------------------------
1 |val g: ("Foo" | 1) = null
| ^^^^
| Found: Null
| Required: ("Foo" : String) | (1 : Int)
longer explanation available when compiling with `-explain`
1 error found
scala> val h: ("Foo" | Int) = null
val h: "Foo" | Int = null
scala> val i: ("Foo" | "Bar") = null
-- [E007] Type Mismatch Error: -------------------------------------------------
1 |val i: ("Foo" | "Bar") = null
| ^^^^
| Found: Null
| Required: ("Foo" : String) | ("Bar" : String)
longer explanation available when compiling with `-explain`
1 error found
Expectation
Either:
- The declarations for
f
andh
are invalid - The declarations for
g
andi
are valid
If Scala 2 behaviors are wanted to be kept, then the proper path is taking the (2.) options.
However, if (2.) is taken, it means that any AnyRef & Singleton
will actually have two values, not one.