Search code examples
castingdimmutability

Why cannot I cast to immutable in @safe functions? (D)


Why cannot I cast mutable variables to immutable values in @safe functions? Also, is there a workaround for this?

@safe pure immutable(char[][char[]]) getNameValuePair {
    immutable(char[])[immutable(char[])] pair;
    // logics filling the pair here
    return cast(immutable(char[][char[]])) pair;
}

This code will cause the compile error:

Error: cast from immutable(char[])[immutable(char[])] to immutable(char[][const(char)[]]) not allowed in safe code

When I do return pair.idup, I get the error: no property 'idup' for type 'immutable(char[])[immutable(char[])]'.


Solution

  • The purpose of @safe is to verify memory integrity, casting is a command to ignore safety and "do what I say." I'm not sure what work is being done to identify "safe" casts.

    A workaround is to use @trusted, but ultimately you're just doing it wrong. Your function is pure, so it is able to assign into an immutable instance:

    void main()
    {
        immutable(char[][immutable(char[])]) ans = getNameValuePair();
    }
    
    @safe pure immutable(char[])[immutable(char[])] getNameValuePair() {
        immutable(char[])[immutable(char[])] pair;
        // logics filling the pair here
        return pair;
    }
    

    Note that the type which comes out has the key as an immutable(char[]) and not a char[] which you were trying to cast to (thus breaking the guarantees of the pure/immutable type you declared). In other words, thank the type system for correcting your mistake.