| |
 | Posted by jmh530 in reply to Dukc | Permalink Reply |
|
jmh530 
| On Tuesday, 6 May 2025 at 20:12:18 UTC, Dukc wrote:
> On Tuesday, 6 May 2025 at 14:48:27 UTC, jmh530 wrote:
> It might be helpful to example where Rust's version of some code let's you prove something is safe with the borrow checker, but D's version doesn't.
You're right. Have a look at my post earlier on this thread:
> On Tuesday, 29 April 2025 at 17:12:41 UTC, Walter Bright wrote:
> So I implemented a borrow checker for D, and it is enabled by adding the @live annotation for a function, which turns on the borrow checker for that function. There are no syntax or semantic changes to the language, other than laying on a borrow checker.
There's a difference.
In Rust, as I understand it, if you have a function like
fn free(ptr: MyCustomPointer)
{ // ...
}
it is 100% safe to use. The compiler will not let you double-free or use after free, unless you use the unsafe block to do so.
But you can't have
@trusted void free(MyCustomPointer ptr)
{ // ...
}
in D because it would be unsafe to use from a non-@live function.
If we had a way to say that "this function can be called from @safe , if and only if it's usage is guarded with @live " then it would be equal to the Rust borrow checker.
Ah, I remember that. Thanks.
Just to be clear, the @trusted function you provide could be called by an @safe function, but your point is that it may actually be unsafe to do so. The real goal is to enable more code to actually be safe, not to just slap @trusted on things.
The examples in the @live spec don't reference @safe. But it does have an example of a non-@live release function that is called by an @live test function that prevents use after free.
I can think of a few different ways forward (by no means limited to just this)
- Do @safe inference on @live functions. I assume a body is needed on @live functions (Rust requires a body unless a trait or extern function, and extern is only allowed in unsafe code). So that might be good idea on its own merits.
That being said, it doesn't really help you if the @live function is calling an @system function. Also, @live functions can call non-@live functions (although for an @safe @live function all the functions called by it need to be @safe/@trusted too), so it wouldn't necessarily be a transitive inference all the way down (i.e. it hits the first unattributed function and becomes @system).
-
Enhance the @safe definition so that an @safe @live function can call an @system function so long as the function it calls abides by certain restrictions. Obviously, the spec would need to clearly state what the restrictions are. One limitation would be that to verify that a @system function abides by these restrictions would require having the function body.
-
Add a @safeiflive attribute such that the function is @safe if called by a @live function and @system otherwise. As above, the team would need to pin down exactly what is allowed. After all, why couldn't it just be marked @safe? What @safe restrictions could be relaxed if @live is being enforced. Would require some thought, I imagine, but probably useful to think about. The downside is that it's more attributes.
-
Add @trustediflive, similar to above such that it is @trusted if called by a @live function and @system otherwise. Let's the user make the decision, more flexible. I think @trustediflive is kind of in line with what you were suggesting.
|