Thread overview
[Issue 8817] New: Symbols named init should be illegal
Oct 14, 2012
Jonathan M Davis
Oct 14, 2012
Jonathan M Davis
October 14, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8817

           Summary: Symbols named init should be illegal
           Product: D
           Version: unspecified
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: jmdavisProg@gmx.com


--- Comment #0 from Jonathan M Davis <jmdavisProg@gmx.com> 2012-10-14 00:04:46 PDT ---
The fact that the compiler currently allows any symbols to be named init just causes problems. For instance, take this program:

struct S
{
    int i = 2;

    this(int j)
    {
        assert(i == 2);
        i = j;
    }

    @property static init()
    {
        return S(5);
    }
}

void main()
{
    assert(S.init == S(2));
}


The assertion in main fails, while the assertion in the constructor succeeds. That means that it's failing to actually override the init property for S (which is good), but now the init property for S is inaccessible. This is dangerous and will break all kinds of code. This sort of thing should just be disallowed. It gains us nothing and just causes problems. Similarly, this code

struct S
{
    int i = 2;

    this(int j)
    {
        assert(i == 2);
        i = j;
    }

    @property S init()
    {
        return S(5);
    }
}

void main()
{
    assert(S.init == S(2));
}

results in this compilation error:

q.d(19): Error: need 'this' for init type @property S()

So, again, it makes it impossible to access the type's init property.

For some reason, TDPL (p. 275) specifically permits enums to declare min, max, and init properties, though it _does_ tell you that it's a bad idea to do so. So, if that's to be permitted, init would still have to be allowed there, but I'd strongly argue that that should be changed. And note that just like with structs, it causes weird issues:

enum MyEnum : int { a, b, c, init }

void main()
{
    MyEnum e;
    assert(e == MyEnum.a);
    assert(MyEnum.init == MyEnum.a);
}

The first assertion passes but the second fails, meaning that once again, you can't get at the init property of the type anymore. Sure, declaring init as the first value fixes that, but init would be the first value anyway if init weren't explicitly declared. See issue# 8816.

The only situation where explicitly declaring init might make some sense would be to @disable it, but the syntax for disabling init is @disable this(); and not anything directly involving init. You can try and declare

struct S
{
    int i;
    @disable static S init;
}

void main()
{
    S s;
}

but it compiles just fine.

At minimum, I would strongly argue that any and all symbols which could conflict with the actual init property for a type should be made illegal. There are a few cases where it may not cause problems (e.g. a local variable), but I'd argue that it would be cleaner to just disallow those as well. If need be, maybe init should become a keyword. Certainly, the current situation just permits bugs and the ability to declare symbols named init which conflict with the actual init property for a type needs to be eliminated.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 14, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8817


Alex Rønne Petersen <alex@lycus.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |alex@lycus.org


--- Comment #1 from Alex Rønne Petersen <alex@lycus.org> 2012-10-14 09:38:30 CEST ---
This actually happens to be a problem in druntime's TypeInfo classes because they have a property called init. A lot of code currently relies on that 'overload' of the init symbol.

https://github.com/D-Programming-Language/druntime/blob/master/src/object.di#L75

That comment has been there for eons. What do we do about it?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 14, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8817



--- Comment #2 from Jonathan M Davis <jmdavisProg@gmx.com> 2012-10-14 00:48:24 PDT ---
> That comment has been there for eons. What do we do about it?

Create a function with the correct name (whatever that is - initialize?) and mark the old one as scheduled for deprecation making sure that we put an appropriate note in the changelog (in red if we think that it's major enough - I don't know how much code really uses TypeInfo, let alone TypeInfo.init() though). Then we deprecate it. It'll probably have to stick around as deprecated for a while to help the transition, but after that, we remove it, and it won't cause an issues any longer.

Unfortunately, it wouldn't surprise me if there are plenty of types out there with an init function (std.file.DirEntry used to have one), but IMHO it's just fundamentally broken to allow that given how it conflicts with the actual init property. And I think that this is a case where it's worth breaking code if we have to (but that makes it that much more critical that we make the changes necessary for this sooner rather than later).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------