Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3.3 impl of a 2.13 trait ignores field annotation target #19205

Open
akshaal opened this issue Dec 5, 2023 · 3 comments
Open

3.3 impl of a 2.13 trait ignores field annotation target #19205

akshaal opened this issue Dec 5, 2023 · 3 comments

Comments

@akshaal
Copy link

akshaal commented Dec 5, 2023

When Dotty generates an implementation for a field defined in a trait, it loses annotation target information when the trait itself is compiled with Scala 2.13.

Source code

This is a minimized example to demonstrate the problem. Originally it is a case in which A is actually Rule annotation from the junit library. Trait provides an implementation of a field containing @org.junit.Rule for junit tests. Impl is a test class consuming Trait.
Junit framework requires @rule definitions to be public, therefore the definition is requested to be placed on the getter.

x/A.java

package x;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface A {
}

x/Trait.scala

package x

import scala.annotation.meta.getter;

trait Trait {
    @(A @getter)
    val x = new Object
}

x/Impl.scala

package x

class Impl extends Trait

Mix of scala 2.13 and 3.3.1

Lets say x/Trait.class is located in a library compiled with scala 2.13 and x/Impl.scala consumes the library and compiles the Impl.scala with scala 3.3.1. This produce a wrong x/Impl.class. The annotation ends up on the private field instead of the public getter. Below are resulting classes decompiled with CFR to java:

Originally compiled with scala 2.13, Trait.class decompiles to:

public interface Trait {
    public void x$Trait$_setter_$x_$eq(Object var1);

    @A
    public Object x();

    public static void $init$(Trait $this) {
        $this.x$Trait$_setter_$x_$eq(new Object());
    }
}

Originally compiled with scala 3.3, Impl.class decompiles to:

public class Impl implements Trait {
    @A // <---------------------- THE BUG -----------
    private Object x;

    public Impl() {
        Trait.$init$(this);
        Statics.releaseFence();
    }

    // No annotation here
    @Override
    public Object x() {
        return this.x;
    }

    @Override
    public void x$Trait$_setter_$x_$eq(Object x$0) {
        this.x = x$0;
    }
}

Only scala 2.13

If everything is compiled with just scala 2.13, then the decompiled Impl.class looks like this:

public class Impl implements Trait {
    private Object x;

    // The annotation is here.
    @A
    @Override
    public Object x() {
        return this.x;
    }

    @Override
    public void x$Trait$_setter_$x_$eq(Object x$1) {
        this.x = x$1;
    }

    public Impl() {
        Trait.$init$(this);
        Statics.releaseFence();
    }
}

Only scala 3.3

Everything is fine here as well.

public interface Trait {
    public static void $init$(Trait $this) {
        $this.x$Trait$_setter_$x_$eq(new Object());
    }

    @A
    public Object x();

    public void x$Trait$_setter_$x_$eq(Object var1);
}
public class Impl implements Trait {
    private Object x;

    public Impl() {
        Trait.$init$(this);
        Statics.releaseFence();
    }

    @A
    @Override
    public Object x() {
        return this.x;
    }

    @Override
    public void x$Trait$_setter_$x_$eq(Object x$0) {
        this.x = x$0;
    }
}
@akshaal akshaal added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Dec 5, 2023
@mbovel mbovel added area:backend Spree Suitable for a future Spree and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Dec 11, 2023
@mbovel
Copy link
Member

mbovel commented Dec 11, 2023

@EugeneFlesselle @entangled90 @AnotherMedo: seems like a nice follow-up of #19207 for a future Spree 🙂

@mbovel
Copy link
Member

mbovel commented Apr 26, 2024

This issue was picked for the Scala Issue Spree of April 30th. @hamzaremmal, @KuceraMartin and @jan-pieter will be working on it. If you have any insight into the issue or guidance on how to fix it, please leave it here.

@mbovel
Copy link
Member

mbovel commented Jul 1, 2024

@hamzaremmal, @KuceraMartin and @jan-pieter, do you remember what the outcome of the spree was? Did you switch to another issue in the end?

@mbovel mbovel removed the Spree Suitable for a future Spree label Sep 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants