@varargs method and separate compilation

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

@varargs method and separate compilation

Iulian Dragos

Hi all,

I just filed SI-10071 and I’m willing to take a shot at fixing it, but I want to check first if:

  • there’s interest in a fix
  • the approach I have in mind is sound

Here’s what happens:

Methods annotated with @varargs get a forwarder that can be called from Java as a vararg method. This transformation is done in uncurry in the tree transformer, so in my example:

import scala.annotation.varargs

trait AbstractProps {
  @varargs def create(x: Int, y: Int*): AbstractProps = null
  // added by uncurry
  <synthetic> def create(x: Int, y: Array[Int]): AbstractProps = create(x, Predef.wrapIntArray(y));
}

Now, if this trait is mixed in another class, this method won’t be added unless the two classes are compiled together. The reason is that uncurry is after pickler so the java vararg method is not in the type of AbstractProps when all we have for AbstractProps is a symbol.

The usual way to deal with such problems is to split the transformation in two parts:

  • an info transform that adds the synthetic method symbol to the owner. This happens for all symbols, whether they come from source or binaries
  • a tree transformation that provides an implementation for that symbol. This only happens then we actually compile that class

Uncurry is already an info transformer, so the phase has the two parts already. However, java varargs did not follow this pattern.

Is there a better way than to move this method symbol creation to the info transformer (who, by the way, lives in scala.reflect.internal)?

iulian

--
« Je déteste la montagne, ça cache le paysage »
Alphonse Allais

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: @varargs method and separate compilation

Lukas Rytz-2
That sounds like the right approach to me.
Thanks!
Lukas

On Fri, Nov 18, 2016 at 3:42 PM, iulian dragos <[hidden email]> wrote:

Hi all,

I just filed SI-10071 and I’m willing to take a shot at fixing it, but I want to check first if:

  • there’s interest in a fix
  • the approach I have in mind is sound

Here’s what happens:

Methods annotated with @varargs get a forwarder that can be called from Java as a vararg method. This transformation is done in uncurry in the tree transformer, so in my example:

import scala.annotation.varargs

trait AbstractProps {
  @varargs def create(x: Int, y: Int*): AbstractProps = null
  // added by uncurry
  <synthetic> def create(x: Int, y: Array[Int]): AbstractProps = create(x, Predef.wrapIntArray(y));
}

Now, if this trait is mixed in another class, this method won’t be added unless the two classes are compiled together. The reason is that uncurry is after pickler so the java vararg method is not in the type of AbstractProps when all we have for AbstractProps is a symbol.

The usual way to deal with such problems is to split the transformation in two parts:

  • an info transform that adds the synthetic method symbol to the owner. This happens for all symbols, whether they come from source or binaries
  • a tree transformation that provides an implementation for that symbol. This only happens then we actually compile that class

Uncurry is already an info transformer, so the phase has the two parts already. However, java varargs did not follow this pattern.

Is there a better way than to move this method symbol creation to the info transformer (who, by the way, lives in scala.reflect.internal)?

iulian

--
« Je déteste la montagne, ça cache le paysage »
Alphonse Allais

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: @varargs method and separate compilation

Iulian Dragos


On Fri, Nov 18, 2016 at 4:35 PM, Lukas Rytz <[hidden email]> wrote:
That sounds like the right approach to me.

Excellent! Any recommendation on linking the new symbol to the original method? In the tree transformer I need to find the "right" forwarder symbol so I reuse it in the tree. 

thanks,
iulian
 
Thanks!
Lukas

On Fri, Nov 18, 2016 at 3:42 PM, iulian dragos <[hidden email]> wrote:

Hi all,

I just filed SI-10071 and I’m willing to take a shot at fixing it, but I want to check first if:

  • there’s interest in a fix
  • the approach I have in mind is sound

Here’s what happens:

Methods annotated with @varargs get a forwarder that can be called from Java as a vararg method. This transformation is done in uncurry in the tree transformer, so in my example:

import scala.annotation.varargs

trait AbstractProps {
  @varargs def create(x: Int, y: Int*): AbstractProps = null
  // added by uncurry
  <synthetic> def create(x: Int, y: Array[Int]): AbstractProps = create(x, Predef.wrapIntArray(y));
}

Now, if this trait is mixed in another class, this method won’t be added unless the two classes are compiled together. The reason is that uncurry is after pickler so the java vararg method is not in the type of AbstractProps when all we have for AbstractProps is a symbol.

The usual way to deal with such problems is to split the transformation in two parts:

  • an info transform that adds the synthetic method symbol to the owner. This happens for all symbols, whether they come from source or binaries
  • a tree transformation that provides an implementation for that symbol. This only happens then we actually compile that class

Uncurry is already an info transformer, so the phase has the two parts already. However, java varargs did not follow this pattern.

Is there a better way than to move this method symbol creation to the info transformer (who, by the way, lives in scala.reflect.internal)?

iulian

--
« Je déteste la montagne, ça cache le paysage »
Alphonse Allais

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.



--
« Je déteste la montagne, ça cache le paysage »
Alphonse Allais

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: @varargs method and separate compilation

Lukas Rytz-2
On Fri, Nov 18, 2016 at 4:47 PM, iulian dragos <[hidden email]> wrote:


On Fri, Nov 18, 2016 at 4:35 PM, Lukas Rytz <[hidden email]> wrote:
That sounds like the right approach to me.

Excellent! Any recommendation on linking the new symbol to the original method? In the tree transformer I need to find the "right" forwarder symbol so I reuse it in the tree. 

We're using attachments more and more lately for this kind of things.
Maybe an exitingUncurry will be necessary?
I don't have time right now to find examples, sorry..
 

thanks,
iulian
 
Thanks!
Lukas

On Fri, Nov 18, 2016 at 3:42 PM, iulian dragos <[hidden email]> wrote:

Hi all,

I just filed SI-10071 and I’m willing to take a shot at fixing it, but I want to check first if:

  • there’s interest in a fix
  • the approach I have in mind is sound

Here’s what happens:

Methods annotated with @varargs get a forwarder that can be called from Java as a vararg method. This transformation is done in uncurry in the tree transformer, so in my example:

import scala.annotation.varargs

trait AbstractProps {
  @varargs def create(x: Int, y: Int*): AbstractProps = null
  // added by uncurry
  <synthetic> def create(x: Int, y: Array[Int]): AbstractProps = create(x, Predef.wrapIntArray(y));
}

Now, if this trait is mixed in another class, this method won’t be added unless the two classes are compiled together. The reason is that uncurry is after pickler so the java vararg method is not in the type of AbstractProps when all we have for AbstractProps is a symbol.

The usual way to deal with such problems is to split the transformation in two parts:

  • an info transform that adds the synthetic method symbol to the owner. This happens for all symbols, whether they come from source or binaries
  • a tree transformation that provides an implementation for that symbol. This only happens then we actually compile that class

Uncurry is already an info transformer, so the phase has the two parts already. However, java varargs did not follow this pattern.

Is there a better way than to move this method symbol creation to the info transformer (who, by the way, lives in scala.reflect.internal)?

iulian

--
« Je déteste la montagne, ça cache le paysage »
Alphonse Allais

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.



--
« Je déteste la montagne, ça cache le paysage »
Alphonse Allais

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.