www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Rikki's Borrow Checker

reply Walter Bright <newshound2 digitalmars.com> writes:
https://github.com/dlang/dmd/pull/23572

Give it a whirl, and let us know what you think!
Aug 27
next sibling parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 28/08/2026 8:35 AM, Walter Bright wrote:
 https://github.com/dlang/dmd/pull/23572
 
 Give it a whirl, and let us know what you think!
Thanks Walter for the merge! This unblocks my sumtypes and matching DIP/PR. It'll allow me to solve for the following program corruption: ```d st.match { (ref v) => st = ST.init, v }; ```
Aug 27
parent reply xoxorwr <xororwr gmail.com> writes:
On Thursday, 27 August 2026 at 20:49:32 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 On 28/08/2026 8:35 AM, Walter Bright wrote:
 https://github.com/dlang/dmd/pull/23572
 
 Give it a whirl, and let us know what you think!
Thanks Walter for the merge! This unblocks my sumtypes and matching DIP/PR. It'll allow me to solve for the following program corruption: ```d st.match { (ref v) => st = ST.init, v }; ```
`match` with lambda syntax onto sumtypes is more inconsistent clutter this language doesn't need. This will ruin D, yet again. Pattern matching on sumtypes belongs in `switch`, it's a type switch, not justification for closures.
Aug 29
next sibling parent reply Kapendev <alexandroskapretsos gmail.com> writes:
On Saturday, 29 August 2026 at 15:26:31 UTC, xoxorwr wrote:
 On Thursday, 27 August 2026 at 20:49:32 UTC, Richard (Rikki) 
 Andrew Cattermole wrote:
 On 28/08/2026 8:35 AM, Walter Bright wrote:
 https://github.com/dlang/dmd/pull/23572
 
 Give it a whirl, and let us know what you think!
Thanks Walter for the merge! This unblocks my sumtypes and matching DIP/PR. It'll allow me to solve for the following program corruption: ```d st.match { (ref v) => st = ST.init, v }; ```
`match` with lambda syntax onto sumtypes is more inconsistent clutter this language doesn't need. This will ruin D, yet again. Pattern matching on sumtypes belongs in `switch`, it's a type switch, not justification for closures.
Technically, almost everything in that snippet is already in D. ---
 Sometimes we make new friends along the way - monkyyy
Aug 29
next sibling parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 30/08/2026 3:46 PM, Kapendev wrote:
 Technically, almost everything in that snippet is already in D.
Yup. Expression . Identifier PunctationOpen Args..., PunctuationClose UFCS/method calls. Different punctuation, but overall pattern is already in grammar as part of unary expressions. Nothing new.
Aug 29
prev sibling parent reply xoxorwr <xororwr gmail.com> writes:
On Sunday, 30 August 2026 at 03:46:08 UTC, Kapendev wrote:
 On Saturday, 29 August 2026 at 15:26:31 UTC, xoxorwr wrote:
 On Thursday, 27 August 2026 at 20:49:32 UTC, Richard (Rikki) 
 Andrew Cattermole wrote:
 On 28/08/2026 8:35 AM, Walter Bright wrote:
 https://github.com/dlang/dmd/pull/23572
 
 Give it a whirl, and let us know what you think!
Thanks Walter for the merge! This unblocks my sumtypes and matching DIP/PR. It'll allow me to solve for the following program corruption: ```d st.match { (ref v) => st = ST.init, v }; ```
`match` with lambda syntax onto sumtypes is more inconsistent clutter this language doesn't need. This will ruin D, yet again. Pattern matching on sumtypes belongs in `switch`, it's a type switch, not justification for closures.
Technically, almost everything in that snippet is already in D. ---
 Sometimes we make new friends along the way - monkyyy
