New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect (or missing) implicit cast on array #795

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

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.

@alexnask

This comment has been minimized.

Collaborator

alexnask commented Aug 18, 2014

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

This comment has been minimized.

Collaborator

fasterthanlime commented Jul 8, 2015

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment