[ 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)