| |
![Jonathan M Davis's Gravatar profile Gravatar of Jonathan M Davis](//www.gravatar.com/avatar/c2372c89dbe85590c9c1dd06c6f998e0?d=identicon&s=32) | Posted by Jonathan M Davis in reply to Forest | Permalink Reply |
|
Jonathan M Davis ![Jonathan M Davis's Gravatar profile Gravatar of Jonathan M Davis](//www.gravatar.com/avatar/c2372c89dbe85590c9c1dd06c6f998e0?d=identicon&s=80)
Posted in reply to Forest
| On Tuesday, February 13, 2024 12:40:57 AM MST Forest via Digitalmars-d-learn wrote:
> I may have found a bug in assumeUTF(), but being new to D, I'm
> not sure.
>
> The description:
> > Assume the given array of integers arr is a well-formed UTF
> > string and return it typed as a UTF string.
> > ubyte becomes char, ushort becomes wchar and uint becomes
> > dchar. Type qualifiers are preserved.
>
> The declaration:
>
> ```d
> auto assumeUTF(T)(T[] arr)
> if (staticIndexOf!(immutable T, immutable ubyte, immutable
> ushort, immutable uint) != -1)
> ```
>
> Shouldn't that precondition's `immutable T` be simply `T`?
>
> As it stands, I can do this with no complaints from the compiler...
>
> ```d
> string test(ubyte[] arr)
> {
> import std.string;
> return arr.assumeUTF;
> }
>
> ```
>
> ...and accidentally end up with a "string" pointing at mutable data.
>
> Am I missing something?
It's not a bug in assumeUTF. if you changed your code to
string test(ubyte[] arr)
{
import std.string;
pragma(msg, typeof(arr.assumeUTF));
return arr.assumeUTF;
}
then the compiler will output
char[]
because assumeUTF retains the type qualifier of the original type (as its documentation explains). Rather, it looks like the problem here is that dmd will implictly change the constness of a return value when it thinks that it can do so to make the code work. Essentially, that means that the function has to be pure and that the return value can't have come from any of the function's arguments. And at a glance, that would be true here, because no char[] was passed into assumeUTF. However, casting from ubyte[] to char[] is @safe, so dmd should be taking that possibility into account, and it's apparently not.
So, there's definitely a bug here, but it's a dmd bug. Its checks for whether it can safely change the constness of the return type apparently aren't sophisticated enough to catch this case.
- Jonathan M Davis
|