June 12, 2021
On 11.06.21 05:12, Walter Bright wrote:
> Hence a simple solution:
> 
> Make move() @trusted.

You can't make `move` @trusted.

Consider a simplified `move`:

```d
void move(ref return scope int* source, ref scope int* target) @safe
{
    target = source; /* error */
}
```

An @trusted function must still obey the spec. The spec says that the value of `source` cannot be assigned to `target`. The compiler assumes that that holds. If you abuse @trusted to break that assumption, undefined behavior follows.

For example, you would allow the following:

```d
int* target;
void f() @safe
{
    int local;
    int* source = &local;
    move(source, target); /* uh-oh */
}
```

> Write an @safe alternative to move() with the parameters swapped.

If you could make `move` @trusted, there would be no need for an @safe alternative. @safe and @trusted are the same from the perspective of the caller (unless you apply @trusted incorrectly).
June 12, 2021

Just a question: How will DIP1000 work with custom pointer types?

As in, you don't want the lifetime of the pointer-object, but the pointed-to-object.

June 12, 2021

On Saturday, 12 June 2021 at 08:23:10 UTC, Ola Fosheim Grøstad wrote:

>

Just a question: How will DIP1000 work with custom pointer types?

As in, you don't want the lifetime of the pointer-object, but the pointed-to-object.

scope currently applies to the pointed-to-object. For structs, it is applied to each member that is a type with pointers. For struct Ptr {int* ptr;}, a scope Ptr is treated the same as a scope int*. For struct Handle { int handle; }, a scope Handle is treated like scope int (which gets its scope stripped away because it has no pointers).

June 12, 2021

On Saturday, 12 June 2021 at 18:12:34 UTC, Dennis wrote:

>

scope currently applies to the pointed-to-object. For structs, it is applied to each member that is a type with pointers. For struct Ptr {int* ptr;}, a scope Ptr is treated the same as a scope int*. For struct Handle { int handle; }, a scope Handle is treated like scope int (which gets its scope stripped away because it has no pointers).

Ok, I get it (?) So basically it works if one always transfer smart pointers by value. Although, something like a linked list would not work as it isn't transitive and there is no way to make it transitive? Or?

June 12, 2021

On Saturday, 12 June 2021 at 18:18:18 UTC, Ola Fosheim Grøstad wrote:

>

So basically it works if one always transfer smart pointers by value.

You can pass them by ref, which is like a non-null pointer with built-in scope. So if you have a ref scope int*, you actually have two layers of scope: both the pointer variable and the pointed-to-object have a restricted lifetime. You can't take the address of a ref scope int* though, since that would result in a double-scope int** which dip1000 can't express.

>

Although, something like a linked list would not work as it isn't transitive and there is no way to make it transitive? Or?

If you give public access to the Node* next member, then you can freely escape node.next.next indeed. If you encapsulate it and only allow accessing nodes through return scope member functions, then you can make a fully scope linked list with e.g. all the nodes allocated on the stack.

June 12, 2021

On Saturday, 12 June 2021 at 18:35:02 UTC, Dennis wrote:

>

If you give public access to the Node* next member, then you can freely escape node.next.next indeed. If you encapsulate it and only allow accessing nodes through return scope member functions, then you can make a fully scope linked list with e.g. all the nodes allocated on the stack.

There should be some way for an ADT to state that objects they produce have the same lifetime as themselves.

So if I had a linked list wrapper. And you call wrapper.find_node(…) then the wrapper object should be able to signal that the returned node has the same lifetime.

June 12, 2021

On Saturday, 12 June 2021 at 19:12:27 UTC, Ola Fosheim Grøstad wrote:

>

There should be some way for an ADT to state that objects they produce have the same lifetime as themselves.

So if I had a linked list wrapper. And you call wrapper.find_node(…) then the wrapper object should be able to signal that the returned node has the same lifetime.

That sounds like return scope, as long as you wrap the linked list by value and not by pointer.

June 12, 2021

On Saturday, 12 June 2021 at 22:23:45 UTC, Dennis wrote:

>

That sounds like return scope, as long as you wrap the linked list by value and not by pointer.

Ok, thanks! I guess I will have to implement a test case and see how it works out.

June 12, 2021
On 6/11/2021 3:27 AM, Dennis wrote:
> On Friday, 11 June 2021 at 03:12:29 UTC, Walter Bright wrote:
>> Hence a simple solution:
>>
>> Make move() @trusted.
> 
> I don't think that makes sense. `move` is `@safe` anyway for non-scope inputs, and for scope inputs you wouldn't want it to lie about its interface (pretending it's `scope` when it isn't). Also you don't want it to call a `@system` move constructor in `@safe` code.
> 
>> Write an @safe alternative to move() with the parameters swapped.
> 
> What would that alternative be called?
> 

Consider:

   a = b;

Naturally, it moves right to left. We already have a word for that in the library, "emplace".
June 12, 2021
On 6/12/2021 12:33 AM, ag0aep6g wrote:
> On 11.06.21 05:12, Walter Bright wrote:
>> Hence a simple solution:
>>
>> Make move() @trusted.
> 
> You can't make `move` @trusted.

You're right. @system then.


>> Write an @safe alternative to move() with the parameters swapped.
> If you could make `move` @trusted, there would be no need for an @safe alternative.

Right. But a compiler feature to support one function seems excessive.