On 07/17/2018 03:03 PM, aliak00 wrote:
Can you explain a bit more here? How does having implicit as a compiler recognized UDA avoid breaking changes as opposed to it being implemented like @nogc/@safe (how are those implemented differently anyway?)

In a UDA `@implicit`, `implicit` is just a normal symbol. So the normal lookup rules apply. In particular, you can shadow an imported `implicit` with a local one:

    --- object.d
    enum implicit = 1; /* Actual implementation would be different. */

    --- bar.d
    /* invisible default `import object` here */
    @implicit void f() {}
    static assert(__traits(getAttributes, f)[0] == 1);
        /* Passes. `object.implicit` is used. */

    --- baz.d
    /* invisible default `import object` here */
    enum implicit = 2;
    @implicit void f() {}
    static assert(__traits(getAttributes, f)[0] == 2);
        /* Passes. The local `implicit` is used. */

You can't do that with `@safe`, because `@safe` is not a UDA, and `safe` is not a symbol there. `@safe` is special syntax, recognized as a whole by the parser. No symbol lookup is happening.

You can see the difference if you change all occurrences of "implicit" to "safe" in that code. Won't work.

As for breakage, baz.d is working code today. With `@implicit` as a UDA, it keeps working in the same way. With `@implicit` as a new non-UDA attribute, it will change its meaning, and the assert will fail.

Reply via email to