October 25, 2022

On Tuesday, 25 October 2022 at 14:14:00 UTC, Quirin Schroll wrote:

>

Asking curiously, wasn’t the function UB before, but the behavior changed?

Until very recently, the language spec [1] said that a scope parameter "must not escape", but was silent on whether the same rule applied to scope local variables (although it would be reasonable to infer that it did).

At some point between the release of DMD 2.100.2 and current master, the spec was updated to additionally state that returning a scope variable from a function is "disallowed" [2].

So, yes, I think the most reasonable interpretation is that this was always intended to be UB. But I am not confident that the average D user would have known for certain it was UB at the time DMD 2.100.2 was released.

[1] https://dlang.org/spec/function.html#scope-parameters
[2] https://dlang.org/spec/attribute.html#scope

October 26, 2022
On 10/24/2022 6:35 PM, Steven Schveighoffer wrote:
> In a `@trusted` function today, without dip1000, the above is perfectly reasonable and not invalid. Will dip1000 make it corrupt memory?

A very good question. Clearly, having code work when it is @safe, but cause memory corruption when it is marked @trusted, is the wrong solution. This should never happen. I'm not sure what the solution should be here.

October 26, 2022
On 26/10/2022 9:03 PM, Walter Bright wrote:
> On 10/24/2022 6:35 PM, Steven Schveighoffer wrote:
>> In a `@trusted` function today, without dip1000, the above is perfectly reasonable and not invalid. Will dip1000 make it corrupt memory?
> 
> A very good question. Clearly, having code work when it is @safe, but cause memory corruption when it is marked @trusted, is the wrong solution. This should never happen. I'm not sure what the solution should be here.

At the very least, if no solution can be determined this needs to be reverted before 2.101.0.

October 26, 2022
On Wednesday, 26 October 2022 at 08:37:36 UTC, rikki cattermole wrote:
> On 26/10/2022 9:03 PM, Walter Bright wrote:
>> A very good question. Clearly, having code work when it is @safe, but cause memory corruption when it is marked @trusted, is the wrong solution. This should never happen. I'm not sure what the solution should be here.
>
> At the very least, if no solution can be determined this needs to be reverted before 2.101.0.

There's nothing to revert that corrupts memory (without incorrectly writing scope), see Paul's reply.
October 26, 2022
On Wednesday, 26 October 2022 at 08:03:37 UTC, Walter Bright wrote:

> A very good question. Clearly, having code work when it is @safe, but cause memory corruption when it is marked @trusted, is the wrong solution. This should never happen. I'm not sure what the solution should be here.

Is not trusted code (note my little D experience so sorry if I am asking something relatively stupid) unsafe? I mean, @safe is safe, @trusted is ??, @system is you go your own.

- So what are the guarantees of @trusted compared to @system?


Also, as far as I understood from my limited D usage, only type[N] are static arrays on the stack and the rest are GC-allocated, by default, right?

So in the presence of scope, probably that should be a dynamically sized array that was to be "freed" by the GC and invalid at the end of the function.

I would assume a move can be done if the array is not static, independently of scope being there or not and an error if it is statically allocated, since the return type is type[] (without explicit size in the type).
October 26, 2022

On Wednesday, 26 October 2022 at 08:03:37 UTC, Walter Bright wrote:

>

On 10/24/2022 6:35 PM, Steven Schveighoffer wrote:

>

In a @trusted function today, without dip1000, the above is perfectly reasonable and not invalid. Will dip1000 make it corrupt memory?

A very good question. Clearly, having code work when it is @safe, but cause memory corruption when it is marked @trusted, is the wrong solution. This should never happen. I'm not sure what the solution should be here.

It's not quite exactly that. The code in question fails with @safe.

The problem is that Steven's @trusted code not only happens to work, but is defined behaviour without dip1000, yet undefined behaviour with -preview=dip1000.

My proposal: disable local variable scope inference for @system and @trusted code. This has the downside that it's difficult to test whether the implementation really turns the inference off. But unless we're ready to ditch scope inference altogether I can't come up with anything better.

