Octavia Togami created GROOVY-12203:
---------------------------------------
Summary: False positive "name clash" for a valid override when a
`? super` wildcard uses a type that declares the same type variable name
Key: GROOVY-12203
URL: https://issues.apache.org/jira/browse/GROOVY-12203
Project: Groovy
Issue Type: Bug
Components: Compiler
Affects Versions: 5.0.7
Reporter: Octavia Togami
The following code in a `Repro.groovy` will cause the error:
{code:groovy}
interface Box<T> { }
interface Spec {
<T extends Number> void m(Box<? super T> b)
}
class Impl implements Spec {
@Override
<T extends Number> void m(Box<? super T> b) { }
}
{code}
{code:sh}
$ groovyc Repro.groovy
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Repro.groovy: 8: name clash: m(Box<? super T>) in class 'Impl' and m(Box<?
super T>) in interface 'Spec' have the same erasure, yet neither overrides the
other.
@ line 8, column 5.
@Override
^
1 error
{code}
The two signatures in the message are identical. This worked fine in Groovy 4
and compiles
under {{javac}} as well.
Renaming {{{}Box{}}}'s own type variable fixes it, with nothing else changed:
{code:groovy}
interface Box<X> { }
{code}
So the check appears to be keying on the name.
Only the interface side matters. If the interface declares
{{<D extends Number> void m(Box<? super D> b)}} and the class declares
{{{}<T extends Number> void m(Box<? super T> b){}}}, it compiles.
Because it keys on the name, whether a type trips it depends on what that type
happens to
call its own type variable. With a method variable named {{{}T{}}},
{{{}Consumer{}}}, {{{}Supplier{}}},
{{{}Function{}}}, {{Comparator}} and {{Iterable}} all fail, while
{{{}List<E>{}}}, {{Collection<E>}}
and {{Callable<V>}} are fine. {{List}} fails too once the method variable is
renamed to {{{}E{}}}.
It also does not matter whether the supertype is a Java interface, a Groovy
interface or a
Groovy abstract class, or whether it is precompiled.
This bisects to 5.0.0-beta-1: 5.0.0-alpha-12 compiles it and 5.0.0-beta-1 does
not. That is
the fix version of GROOVY-11550, which added
{{ClassCompletionVerifier#checkMethodsForOverridingIssue}} in
[https://github.com/apache/groovy/commit/a3c59394977fd9feb5220812f62b6fd0b60a0739].
That seems likely to be the cause of the issue in some manner.
This was shrunk from real code in Gradle.
{{org.gradle.api.problems.ProblemSpec}} declares:
{code:java}
<T extends AdditionalData> ProblemSpec additionalData(Class<T> type, Action<?
super T> config);
{code}
and {{org.gradle.api.Action}} also names its type variable {{{}T{}}}, so no
Groovy 5 class can
implement it.
[https://github.com/gradle/gradle/blob/216ed75ae0d82b8bd1fdd3880f7e752f58e7aba9/platforms/ide/problems-api/src/main/java/org/gradle/api/problems/ProblemSpec.java#L162]
--
This message was sent by Atlassian Jira
(v8.20.10#820010)