forked from scala/scala3
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix scala#9482: implement manifest algorithm
- Loading branch information
1 parent
cf6fa97
commit 798af02
Showing
8 changed files
with
366 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
val `Array[Nothing]` = manifest[Array[Nothing]] // error | ||
val `Array[Null]` = manifest[Array[Null]] // error | ||
val m_Nothing = manifest[Nothing] // error | ||
val m_Null = manifest[Null] // error | ||
|
||
val `Array[? <: Nothing]` = manifest[Array[? <: Nothing]] // error | ||
val `Array[? <: Null]` = manifest[Array[? <: Null]] // error | ||
|
||
val `Int @unchecked` = manifest[Int @unchecked] // error | ||
|
||
val `0 | 1` = manifest[0 | 1] // error | ||
|
||
class Box[T] { | ||
val m = manifest[T] // error | ||
} | ||
|
||
object Foo { | ||
type F[T] <: T | ||
manifest[Array[F[Int]]] // error | ||
} | ||
|
||
object opaques { | ||
opaque type OpaqueList[+A] = List[A] | ||
} | ||
import opaques.* | ||
|
||
val `OpaqueList[Int]` = manifest[OpaqueList[Int]] // error (opaque types are not supported) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import scala.reflect.OptManifest | ||
|
||
object Ref { | ||
def make[A: OptManifest]: Ref[A] = ??? | ||
} | ||
trait Ref[A] | ||
|
||
trait Foo[A] { | ||
val bar = Ref.make[Int] | ||
val baz: Ref[A] = Ref.make | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
object Foo { | ||
|
||
object opaques { | ||
opaque type Inner = String | ||
val i: Inner = "i" | ||
} | ||
|
||
val singleton: opaques.Inner = opaques.i | ||
|
||
val om_Inner = optManifest[opaques.Inner] // NoManifest | ||
val om_singleton = optManifest[singleton.type] // NoManifest | ||
val ct_Inner = reflect.classTag[opaques.Inner] | ||
val ct_singleton = reflect.classTag[singleton.type] | ||
} | ||
|
||
val `List[Nothing]` = manifest[List[Nothing]] | ||
val `List[Array[Nothing]]` = manifest[List[Array[Nothing]]] // ok when Nothing is not the argument of top-level array | ||
|
||
val `Array[Array[List[Int]]]` = manifest[Array[Array[List[Int]]]] | ||
|
||
trait Mixin[T <: Mixin[T]] { type Self = T } | ||
class Baz extends Mixin[Baz] { val m = manifest[Self] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import scala.reflect.{OptManifest, ClassTag} | ||
|
||
object Ref { | ||
|
||
object Sentinel | ||
|
||
def makeWithArr[A: OptManifest]: String = optManifest[A] match { | ||
case m: ClassTag[_] => m.newArray(0).asInstanceOf[AnyRef] match { | ||
// these can be reordered, so long as Unit comes before AnyRef | ||
case _: Array[Boolean] => "bool" | ||
case _: Array[Byte] => "byte" | ||
case _: Array[Short] => "short" | ||
case _: Array[Char] => "char" | ||
case _: Array[Int] => "int" | ||
case _: Array[Float] => "float" | ||
case _: Array[Long] => "long" | ||
case _: Array[Double] => "double" | ||
case _: Array[Unit] => "unit" | ||
case a: Array[AnyRef] => a.getClass.getComponentType.getName | ||
} | ||
case _ => "<?>" | ||
} | ||
|
||
def make[A: OptManifest]: String = optManifest[A] match { | ||
case m: ClassTag[a] => m match { | ||
case ClassTag.Boolean => "bool" | ||
case ClassTag.Byte => "byte" | ||
case ClassTag.Short => "short" | ||
case ClassTag.Char => "char" | ||
case ClassTag.Int => "int" | ||
case ClassTag.Float => "float" | ||
case ClassTag.Long => "long" | ||
case ClassTag.Double => "double" | ||
case ClassTag.Unit => "unit" | ||
case ClassTag.Any => "any" | ||
case ClassTag.AnyVal => "anyval" | ||
case ClassTag.Object => "anyref" | ||
case _ => m.runtimeClass.getName | ||
} | ||
case NoManifest => "<?>" | ||
} | ||
|
||
} | ||
|
||
import Ref.* | ||
|
||
def baz[A] = Ref.makeWithArr[A] | ||
def qux[A] = Ref.make[A] | ||
|
||
@main def Test = { | ||
|
||
assert(Ref.makeWithArr[Boolean] == "bool") | ||
assert(Ref.makeWithArr[Byte] == "byte") | ||
assert(Ref.makeWithArr[Short] == "short") | ||
assert(Ref.makeWithArr[Char] == "char") | ||
assert(Ref.makeWithArr[Int] == "int") | ||
assert(Ref.makeWithArr[Float] == "float") | ||
assert(Ref.makeWithArr[Long] == "long") | ||
assert(Ref.makeWithArr[Double] == "double") | ||
assert(Ref.makeWithArr[Unit] == "unit") | ||
assert(Ref.makeWithArr["abc"] == "java.lang.String") | ||
assert(Ref.makeWithArr[Null] == "<?>") | ||
assert(Ref.makeWithArr[Nothing] == "<?>") | ||
assert(baz[Int] == "<?>") | ||
|
||
assert(Ref.make[Boolean] == "bool") | ||
assert(Ref.make[Byte] == "byte") | ||
assert(Ref.make[Short] == "short") | ||
assert(Ref.make[Char] == "char") | ||
assert(Ref.make[Int] == "int") | ||
assert(Ref.make[Float] == "float") | ||
assert(Ref.make[Long] == "long") | ||
assert(Ref.make[Double] == "double") | ||
assert(Ref.make[Unit] == "unit") | ||
assert(Ref.make[Any] == "any") | ||
assert(Ref.make[AnyVal] == "anyval") | ||
assert(Ref.make[AnyRef] == "anyref") | ||
assert(Ref.make["abc"] == "java.lang.String") | ||
assert(Ref.make[Null] == "<?>") | ||
assert(Ref.make[Nothing] == "<?>") | ||
assert(qux[Int] == "<?>") | ||
|
||
} |
Oops, something went wrong.