Bug 17567 – make shared methods callable on unshared objects (and covariant)

Status
RESOLVED
Resolution
WONTFIX
Severity
enhancement
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2017-06-28T13:40:00Z
Last change time
2017-06-28T19:57:41Z
Assigned to
nobody
Creator
code

Comments

Comment #0 by code — 2017-06-28T13:40:42Z
cat > bug.d << CODE struct S { void func() shared {} } void bug() { S s; s.func; } dmd -c bug ---- bug.d(9): Error: shared method bug.S.func is not callable using a non-shared object ---- cat > bug2.d << CODE interface I { void func(); } class C : I { void func() shared {} } CODE dmd -c bug ---- bug.d(5): Error: class bug.C interface function 'void func()' is not implemented ---- Both of these use-cases should be supported. Shared on a methods guarantees thread-safety which is compatible with being used in an unshared manner. Therefor shared methods should be fully covariant to unshared methods. This does not touch shared as type qualifier, `shared(T)` means the type is shared between threads, and hence is obviously not convertible to `T`. Looks like this would be the first storage class where we'd support covariance and real overloading. While overloading, e.g. `nothrow` and non-`nothrow` methods is not an error, the compiler always prefers `nothrow`, `pure`, `@safe`, or `@nogc` methods. But overloading should prefer unshared methods over `shared` ones, e.g. because the methods might avoid using a mutex.
Comment #1 by andrei — 2017-06-28T14:06:15Z
This is not possible. Thanks Timon Gehr for explaining this to me. Consider: shared int* p; struct S { int x; void func() shared { p = &x; } } void bug() { auto p = new S; p.func; ++p.x; } At this point we have threads getting shared access to x, but the current thread believes x is unshared.
Comment #2 by code — 2017-06-28T14:23:11Z
(In reply to Andrei Alexandrescu from comment #1) > At this point we have threads getting shared access to x, but the current > thread believes x is unshared. It already seemed too simple to work out :). So this would only work with some inout flavor of shared which likely wouldn't be worth the trouble.
Comment #3 by bugzilla — 2017-06-28T19:57:41Z
(In reply to Martin Nowak from comment #2) > It already seemed too simple to work out :). We worked out the rules for implicit conversions (used for covariance/contravariance) back when we came up with const/shared/etc. It's best to derive these in isolation, and then apply them without needing to work it out again. (It's a lot like using the chain rule for derivatives. Derive the chain rule, prove it's correct, then just apply it as a given.) I've gone through the same process with scope conversions. I kept confusing myself until I finally sat down and worked up a chart with the rules, convinced myself that that was correct, and then just applied them without worrying about it.