https://issues.dlang.org/show_bug.cgi?id=21565

Paul Backus <snarwin+bugzi...@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |snarwin+bugzi...@gmail.com

--- Comment #2 from Paul Backus <snarwin+bugzi...@gmail.com> ---
> One might suggest that there is no harm in allowing mutating a scalar that
> overlaps with a pointer if the pointer cannot be accessed. But this is a
> naive view of code. Not all code is @safe, and if @trusted code cannot be
> reasoned about without also having to manually verify all @safe code, then 
> there is no point to @trusted code.

I think there are two possible interpretations here.

Background: @trusted code is permitted by the language spec to assume its
arguments are free from unsafe aliasing and unsafe values [1], so anything that
allows unsafe values or unsafe aliasing to be created in @safe code is a bug in
@safe, not in any particular piece of @trusted code.

The question is: should the value of `t` after `t.x = 5`, in comment 1's
example, be considered an unsafe value?

If we go by the definition in the spec, the answer is clearly "yes":

> A struct/union instance is safe when:
> 
> * the values of its accessible fields are safe, and
> * it does not introduce unsafe aliasing with unions.

The union type `T` overlaps an integer and a pointer, so *any* value of type
`T` is automatically unsafe.

It follows from this interpretation that we should not be allowed to use `T` in
@safe code *at all*, and that *any* @trusted function that receives an argument
of type `T` is allowed to cause undefined behavior, regardless of that
argument's value.

This is probably not the conclusion we wanted to end up at, so let's try again.

If we amend the spec as follows:

> A struct/union instance is safe when:
> 
> * the values of its accessible fields are safe, and
> * it does not introduce unsafe aliasing with unions **that is accessible
>   from @safe code**.

...then `t`'s value becomes safe, and we are allowed to use it in @safe and
@trusted code as long as we are careful not to let @safe code access `t.x` and
`t.y` at the same time.

I think this interpretation is much more useful, and almost certainly the
intended one, so I suggest that this is really a bug in the spec, not the
implementation.

[1] https://dlang.org/spec/function.html#safe-interfaces

--

Reply via email to