Precisely. If it can already be expressed cleanly as with existing D constructs, why bother making it a language feature to begin with? And if does become a language feature, it should integrate with `switch`, bnot introduce a second mechanism.
Aug 29
parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 30/08/2026 6:14 PM, xoxorwr wrote:
 Precisely. If it can already be expressed cleanly as with existing D 
 constructs, why bother making it a language feature to begin with? And 
 if does become a language feature, it should integrate with |switch|, 
 bnot introduce a second mechanism.
It cannot be expressed cleanly with existing D constructs. I.e. by-ref parameters in the handlers cannot be made safe. And all those extra function calls are not the cheapest thing, its overhead that can be eliminated.
Aug 29
parent xoxorwr <xororwr gmail.com> writes:
On Sunday, 30 August 2026 at 06:16:32 UTC, Richard (Rikki) Andrew 
Cattermole wrote:
 On 30/08/2026 6:14 PM, xoxorwr wrote:
 Precisely. If it can already be expressed cleanly as with 
 existing D constructs, why bother making it a language feature 
 to begin with? And if does become a language feature, it 
 should integrate with |switch|, bnot introduce a second 
 mechanism.
It cannot be expressed cleanly with existing D constructs. I.e. by-ref parameters in the handlers cannot be made safe. And all those extra function calls are not the cheapest thing, its overhead that can be eliminated.
Nothing stops that in switch itself, dmd just doesn't do it there yet. Fix it there. That's the whole problem with D, and a common frustration for new users, too many constructs doing the same job, none of them finished, none of them talking to each other.
Aug 30
prev sibling parent Meta <jared771 gmail.com> writes:
On Saturday, 29 August 2026 at 15:26:31 UTC, xoxorwr wrote:
 On Thursday, 27 August 2026 at 20:49:32 UTC, Richard (Rikki) 
 Andrew Cattermole wrote:
 On 28/08/2026 8:35 AM, Walter Bright wrote:
 https://github.com/dlang/dmd/pull/23572
 
 Give it a whirl, and let us know what you think!
Thanks Walter for the merge! This unblocks my sumtypes and matching DIP/PR. It'll allow me to solve for the following program corruption: ```d st.match { (ref v) => st = ST.init, v }; ```
`match` with lambda syntax onto sumtypes is more inconsistent clutter this language doesn't need. This will ruin D, yet again. Pattern matching on sumtypes belongs in `switch`, it's a type switch, not justification for closures.
I proposed an alternate model that includes switch expressions with Rust-like destructuring (not fully implemented but a good chunk works): https://github.com/dlang/dmd/pull/23744
Aug 29
prev sibling next sibling parent reply monkyyy <crazymonkyyy gmail.com> writes:
On Thursday, 27 August 2026 at 20:35:04 UTC, Walter Bright wrote:
 https://github.com/dlang/dmd/pull/23572

 Give it a whirl, and let us know what you think!
... Your merging ai generated borrow checkers but shipping a data structure was a bridge to far?
Aug 27
parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 28/08/2026 9:30 AM, monkyyy wrote:
 On Thursday, 27 August 2026 at 20:35:04 UTC, Walter Bright wrote:
 https://github.com/dlang/dmd/pull/23572

 Give it a whirl, and let us know what you think!
... Your merging ai generated borrow checkers but shipping a data structure was a bridge to far?
Lol, the borrow checker as a feature requires escape analysis. Escape analysis was a massive PR compared. That was all written by me without LLM assistance. The LLM solved a very hard problem, a many to many, which I was getting mentally blocked on. As for data structures, it'll be part of PhobosV3, thanks to DIP1000 dieing they are now unblocked. PhobosV2 is now basically at scope in terms of modules.
Aug 27
parent monkyyy <crazymonkyyy gmail.com> writes:
On Thursday, 27 August 2026 at 21:37:08 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 On 28/08/2026 9:30 AM, monkyyy wrote:
 On Thursday, 27 August 2026 at 20:35:04 UTC, Walter Bright 
 wrote:
 https://github.com/dlang/dmd/pull/23572

 Give it a whirl, and let us know what you think!
