[Issue 19113] New: Shadowing with-object members with local variables should be an error or warning
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Mon Jul 23 11:37:18 UTC 2018
https://issues.dlang.org/show_bug.cgi?id=19113
Issue ID: 19113
Summary: Shadowing with-object members with local variables
should be an error or warning
Product: D
Version: D2
Hardware: x86_64
OS: Linux
Status: NEW
Severity: enhancement
Priority: P1
Component: dmd
Assignee: nobody at puremagic.com
Reporter: zorael at gmail.com
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
--
More information about the Digitalmars-d-bugs
mailing list