- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Preserving traits with manifests
Fri, 2011-12-09, 14:00
Hi,
Is it possible to preserve all traits of a type T when using
erasure.newInstance() of a Manifest[T]? My attempt compiles, but
results in a ClassCastException.
trait ExampleTrait { def traitMethod = "trait!" }
class ExampleClass
object ManifestTest extends App {
def instantiate[T](implicit m: Manifest[T]) =
m.erasure.newInstance().asInstanceOf[T]
val instance: ExampleClass with ExampleTrait =
instantiate[ExampleClass with ExampleTrait]
instance.traitMethod
}
Compiles, but at runtime:
Exception in thread "main" java.lang.ClassCastException: ExampleClass
cannot be cast to ExampleTrait
at ManifestTest$delayedInit$body.apply(ManifestTest.scala:8)
Fri, 2011-12-09, 15:21
#2
Re: Preserving traits with manifests
Maybe you can make a separate asInstanceOf/isInstanceOf issue for your
manifested parametric structural mixin trait case.
On 9 dec, 14:00, Adam Rabung wrote:
> Hi,
> Is it possible to preserve all traits of a type T when using
> erasure.newInstance() of a Manifest[T]? My attempt compiles, but
> results in a ClassCastException.
>
> trait ExampleTrait { def traitMethod = "trait!" }
>
> class ExampleClass
>
> object ManifestTest extends App {
> def instantiate[T](implicit m: Manifest[T]) =
> m.erasure.newInstance().asInstanceOf[T]
> val instance: ExampleClass with ExampleTrait =
> instantiate[ExampleClass with ExampleTrait]
> instance.traitMethod
>
> }
>
> Compiles, but at runtime:
> Exception in thread "main" java.lang.ClassCastException: ExampleClass
> cannot be cast to ExampleTrait
> at ManifestTest$delayedInit$body.apply(ManifestTest.scala:8)
I had a similar problem too and was struggling too and made an issue.
https://issues.scala-lang.org/browse/SI-5042
which is about manifested parametric polymorphism doesn't seem to work
correctly with asInstanceOf/isInstanceOf.
My wild guess is that it seems that it does some internal up- en
downcasts and then when it wants to do the real coercion it is in some
other branche of the inheritance tree which does not have a subtyping
relation with the target.
In your case it may be even true that there is no real subtyping
relation, because you are making use of a structural type in a trait
which is mixed in in a class. But imo mixin traits can also be seen as
a form of multiple inheritance but then dynamically.
Maybe asInstanceOf/isInstanceOf works only correctly with statical
typed coercions. But still it is strange that there is no compile time
warning that this is not going to work in runtime. Instead, the
manifest takes away the unchecked type erasure warning for my
parametric polymorphism case.
No solution found yet.
On 9 dec, 14:00, Adam Rabung wrote:
> Hi,
> Is it possible to preserve all traits of a type T when using
> erasure.newInstance() of a Manifest[T]? My attempt compiles, but
> results in a ClassCastException.
>
> trait ExampleTrait { def traitMethod = "trait!" }
>
> class ExampleClass
>
> object ManifestTest extends App {
> def instantiate[T](implicit m: Manifest[T]) =
> m.erasure.newInstance().asInstanceOf[T]
> val instance: ExampleClass with ExampleTrait =
> instantiate[ExampleClass with ExampleTrait]
> instance.traitMethod
>
> }
>
> Compiles, but at runtime:
> Exception in thread "main" java.lang.ClassCastException: ExampleClass
> cannot be cast to ExampleTrait
> at ManifestTest$delayedInit$body.apply(ManifestTest.scala:8)