Bug 22663 – Module is not recognized inside an "if"

Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2022-01-10T08:21:00Z
Last change time
2022-01-17T11:49:26Z
Assigned to
No Owner
Creator
rempas

Comments

Comment #0 by rempas — 2022-01-10T08:21:00Z
I'm having a very very weird bug. So the main idea is that I have a module called "number_conv" which is inside a package called "enums". So we can imagine the file structure like that: > dub.sdl > source > | app.d > | conv.d // The actual file that does the calls to the enum from "number_conv" > | enums > | number_conv.d So the problem here is that I have defined an enum inside the "number_conv" module called "digit_count". When I try to use this enum, I'm calling it using the following syntax `number_conv.digit_count!`. This will work as expected except for one call that will not recognize "number_conv" and say that it is an unknown identifier. I have created the smallest possible files to represent the actual problem and tested them inside the "/tmp" directory. Here are the files File: test.d Code: ``` import enums.number_conv; enum is_same(alias value, T) = is(typeof(value) == T); enum is_signed(alias value) = is_same!(value, byte) || is_same!(value, short) || is_same!(value, int) || is_same!(value, long); enum is_unsigned(alias value) = is_same!(value, ubyte) || is_same!(value, ushort) || is_same!(value, uint) || is_same!(value, ulong); char* to_str(T)(T num, ubyte base = 10) { static if (is_unsigned!num) { ubyte i; static if (is_same!(num, ubyte)) { mixin(number_conv.digit_count!("4", "3", "9", "4")); } else static if (is_same!(num, ushort)) { mixin(number_conv.digit_count!("6", "5", "17", "7")); } else static if (is_same!(num, uint)) { mixin(number_conv.digit_count!("11", "9", "33", "12")); } else { mixin(number_conv.digit_count!("21", "17", "65", "23")); } return cast(char*)"0"; } else static if (is_signed!num) { if (num == 0) bool min_num = false; ubyte i; static if (is_same!(num, byte)) { mixin(number_conv.digit_count!("5", "4", "10", "5")); } else static if (is_same!(num, short)) { mixin(number_conv.digit_count!("7", "6", "18", "8")); } else static if (is_same!(num, int)) { mixin(number_conv.digit_count!("12", "10", "34", "13")); // If we remove "number_conv" here and just use "digit_count!", it will work } else { mixin(number_conv.digit_count!("21", "18", "66", "24")); } return cast(char*)"0"; } } extern (C) void main() { import core.stdc.stdio; printf("The number is %s", to_str(2737)); } ``` File: enums/number_conv.d Code: ``` module enums.number_conv; enum digit_count(string dec, string hex, string bin, string oct) = ` if (base == 10) i = ` ~ dec ~ `; else if (base == 16) i = ` ~ hex ~ `; else if (base == 2) i = ` ~ bin ~ `; else if (base == 8) i = ` ~ oct ~ `; `; ```
Comment #1 by razvan.nitu1305 — 2022-01-17T11:49:26Z
You cannot use `number_conv.digit_count` because this symbol technically does not exist in the compiler. You can either use `enums.number_conv.digit_count` or the shorter`digit_count` directly. This is a mistake on your side, the compiler is not doing anything wrong. The fact that only one occurrence errors while the rest do not can be explained by the fact that you are using compile time conditions. Basically, the other branches do not exist for the compiler because the conditions are not met. You will notice that the branch where the name fails is where the parameter is an int; that is because 2737 is viewed as an int by the compiler. If you instantiate the function with let's say a byte, then the error will be moved on that branch. As a conclusion, the compiler works as expected. You need to correctly use the identifiers. Closing as invalid.