Darned little of the aa interfaces are usable in an @safe context. The api I hit first is aa.keys, but on looking at object.di and aaA.d, about the only ones that _are_ @safe is aaLiteral and friends. Not even _aaLen is @safe.
Comment #1 by braddr — 2015-04-14T01:06:07Z
module safeaa;
void main() @safe
{
string[string] saa = [ "a" : "1", "b" : "2" ];
string s = saa["a"];
saa["c"] = "3";
if ("c" in saa) {}
size_t l = saa.length;
foreach(k; saa.keys) {}
foreach(k; saa.byKey) {}
foreach(v; saa.values) {}
foreach(v; saa.byValue) {}
}
safeaa.d(15): Error: safe function 'D main' cannot call system function 'object.keys!(string[string], string, string).keys'
safeaa.d(17): Error: safe function 'D main' cannot call system function 'object.byKey!(string[string], string, string).byKey'
safeaa.d(17): Error: safe function 'D main' cannot call system function 'object.byKey!(string[string], string, string).byKey.Result.empty'
safeaa.d(17): Error: safe function 'D main' cannot call system function 'object.byKey!(string[string], string, string).byKey.Result.popFront'
safeaa.d(17): Error: safe function 'D main' cannot call system function 'object.byKey!(string[string], string, string).byKey.Result.front'
safeaa.d(19): Error: safe function 'D main' cannot call system function 'object.values!(string[string], string, string).values'
safeaa.d(21): Error: safe function 'D main' cannot call system function 'object.byValue!(string[string], string, string).byValue'
safeaa.d(21): Error: safe function 'D main' cannot call system function 'object.byValue!(string[string], string, string).byValue.Result.empty'
safeaa.d(21): Error: safe function 'D main' cannot call system function 'object.byValue!(string[string], string, string).byValue.Result.popFront'
safeaa.d(21): Error: safe function 'D main' cannot call system function 'object.byValue!(string[string], string, string).byValue.Result.front'
I'm not sure why saa.length builds since _aaLen isn't marked @safe. Probably the compiler making assumptions that the code doesn't declare.
Comment #2 by dhasenan — 2016-03-23T01:03:19Z
I can simply make .keys and .values @trusted. Brad Roberts, is that acceptable?
These functions, being in druntime and applying to a widely used type, *should* be reliably safe, and there shouldn't be anything special you need to do, no precautions you need to take, to make them work safely.
Comment #3 by braddr — 2016-03-23T05:50:41Z
Not sure without looking at the implementation. There's a lot of delicate issues with lifetime of memory around the aa code.
Comment #4 by schveiguy — 2016-03-24T14:45:24Z
I'm unsure why these are not safe in the first place. I think we should be able to make them safe in both implementation and wrapper interface.
I'd like to see at least an attempt to make them safe in the implementation (even if we need to have @trusted wrappers for a few lines).
Comment #5 by dhasenan — 2016-03-26T17:06:32Z
After taking a closer look, AAs already allow you to violate @safety: opEquals and postblit are not required to be @safe, and toHash is only required to be @safe it opEquals is present. This allows you to call @system code from @safe code without a @trusted intermediary.
The `keys`, `values`, `byKey`, and `byValue` methods don't use opEquals or toHash but do use postblit. Making them @trusted would exacerbate the existing problem.
In the implementation in rt/aaA.d, everything uses RTTI to access opEquals, toHash, and postblit. This obscures the difference, so those methods can't ever be @safe and it's invalid to make them @trusted. (Unless we start requiring opEquals, toHash, and postblit to be @safe.)
The wrappers, being templates, can explicitly detect when the types involved can be used safely and mark themselves @trusted in that case.
Beyond that huge problem, there are a number of minor things that aaA.d does that aren't @safe but can be made @trusted. Much of the implementation can be brought closer to @safe standards.
@nordlow updated dlang/druntime pull request #3528 "Fix Issue 14439 - aa's keys, values not usable in @safe context " fixing this issue:
- Fix Issue 14439 - aa's keys, values not usable in @safe context
https://github.com/dlang/druntime/pull/3528
Comment #9 by dlang-bot — 2021-08-05T11:18:46Z
dlang/druntime pull request #3528 "Fix Issue 14439 - aa's keys, values not usable in @safe context " was merged into master:
- e970797b6d9f502d05b3ff6005188ad1f404daae by Per Nordlöw:
Fix Issue 14439 - aa's keys, values not usable in @safe context
https://github.com/dlang/druntime/pull/3528