... Your merging ai generated borrow checkers but shipping a data structure was a bridge to far?
Lol, the borrow checker as a feature requires escape analysis. Escape analysis was a massive PR compared. That was all written by me without LLM assistance. The LLM solved a very hard problem, a many to many, which I was getting mentally blocked on. As for data structures, it'll be part of PhobosV3, thanks to DIP1000 dieing they are now unblocked. PhobosV2 is now basically at scope in terms of modules.
https://forum.dlang.org/post/uyjbqvfoxfzhzwsacqhq forum.dlang.org by all means, throw this formally specified, fancy, data structure at an ai to make it follow the phoboes anti-style
Aug 27
prev sibling parent reply Nick Treleaven <nick geany.org> writes:
On Thursday, 27 August 2026 at 20:35:04 UTC, Walter Bright wrote:
 https://github.com/dlang/dmd/pull/23572

 Give it a whirl, and let us know what you think!
Looks good so far, but there may be some issues. Using the Buffer struct from the [changelog item](https://dlang.org/changelog/pending.html#dmd.fastdfa.borrowchecker): ```d import std.stdio; void test() { Buffer s; int* c = s.get(); call(s, c); // error, owner of active borrow may be mutated borrow(c); // same error, but no owner is passed and parameter is scope s = s.init; // no error destroy(s); // no error writeln(*c); } void call(ref const Buffer, scope int*); // but Buffer is const! void borrow(scope int*); ``` Error also happens without `call`'s `ref` parameter.
Aug 29
parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 29/08/2026 9:21 PM, Nick Treleaven wrote:
      Buffer s;
      int* c = s.get();
      call(s, c); // error, owner of active borrow may be mutated
      borrow(c); // same error, but no owner is passed and parameter is 
 scope
These however should not.
      s = s.init; // no error
      destroy(s); // no error
They should error. ``` testdfa\startd.d(24): Error: Cannot mutate the owner of an active borrow s = s.init; // error ^ testdfa\startd.d(19): For variable `s` Buffer s; ^ testdfa\startd.d(20): Borrowed here int* c = s.get(); ^ testdfa\startd.d(25): Error: Cannot pass the owner of an active borrow to a function that may mutate it destroy(s); // error ^ testdfa\startd.d(25): Parameter `obj` must be const or immutable destroy(s); // error ^ testdfa\startd.d(20): Borrowed here int* c = s.get(); ^ ``` Thanks for finding these issues. I have gotten good progress today but now I'm tired so won't be PR'd today. https://github.com/rikkimax/dmd/tree/fastdfa-fix-borrowcheck There is still some regressions to deal with (original output does not match current): ``` ..\test\fail_compilation\fastdfa.d(1418): Error: Cannot pass the owner of an active borrow to a function that may mutate it ..\test\fail_compilation\fastdfa.d(1418): Parameter `p` must be const or immutable ..\test\fail_compilation\fastdfa.d(1417): Borrowed here ..\test\fail_compilation\fastdfa.d(1418): Error: Cannot mutate the owner of an active borrow ..\test\fail_compilation\fastdfa.d(1416): For variable `x` ..\test\fail_compilation\fastdfa.d(1417): Borrowed here fail_compilation/fastdfa.d(1425): Error: Cannot pass the owner of an active borrow to a function that may mutate it fail_compilation/fastdfa.d(1425): Parameter `p` must be const or immutable fail_compilation/fastdfa.d(1424): Borrowed here ..\test\fail_compilation\fastdfa.d(1441): Error: Cannot mutate the owner of an active borrow ..\test\fail_compilation\fastdfa.d(1439): For variable `s` ..\test\fail_compilation\fastdfa.d(1440): Borrowed here ..\test\fail_compilation\fastdfa.d(1441): Error: Cannot mutate the owner of an active borrow ..\test\fail_compilation\fastdfa.d(1439): For variable `s` ..\test\fail_compilation\fastdfa.d(1440): Borrowed here ```
Aug 29