[
https://issues.apache.org/jira/browse/GROOVY-12755?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18141667#comment-18141667
]
ASF GitHub Bot commented on GROOVY-12755:
-----------------------------------------
codeconsole opened a new pull request, #3286:
URL: https://github.com/apache/groovy/pull/3286
https://issues.apache.org/jira/browse/GROOVY-12755
Stacked on #3285 (GROOVY-12754). Only the last commit is new here.
Since GROOVY-12714, static type checking rejects `x.getClass()` where a
`Class<? extends T>` is expected, because it types the call as `Class<?>`, the
declared return type of `Object#getClass()`. javac types it as `Class<? extends
|T|>` (JLS 4.3.2), the erasure of the receiver's static type. Grails no longer
compiles against GROOVY_6_0_X because of this, for example:
```groovy
// withTenant(Class<? extends Datastore> datastoreClass, Serializable
tenantId, Closure<T> callable)
CurrentTenantHolder.withTenant(datastore.getClass(), tenantId) { ... }
```
`inferReturnTypeGenerics` now types `e.getClass()`, and so `e.class`, as
`Class<? extends |T|>`: a type variable becomes its bound, type arguments are
dropped, an array keeps its dimensions, and a primitive receiver is boxed. The
bound is a raw type, as if written in source.
That makes more calls pass a `Class<? extends X>` to a bounded `<T extends
B> m(Class<T>)`, which GROOVY-12754 fixes. Without it, `foo(l.class, l)` in
`testMethodLevelGenericsForMethodCall` fails.
Two existing expectations change. The inferred type of `list.class` for a
raw `List`, in `FieldsAndPropertiesSTCTest`, is now `Class<? extends
java.util.List>` rather than `Class<? extends java.lang.Object>`. The
GROOVY-5415 message now names `Class<? extends ClassB>`.
`GenericsJavaCompatibilityTest` checks against javac: passing, returning and
assigning a `getClass()` result, with a type variable, a raw type and an array,
plus a negative case for an `Object` receiver. `GenericsSTCTest` covers the
Groovy forms: `.class`, an implicit `this`, a closure, a static context, a
primitive, arrays and a type variable. They fail without the change.
Please also apply this to GROOVY_6_0_X, after GROOVY-12754. Both cherry-pick
cleanly, and with them the four Grails modules that fail compile against the
branch.
> STC: e.getClass() is typed Class<?>, so since GROOVY-12714 it is rejected
> where a Class<? extends T> is expected
> ----------------------------------------------------------------------------------------------------------------
>
> Key: GROOVY-12755
> URL: https://issues.apache.org/jira/browse/GROOVY-12755
> Project: Groovy
> Issue Type: Bug
> Components: Static Type Checker
> Affects Versions: 7.0.0-alpha-1, 6.0.1
> Reporter: Scott Murphy Heiberg
> Priority: Major
>
> JLS 4.3.2 gives a call {{e.getClass()}} the type {{Class<? extends |T|>}},
> where {{|T|}} is the erasure of the static type of {{e}}. Static type
> checking types it with the declared return type of {{Object#getClass()}},
> {{Class<?>}}. Until GROOVY-12714 the wildcard check accepted {{Class<?>}}
> where a {{Class<? extends T>}} was expected. Since GROOVY-12714 (GROOVY_6_0_X
> and master) it is rejected:
> {code:groovy}
> @groovy.transform.CompileStatic
> class C {
> interface Store {}
> static <T> T with(Class<? extends Store> type, Closure<T> body) {
> body.call() }
> static class Adapter { Adapter(Class<? extends Store> type) {} }
> static Object viaMethod(Store store) { with(store.getClass()) { 1 } }
> static Object viaProperty(Store store) { with(store.class) { 1 } }
> static Object viaConstructor(Store store) { new Adapter(store.getClass())
> }
> static Class<? extends Store> viaReturn(Store store) { store.getClass() }
> }
> {code}
> {noformat}
> [Static type checking] - Cannot call <T> C#with(java.lang.Class<? extends
> C.Store>, groovy.lang.Closure<T>) with arguments [java.lang.Class<?>,
> groovy.lang.Closure]
> [Static type checking] - Cannot call <T> C#with(java.lang.Class<? extends
> C.Store>, groovy.lang.Closure<T>) with arguments [java.lang.Class<?>,
> groovy.lang.Closure]
> [Static type checking] - Cannot call C$Adapter#<init>(java.lang.Class<?
> extends C.Store>) with arguments [java.lang.Class<?>]
> [Static type checking] - Incompatible generic argument types. Cannot assign
> java.lang.Class<?> to: java.lang.Class<? extends C.Store>
> {noformat}
> javac accepts the equivalent Java. Grails no longer compiles against
> GROOVY_6_0_X: it passes {{datastore.getClass()}} to a {{Class<? extends
> Datastore>}} parameter and {{registrar.getClass()}} to a {{Class<? extends
> BeanRegistrar>}} one
> (https://github.com/apache/grails-core/actions/runs/42702095261).
> Typing {{e.getClass()}} and {{e.class}} as {{Class<? extends |T|>}} makes
> more calls pass an upper-bounded wildcard for a bounded type parameter, such
> as {{foo(list.class)}} for {{<T extends List<Integer>> foo(Class<T>)}}, which
> GROOVY-12754 rejected. So this depends on GROOVY-12754.
> The inferred type of {{list.class}} for a raw {{List list}} changes from
> {{Class<? extends Object>}} to {{Class<? extends List>}}, and the GROOVY-5415
> error for {{a.bar(this.getClass())}} now names {{Class<? extends ClassB>}};
> the two tests that assert those types are updated.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)