Comment #0 by john.loughran.colvin — 2015-09-25T10:24:42Z
v1:
===
import std.math;
auto sin(float x) { return .sin(x); }
void main() { auto a = sin(3.4f); }
hijack.d(3): Error: forward reference to inferred return type of function call module hijack.sin(x)
v2:
===
import std.math;
auto sin(float x) { return std.math.sin(x); }
void main() { auto a = sin(3.4f); }
No errors
v3:
===
import std.math : sin;
auto sin(float x) { return std.math.sin(x); }
void main() { auto a = sin(3.4f); }
hijack.d(3): Error: undefined identifier 'std'
v4:
===
import std.math : sin;
auto sin(float x) { return .sin(x); }
void main() { auto a = sin(3.4f); }
hijack.d(3): Error: hijack.sin called with argument types (float) matches both:
/usr/local/Cellar/dmd/2.068.2/include/d2/std/math.d(664): std.math.sin(float x)
and:
hijack.d(3): hijack.sin(float x)
v5:
===
import std.math;
import std.math : sin;
auto sin(float x) { return std.math.sin(x); }
void main() { auto a = sin(3.4f); }
hijack.d(6): Error: hijack.sin called with argument types (float) matches both:
/usr/local/Cellar/dmd/2.068.2/include/d2/std/math.d(664): std.math.sin(float x)
and:
hijack.d(4): hijack.sin(float x)
Comparing v2 and v3:
Why does using a selective import prevent use of the fully qualified name?
Comparing v1 and v4:
Why does using a selective import completely change the error message?
comparing v2 and v5:
Why does adding a selective import trigger a conflict? Why is there not a conflict in v2?
It seems like either I am totally misunderstanding things or some of these are bugs.
Comment #1 by john.loughran.colvin — 2015-09-25T10:25:36Z
Comment #2 by razvan.nitu1305 — 2022-10-13T07:19:03Z
All the behavior exhibited here is according to the spec.
v1: The global import introduces the namespace of std.math, however, module symbols have precedence over that. Unfortunately, the dot (.) notation does not help you here since it simply instructs the compiler to search for the symbol at module scope. So it does and it finds the user defined sin and concludes that you are having a forward reference problem and cannot deduce the type. Expected behvior.
v2: By using the FQN you instruct the compiler to look in std.math and that solves the issue.
v3: Selective imports are translated behind the scenes to an alias declaration, i.e. alias sin = std.math.sin. This introduces the std.math.sin in the overload set of the the sin in the current module. However, the fully qualified name is not introduced in the namespace.
v4: std.math.sin and sin are now in the same overload set so naturally you get a conflict.
v5: same as v4. The fact that there is an extra `import std.math` simply instructs the compiler that the `std.math` symbol is visibile, but std.math.sin and sin are still in the same overload set.
This all is expected behavior and changing any of the above behavior will most likely cause lots of breakages.
I'm closing this as INVALID.