I believe this is scala bug 7521:

https://github.com/scala/bug/issues/7521

Skimming the comments and other referenced issues, I don't see anyone
mentioning a workaround. Appears the fix was added in 2.12, which makes
sense based on the behavior you're seeing.

On 12/17/19 1:19 PM, Sloane, Brandon wrote:
> While debugging my latest DataValue PR under 2.11, I came across what I 
> believe to be a compiler bug.
> 
> Recall that we have source code along the lines of:
> 
> ...
>   @inline implicit def toDataValue(v: DFDLTime): DataValueTime = new 
> DataValue(v)
>   @inline implicit def toDataValue(v: Array[Byte]): DataValueByteArray = new 
> DataValue(v)
>   @inline implicit def toDataValue(v: JBoolean): DataValueBool = new 
> DataValue(v)
>   @inline implicit def toDataValue(v: JNumber): DataValueNumber = new 
> DataValue(v)
> ...
> 
> Under 2.11, this gets compiled to:
> 
> ...
>   public org.apache.daffodil.calendar.DFDLDate 
> toDataValue(org.apache.daffodil.calendar.DFDLDate);
>     Code:
>        0: aload_1
>        1: areturn
> 
>   public org.apache.daffodil.calendar.DFDLTime 
> toDataValue(org.apache.daffodil.calendar.DFDLTime);
>     Code:
>        0: aload_1
>        1: areturn
> 
>   public byte[] toDataValue(byte[]);
>     Code:
>        0: getstatic     #35                 // Field 
> scala/runtime/ScalaRunTime$.MODULE$:Lscala/runtime/ScalaRunTime$;
>        3: aload_1
>        4: invokevirtual #39                 // Method 
> scala/runtime/ScalaRunTime$.toObjectArray:(Ljava/lang/Object;)[Ljava/lang/Object;
>        7: checkcast     #41                 // class "[Ljava/lang/Byte;"
>       10: areturn
> 
>   public java.lang.Boolean toDataValue(java.lang.Boolean);
>     Code:
>        0: aload_1
>        1: areturn
> 
>   public java.lang.Number toDataValue(java.lang.Number);
>     Code:
>        0: aload_1
>        1: areturn
> ...
> 
> Note that for every instant accept byte[], the function compiles to a simple 
> identity function.
> 
> When compiled under 2.12, the byte[] instance gets compiled to identity as 
> well:
> 
>   public byte[] toDataValue(byte[]);
>     Code:
>        0: aload_1
>        1: areturn
> 
> The 2.11 version is not just inefficient; it is also wrong. It first converts 
> to an array of Objects (which implies boxing), before attempting to cast said 
> array to an array of (boxed) Bytes. This case fails , as Object[] does not 
> extends Byte[].
> 
> Even if this cast were to succeed, the function would then be attempting to 
> return an array of boxed java.lang.Byte, while its signature indicates it 
> should be returning an array of unboxed bytes.
> 
> (As an asside, at the callpoint I looked at in 2.12 optimizes this function 
> out entirely; the 2.11 version makes a standard function call to toDataValue)
> 
> I'm at a bit of a loss as to how to proceed. This bug seems fatal to the idea 
> of having an AnyVal DataValue class, and we do not have much wiggle-room to 
> tweak our source code to avoid triggering it.
> 
> Thoughts?
> 
> 
> Brandon T. Sloane
> 
> Associate, Services
> 
> bslo...@tresys.com | tresys.com
> 

Reply via email to