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:[email protected]]
Sent: Wednesday, December 02, 2015 9:48 AM
To: [email protected]
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 
<[email protected]<mailto:[email protected]>>:
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.

Reply via email to