Thread overview
DIP1014, DIP1000 and use-after-move bugs
Jul 11, 2019
Max Haughton
Jul 11, 2019
Paul Backus
Jul 11, 2019
Max Haughton
Jul 11, 2019
Paul Backus
Jul 11, 2019
Sebastiaan Koppe
July 11, 2019
I think "DIP1000"(i.e. whatever it becomes) should eventually disallow use after move.

This should probably be by default but allow tagging a move operator as safe to reuse.

I haven't got a clue where to start an implementation but I think this would be a good step once DIP1014 is implemented.
July 11, 2019
On Thursday, 11 July 2019 at 10:19:16 UTC, Max Haughton wrote:
> I think "DIP1000"(i.e. whatever it becomes) should eventually disallow use after move.
>
> This should probably be by default but allow tagging a move operator as safe to reuse.
>
> I haven't got a clue where to start an implementation but I think this would be a good step once DIP1014 is implemented.

I don't think this can be done without adding something like Rust's borrow checker to D.

Since D's `move` resets the moved-from object to its .init value, a use-after-move is just a logic error, not undefined behavior, so there's nothing un-@safe about it.
July 11, 2019
On Thursday, 11 July 2019 at 10:19:16 UTC, Max Haughton wrote:
> I think "DIP1000"(i.e. whatever it becomes) should eventually disallow use after move.
>
> This should probably be by default but allow tagging a move operator as safe to reuse.
>
> I haven't got a clue where to start an implementation but I think this would be a good step once DIP1014 is implemented.

I agree. Made a post earlier about it.

Just yesterday saw this: https://awesomekling.github.io/Catching-use-after-move-bugs-with-Clang-consumed-annotations/
July 11, 2019
On Thursday, 11 July 2019 at 13:33:03 UTC, Paul Backus wrote:
> On Thursday, 11 July 2019 at 10:19:16 UTC, Max Haughton wrote:
>> I think "DIP1000"(i.e. whatever it becomes) should eventually disallow use after move.
>>
>> This should probably be by default but allow tagging a move operator as safe to reuse.
>>
>> I haven't got a clue where to start an implementation but I think this would be a good step once DIP1014 is implemented.
>
> I don't think this can be done without adding something like Rust's borrow checker to D.
>
> Since D's `move` resets the moved-from object to its .init value, a use-after-move is just a logic error, not undefined behavior, so there's nothing un-@safe about it.

wrt a borrow checker, we already have lifetimes so an extremely basic borrow checker (if it could fit syntactically) would be interesting.


Move: Is that still the case after DIP1014, I.e. you can do arbitrary work in opPostMove... Right?

The system I propose is opt-in/out, i.e. avoidable either way, do you can choose to make it an error by tagging opPostMove. This could alleviate some fairly massive bugs that come with using move semantics by accidently reusing an invalid object.


July 11, 2019
On Thursday, 11 July 2019 at 19:01:47 UTC, Max Haughton wrote:
> Move: Is that still the case after DIP1014, I.e. you can do arbitrary work in opPostMove... Right?

Well, presumably opPostMove is run *before* the source is set to .init; it wouldn't make much sense otherwise.