[Issue 22221] [dip1000] pure function can escape parameters through Exception
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Thu Feb 17 14:14:38 UTC 2022
https://issues.dlang.org/show_bug.cgi?id=22221
--- Comment #4 from Dennis <dkorpel at live.nl> ---
(In reply to Walter Bright from comment #3)
> Therefore, this fix will be both correct and break the least amount of code.
I'm not sure, what's left blocking the fix PR is 1 function in excel-D
(shouldEqual) and some Phobos unittests. It's unknown how much breakage results
from your proposal.
> For code that does break, the solution is to make a copy of the parameter,
> and throw the copy. This is workable since scope is not transitive.
How would you explain that special case to D users?
Let's consider the most obvious example:
```
void enforce(bool x, string msg) @safe pure
{
if (!x)
throw new Exception(msg);
}
```
The compiler will ask you to make a copy of the `msg` string for no good
reason. Now consider this variant that returns the first argument (like in
Phobos):
```
int* enforce(int* x, string msg) @safe pure
{
if (!x)
throw new Exception(msg);
return x;
}
```
Because the return value has a pointer now, `msg` will not infer `scope` from
`pure` anyway, so the compiler either:
- allows it, meaning that changing the return type causes a weird unrelated
error about throwing `msg`
- still give an error, meaning you have to make a copy of `msg`, and still
cannot assign a `scope` string to the parameter!
Finally, consider giving an auto return type:
```
auto enforce(bool x, string msg)
{
if (!x)
throw new Exception(msg);
}
```
How are the attributes inferred? Possibilities are:
- impure @system
- impure @safe
- pure @system
Will this pick the `@safe` one? What if I explicitly specify `pure`, will it
infer `@system` then?
This looks like a special case that has a ripple effect of complexity, I can't
see this being a good idea.
--
More information about the Digitalmars-d-bugs
mailing list