Incorrect (or missing) implicit cast on array #795

Closed
zhaihj opened this Issue Aug 18, 2014 · 2 comments

Projects

None yet

3 participants

@zhaihj
Contributor
zhaihj commented Aug 18, 2014
foo: func~SizeT->SSizeT[]{
    return [1,2,3,4]
}

foo: func~Int->Int[]{
    return [1,2,3,4]
}

main: func(){
    foo~SizeT()[0] toString() println()
    foo~Int()[0] toString() println()
}

gives:

8589934593
1

instead of

1
1

8589934593 = 2<<32 + 1

Generated Code:

_lang_array__Array return__foo_SizeT() {
    _lang_array__Array __arrLit1 = _lang_array__Array_new(lang_Numbers__Int, 4);

    {
        lang_Numbers__Int* __ptrLit2 = (lang_Numbers__Int[]) { 1, 2, 3, 4 };
        lang_Memory__memcpy(__arrLit1.data, __ptrLit2, 4 * ((lang_types__Class*)lang_Numbers__Int_class())->size);
    }
    return ((_lang_array__Array) (__arrLit1));
}

lang_String__String_println(lang_Numbers__SSizeT_toString(_lang_array__Array_get(return__foo_SizeT(), 0, lang_Numbers__SSizeT)));

It clear that [1,2,3] is infered as Int[] but used as SSizeT[] without (element-wise) cast.

@shamanas
Collaborator

Yeah it seems that the array is inferred to be Int[], as you said, because integer literals are of type Int and the whole array is then implicitely casted to SSizeT[].

Rock doesn't recognize that elements of the array must be casted, it only casts the array itself.

As a temporary workaround, you can cast the first element of the array (when constructing it) to SSizeT to force rock to infer the type of the array to SSizeT.

@fasterthanlime
Collaborator

Note that this works:

use sam-assert

foo: func ~SizeT -> SSizeT[] {
    arr: SSizeT[] = [1, 2, 3, 4]
    return arr
}

foo: func ~Int -> Int[] {
    return [1, 2, 3, 4]
}

main: func(){
    expect("1", foo~SizeT()[0] toString())
    expect("1", foo~Int()[0] toString())
}

I'm pretty sure rock should forbid array casts of any form. In your case.. it might be that it should work, I'm not entirely sure yet. But I'm wondering what's the timing with autoReturn. It would have to be aware it's returned to infer its type, so:

// would work
foo: func -> SSizeT[] { 
  [1, 2, 3]
}

// wouldn't work
foo: func -> SSizeT[] { 
  a := [1, 2, 3]
  a
}

So.. is it really worth trying to make it work like that?

@fasterthanlime fasterthanlime modified the milestone: 0.9.10 Jul 10, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment