[ 
https://issues.apache.org/jira/browse/GROOVY-8965?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17564321#comment-17564321
 ] 

Eric Milles commented on GROOVY-8965:
-------------------------------------

What I have -- I can push my branch if you'd like to look it over -- adds LUB 
(which is just {{instanceof}} type in case of single) to receivers list, then 
declared/inferred type, then bound types and self types and so on as before.  
This means Number will be checked for floatValue in this example and will 
succeed.

When you have "a instanceof Integer || a instanceof Double" the inferred type 
is UnionType:Integer+Double and this gets added as the second receiver to 
check.  I did think about adding the original declared type (Object in this 
case) by itself but that is mixed into the inferred type in the current 
implementation.  For example: "def m(CharSequence cs) \{ if (cs instanceof 
Serializable) cs.something(); \}" Would check for "something()" against 
UnionType:CharSequence+Serializable.  (This is probably supposed to be the 
other kind of type since it is both CharSequence *and* Serializable, but I lack 
test cases for this kind of thing.)

The duck-typing case -- "(obj instanceof List || obj instanceof Map) ? 
obj.size() : 1" -- will now produce an ambiguous method error.  Old code added 
List and Map separately before UnionType:List+Map, so only one of the two 
needed to have "size()" for type-checking to pass.  I think it would still pass 
if only one has "size()"; I need to set up a test case for this.  I am 
exploring adding something in {{disambiguateMethods}} to switch to a dynamic 
call for the duck-typing case.  But I could push with what I have since before 
you got a runtime exception under @CS when you pass one of the two types.  So 
the ambiguous method error at least gives you a chance at compile time to make 
a change.

> instanceof with || inserts wrong cast
> -------------------------------------
>
>                 Key: GROOVY-8965
>                 URL: https://issues.apache.org/jira/browse/GROOVY-8965
>             Project: Groovy
>          Issue Type: Bug
>          Components: Static compilation
>    Affects Versions: 2.5.5
>            Reporter: Daniil Ovchinnikov
>            Assignee: Eric Milles
>            Priority: Major
>
> {code:java}
> @groovy.transform.CompileStatic
> def foo(a) {
>     if (a instanceof Integer || a instanceof Double) {
>         a.floatValue() // expected: cast to Number; actual: cast to Integer
>     }
> }
> println foo(1d).class // CCE: java.lang.Double cannot be cast to 
> java.lang.Integer
> {code}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to