Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shadowing with-object members with local variables should be an error or warning #19464

Open
dlangBugzillaToGithub opened this issue Jul 23, 2018 · 0 comments

Comments

@dlangBugzillaToGithub
Copy link

JR reported this on 2018-07-23T11:37:18Z

Transferred from https://issues.dlang.org/show_bug.cgi?id=19113

Description

The with statement guards against accidentally shadowing local variables with variables inside the with-object.

> Use of with object symbols that shadow local symbols with the
> same identifier are not allowed. This is to reduce the risk of
> inadvertant breakage of with statements when new members are
> added to the object declaration.
https://dlang.org/spec/statement.html#WithStatement

---

struct S
{
    float x;
}

void main()
{
    int x;
    S s;
    with (s)
    {
        x++;  // error, shadows the int x declaration
    }
}

---

The inverse is not true, however, and a variable declared in the with scope will happily shadow variables in the with-object.

---

struct S
{
    float x;
}

void main()
{
    S s;
    with (s)
    {
        int x;  // no error yet clobbers s.x
    }
}

---

When you use with (x.y.z) you're trying to minimize having to type out repeated references to x.y.z.(member) for every member, and thus oftentimes while working on things in the context of x.y.z. This is weak to human mistakes of reusing contextual variable names, and becomes increasingly so as the type of the with-symbol gains members.

For example, use of with on instances of struct Room with a largely complete set of members north, east, south, west, will be very likely to accidentally shadow this way unless the programmer has actual knowledge of the issue and thus names locals thisNorth, myEast, south_ or similar.

A concrete example is in the IRC bot in [1], where I'm splitting up a string into its prefix and prefix/mode character components. I use with (parser.bot.server) to avoid having to type all that out, but I inadvertently reused the name "prefixes" (line 1881) for a local when I later intended the with statement to resolve it to parser.bot.server.prefixes[2]. This meant that changes to parser.bot.server.prefixes were silently lost to the local prefixes with no warning.

It is error-prone to allow locals-shadowing-withs, and I argue that it would be in the spirit of the existing restrictions to also restrict it this way. Code breakage would largely only occur where code was silently broken in the first place, and easily fixed by simple editor search and selective replace.

https://forum.dlang.org/post/lklxqhwrppbyvzznqney@forum.dlang.org

[1]: https://github.com/zorael/kameloso/blob/93002da193eac2dfbfeb6c8756feb2d74a345530/source/kameloso/irc.d#L1887
[2]: https://github.com/zorael/kameloso/blob/93002da193eac2dfbfeb6c8756feb2d74a345530/source/kameloso/ircdefs.d#L1046
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant