groovy-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Frank Pavageau (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (GROOVY-7363) Frequent compilation error on cascading generic types
Date Mon, 03 Aug 2015 15:46:05 GMT

    [ https://issues.apache.org/jira/browse/GROOVY-7363?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14652005#comment-14652005
] 

Frank Pavageau commented on GROOVY-7363:
----------------------------------------

I've been trying to create a test case for this bug, but it has proven difficult due to the
fact that it's not 100% reproducible. I've tried running the body of the test in a loop (using
{{100.times}} for example) but it either fails immediately or never, so it's probably related
to an initialization. With the minimal test case I eventually created, the static type check
fails 46% of the time.

However, while building this minimal test case and removing as much stuff as I could, I noticed
that some modifications removed the bug, and it led me to an interesting discovery. The test
case runs the following script:
{code}
assertScript """import org.codehaus.groovy.classgen.asm.sc.bugs.support.Groovy7363Support
    Groovy7363Support.ABC a = new Groovy7363Support.ABC()
    println('' + a.b.object.value)
"""
{code}
which fails, as in my original report, with:
{noformat}
TestScripttestCascadingGenericTypes0.groovy: 3: [Static type checking] - No such property:
value for class: T
@ line 3, column 26.
               println('' + a.b.object.value)
                            ^
{noformat}
The support Java code started with:
{code}
public class Groovy7363Support {
    public interface A<T, U extends B<T>> {
        U getB();

        void setB(U b);
    }

    public static class ABC implements A<C, BC> {
        @Override
        public BC getB() {
            return new BC();
        }

        @Override
        public void setB(BC b) {}
    }

    // ...
}
{code}


The setter did not seem necessary in the interface so I removed it, along with its implementation,
and then the check passed. I then added the setter back, but only in the implementation, and
the check failed again (46% of the time):
{code}
public class Groovy7363Support {
    public interface A<T, U extends B<T>> {
        U getB();
    }

    public static class ABC implements A<C, BC> {
        @Override
        public BC getB() {
            return new BC();
        }

        public void setB(BC b) {}
    }

    // ...
}
{code}


And then I remembered that classes implementing generics have synthetic bridge methods generated
by the compilation, so I wondered if changing the order of the methods might influence the
output. And indeed, moving the setter first in front of the getter makes the check fail reliably
_on my machine_ (MacOS X 10.10.4, 64-bit Oracle JDK 1.7.0u75):
{code}
public class Groovy7363Support {
    public interface A<T, U extends B<T>> {
        U getB();
    }

    public static class ABC implements A<C, BC> {
        public void setB(BC b) {}

        @Override
        public BC getB() {
            return new BC();
        }
    }

    // ...
}
{code}


Still, I'm reluctant to actually create a pull request from [my branch|https://github.com/apache/incubator-groovy/compare/GROOVY_2_4_X...fpavageau:GROOVY-7363?expand=1]
because the test could actually be flaky in other environments. But [the code is there|https://github.com/fpavageau/incubator-groovy/tree/GROOVY-7363],
and I might try and debug it myself, to find where the analysis of the {{ABC}} class takes
place and incorrectly initializes the context.

> Frequent compilation error on cascading generic types
> -----------------------------------------------------
>
>                 Key: GROOVY-7363
>                 URL: https://issues.apache.org/jira/browse/GROOVY-7363
>             Project: Groovy
>          Issue Type: Bug
>          Components: Static Type Checker
>    Affects Versions: 2.4.2
>         Environment: MacOS X
> Oracle JDK 1.7u75 / 1.8u40
> Maven 3.0.5
>            Reporter: Frank Pavageau
>            Assignee: C├ędric Champeau
>         Attachments: lost-cascading-types.tar.gz
>
>
> Most of the time, I get the following compilation error:
> {noformat}
> [ERROR] /Users/fpavageau/devs/bugs/lost-cascading-types/src/main/groovy/BadType.groovy:
22: [Static type checking] - No such property: start for class: T
> [ERROR] @ line 22, column 22.
> [ERROR] println("" + rel.currentState.state.start)
> [ERROR] ^
> [ERROR] 
> [ERROR] 1 error
> {noformat}
> where {{rel}} is an instance of a non-parameterized (Java) class implementing a generic
interface with the {{currentState}} generic property. So the type of the property should actually
be known, but it's lost and I get a compilation error because the {{start}} property is not
part of the lower-bound type of {{currentState}}.
> When I say "most of the time", it's because the compilation error is not always triggered
(so lots of debugging fun!). I've tried with Oracle JDK 1.7u75 and 1.8u40, and I get around
87% of failures:
> {code:title=JDK 1.7}
> $ failures=0; for i in {1..100}; do mvn clean package > /dev/null 2>&1 || ((failures++));
done; echo $failures
> 87
> {code}
> {code:title=JDK 1.8}
> $ failures=0; for i in {1..100}; do mvn clean package > /dev/null 2>&1 || ((failures++));
done; echo $failures
> 88
> {code}
> I'm attaching a test case, which is also available on [Github|https://github.com/fpavageau/lost-cascading-types].



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Mime
View raw message