misplaced @trust?

Zach the Mystic via Digitalmars-d digitalmars-d at puremagic.com
Thu Feb 5 10:12:09 PST 2015


On Thursday, 5 February 2015 at 16:50:18 UTC, Steven 
Schveighoffer wrote:
> Reading the thread in bug report 
> https://issues.dlang.org/show_bug.cgi?id=14125 gets me 
> thinking, perhaps @trusted is mis-designed.
>
> At the moment, a @trusted function is the same as a @system 
> function, but is allowed to be called from a @safe function. 
> And that's it.
>
> But a @trusted function may only need to be marked @trusted 
> because of a few lines of code. So we now use this mechanism 
> where we mark the @trusted portions with a lambda or static 
> nested function, and call that internally, and mark the entire 
> function @safe.
>
> The benefit of this is, for the 90% of the code that is @safe, 
> the compiler is used as a tool to check the @safe-ty of the 
> function. For the 10% that isn't, we have contained it and 
> marked it, and we can focus on that portion for scrutiny. This 
> becomes EXTREMELY important when it comes to maintenance.
>
> For example, if a @trusted function has some code added to it, 
> the new code needs to be measured to see if it really is safe 
> to call from a @safe function. This may be no easy feat.
>
> At least with the @trusted inner function/lambda, you limit 
> yourself to the code that has been marked as such, and you 
> don't need to worry about the actual @safe code that is added 
> to the function.
>
> Or do you?... the problem with this mentality is interactions 
> with data inside the @safe code after a @trusted function is 
> called can still be subject to memory safety issues. An example 
> (using static functions for clarity):
>
> void foo() @safe
> {
>    static auto tmalloc(size_t x) @trusted {return (cast(int 
> *)malloc(x * sizeof(int)))[0..x];}
>    static void tfree(void[] arr) @trusted {free(arr.ptr);}
>
>    auto mem = tmalloc(100);
>    tfree(mem);
>    mem[0] = 5;
> }
>
> Note that the final line in the function, setting mem[0] to 5, 
> is the only unsafe part. it's safe to malloc, it's safe to free 
> as long as you don't ever refer to that memory again.
>
> But the problem with the above is that @trusted is not needed 
> to apply to the mem[0] = 5 call. And imagine that the mem[0] = 
> 5 function may be simply added, by another person who didn't 
> understand the context. Marking the whole function as safe is 
> kind of meaningless here.
>
> Changing gears, one of the issues raised in the aforementioned 
> bug is that a function like this really should be marked 
> trusted in its entirety. But what does this actually mean?
>
> When we mark a function @safe, we can assume that the compiler 
> has checked it for us. When we mark a function @trusted, we can 
> assume the compiler has NOT checked it for us. But how does 
> this help? A @safe function can call a @trusted function. So 
> there is little difference between a @safe and a @trusted 
> function from an API point of view. I would contend that 
> @trusted really should NEVER HAVE BEEN a function attribute. 
> You may as well call them all @safe, there is no difference.
>
> What I think we need to approach this correctly is that instead 
> of marking *functions* with @trusted, we need to mark *data* 
> and *calls* with @trusted. Once data is used inside a @trusted 
> island, it becomes tainted with the @trusted mark. The compiler 
> can no longer guarantee safety for that data.
>
> So how can we implement this without too much pain? I envision 
> that we can mark lines or blocks inside a @safe function as 
> @trusted (a @trusted block inside a @system function would be a 
> no-op, but allowed). I also envision that any variable used 
> inside the function is internally marked as @safe until it's 
> used in a @trusted block, and then is marked as @trusted (again 
> internally, no requirement to mark in syntax). If at any time 
> during compilation a @trusted variable is used in @safe code, 
> it's a compile error.
>
> There may be situations in which you DO need this to work, and 
> in those cases, I would say a cast(@safe) could get rid of that 
> mark. For example, if you want to return the result of a 
> @trusted call in a @safe function.
>
> Such a change would be somewhat disruptive, but much more in 
> line with what @trusted calls really mean.
>
> I've left some of the details fuzzy on purpose, because I'm not 
> a compiler writer :)
>
> Destroy
>
> -Steve

Hey I like the creativity you're showing. Just to give people a 
concrete idea, you might show some sample code and illustrate how 
things work. It sure helps when I'm trying to think about things.


More information about the Digitalmars-d mailing list