groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Winnebeck, Jason" <Jason.Winneb...@windstream.com>
Subject RE: CompileStatic and right-hand-side literals
Date Wed, 02 Dec 2015 15:55:39 GMT
It is technically correct, but for example I was able to assign [a: ‘1’] to a Map<String,
Object>, so for variable assignment it works, but not for plus.

In my second example I use Collections.emptyList(), which in Java exists expressly to avoid
casts that are required when using Collections.EMPTY_LIST. So this is code that would work
in Java exactly as-is but does not work in Groovy. It means that the ability to return template
generic type seems not to exist in Groovy.

In both cases, I can use a cast to fix the issue, although in IntelliJ it’s annoying because
it thinks you can’t cast a Map<String, Integer> to a Map<String, Object> (which
would be true in Java code), although groovyc itself allows it. So then you have the awkward
workaround of [b: (Object)2], which seems very anti-Groovy (especially given the very recent
conversation on this list about removing unnecessary syntax around closures). In the second
case, I can use Collections.<Integer>emptyList(), but in this case the Groovy code is
more verbose than the Java code.

Jason

From: Cédric Champeau [mailto:cedric.champeau@gmail.com]
Sent: Wednesday, December 02, 2015 9:48 AM
To: users@groovy.apache.org
Subject: Re: CompileStatic and right-hand-side literals

I think that the type checker is technically correct here. The RHS is correctly inferred (it's
a `Map<String, String>`). And since you are trying to assign it to `Map<String, Object>`
it fails. It's a consequence of inference of literals (Java doesn't have such literals so
no such issues). You have to separate declaration from assignment, or use a cast.

2015-12-02 15:44 GMT+01:00 Winnebeck, Jason <Jason.Winnebeck@windstream.com<mailto:Jason.Winnebeck@windstream.com>>:
Is there a way to avoid awkward typing issues with literals as in this case:

@CompileStatic
void f() {
  Map<String, Object> x = [a: '1']
  println x + [b: 2]
}

This results in the following errors in 2.4.5:

[Static type checking] - Incompatible generic argument types. Cannot assign java.util.LinkedHashMap
<java.lang.String, java.lang.String> to: java.util.Map <String, Object>
 at line: 3, column: 27

[Static type checking] - Cannot call <K,V> java.util.LinkedHashMap <java.lang.String,
java.lang.String>#plus(java.util.Map <java.lang.String, java.lang.String>) with arguments
[java.util.LinkedHashMap <java.lang.String, java.lang.Integer>]
 at line: 4, column: 13

It seems that the static compiler has issues with inferring RHS types. I think it might be
similar to this case I run into from time to time:

@CompileStatic
void g(List<Integer> items) {}

@CompileStatic
void h() {
  g(Collections.emptyList())
}

Results in:
[Static type checking] - Cannot call ConsoleScript6#g(java.util.List <java.lang.Integer>)
with arguments [java.util.List <T extends java.lang.Object>]

Jason Winnebeck

----------------------------------------------------------------------
This email message and any attachments are for the sole use of the intended recipient(s).
Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the
intended recipient, please contact the sender by reply email and destroy all copies of the
original message and any attachments.

Mime
View raw message