On Borrow Checking
Richard (Rikki) Andrew Cattermole
richard at cattermole.co.nz
Sat May 10 04:40:18 UTC 2025
On 10/05/2025 4:21 PM, Walter Bright wrote:
> On 5/4/2025 3:49 PM, Richard (Rikki) Andrew Cattermole wrote:
>> On 05/05/2025 8:50 AM, Walter Bright wrote:
>>> The point of the borrow checker is to ensure there is exactly one
>>> point of origin for a pointer and exactly one point of termination
>>> for it.
>>
>> Hang on, that isn't the point of it at all.
>>
>> A borrow checker has got the _side effect_ of only having one entry
>> and exit point for an object.
>>
>> But the _objective_ is to loosen the restrictions that an _ownership
>> transfer system_ imposes on the type system whilst keeping its
>> guarantees.
>
> I don't see how that would be workable.
Okay that is interesting.
>> We do not have an ownership transfer system in D.
>
> Yes we do, in @live code. That's exactly what it does. A pointer
> assignment to another pointer transfers the ownership to the lvalue, and
> the rvalue becomes "dead".
That is an owner state in the DFA.
Ownership transfer system operates at the type qualifier level and
applies to a variable regardless of what function it is in.
See isolated from Midori, which was designed with D's type system in mind.
Currently people fake having one, by using a struct with a copy
constructor that resets the old value.
>> herefore we cannnot have a borrow checker.
>
> The implementation shows it works.
>
>
>> What we do have is a liveliness analysis with guaranteed modelability,
>> and we do have a use for that, @restrict.
>>
>> Enforcing @restrict could be an incredibly useful tool to those who do
>> data processing with simd, right now they are doing this by hand.
>
> Restricted pointers in C are guaranteed only by the user, the compiler
> does no checking.
>
> You cannot vet restricted pointers without a borrow checker.
Exactly, so what I've been thinking is tying @live to @restrict, which
would make it a very useful tool.
This is something it could shine at, given its current implementation
details.
----------------------------------------------------------------------
I want to go back to an earlier example I did elsewhere, where I have
this type qualifier ``unique``, that is for an ownership transfer system.
If you have an ownership transfer system without a borrow checker:
```d
void func(scope ref int*) {}
unique(int*) a = ...;
assert(a !is null);
unique(int*) b = a;
assert(a is null);
assert(b !is null);
func(b); // error
```
Very annoying, it is what we have today if we fake it with a struct,
except people will use alias this... and no more compiler error.
When you have both an ownership transfer system with a borrow checker:
```d
void func(scope ref int*) {}
unique(int*) a = ...;
assert(a !is null);
unique(int*) b = a;
assert(a is null);
assert(b !is null);
func(b); // ok
```
You may notice that unique may implicitly be removed in the type system.
It is not the type systems job to care about it being removed.
It is the job of the borrow checker to enforce the guarantee the origin
outliving the borrow.
This is what I mean by: "But the _objective_ is to loosen the
restrictions that an _ownership transfer system_ imposes on the type
system whilst keeping its guarantees."
In practice it just means that the type system doesn't need to solve a
problem that a DFA is going to later on.
More information about the Digitalmars-d
mailing list