Thread overview
[Issue 17578] Propagate the common qualifier of fields to the containing type
Jun 30, 2017
ZombineDev
Jun 30, 2017
Jonathan M Davis
Jul 01, 2017
ponce
Jul 01, 2017
timon.gehr@gmx.ch
Jul 01, 2017
timon.gehr@gmx.ch
Jul 01, 2017
timon.gehr@gmx.ch
Dec 17, 2022
Iain Buclaw
June 30, 2017
https://issues.dlang.org/show_bug.cgi?id=17578

ZombineDev <petar.p.kirov@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |petar.p.kirov@gmail.com

--
June 30, 2017
https://issues.dlang.org/show_bug.cgi?id=17578

Jonathan M Davis <issues.dlang@jmdavisProg.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |issues.dlang@jmdavisProg.co
                   |                            |m

--- Comment #1 from Jonathan M Davis <issues.dlang@jmdavisProg.com> ---
This seems reasonable, though I expect that it would be of limited usefulness. Certanily, I normally recommend to people that they not make any members in a struct const or immutable if they can help it, because it gets in the way of basic operations like copying and assignment (e.g. not being able to assign to a mutable struct is the sort of thing that causes confusion, but that's exactly what happens when you have a const member variable). So, I doubt that this change would affect much, but I see no conceptual reason why it would be a problem, and given that you've created this enhancement, I expect that you've found at least one use case where it makes sense.

--
July 01, 2017
https://issues.dlang.org/show_bug.cgi?id=17578

ponce <aliloko@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |aliloko@gmail.com

--- Comment #2 from ponce <aliloko@gmail.com> ---
Does this mean having shared field will turn the entire containing struct/class into shared itself? This would propagate to the whole application I fear.

--
July 01, 2017
https://issues.dlang.org/show_bug.cgi?id=17578

timon.gehr@gmx.ch changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |timon.gehr@gmx.ch

--- Comment #3 from timon.gehr@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.

--
July 01, 2017
https://issues.dlang.org/show_bug.cgi?id=17578

--- Comment #4 from timon.gehr@gmx.ch ---
Typo: (In reply to timon.gehr from comment #3)
> ...
> - 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).

Typo: should say shared(S) instead of shared S and shared(C).

--
July 01, 2017
https://issues.dlang.org/show_bug.cgi?id=17578

--- Comment #5 from timon.gehr@gmx.ch ---
(In reply to timon.gehr from comment #3)
> ...
> 
> shared class SharedWidget: IWidget{
>     SharedCounter c; // note: shared(SharedCounter)==SharedCounter

Stale comment. Actually shared(SharedCounter)!=SharedCounter but they convert
to each other.

--
July 01, 2017
https://issues.dlang.org/show_bug.cgi?id=17578

--- Comment #6 from Andrei Alexandrescu <andrei@erdani.com> ---
Love where this is going, thanks Timon!

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=17578

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P4

--
December 13
https://issues.dlang.org/show_bug.cgi?id=17578

--- Comment #7 from dlangBugzillaToGithub <robert.schadek@posteo.de> ---
THIS ISSUE HAS BEEN MOVED TO GITHUB

https://github.com/dlang/dmd/issues/17802

DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB

--