Bug 14161 – UFCS call does not abide by scope

Status
RESOLVED
Resolution
INVALID
Severity
enhancement
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2015-02-10T03:59:00Z
Last change time
2015-02-10T16:45:22Z
Assigned to
nobody
Creator
alphaglosined

Comments

Comment #0 by alphaglosined — 2015-02-10T03:59:13Z
If global function declared as same name to a local function pointer, UFCS will call the global function. Discovered: http://forum.dlang.org/post/[email protected] > import std.stdio; > > void f(int a) { > writeln("it's a function! : ", a); > } > > void main() { > auto f = function (int a) {writeln("It's a variable! : ", a);}; > 5.f(); > f(5); > } > > Output: > > it's a function! : 5 > It's a variable! : 5
Comment #1 by ufm — 2015-02-10T04:11:15Z
Moreover. If the function is not defined (only pointer), I get this error: aa.d(5): Error: no property 'f' for type 'int' when try use 5.f();
Comment #2 by ketmar — 2015-02-10T11:38:27Z
not a bug. UFCS is designed to ignore local definitions. http://dlang.org/function.html#pseudo-member
Comment #3 by ufm — 2015-02-10T12:47:40Z
I think this code should generate warning as least.
Comment #4 by ketmar — 2015-02-10T12:57:04Z
please, open ER for it. this is definitely not a bug, so it shouldn't be opened as *bug* report, especially with the current subj. and then please close this as "notabug" again.
Comment #5 by schveiguy — 2015-02-10T15:13:27Z
Actually, don't open another enhancement request, it will be closed as invalid as well. The case you are trying to solve was already considered specifically inside the spec and described as invalid. Only module-level UFCS functions will be considered, and this is intentional.
Comment #6 by ketmar — 2015-02-10T15:21:49Z
Fyodor is not talking about "fixing" UFCS. what he talking about is issuing a warning when there is local declaration with the same name as global one, and global one was chosen by UFCS. here compiler should issue warning that "global 'f' chosen for UFCS instead of local one". yes, this is by spec, but sometimes people forgetting about this and expecting local call. the code compiles fine, but does wrong things, and this can be very puzzling. yet this is against the "D is only for smarts", so i don't think that such warning will be added. the standard answer to this is "use lint tool instead" — as for some other warnings that affects newcomers, who don't want to run lint each time. D is inherently hostile to newcomers.
Comment #7 by bearophile_hugs — 2015-02-10T15:40:30Z
(In reply to Ketmar Dark from comment #6) > here compiler should issue warning that "global 'f' chosen for UFCS instead > of local one". yes, this is by spec, but sometimes people forgetting about > this and expecting local call. This code prints "foo2" without warnings and errors: import std.stdio; void foo() { writeln("foo1"); } void main() { void foo() { writeln("foo2"); } foo(); } while this gives a shadowing error message: struct Foo { int x; } void main() { int x; Foo f; with (f) x++; } test.d(6): Error: with symbol test.Foo.x is shadowing local symbol test.main.x In theory this looks like the first case, where a local function (pointer) silently shadows a module-level function: import std.stdio; void foo(int a) { writeln("it's a function! : ", a); } void main() { auto foo = (int a) { writeln("It's a variable! : ", a); }; 5.foo(); foo(5); } But this behaviour looks a little surprising. So perhaps in this case specifc it's better to give a shadowing error (with a warning/deprecation phase first), to avoid ambiguity. Like with() when no actual ambiguity is present in the code, no error message should be generated.
Comment #8 by ketmar — 2015-02-10T15:50:18Z
i don't think that shadowing globals should always generate warning. i believe that it's enough to generate warning only when there is possible UFCS shadowing. so: import std.stdio; void foo(int a) { writeln("it's a function! : ", a); } void main() { auto foo = (int a) { writeln("It's a variable! : ", a); }; //5.foo(); foo(5); } no warning. but with uncommented `5.foo();` there should be a warning. shadowing global functions with locals is not a big deal in a good written code, but remembering that UFCS ignores locals and picks globals instead is something that should better be told by the compiler.
Comment #9 by schveiguy — 2015-02-10T16:37:24Z
(In reply to bearophile_hugs from comment #7) > But this behaviour looks a little surprising. So perhaps in this case > specifc it's better to give a shadowing error (with a warning/deprecation > phase first), to avoid ambiguity. Like with() when no actual ambiguity is > present in the code, no error message should be generated. Shadowing is only allowed on global scope. The reasons are simple: 1. You often have little control over what modules you import define. 2. You can use '.' to distinguish between your local symbol and the global one. (In reply to Ketmar Dark from comment #8) > i don't think that shadowing globals should always generate warning. i > believe that it's enough to generate warning only when there is possible > UFCS shadowing. I am not of the opinion that UFCS is so special we need to bend over backwards to make it work in all cases. The underlying request that must be implemented before we even consider adding a warning for a conflict is that you need to be able to use UFCS on function pointers or even nested or member functions. I don't think we should even do that, and without that, there isn't a point for a warning here. There is always the possibility to use normal function call syntax.
Comment #10 by ketmar — 2015-02-10T16:45:22Z
ah, the normal D attitude. "beginners sux!" (c) pascal/Cubic Team