[Issue 17578] Propagate the common qualifier of fields to the containing type
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Sat Jul 1 13:25:57 PDT 2017
https://issues.dlang.org/show_bug.cgi?id=17578
timon.gehr at gmx.ch changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |timon.gehr at gmx.ch
--- Comment #3 from timon.gehr at gmx.ch ---
Refined design from discussion with Walter and Andrei (whenever I say 'shared',
the same applies for the other qualifiers):
Rationale:
- Implicitly changing semantics based on (possibly private) field types breaks
encapsulation: adding an unshared private member can break client code. This is
bad.
- There is already the possibility to declare a struct or class as shared,
which currently just makes all of its members shared. For such types, it is
documented on the outside that all members are shared, so it is fair game to
change behaviour based on those external qualifiers.
Proposal:
- For a shared struct S, S and shared S should be the same type. This type
behaves the same as the current type shared(C). For a shared class C, C and
shared(C) should be different but interconvertible types (reflecting the
difference between shared(T)* and shared(T*)). Methods of a shared class C
(which are shared methods) can be called on receivers of type C in addition to
receivers of type shared(C). Methods of a shared class can override/implement
unshared methods of the parent class/interfaces. If both shared and unshared
overloads are present in the parent class/interfaces, it overrides/implements
/both/ of them.
abstract class ICounter{
abstract int get();
abstract void increment();
}
shared class SharedCounter: ICounter{
int x; // shared
int get(){ // shared, but implements unshared method
return x;
}
void increment(){
atomicIncrement(x);
}
}
class UnsharedCounter: ICounter{
int x;
int get(){
return x;
}
void increment(){
x++;
}
}
interface IWidget{
ICounter getCounter();
}
shared class SharedWidget: IWidget{
SharedCounter c; // note: shared(SharedCounter)==SharedCounter
SharedCounter getCounter(){
return c;
}
}
class UnsharedWidget: IWidget{
UnsharedCounter c;
UnsharedCounter getCounter(){
return c;
}
}
- Justification of soundness: Because all members of a shared class C are
shared, conversion between C and shared(C) is sound (this is like conversion
between shared(T)* and shared(T*).) In particular, it is sound for shared
methods of C to override/implement unshared methods, because this just amounts
to a conversion C->shared(C) when the parent method is called.
--
More information about the Digitalmars-d-bugs
mailing list