October 26, 2022
On Wednesday, 26 October 2022 at 10:43:11 UTC, German Diago wrote:
> On Wednesday, 26 October 2022 at 08:03:37 UTC, Walter Bright wrote:
>
>> A very good question. Clearly, having code work when it is @safe, but cause memory corruption when it is marked @trusted, is the wrong solution. This should never happen. I'm not sure what the solution should be here.
>
> Is not trusted code (note my little D experience so sorry if I am asking something relatively stupid) unsafe? I mean, @safe is safe, @trusted is ??, @system is you go your own.

@safe: it's like a seat belt. You can take your children, who come to see their uncle at the weekend, by car with their seat belts.

@trusted: it's like an uncle who didn't crash with his tractor. You can take your children around the field with their uncles by tractor.

We trust the uncle, but even if he did not have an accident, this 2nd situation is not safe.

SDB@79
October 26, 2022

On 10/26/22 4:03 AM, Walter Bright wrote:

>

On 10/24/2022 6:35 PM, Steven Schveighoffer wrote:

>

In a @trusted function today, without dip1000, the above is perfectly reasonable and not invalid. Will dip1000 make it corrupt memory?

A very good question. Clearly, having code work when it is @safe, but cause memory corruption when it is marked @trusted, is the wrong solution. This should never happen. I'm not sure what the solution should be here.

I should be clear here -- the code does not compile in @safe code, but is perfectly reasonable as @trusted code.

What I don't want is the compiler taking actions based on scope inference that cause memory corruption.

I get that we can say "if it wouldn't compile in @safe, it's on you to make sure it doesn't corrupt memory as @trusted". But if the reason it's unsafe is not because of things you wrote, but because of compiler inference (as in this case), then the compiler should either not do the inference, or not hoist allocations to the stack based on that inference.

A philosophy/statement to that effect should be satisfactory. The last thing we want dip1000 to do is cause memory corruption.

-Steve

October 26, 2022

On 10/26/22 8:49 AM, Dukc wrote:

>

On Wednesday, 26 October 2022 at 08:03:37 UTC, Walter Bright wrote:

>

On 10/24/2022 6:35 PM, Steven Schveighoffer wrote:

>

In a @trusted function today, without dip1000, the above is perfectly reasonable and not invalid. Will dip1000 make it corrupt memory?

A very good question. Clearly, having code work when it is @safe, but cause memory corruption when it is marked @trusted, is the wrong solution. This should never happen. I'm not sure what the solution should be here.

It's not quite exactly that. The code in question fails with @safe.

The problem is that Steven's @trusted code not only happens to work, but is defined behaviour without dip1000, yet undefined behaviour with -preview=dip1000.

Yes, maybe. I don't know if it's UB, because I don't know the rules/philosophy.

>

My proposal: disable local variable scope inference for @system and @trusted code. This has the downside that it's difficult to test whether the implementation really turns the inference off. But unless we're ready to ditch scope inference altogether I can't come up with anything better.

This is a possibility. I don't know the consequences of this, especially for template code.

-Steve

October 26, 2022

On Wednesday, 26 October 2022 at 10:43:11 UTC, German Diago wrote:

>

Is not trusted code (note my little D experience so sorry if I am asking something relatively stupid) unsafe? I mean, @safe is safe, @trusted is ??, @system is you go your own.

  • So what are the guarantees of @trusted compared to @system?

A @safe function is guaranteed by the compiler to be memory safe to call from other @safe code with (almost) any possible arguments and under (almost) any circumstances.

A @trusted function is guaranteed by its author to be memory safe to call from other @safe code with (almost) any possible arguments and under (almost) any circumstances.

A @system function may require the caller to follow additional rules beyond those enforced by the compiler, even in @safe code, to maintain memory safety. Since the compiler does not know what these additional rules are and cannot enforce them automatically, calling @system functions directly from @safe code is forbidden.

Attribute Must check definition Must check each caller
@safe compiler compiler
@trusted programmer compiler
@system programmer programmer

Assume the function is implemented correctly, then try to figure out how to call the function from @safe code in a way that violates memory safety. If there is a way to do so, the function should be @system.

Otherwise, it should be @safe if that compiles, or @trusted if not.