Is @safe still a work-in-progress?

Steven Schveighoffer schveiguy at gmail.com
Thu Aug 23 13:32:51 UTC 2018


On 8/23/18 4:58 AM, Walter Bright wrote:
> On 8/22/2018 6:50 AM, Steven Schveighoffer wrote:
>> What about:
>>
>> size_t put(sink, parameters...)
>>
>> Does this qualify as the sink being the "return" type? Obviously the 
>> real return can't contain any references, so it trivially can be ruled 
>> out as the destination of any escaping parameters.
> 
> Your reasoning is correct, but currently it only applies with 'void' 
> return types.
> 
> 
>> Or how about a member function that takes a ref parameter? Is `this` 
>> the "return" or is the ref parameter the "return"?
> 
> `this` is the ref parameter. In particular, consider a constructor:
> 
>    struct S {
>       int* p;
>       this(return scope int* p) { this.p = p; }
>    }
> 
>    int i;
>    S s = S(&i);
> 
> This code appears in Phobos, and it is very reasonable to expect it to 
> check as safe.

What I mean to say is, we have a semantic today -- the return value is 
hooked to any `return` parameters, end of story. This is clear, concise, 
and easy to understand.

You are saying that in some cases, the return value is actually 
deposited in the `this` parameter. In cases where the actual return type 
is void, OK, I see that we can tack on that rule without issues.

Furthermore any member function (or UFCS function for that matter) 
REQUIRES the first parameter to be the aggregate. How do you make a 
member function that stuffs the return into a different parameter 
properly typecheck? What rule do we tack on then? It's going to be 
confusing to anyone who writes their API thinking about how it's call 
syntax reads, not how the compiler wants to do flow analysis.

Not to mention, the keyword is `return`, not `returnorfirstparam`. It's 
still going to be confusing no matter how you look at it.

>> My problem with the idea is that it is going to seem flaky -- we are 
>> using convention to dictate what is actually the return parameter, vs. 
>> what semantically happens inside the function. It's going to confuse 
>> anyone trying to do it a different way. I've experienced this in the 
>> past with things like toHash, where if you didn't define it with the 
>> exact signature, it wouldn't actually be used.
>>
>> I realize obviously, that `put` is already specified. But as I said in 
>> the bug report, we should think twice about defining rules based 
>> solely on how Phobos does things, and calling that the solution.
> 
> Phobos doesn't do this by accident. It's how constructors work (see 
> above) and how pipeline programming works.

Constructors I agree are reasonable to consider `this` to be the return 
value. On that point, I would say we should definitely go ahead with 
making that rule, and I think it will lead to no confusion whatsoever.

pipeline programming depends on returning something other than `void`, 
so I don't see how this applies.

It's more when you are setting members via properties where this comes 
into play. We need it -- we need this ability to tell the compiler "this 
parameter connects to this other parameter". I just don't know if the 
proposed rules are a) good enough for the general case, and b) don't 
cause more confusion than they are worth.

>> As for things being made "more flexible in the future" this basically 
>> translates to code breakage. For example, if you are depending on only 
>> the first parameter being considered the "return" value, and all of a 
>> sudden it changes to encompass all your parameters, your existing code 
>> may fail to compile, even if it's correctly safe and properly annotated.
> 
> It's a good point. But I don't see an obvious use case for considering 
> all the ref parameters as being returns.

You would have to consider the shortest liftetime and assume everything 
goes there. It would restrict your legitimate calls. Only mitigating 
factor may be if you take the ones you aren't going to modify as const 
or inout.

>> > I want to ensure Atila is successful with this. But that means 
>> Phobos has to
>>> compile with dip1000. So I need to make it work.
>>>
>>
>> I think it's a very worthy goal to make Phobos work, and a great proof 
>> of concept for dip1000's veracity.
>>
>> However, one-off rules just to make it work with existing code go 
>> against that goal IMO. Rules that stand on their own I think will fare 
>> better than ones that are loopholes to allow existing code to compile.
> 
> I couldn't come up with a better idea than this, and this one works.
> 

I want to stress that it may be a valid solution, but we should strive 
to prove the solutions are the best possible rather than just use 
duct-tape methodology.

It should even be considered that perhaps there are better solutions 
even than the approach dip1000 has taken.

I also want to point out that the attitude of 'we could just fix it, but 
nobody will pull my request' is unhelpful. We want to make sure we have 
the best solution possible, don't take criticism as meaningless petty 
bickering. People are genuinely trying to make sure D is improved. 
Hostility towards reviews or debate doesn't foster that.

-Steve


More information about the Digitalmars-d mailing list