This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Preserving traits with manifests

2 replies
Adam Rabung
Joined: 2010-04-23,
User offline. Last seen 42 years 45 weeks ago.

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)

DaveScala
Joined: 2011-03-18,
User offline. Last seen 1 year 21 weeks ago.
Re: Preserving traits with manifests

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)

DaveScala
Joined: 2011-03-18,
User offline. Last seen 1 year 21 weeks ago.
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)

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland