April 15, 2023
On Saturday, 15 April 2023 at 12:45:31 UTC, Richard (Rikki) Andrew Cattermole wrote:
> It was bad analysis by the compiler, which has since been corrected.
>
> It should have been applied only to @safe code.

But why is the @unsafe programmer now left unprotected in cases like this

```
ref int foo (ref int i)
//           `------- automatically insert `return` here?
{
   return i;
}
```

where the compiler recognizes that the function returns a ref parameter?

Under which circumstances is it a mistake to insert the `return` at the indicated position? If there are none why can't it be done implicitly (automatically)?
April 16, 2023
On 16/04/2023 1:20 AM, kdevel wrote:
> On Saturday, 15 April 2023 at 12:45:31 UTC, Richard (Rikki) Andrew Cattermole wrote:
>> It was bad analysis by the compiler, which has since been corrected.
>>
>> It should have been applied only to @safe code.
> 
> But why is the @unsafe programmer now left unprotected in cases like this
> 
> ```
> ref int foo (ref int i)
> //           `------- automatically insert `return` here?
> {
>     return i;
> }
> ```
> 
> where the compiler recognizes that the function returns a ref parameter?
> 
> Under which circumstances is it a mistake to insert the `return` at the indicated position? If there are none why can't it be done implicitly (automatically)?

@system (which is currently the default, there is a strong desire to change this), does no safety checks.

You are on your own to do whatever unsafe thing you want.

If you want safety checks, use @safe.
April 15, 2023
On Saturday, 15 April 2023 at 13:24:52 UTC, Richard (Rikki) Andrew Cattermole wrote:
> On 16/04/2023 1:20 AM, kdevel wrote:
>> On Saturday, 15 April 2023 at 12:45:31 UTC, Richard (Rikki) Andrew Cattermole wrote:
>>> It was bad analysis by the compiler, which has since been corrected.
>>>
>>> It should have been applied only to @safe code.
>> 
>> But why is the @unsafe programmer now left unprotected in cases like this
>> 
>> ```
>> ref int foo (ref int i)
>> //           `------- automatically insert `return` here?
>> {
>>     return i;
>> }
>> ```
>> 
>> where the compiler recognizes that the function returns a ref parameter?
>> 
>> Under which circumstances is it a mistake to insert the `return` at the indicated position? If there are none why can't it be done implicitly (automatically)?
>
> @system (which is currently the default, there is a strong desire to change this), does no safety checks.

When I insert `return` before `ref int` and compile the code dmd says

```
returnref2.d(9): Error: returning `foo(i)` escapes a reference to local variable `i`
```

Isn't this a safety check? (The code does not contain any `@`.)

My question was if it is problematic if dmd inserted a `return` before any `ref` parameter a function returns.

Did the removed code which checked for returning ref parameters have false positives?

If not again my question: Under what circumstances would it be a mistake to insert `return` before the respective `ref` parameter?



April 15, 2023

On Saturday, 15 April 2023 at 13:20:09 UTC, kdevel wrote:

>

Under which circumstances is it a mistake to insert the return at the indicated position? If there are none why can't it be done implicitly (automatically)?

It could be done in the easy example you posted, but generalizing it is harder.

When importing a module, the compiler currently doesn't need to analyze function bodies to get the signature of regular (non-auto/template) functions, which would have to change. Programmers can also currently rely on the fact that the signature they see is the signature they get, but not any longer.

The identity function is really simple, but as soon as control flow (if-statements) come into play, the annotations and their inference become a conservative approximation, which might give false positives in @system code. There would need to be a second system, one which assumes the best instead of assuming the worst.

This adds complexity, just to add some 'intermediate' safety between @system and @safe in a few cases. It's better to keep the rules simple and consistent.

April 15, 2023

On Saturday, 15 April 2023 at 14:10:57 UTC, Dennis wrote:

>

This adds complexity, just to add some 'intermediate' safety between @system and @safe in a few cases. It's better to keep the rules simple and consistent.

To quote my past self:

>

There used to be different rules for lifetime errors in all of these:

  • explicit @system functions
  • @system by default functions (yes, they were special)
  • inferred functions
  • @safe functions
  • @trusted functions

It was really complex and confusing, and I've worked on simplifying it such that all lifetime errors are safety violations like any other. The only exception is directly returning a dangling pointer to a stack variable, which is just an error even in @system code (issue 19873). I don't want to go back to more special cases, especially with the dip1000 by default transition which is complex enough as is.

https://forum.dlang.org/post/nzotevvzvbpqscfxsuod@forum.dlang.org

April 15, 2023

On Saturday, 15 April 2023 at 14:10:57 UTC, Dennis wrote:

>

[...]
This adds complexity, just to add some 'intermediate' safety between @system and @safe in a few cases. It's better to keep the rules simple and consistent.

Thanks for the answer! While playing around with return ref I came across this:

string foo (string s, return ref int i)
{
   return s;
}

auto bar ()
{
   int i;
   string s;
   return foo (s, i);
}
$ dmd rr.d
rr.d(10): Error: returning `foo(s, i)` escapes a reference to local variable `i`

Does that make sense?

April 15, 2023

On Saturday, 15 April 2023 at 14:33:52 UTC, kdevel wrote:

>

Does that make sense?

Whether it makes sense is subjective, but it is by design. Escape analysis considers every pointer the same, it doesn't care about the type / mutability of the pointer. In @system / @trusted code, you could coerce i to become a string and return it:

string foo(string s, return ref int i)
{
   return (cast(immutable char*) &i)[0..4];
}
April 15, 2023

On Saturday, 15 April 2023 at 15:50:18 UTC, Dennis wrote:

>

[...]
care about the type / mutability of the pointer.

Returning i's address in a long does not trigger the escape detector:

long foo (long s, return ref int i)
{
   s = cast (long) &i;
   return s;
}

auto bar ()
{
   int i;
   long s;
   return foo (s, i);
}

dmd compiles this without complaints.

April 16, 2023

On Saturday, 15 April 2023 at 21:00:01 UTC, kdevel wrote:

>

On Saturday, 15 April 2023 at 15:50:18 UTC, Dennis wrote:

>

[...]
care about the type / mutability of the pointer.

Returning i's address in a long does not trigger the escape detector:

It doesn't care about the type of pointer, but it does care about whether the type is/has a pointer in the first place. T*, T[], K[V] (Associative arrays), class, function, delegate are pointers. Static arrays and structs depend on what they contain. Basic types such as long are not pointers, so lifetime checking doesn't apply.

1 2
Next ›   Last »