On Borrow Checking

Walter Bright newshound2 at digitalmars.com
Sat May 10 21:20:11 UTC 2025


1. `scope` is not part of the type. It is a storage class, not a type modifier. 
The only type modifiers are immutable, const, shared and inout. Those are 
pervasively handled throughout the compiler's dealings with types. Making a new 
pointer type would be a huge effort *in addition* to all the other work needed 
to make a borrow checker.

2. We have a lot of experience with transitive attributes. There's a lot of 
resistance to using them because of this. Just look at all the complaints about 
`nogc` being transitive. Personally, I find `const` being transitive as a 
serious impediment to using `const` in the dmd source code. One of the big 
problems is it doesn't work with the Visitor pattern. (There are a couple cases 
where `const` is just cast away, shame on me.)

3. I'm well aware that ideally @live would be sounder if it is transitive. I 
disagree with the notion that it is useless if it is not. I am 98% sure that if 
@live was made transitive, it would be instantly useless because nobody is going 
to be willing to make an existing program or library pass the borrow checker. 
(It took enormous effort for Rust to convince people they had to throw their 
existing code away and recode it from scratch to use the borrow checker.) Much 
of the existing code would have to be thrown out. Making a perfect borrow 
checker is the enemy of making a practical, useful one.

4. Making dip1000 transitive made it impractical to use in existing code.

5. dip1000 makes it an error to assign a scope pointer to multiple indirections 
(because scope isn't a type modifier).

6. When an @live function calls another function, a `scope` parameter is a 
borrow, and a non-scope parameter is an ownership transfer.

7. Compiling an @live function is slow because of the DFA. Making it transitive 
would make it apply to the whole program, which would then compile as slow as Rust.



More information about the Digitalmars-d mailing list