Thread overview
Why is three safety levels need in D?
Nov 17, 2016
Nordlöw
Nov 17, 2016
Stefan Koch
Nov 17, 2016
Nordlöw
Nov 17, 2016
Stefan Koch
Nov 17, 2016
Nordlöw
Nov 17, 2016
Stefan Koch
Nov 17, 2016
Jesse Phillips
Nov 17, 2016
Adam D. Ruppe
Nov 18, 2016
Kagamin
November 17, 2016
Why does D need both `@safe`, `@trusted` and `@system` when Rust seems to get by with only safe (default) and `unsafe`?

https://dlang.org/spec/memory-safe-d.html
http://dlang.org/safed.html
November 17, 2016
On Thursday, 17 November 2016 at 17:18:27 UTC, Nordlöw wrote:
> Why does D need both `@safe`, `@trusted` and `@system` when Rust seems to get by with only safe (default) and `unsafe`?
>
> https://dlang.org/spec/memory-safe-d.html
> http://dlang.org/safed.html

It allows encapsulating unsafe operations in safely-callable wrappers.
November 17, 2016
On Thursday, 17 November 2016 at 17:27:01 UTC, Stefan Koch wrote:
> It allows encapsulating unsafe operations in safely-callable wrappers.

So is this a limitation in Rust? If so, could you give a more concrete D code example that cannot be implemented with only two safety levels?
November 17, 2016
On Thursday, 17 November 2016 at 17:29:20 UTC, Nordlöw wrote:
> On Thursday, 17 November 2016 at 17:27:01 UTC, Stefan Koch wrote:
>> It allows encapsulating unsafe operations in safely-callable wrappers.
>
> So is this a limitation in Rust? If so, could you give a more concrete D code example that cannot be implemented with only two safety levels?

Try to implement a safe memory allocator with only two levels.

Memory is inherently unsafe. But it can be treated in a safe way.
A language that does not allow you to express a middle ground will have a lot of unsafe code that could arguably be seen as safe.
November 17, 2016
On Thursday, 17 November 2016 at 17:33:33 UTC, Stefan Koch wrote:
> Memory is inherently unsafe. But it can be treated in a safe way.
> A language that does not allow you to express a middle ground will have a lot of unsafe code that could arguably be seen as safe.

So in what way would, for instance, a Rust-implementation of D's `Mallocator` be different and more unsafe without `@trusted`?
November 17, 2016
On Thursday, 17 November 2016 at 17:47:21 UTC, Nordlöw wrote:
> On Thursday, 17 November 2016 at 17:33:33 UTC, Stefan Koch wrote:
>> Memory is inherently unsafe. But it can be treated in a safe way.
>> A language that does not allow you to express a middle ground will have a lot of unsafe code that could arguably be seen as safe.
>
> So in what way would, for instance, a Rust-implementation of D's `Mallocator` be different and more unsafe without `@trusted`?

It would be unsafe and all code that uses it would be unsafe as well.

November 17, 2016
On Thursday, 17 November 2016 at 17:18:27 UTC, Nordlöw wrote:
> Why does D need both `@safe`, `@trusted` and `@system` when Rust seems to get by with only safe (default) and `unsafe`?
>
> https://dlang.org/spec/memory-safe-d.html
> http://dlang.org/safed.html

D makes it illegal for @safe code to call @system code. I assume Rust gets by with only two levels because it does not create this restriction.

D doesn't allow @safe to call @system because @system code is intended to be marked as such because if you call it incorrectly it could cause memory corruption and sometimes the API should allow for that. D then requires a safe interface to the @system code to be wrapped with @trusted. The theory is that you can review @system code to check it isn't doing something completely wrong, and then you can check @trusted code to make sure it can't be called in such a way that it will call @system code and corrupt memory.

@system void setPointerValue(T)(T* a, T v) {
    *a = v;
}

@trusted void setArrayValue(T)(T[] a, T v, size_t index) {
    if(index > a.length || index < 0)
        return;

     setPointerValue(&a[index], v);
}

Completely pointless code, but reading the @trusted code we can see it performs the needed validation to prevent corrupting memory when calling setPointerValue.
November 17, 2016
On Thursday, 17 November 2016 at 17:18:27 UTC, Nordlöw wrote:
> Why does D need both `@safe`, `@trusted` and `@system` when Rust seems to get by with only safe (default) and `unsafe`?

I'm pretty sure the Rust `unsafe` just does both D's `@system` AND `@trusted`.

An unsafe function in Rust is like a D @system function.

But an unsafe *block* in Rust, as I understand it, behaves more like D's @trusted - it lets you call unsafe functions from inside a safe function.
November 18, 2016
On Thursday, 17 November 2016 at 17:18:27 UTC, Nordlöw wrote:
> Why does D need both `@safe`, `@trusted` and `@system` when Rust seems to get by with only safe (default) and `unsafe`?

Rust has 3 levels of safety: the code inside unsafe block is @system, and the unsafe block as a whole is a @trusted wrapper providing safe interface to be called by safe code. The rationale for function-level safety is better encapsulation: the function accesses only its parameters and nothing more, but unsafe block has access to all visible local variables of its function, not only those it works with. D supports Rust-style unsafe blocks with @trusted lambdas.