Bug 10253 – Switch and Final Switch do not work with subtyping

Status
NEW
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-06-03T07:00:42Z
Last change time
2024-12-13T18:07:29Z
Assigned to
No Owner
Creator
Andrej Mitrovic
Moved to GitHub: dmd#18596 →

Comments

Comment #0 by andrej.mitrovich — 2013-06-03T07:00:42Z
----- struct Wrapper(E) if (is(E == enum)) { E value; alias value this; } void main() { enum E { a, b } alias Wrapper!E WE; WE we; switch (we) // L14 { case WE.a: break; case WE.b: break; default: } final switch (we) // L21 { case WE.a: break; case WE.b: break; } } ----- test.d(14): Error: 'we' must be of integral or string type, it is a Wrapper!(E) test.d(16): Error: cannot implicitly convert expression (cast(E)0) of type E to Wrapper!(E) test.d(17): Error: cannot implicitly convert expression (cast(E)1) of type E to Wrapper!(E) test.d(21): Error: 'we' must be of integral or string type, it is a Wrapper!(E) test.d(23): Error: cannot implicitly convert expression (cast(E)0) of type E to Wrapper!(E) test.d(24): Error: cannot implicitly convert expression (cast(E)1) of type E to Wrapper!(E) The use-case is the ability to define an enum wrapper which disables default-initialization of the enum and requires explicit initialization, for example: ----- struct ExplicitEnum(E) if (is(E == enum)) { @disable this(); this(E e) { value = e; } E value; alias value this; } /// unittest { /** The library writer would typically disallow access to this enum so it can never be directly used in user-code. */ /* private */ enum MachineEnum { X86, X86_64, } // the fake enum type alias Machine = ExplicitEnum!MachineEnum; static assert(!__traits(compiles, { Machine machine; // compile-time error }())); Machine machine = Machine.X86; // ok } ----- The only missing puzzle piece is the ability to use a switch/final switch on such a wrapper type.
Comment #1 by andrej.mitrovich — 2013-06-03T07:06:49Z
Btw, if there is ever an ambiguity problem on whether to switch on the struct value or the 'alias this' value, then perhaps this feature should only be enabled if the struct has only one field which is the 'alias this' field? Think of it as an "eponymous struct" (maybe that's a bad terminology..).
Comment #2 by andrej.mitrovich — 2013-06-03T07:16:11Z
(In reply to comment #1) > Btw, if there is ever an ambiguity problem on whether to switch on the struct > value or the 'alias this' value, then perhaps this feature should only be > enabled if the struct has only one field which is the 'alias this' field? > > Think of it as an "eponymous struct" (maybe that's a bad terminology..). Forget this whole comment, I *thought* that switching on a struct was already possible. But it isn't, so there's no ambiguity here.
Comment #3 by bearophile_hugs — 2013-06-03T09:45:02Z
(In reply to comment #2) > I *thought* that switching on a struct was already > possible. But it isn't, so there's no ambiguity here. The enhancement request for structs in switches is Issue 596 (Issue 596 also asks for a standard method named unapply() that's called by the switch).
Comment #4 by andrej.mitrovich — 2013-06-03T10:05:54Z
(In reply to comment #3) > (In reply to comment #2) > > > I *thought* that switching on a struct was already > > possible. But it isn't, so there's no ambiguity here. > > The enhancement request for structs in switches is Issue 596 (Issue 596 also > asks for a standard method named unapply() that's called by the switch). I see. In that case the following would be an ambiguity: ----- enum E { a, b } struct S { int x; E e; alias e this; } auto s = S(0, E.a); switch (s) // switch on 's' value or 's.e' value? { } ----- In that case I propose the subtype switch would only work if the struct has only one member which is the alias this variable: ----- struct S { E e; alias e this; } auto s = S(E.a); switch (s) // ok: equivalent to switch on 's.e' { } -----
Comment #5 by robert.schadek — 2024-12-13T18:07:29Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18596 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB