nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.47k stars 1.47k forks source link

[Regression] compiler is not inferring the type of an `enum` marked with the `pure` pragma when there is a type with the same identifier as a value of this enum #23689

Closed rockcavera closed 1 month ago

rockcavera commented 3 months ago

Description

Until recently the compiler was able to correctly infer the code below, however, in the current devel the compiler reports an error

type
  MyEnum {.pure.} = enum
    A, B, C, D

  B = object
    field: int

let x: MyEnum = B # the type is explicit as `MyEnum`, therefore `B` should be inferred as `MyEnum.B`

echo typeof(x)

let y = MyEnum.A

if y in {A, B}: # `B` should be inferred as `MyEnum.B`, as `A` can only be `MyEnum.A`
  echo true

Nim Version

Nim Compiler Version 2.1.1 [Windows: amd64] Compiled at 2024-06-06 Copyright (c) 2006-2024 by Andreas Rumpf

git hash: 8f5ae28fab113c425d22e5abc230f456fa627744 active boot switches: -d:release

Current Output

nim r bug
Hint: used config file 'E:\Nim\config\nim.cfg' [Conf]
Hint: used config file 'E:\Nim\config\config.nims' [Conf]
.......................................................................
C:\Users\josep\desktop\bug.nim(8, 17) Error: type mismatch: got 'typedesc[B]' for 'B' but expected 'MyEnum = enum'

Expected Output

MyEnum
true

Possible Solution

No response

Additional Information

compiles correctly in version 2.0.4 and with 1.6.20

juancarlospaco commented 3 months ago

!nim c

type
  MyEnum {.pure.} = enum
    A, B, C, D

  B = object
    field: int

let x: MyEnum = B # the type is explicit as `MyEnum`, therefore `B` should be inferred as `MyEnum.B`

echo typeof(x)

let y = MyEnum.A

if y in {A, B}: # `B` should be inferred as `MyEnum.B`, as `A` can only be `MyEnum.A`
  echo true
github-actions[bot] commented 3 months ago
:penguin: Linux bisect by @juancarlospaco (collaborator)
devel :-1: FAIL

Output

``` Error: Command failed: nim c --run -d:nimDebug -d:nimDebugDlOpen -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --verbosity:0 --hints:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim /home/runner/work/Nim/Nim/temp.nim(6, 17) Error: type mismatch: got 'typedesc[B]' for 'B' but expected 'MyEnum = enum' assertions.nim(34) raiseAssert Error: unhandled exception: errGenerated [AssertionDefect] ```

IR

Compiled filesize 0 bytes (0 bytes) ```cpp ```

Stats

  • Started 2024-06-06T22:40:40
  • Finished 2024-06-06T22:40:40
  • Duration

AST

```nim nnkStmtList.newTree( nnkTypeSection.newTree( nnkTypeDef.newTree( nnkPragmaExpr.newTree( newIdentNode("MyEnum"), nnkPragma.newTree( newIdentNode("pure") ) ), newEmptyNode(), nnkEnumTy.newTree( newEmptyNode(), newIdentNode("A"), newIdentNode("B"), newIdentNode("C"), newIdentNode("D") ) ), nnkTypeDef.newTree( newIdentNode("B"), newEmptyNode(), nnkObjectTy.newTree( newEmptyNode(), newEmptyNode(), nnkRecList.newTree( nnkIdentDefs.newTree( newIdentNode("field"), newIdentNode("int"), newEmptyNode() ) ) ) ) ), nnkLetSection.newTree( nnkIdentDefs.newTree( newIdentNode("x"), newIdentNode("MyEnum"), newIdentNode("B") ) ), nnkCommand.newTree( newIdentNode("echo"), nnkCall.newTree( newIdentNode("typeof"), newIdentNode("x") ) ), nnkLetSection.newTree( nnkIdentDefs.newTree( newIdentNode("y"), newEmptyNode(), nnkDotExpr.newTree( newIdentNode("MyEnum"), newIdentNode("A") ) ) ), nnkIfStmt.newTree( nnkElifBranch.newTree( nnkInfix.newTree( newIdentNode("in"), newIdentNode("y"), nnkCurly.newTree( newIdentNode("A"), newIdentNode("B") ) ), nnkStmtList.newTree( nnkCommand.newTree( newIdentNode("echo"), newIdentNode("true") ) ) ) ) ) ```
stable :+1: OK

Output

``` MyEnum true ```

IR

Compiled filesize 91.14 Kb (93,328 bytes) ```cpp #define NIM_INTBITS 64 #include "nimbase.h" #define nimfr_(proc, file) \ TFrame FR_; \ FR_.procname = proc; FR_.filename = file; FR_.line = 0; FR_.len = 0; nimFrame(&FR_); #define nimfrs_(proc, file, slots, length) \ struct {TFrame* prev;NCSTRING procname;NI line;NCSTRING filename;NI len;VarSlot s[slots];} FR_; \ FR_.procname = proc; FR_.filename = file; FR_.line = 0; FR_.len = length; nimFrame((TFrame*)&FR_); #define nimln_(n) \ FR_.line = n; #define nimlf_(n, file) \ FR_.line = n; FR_.filename = file; typedef struct NimStrPayload NimStrPayload; typedef struct NimStringV2 NimStringV2; typedef NU8 tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA; struct NimStrPayload { NI cap; NIM_CHAR data[SEQ_DECL_SIZE]; }; struct NimStringV2 { NI len; NimStrPayload* p; }; typedef NimStringV2 tyArray__nHXaesL0DJZHyVS07ARPRA[1]; N_LIB_PRIVATE N_NIMCALL(void, echoBinSafe)(NimStringV2* args_p0, NI args_p0Len_0); N_LIB_PRIVATE N_NIMCALL(void, nimTestErrorFlag)(void); static N_INLINE(void, nimFrame)(TFrame* s_p0); N_LIB_PRIVATE N_NOINLINE(void, callDepthLimitReached__system_u4621)(void); static N_INLINE(void, popFrame)(void); N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus2dot0dot4atslibatssystemdotnim_Init000)(void); N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void); static const struct { NI cap; NIM_CHAR data[6+1]; } TM__SRd76hP9cMfCzdUO857UhQQ_3 = { 6 | NIM_STRLIT_FLAG, "MyEnum" }; static const struct { NI cap; NIM_CHAR data[4+1]; } TM__SRd76hP9cMfCzdUO857UhQQ_5 = { 4 | NIM_STRLIT_FLAG, "true" }; static NIM_CONST tyArray__nHXaesL0DJZHyVS07ARPRA TM__SRd76hP9cMfCzdUO857UhQQ_2 = {{6, (NimStrPayload*)&TM__SRd76hP9cMfCzdUO857UhQQ_3}} ; static NIM_CONST tyArray__nHXaesL0DJZHyVS07ARPRA TM__SRd76hP9cMfCzdUO857UhQQ_4 = {{4, (NimStrPayload*)&TM__SRd76hP9cMfCzdUO857UhQQ_5}} ; N_LIB_PRIVATE NIM_CONST tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA x__temp_u11 = ((tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA)1); N_LIB_PRIVATE NIM_CONST tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA y__temp_u18 = ((tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA)0); extern NIM_THREADVAR TFrame* framePtr__system_u4020; static N_INLINE(void, nimFrame)(TFrame* s_p0) { { if (!(framePtr__system_u4020 == ((TFrame*) NIM_NIL))) goto LA3_; (*s_p0).calldepth = ((NI16)0); } goto LA1_; LA3_: ; { (*s_p0).calldepth = (NI16)((*framePtr__system_u4020).calldepth + ((NI16)1)); } LA1_: ; (*s_p0).prev = framePtr__system_u4020; framePtr__system_u4020 = s_p0; { if (!((*s_p0).calldepth == ((NI16)2000))) goto LA8_; callDepthLimitReached__system_u4621(); } LA8_: ; } static N_INLINE(void, popFrame)(void) { framePtr__system_u4020 = (*framePtr__system_u4020).prev; } N_LIB_PRIVATE void PreMainInner(void) { } N_LIB_PRIVATE int cmdCount; N_LIB_PRIVATE char** cmdLine; N_LIB_PRIVATE char** gEnv; N_LIB_PRIVATE void PreMain(void) { #if 0 void (*volatile inner)(void); inner = PreMainInner; atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus2dot0dot4atslibatssystemdotnim_Init000(); (*inner)(); #else atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus2dot0dot4atslibatssystemdotnim_Init000(); PreMainInner(); #endif } N_LIB_PRIVATE N_CDECL(void, NimMainInner)(void) { NimMainModule(); } N_CDECL(void, NimMain)(void) { #if 0 void (*volatile inner)(void); PreMain(); inner = NimMainInner; (*inner)(); #else PreMain(); NimMainInner(); #endif } int main(int argc, char** args, char** env) { cmdLine = args; cmdCount = argc; gEnv = env; NimMain(); return nim_program_result; } N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void) { { nimfr_("temp", "/home/runner/work/Nim/Nim/temp.nim"); echoBinSafe(TM__SRd76hP9cMfCzdUO857UhQQ_2, 1); { if (!(y__temp_u18 == ((tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA)0) || y__temp_u18 == ((tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA)1))) goto LA3_; echoBinSafe(TM__SRd76hP9cMfCzdUO857UhQQ_4, 1); } LA3_: ; nimTestErrorFlag(); popFrame(); } } ```

Stats

  • Started 2024-06-06T22:40:41
  • Finished 2024-06-06T22:40:41
  • Duration
2.0.4 :+1: OK

Output

``` MyEnum true ```

IR

Compiled filesize 91.14 Kb (93,328 bytes) ```cpp #define NIM_INTBITS 64 #include "nimbase.h" #define nimfr_(proc, file) \ TFrame FR_; \ FR_.procname = proc; FR_.filename = file; FR_.line = 0; FR_.len = 0; nimFrame(&FR_); #define nimfrs_(proc, file, slots, length) \ struct {TFrame* prev;NCSTRING procname;NI line;NCSTRING filename;NI len;VarSlot s[slots];} FR_; \ FR_.procname = proc; FR_.filename = file; FR_.line = 0; FR_.len = length; nimFrame((TFrame*)&FR_); #define nimln_(n) \ FR_.line = n; #define nimlf_(n, file) \ FR_.line = n; FR_.filename = file; typedef struct NimStrPayload NimStrPayload; typedef struct NimStringV2 NimStringV2; typedef NU8 tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA; struct NimStrPayload { NI cap; NIM_CHAR data[SEQ_DECL_SIZE]; }; struct NimStringV2 { NI len; NimStrPayload* p; }; typedef NimStringV2 tyArray__nHXaesL0DJZHyVS07ARPRA[1]; N_LIB_PRIVATE N_NIMCALL(void, echoBinSafe)(NimStringV2* args_p0, NI args_p0Len_0); N_LIB_PRIVATE N_NIMCALL(void, nimTestErrorFlag)(void); static N_INLINE(void, nimFrame)(TFrame* s_p0); N_LIB_PRIVATE N_NOINLINE(void, callDepthLimitReached__system_u4621)(void); static N_INLINE(void, popFrame)(void); N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus2dot0dot4atslibatssystemdotnim_Init000)(void); N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void); static const struct { NI cap; NIM_CHAR data[6+1]; } TM__SRd76hP9cMfCzdUO857UhQQ_3 = { 6 | NIM_STRLIT_FLAG, "MyEnum" }; static const struct { NI cap; NIM_CHAR data[4+1]; } TM__SRd76hP9cMfCzdUO857UhQQ_5 = { 4 | NIM_STRLIT_FLAG, "true" }; static NIM_CONST tyArray__nHXaesL0DJZHyVS07ARPRA TM__SRd76hP9cMfCzdUO857UhQQ_2 = {{6, (NimStrPayload*)&TM__SRd76hP9cMfCzdUO857UhQQ_3}} ; static NIM_CONST tyArray__nHXaesL0DJZHyVS07ARPRA TM__SRd76hP9cMfCzdUO857UhQQ_4 = {{4, (NimStrPayload*)&TM__SRd76hP9cMfCzdUO857UhQQ_5}} ; N_LIB_PRIVATE NIM_CONST tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA x__temp_u11 = ((tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA)1); N_LIB_PRIVATE NIM_CONST tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA y__temp_u18 = ((tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA)0); extern NIM_THREADVAR TFrame* framePtr__system_u4020; static N_INLINE(void, nimFrame)(TFrame* s_p0) { { if (!(framePtr__system_u4020 == ((TFrame*) NIM_NIL))) goto LA3_; (*s_p0).calldepth = ((NI16)0); } goto LA1_; LA3_: ; { (*s_p0).calldepth = (NI16)((*framePtr__system_u4020).calldepth + ((NI16)1)); } LA1_: ; (*s_p0).prev = framePtr__system_u4020; framePtr__system_u4020 = s_p0; { if (!((*s_p0).calldepth == ((NI16)2000))) goto LA8_; callDepthLimitReached__system_u4621(); } LA8_: ; } static N_INLINE(void, popFrame)(void) { framePtr__system_u4020 = (*framePtr__system_u4020).prev; } N_LIB_PRIVATE void PreMainInner(void) { } N_LIB_PRIVATE int cmdCount; N_LIB_PRIVATE char** cmdLine; N_LIB_PRIVATE char** gEnv; N_LIB_PRIVATE void PreMain(void) { #if 0 void (*volatile inner)(void); inner = PreMainInner; atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus2dot0dot4atslibatssystemdotnim_Init000(); (*inner)(); #else atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus2dot0dot4atslibatssystemdotnim_Init000(); PreMainInner(); #endif } N_LIB_PRIVATE N_CDECL(void, NimMainInner)(void) { NimMainModule(); } N_CDECL(void, NimMain)(void) { #if 0 void (*volatile inner)(void); PreMain(); inner = NimMainInner; (*inner)(); #else PreMain(); NimMainInner(); #endif } int main(int argc, char** args, char** env) { cmdLine = args; cmdCount = argc; gEnv = env; NimMain(); return nim_program_result; } N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void) { { nimfr_("temp", "/home/runner/work/Nim/Nim/temp.nim"); echoBinSafe(TM__SRd76hP9cMfCzdUO857UhQQ_2, 1); { if (!(y__temp_u18 == ((tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA)0) || y__temp_u18 == ((tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA)1))) goto LA3_; echoBinSafe(TM__SRd76hP9cMfCzdUO857UhQQ_4, 1); } LA3_: ; nimTestErrorFlag(); popFrame(); } } ```

Stats

  • Started 2024-06-06T22:40:42
  • Finished 2024-06-06T22:40:42
  • Duration
2.0.0 :+1: OK

Output

``` MyEnum true ```

IR

Compiled filesize 91.14 Kb (93,328 bytes) ```cpp #define NIM_INTBITS 64 #include "nimbase.h" #define nimfr_(proc, file) \ TFrame FR_; \ FR_.procname = proc; FR_.filename = file; FR_.line = 0; FR_.len = 0; nimFrame(&FR_); #define nimfrs_(proc, file, slots, length) \ struct {TFrame* prev;NCSTRING procname;NI line;NCSTRING filename;NI len;VarSlot s[slots];} FR_; \ FR_.procname = proc; FR_.filename = file; FR_.line = 0; FR_.len = length; nimFrame((TFrame*)&FR_); #define nimln_(n) \ FR_.line = n; #define nimlf_(n, file) \ FR_.line = n; FR_.filename = file; typedef struct NimStrPayload NimStrPayload; typedef struct NimStringV2 NimStringV2; typedef NU8 tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA; struct NimStrPayload { NI cap; NIM_CHAR data[SEQ_DECL_SIZE]; }; struct NimStringV2 { NI len; NimStrPayload* p; }; typedef NimStringV2 tyArray__nHXaesL0DJZHyVS07ARPRA[1]; N_LIB_PRIVATE N_NIMCALL(void, echoBinSafe)(NimStringV2* args_p0, NI args_p0Len_0); N_LIB_PRIVATE N_NIMCALL(void, nimTestErrorFlag)(void); static N_INLINE(void, nimFrame)(TFrame* s_p0); N_LIB_PRIVATE N_NOINLINE(void, callDepthLimitReached__system_u4607)(void); static N_INLINE(void, popFrame)(void); N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus2dot0dot0atslibatssystemdotnim_Init000)(void); N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void); static const struct { NI cap; NIM_CHAR data[6+1]; } TM__SRd76hP9cMfCzdUO857UhQQ_3 = { 6 | NIM_STRLIT_FLAG, "MyEnum" }; static const struct { NI cap; NIM_CHAR data[4+1]; } TM__SRd76hP9cMfCzdUO857UhQQ_5 = { 4 | NIM_STRLIT_FLAG, "true" }; static NIM_CONST tyArray__nHXaesL0DJZHyVS07ARPRA TM__SRd76hP9cMfCzdUO857UhQQ_2 = {{6, (NimStrPayload*)&TM__SRd76hP9cMfCzdUO857UhQQ_3}} ; static NIM_CONST tyArray__nHXaesL0DJZHyVS07ARPRA TM__SRd76hP9cMfCzdUO857UhQQ_4 = {{4, (NimStrPayload*)&TM__SRd76hP9cMfCzdUO857UhQQ_5}} ; N_LIB_PRIVATE NIM_CONST tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA x__temp_u11 = ((tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA)1); N_LIB_PRIVATE NIM_CONST tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA y__temp_u18 = ((tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA)0); extern NIM_THREADVAR TFrame* framePtr__system_u4006; static N_INLINE(void, nimFrame)(TFrame* s_p0) { { if (!(framePtr__system_u4006 == ((TFrame*) NIM_NIL))) goto LA3_; (*s_p0).calldepth = ((NI16)0); } goto LA1_; LA3_: ; { (*s_p0).calldepth = (NI16)((*framePtr__system_u4006).calldepth + ((NI16)1)); } LA1_: ; (*s_p0).prev = framePtr__system_u4006; framePtr__system_u4006 = s_p0; { if (!((*s_p0).calldepth == ((NI16)2000))) goto LA8_; callDepthLimitReached__system_u4607(); } LA8_: ; } static N_INLINE(void, popFrame)(void) { framePtr__system_u4006 = (*framePtr__system_u4006).prev; } N_LIB_PRIVATE void PreMainInner(void) { } N_LIB_PRIVATE int cmdCount; N_LIB_PRIVATE char** cmdLine; N_LIB_PRIVATE char** gEnv; N_LIB_PRIVATE void PreMain(void) { #if 0 void (*volatile inner)(void); inner = PreMainInner; atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus2dot0dot0atslibatssystemdotnim_Init000(); (*inner)(); #else atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus2dot0dot0atslibatssystemdotnim_Init000(); PreMainInner(); #endif } N_LIB_PRIVATE N_CDECL(void, NimMainInner)(void) { NimMainModule(); } N_CDECL(void, NimMain)(void) { #if 0 void (*volatile inner)(void); PreMain(); inner = NimMainInner; (*inner)(); #else PreMain(); NimMainInner(); #endif } int main(int argc, char** args, char** env) { cmdLine = args; cmdCount = argc; gEnv = env; NimMain(); return nim_program_result; } N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void) { { nimfr_("temp", "/home/runner/work/Nim/Nim/temp.nim"); echoBinSafe(TM__SRd76hP9cMfCzdUO857UhQQ_2, 1); { if (!(y__temp_u18 == ((tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA)0) || y__temp_u18 == ((tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA)1))) goto LA3_; echoBinSafe(TM__SRd76hP9cMfCzdUO857UhQQ_4, 1); } LA3_: ; nimTestErrorFlag(); popFrame(); } } ```

Stats

  • Started 2024-06-06T22:40:45
  • Finished 2024-06-06T22:40:45
  • Duration
1.6.20 :+1: OK

Output

``` MyEnum true ```

IR

Compiled filesize 96.23 Kb (98,544 bytes) ```cpp #define NIM_INTBITS 64 #include "nimbase.h" # define nimfr_(proc, file) \ TFrame FR_; \ FR_.procname = proc; FR_.filename = file; FR_.line = 0; FR_.len = 0; nimFrame(&FR_); # define nimfrs_(proc, file, slots, length) \ struct {TFrame* prev;NCSTRING procname;NI line;NCSTRING filename; NI len; VarSlot s[slots];} FR_; \ FR_.procname = proc; FR_.filename = file; FR_.line = 0; FR_.len = length; nimFrame((TFrame*)&FR_); # define nimln_(n, file) \ FR_.line = n; FR_.filename = file; typedef struct NimStringDesc NimStringDesc; typedef struct TGenericSeq TGenericSeq; typedef NU8 tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA; struct TGenericSeq { NI len; NI reserved; }; struct NimStringDesc { TGenericSeq Sup; NIM_CHAR data[SEQ_DECL_SIZE]; }; typedef NimStringDesc* tyArray__nHXaesL0DJZHyVS07ARPRA[1]; N_LIB_PRIVATE N_NIMCALL(void, echoBinSafe)(NimStringDesc** args, NI argsLen_0); static N_INLINE(void, initStackBottomWith)(void* locals); N_LIB_PRIVATE N_NOINLINE(void, nimGC_setStackBottom)(void* theStackBottom); static N_INLINE(void, nimFrame)(TFrame* s); N_LIB_PRIVATE N_NOINLINE(void, callDepthLimitReached__system_u2997)(void); static N_INLINE(void, popFrame)(void); N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus1dot6dot20atslibatssystemdotnim_DatInit000)(void); N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus1dot6dot20atslibatssystemdotnim_Init000)(void); N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void); STRING_LITERAL(TM__SRd76hP9cMfCzdUO857UhQQ_3, "MyEnum", 6); static NIM_CONST tyArray__nHXaesL0DJZHyVS07ARPRA TM__SRd76hP9cMfCzdUO857UhQQ_2 = {((NimStringDesc*) &TM__SRd76hP9cMfCzdUO857UhQQ_3)} ; STRING_LITERAL(TM__SRd76hP9cMfCzdUO857UhQQ_5, "true", 4); static NIM_CONST tyArray__nHXaesL0DJZHyVS07ARPRA TM__SRd76hP9cMfCzdUO857UhQQ_4 = {((NimStringDesc*) &TM__SRd76hP9cMfCzdUO857UhQQ_5)} ; N_LIB_PRIVATE NIM_CONST tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA x__temp_u11 = ((tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA) 1); N_LIB_PRIVATE NIM_CONST tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA y__temp_u18 = ((tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA) 0); extern TFrame* framePtr__system_u2564; static N_INLINE(void, initStackBottomWith)(void* locals) { nimGC_setStackBottom(locals); } static N_INLINE(void, nimFrame)(TFrame* s) { { if (!(framePtr__system_u2564 == ((TFrame*) NIM_NIL))) goto LA3_; (*s).calldepth = ((NI16) 0); } goto LA1_; LA3_: ; { (*s).calldepth = (NI16)((*framePtr__system_u2564).calldepth + ((NI16) 1)); } LA1_: ; (*s).prev = framePtr__system_u2564; framePtr__system_u2564 = s; { if (!((*s).calldepth == ((NI16) 2000))) goto LA8_; callDepthLimitReached__system_u2997(); } LA8_: ; } static N_INLINE(void, popFrame)(void) { framePtr__system_u2564 = (*framePtr__system_u2564).prev; } N_LIB_PRIVATE void PreMainInner(void) { } N_LIB_PRIVATE int cmdCount; N_LIB_PRIVATE char** cmdLine; N_LIB_PRIVATE char** gEnv; N_LIB_PRIVATE void PreMain(void) { void (*volatile inner)(void); inner = PreMainInner; atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus1dot6dot20atslibatssystemdotnim_DatInit000(); initStackBottomWith((void *)&inner); atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus1dot6dot20atslibatssystemdotnim_Init000(); (*inner)(); } N_LIB_PRIVATE N_CDECL(void, NimMainInner)(void) { NimMainModule(); } N_CDECL(void, NimMain)(void) { void (*volatile inner)(void); PreMain(); inner = NimMainInner; initStackBottomWith((void *)&inner); (*inner)(); } int main(int argc, char** args, char** env) { cmdLine = args; cmdCount = argc; gEnv = env; NimMain(); return nim_program_result; } N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void) { { nimfr_("temp", "/home/runner/work/Nim/Nim/temp.nim"); echoBinSafe(TM__SRd76hP9cMfCzdUO857UhQQ_2, 1); { if (!((3 &((NU8)1<<((NU)(y__temp_u18)&7U)))!=0)) goto LA3_; echoBinSafe(TM__SRd76hP9cMfCzdUO857UhQQ_4, 1); } LA3_: ; popFrame(); } } ```

Stats

  • Started 2024-06-06T22:40:47
  • Finished 2024-06-06T22:40:48
  • Duration
1.4.8 :-1: FAIL

Output

``` Error: Command failed: nim c --run -d:nimDebug -d:nimDebugDlOpen -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --verbosity:0 --hints:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim /home/runner/work/Nim/Nim/temp.nim(6, 17) Error: type mismatch: got but expected 'MyEnum = enum' ```

IR

Compiled filesize 96.23 Kb (98,544 bytes) ```cpp #define NIM_INTBITS 64 #include "nimbase.h" # define nimfr_(proc, file) \ TFrame FR_; \ FR_.procname = proc; FR_.filename = file; FR_.line = 0; FR_.len = 0; nimFrame(&FR_); # define nimfrs_(proc, file, slots, length) \ struct {TFrame* prev;NCSTRING procname;NI line;NCSTRING filename; NI len; VarSlot s[slots];} FR_; \ FR_.procname = proc; FR_.filename = file; FR_.line = 0; FR_.len = length; nimFrame((TFrame*)&FR_); # define nimln_(n, file) \ FR_.line = n; FR_.filename = file; typedef struct NimStringDesc NimStringDesc; typedef struct TGenericSeq TGenericSeq; typedef NU8 tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA; struct TGenericSeq { NI len; NI reserved; }; struct NimStringDesc { TGenericSeq Sup; NIM_CHAR data[SEQ_DECL_SIZE]; }; typedef NimStringDesc* tyArray__nHXaesL0DJZHyVS07ARPRA[1]; N_LIB_PRIVATE N_NIMCALL(void, echoBinSafe)(NimStringDesc** args, NI argsLen_0); static N_INLINE(void, initStackBottomWith)(void* locals); N_LIB_PRIVATE N_NOINLINE(void, nimGC_setStackBottom)(void* theStackBottom); static N_INLINE(void, nimFrame)(TFrame* s); N_LIB_PRIVATE N_NOINLINE(void, callDepthLimitReached__system_u2997)(void); static N_INLINE(void, popFrame)(void); N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus1dot6dot20atslibatssystemdotnim_DatInit000)(void); N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus1dot6dot20atslibatssystemdotnim_Init000)(void); N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void); STRING_LITERAL(TM__SRd76hP9cMfCzdUO857UhQQ_3, "MyEnum", 6); static NIM_CONST tyArray__nHXaesL0DJZHyVS07ARPRA TM__SRd76hP9cMfCzdUO857UhQQ_2 = {((NimStringDesc*) &TM__SRd76hP9cMfCzdUO857UhQQ_3)} ; STRING_LITERAL(TM__SRd76hP9cMfCzdUO857UhQQ_5, "true", 4); static NIM_CONST tyArray__nHXaesL0DJZHyVS07ARPRA TM__SRd76hP9cMfCzdUO857UhQQ_4 = {((NimStringDesc*) &TM__SRd76hP9cMfCzdUO857UhQQ_5)} ; N_LIB_PRIVATE NIM_CONST tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA x__temp_u11 = ((tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA) 1); N_LIB_PRIVATE NIM_CONST tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA y__temp_u18 = ((tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA) 0); extern TFrame* framePtr__system_u2564; static N_INLINE(void, initStackBottomWith)(void* locals) { nimGC_setStackBottom(locals); } static N_INLINE(void, nimFrame)(TFrame* s) { { if (!(framePtr__system_u2564 == ((TFrame*) NIM_NIL))) goto LA3_; (*s).calldepth = ((NI16) 0); } goto LA1_; LA3_: ; { (*s).calldepth = (NI16)((*framePtr__system_u2564).calldepth + ((NI16) 1)); } LA1_: ; (*s).prev = framePtr__system_u2564; framePtr__system_u2564 = s; { if (!((*s).calldepth == ((NI16) 2000))) goto LA8_; callDepthLimitReached__system_u2997(); } LA8_: ; } static N_INLINE(void, popFrame)(void) { framePtr__system_u2564 = (*framePtr__system_u2564).prev; } N_LIB_PRIVATE void PreMainInner(void) { } N_LIB_PRIVATE int cmdCount; N_LIB_PRIVATE char** cmdLine; N_LIB_PRIVATE char** gEnv; N_LIB_PRIVATE void PreMain(void) { void (*volatile inner)(void); inner = PreMainInner; atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus1dot6dot20atslibatssystemdotnim_DatInit000(); initStackBottomWith((void *)&inner); atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus1dot6dot20atslibatssystemdotnim_Init000(); (*inner)(); } N_LIB_PRIVATE N_CDECL(void, NimMainInner)(void) { NimMainModule(); } N_CDECL(void, NimMain)(void) { void (*volatile inner)(void); PreMain(); inner = NimMainInner; initStackBottomWith((void *)&inner); (*inner)(); } int main(int argc, char** args, char** env) { cmdLine = args; cmdCount = argc; gEnv = env; NimMain(); return nim_program_result; } N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void) { { nimfr_("temp", "/home/runner/work/Nim/Nim/temp.nim"); echoBinSafe(TM__SRd76hP9cMfCzdUO857UhQQ_2, 1); { if (!((3 &((NU8)1<<((NU)(y__temp_u18)&7U)))!=0)) goto LA3_; echoBinSafe(TM__SRd76hP9cMfCzdUO857UhQQ_4, 1); } LA3_: ; popFrame(); } } ```

Stats

  • Started 2024-06-06T22:40:50
  • Finished 2024-06-06T22:40:50
  • Duration

AST

```nim nnkStmtList.newTree( nnkTypeSection.newTree( nnkTypeDef.newTree( nnkPragmaExpr.newTree( newIdentNode("MyEnum"), nnkPragma.newTree( newIdentNode("pure") ) ), newEmptyNode(), nnkEnumTy.newTree( newEmptyNode(), newIdentNode("A"), newIdentNode("B"), newIdentNode("C"), newIdentNode("D") ) ), nnkTypeDef.newTree( newIdentNode("B"), newEmptyNode(), nnkObjectTy.newTree( newEmptyNode(), newEmptyNode(), nnkRecList.newTree( nnkIdentDefs.newTree( newIdentNode("field"), newIdentNode("int"), newEmptyNode() ) ) ) ) ), nnkLetSection.newTree( nnkIdentDefs.newTree( newIdentNode("x"), newIdentNode("MyEnum"), newIdentNode("B") ) ), nnkCommand.newTree( newIdentNode("echo"), nnkCall.newTree( newIdentNode("typeof"), newIdentNode("x") ) ), nnkLetSection.newTree( nnkIdentDefs.newTree( newIdentNode("y"), newEmptyNode(), nnkDotExpr.newTree( newIdentNode("MyEnum"), newIdentNode("A") ) ) ), nnkIfStmt.newTree( nnkElifBranch.newTree( nnkInfix.newTree( newIdentNode("in"), newIdentNode("y"), nnkCurly.newTree( newIdentNode("A"), newIdentNode("B") ) ), nnkStmtList.newTree( nnkCommand.newTree( newIdentNode("echo"), newIdentNode("true") ) ) ) ) ) ```
1.2.18 :-1: FAIL

Output

``` Error: Command failed: nim c --run -d:nimDebug -d:nimDebugDlOpen -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --verbosity:0 --hints:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim /home/runner/work/Nim/Nim/temp.nim(6, 17) Error: 'typedesc' metatype is not valid here; typed '=' instead of ':'? ```

IR

Compiled filesize 96.23 Kb (98,544 bytes) ```cpp #define NIM_INTBITS 64 #include "nimbase.h" # define nimfr_(proc, file) \ TFrame FR_; \ FR_.procname = proc; FR_.filename = file; FR_.line = 0; FR_.len = 0; nimFrame(&FR_); # define nimfrs_(proc, file, slots, length) \ struct {TFrame* prev;NCSTRING procname;NI line;NCSTRING filename; NI len; VarSlot s[slots];} FR_; \ FR_.procname = proc; FR_.filename = file; FR_.line = 0; FR_.len = length; nimFrame((TFrame*)&FR_); # define nimln_(n, file) \ FR_.line = n; FR_.filename = file; typedef struct NimStringDesc NimStringDesc; typedef struct TGenericSeq TGenericSeq; typedef NU8 tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA; struct TGenericSeq { NI len; NI reserved; }; struct NimStringDesc { TGenericSeq Sup; NIM_CHAR data[SEQ_DECL_SIZE]; }; typedef NimStringDesc* tyArray__nHXaesL0DJZHyVS07ARPRA[1]; N_LIB_PRIVATE N_NIMCALL(void, echoBinSafe)(NimStringDesc** args, NI argsLen_0); static N_INLINE(void, initStackBottomWith)(void* locals); N_LIB_PRIVATE N_NOINLINE(void, nimGC_setStackBottom)(void* theStackBottom); static N_INLINE(void, nimFrame)(TFrame* s); N_LIB_PRIVATE N_NOINLINE(void, callDepthLimitReached__system_u2997)(void); static N_INLINE(void, popFrame)(void); N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus1dot6dot20atslibatssystemdotnim_DatInit000)(void); N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus1dot6dot20atslibatssystemdotnim_Init000)(void); N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void); STRING_LITERAL(TM__SRd76hP9cMfCzdUO857UhQQ_3, "MyEnum", 6); static NIM_CONST tyArray__nHXaesL0DJZHyVS07ARPRA TM__SRd76hP9cMfCzdUO857UhQQ_2 = {((NimStringDesc*) &TM__SRd76hP9cMfCzdUO857UhQQ_3)} ; STRING_LITERAL(TM__SRd76hP9cMfCzdUO857UhQQ_5, "true", 4); static NIM_CONST tyArray__nHXaesL0DJZHyVS07ARPRA TM__SRd76hP9cMfCzdUO857UhQQ_4 = {((NimStringDesc*) &TM__SRd76hP9cMfCzdUO857UhQQ_5)} ; N_LIB_PRIVATE NIM_CONST tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA x__temp_u11 = ((tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA) 1); N_LIB_PRIVATE NIM_CONST tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA y__temp_u18 = ((tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA) 0); extern TFrame* framePtr__system_u2564; static N_INLINE(void, initStackBottomWith)(void* locals) { nimGC_setStackBottom(locals); } static N_INLINE(void, nimFrame)(TFrame* s) { { if (!(framePtr__system_u2564 == ((TFrame*) NIM_NIL))) goto LA3_; (*s).calldepth = ((NI16) 0); } goto LA1_; LA3_: ; { (*s).calldepth = (NI16)((*framePtr__system_u2564).calldepth + ((NI16) 1)); } LA1_: ; (*s).prev = framePtr__system_u2564; framePtr__system_u2564 = s; { if (!((*s).calldepth == ((NI16) 2000))) goto LA8_; callDepthLimitReached__system_u2997(); } LA8_: ; } static N_INLINE(void, popFrame)(void) { framePtr__system_u2564 = (*framePtr__system_u2564).prev; } N_LIB_PRIVATE void PreMainInner(void) { } N_LIB_PRIVATE int cmdCount; N_LIB_PRIVATE char** cmdLine; N_LIB_PRIVATE char** gEnv; N_LIB_PRIVATE void PreMain(void) { void (*volatile inner)(void); inner = PreMainInner; atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus1dot6dot20atslibatssystemdotnim_DatInit000(); initStackBottomWith((void *)&inner); atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus1dot6dot20atslibatssystemdotnim_Init000(); (*inner)(); } N_LIB_PRIVATE N_CDECL(void, NimMainInner)(void) { NimMainModule(); } N_CDECL(void, NimMain)(void) { void (*volatile inner)(void); PreMain(); inner = NimMainInner; initStackBottomWith((void *)&inner); (*inner)(); } int main(int argc, char** args, char** env) { cmdLine = args; cmdCount = argc; gEnv = env; NimMain(); return nim_program_result; } N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void) { { nimfr_("temp", "/home/runner/work/Nim/Nim/temp.nim"); echoBinSafe(TM__SRd76hP9cMfCzdUO857UhQQ_2, 1); { if (!((3 &((NU8)1<<((NU)(y__temp_u18)&7U)))!=0)) goto LA3_; echoBinSafe(TM__SRd76hP9cMfCzdUO857UhQQ_4, 1); } LA3_: ; popFrame(); } } ```

Stats

  • Started 2024-06-06T22:40:53
  • Finished 2024-06-06T22:40:53
  • Duration

AST

```nim nnkStmtList.newTree( nnkTypeSection.newTree( nnkTypeDef.newTree( nnkPragmaExpr.newTree( newIdentNode("MyEnum"), nnkPragma.newTree( newIdentNode("pure") ) ), newEmptyNode(), nnkEnumTy.newTree( newEmptyNode(), newIdentNode("A"), newIdentNode("B"), newIdentNode("C"), newIdentNode("D") ) ), nnkTypeDef.newTree( newIdentNode("B"), newEmptyNode(), nnkObjectTy.newTree( newEmptyNode(), newEmptyNode(), nnkRecList.newTree( nnkIdentDefs.newTree( newIdentNode("field"), newIdentNode("int"), newEmptyNode() ) ) ) ) ), nnkLetSection.newTree( nnkIdentDefs.newTree( newIdentNode("x"), newIdentNode("MyEnum"), newIdentNode("B") ) ), nnkCommand.newTree( newIdentNode("echo"), nnkCall.newTree( newIdentNode("typeof"), newIdentNode("x") ) ), nnkLetSection.newTree( nnkIdentDefs.newTree( newIdentNode("y"), newEmptyNode(), nnkDotExpr.newTree( newIdentNode("MyEnum"), newIdentNode("A") ) ) ), nnkIfStmt.newTree( nnkElifBranch.newTree( nnkInfix.newTree( newIdentNode("in"), newIdentNode("y"), nnkCurly.newTree( newIdentNode("A"), newIdentNode("B") ) ), nnkStmtList.newTree( nnkCommand.newTree( newIdentNode("echo"), newIdentNode("true") ) ) ) ) ) ```
1.0.10 :-1: FAIL

Output

``` Error: Command failed: nim c --run -d:nimDebug -d:nimDebugDlOpen -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --verbosity:0 --hints:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim /home/runner/work/Nim/Nim/temp.nim(6, 17) Error: 'typedesc' metatype is not valid here; typed '=' instead of ':'? ```

IR

Compiled filesize 96.23 Kb (98,544 bytes) ```cpp #define NIM_INTBITS 64 #include "nimbase.h" # define nimfr_(proc, file) \ TFrame FR_; \ FR_.procname = proc; FR_.filename = file; FR_.line = 0; FR_.len = 0; nimFrame(&FR_); # define nimfrs_(proc, file, slots, length) \ struct {TFrame* prev;NCSTRING procname;NI line;NCSTRING filename; NI len; VarSlot s[slots];} FR_; \ FR_.procname = proc; FR_.filename = file; FR_.line = 0; FR_.len = length; nimFrame((TFrame*)&FR_); # define nimln_(n, file) \ FR_.line = n; FR_.filename = file; typedef struct NimStringDesc NimStringDesc; typedef struct TGenericSeq TGenericSeq; typedef NU8 tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA; struct TGenericSeq { NI len; NI reserved; }; struct NimStringDesc { TGenericSeq Sup; NIM_CHAR data[SEQ_DECL_SIZE]; }; typedef NimStringDesc* tyArray__nHXaesL0DJZHyVS07ARPRA[1]; N_LIB_PRIVATE N_NIMCALL(void, echoBinSafe)(NimStringDesc** args, NI argsLen_0); static N_INLINE(void, initStackBottomWith)(void* locals); N_LIB_PRIVATE N_NOINLINE(void, nimGC_setStackBottom)(void* theStackBottom); static N_INLINE(void, nimFrame)(TFrame* s); N_LIB_PRIVATE N_NOINLINE(void, callDepthLimitReached__system_u2997)(void); static N_INLINE(void, popFrame)(void); N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus1dot6dot20atslibatssystemdotnim_DatInit000)(void); N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus1dot6dot20atslibatssystemdotnim_Init000)(void); N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void); STRING_LITERAL(TM__SRd76hP9cMfCzdUO857UhQQ_3, "MyEnum", 6); static NIM_CONST tyArray__nHXaesL0DJZHyVS07ARPRA TM__SRd76hP9cMfCzdUO857UhQQ_2 = {((NimStringDesc*) &TM__SRd76hP9cMfCzdUO857UhQQ_3)} ; STRING_LITERAL(TM__SRd76hP9cMfCzdUO857UhQQ_5, "true", 4); static NIM_CONST tyArray__nHXaesL0DJZHyVS07ARPRA TM__SRd76hP9cMfCzdUO857UhQQ_4 = {((NimStringDesc*) &TM__SRd76hP9cMfCzdUO857UhQQ_5)} ; N_LIB_PRIVATE NIM_CONST tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA x__temp_u11 = ((tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA) 1); N_LIB_PRIVATE NIM_CONST tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA y__temp_u18 = ((tyEnum_MyEnum__fWM7CunRIhxpmojnK9ayfmA) 0); extern TFrame* framePtr__system_u2564; static N_INLINE(void, initStackBottomWith)(void* locals) { nimGC_setStackBottom(locals); } static N_INLINE(void, nimFrame)(TFrame* s) { { if (!(framePtr__system_u2564 == ((TFrame*) NIM_NIL))) goto LA3_; (*s).calldepth = ((NI16) 0); } goto LA1_; LA3_: ; { (*s).calldepth = (NI16)((*framePtr__system_u2564).calldepth + ((NI16) 1)); } LA1_: ; (*s).prev = framePtr__system_u2564; framePtr__system_u2564 = s; { if (!((*s).calldepth == ((NI16) 2000))) goto LA8_; callDepthLimitReached__system_u2997(); } LA8_: ; } static N_INLINE(void, popFrame)(void) { framePtr__system_u2564 = (*framePtr__system_u2564).prev; } N_LIB_PRIVATE void PreMainInner(void) { } N_LIB_PRIVATE int cmdCount; N_LIB_PRIVATE char** cmdLine; N_LIB_PRIVATE char** gEnv; N_LIB_PRIVATE void PreMain(void) { void (*volatile inner)(void); inner = PreMainInner; atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus1dot6dot20atslibatssystemdotnim_DatInit000(); initStackBottomWith((void *)&inner); atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus1dot6dot20atslibatssystemdotnim_Init000(); (*inner)(); } N_LIB_PRIVATE N_CDECL(void, NimMainInner)(void) { NimMainModule(); } N_CDECL(void, NimMain)(void) { void (*volatile inner)(void); PreMain(); inner = NimMainInner; initStackBottomWith((void *)&inner); (*inner)(); } int main(int argc, char** args, char** env) { cmdLine = args; cmdCount = argc; gEnv = env; NimMain(); return nim_program_result; } N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void) { { nimfr_("temp", "/home/runner/work/Nim/Nim/temp.nim"); echoBinSafe(TM__SRd76hP9cMfCzdUO857UhQQ_2, 1); { if (!((3 &((NU8)1<<((NU)(y__temp_u18)&7U)))!=0)) goto LA3_; echoBinSafe(TM__SRd76hP9cMfCzdUO857UhQQ_4, 1); } LA3_: ; popFrame(); } } ```

Stats

  • Started 2024-06-06T22:40:55
  • Finished 2024-06-06T22:40:55
  • Duration

AST

```nim nnkStmtList.newTree( nnkTypeSection.newTree( nnkTypeDef.newTree( nnkPragmaExpr.newTree( newIdentNode("MyEnum"), nnkPragma.newTree( newIdentNode("pure") ) ), newEmptyNode(), nnkEnumTy.newTree( newEmptyNode(), newIdentNode("A"), newIdentNode("B"), newIdentNode("C"), newIdentNode("D") ) ), nnkTypeDef.newTree( newIdentNode("B"), newEmptyNode(), nnkObjectTy.newTree( newEmptyNode(), newEmptyNode(), nnkRecList.newTree( nnkIdentDefs.newTree( newIdentNode("field"), newIdentNode("int"), newEmptyNode() ) ) ) ) ), nnkLetSection.newTree( nnkIdentDefs.newTree( newIdentNode("x"), newIdentNode("MyEnum"), newIdentNode("B") ) ), nnkCommand.newTree( newIdentNode("echo"), nnkCall.newTree( newIdentNode("typeof"), newIdentNode("x") ) ), nnkLetSection.newTree( nnkIdentDefs.newTree( newIdentNode("y"), newEmptyNode(), nnkDotExpr.newTree( newIdentNode("MyEnum"), newIdentNode("A") ) ) ), nnkIfStmt.newTree( nnkElifBranch.newTree( nnkInfix.newTree( newIdentNode("in"), newIdentNode("y"), nnkCurly.newTree( newIdentNode("A"), newIdentNode("B") ) ), nnkStmtList.newTree( nnkCommand.newTree( newIdentNode("echo"), newIdentNode("true") ) ) ) ) ) ```
#c101490a0 :arrow_right: :bug:

Diagnostics

metagn introduced a bug at 2024-05-10 11:30:57 +0300 on commit #c101490a0 with message: ``` remove bad type inference behavior for enum identifiers (#23588) refs https://github.com/nim-lang/Nim/issues/23586#issuecomment-2102113750 In #20091 a bad kind of type inference was mistakenly left in where if an identifier `abc` had an expected type of an enum type `Enum`, and `Enum` had a member called `abc`, the identifier would change to be that enum member. This causes bugs where a local symbol can have the same name as an enum member but have a different value. I had assumed this behavior was removed since but it wasn't, and CI seems to pass having it removed. A separate PR needs to be made for the 2.0 branch because these lines were moved around during a refactoring in #23123 which is not in 2.0. ``` The bug is in the files: ``` compiler/semexprs.nim tests/lookups/tenumlocalsym.nim ``` The bug can be in the commits: (Diagnostics sometimes off-by-one).
Stats
  • GCC 11.4.0
  • Clang 14.0.0
  • NodeJS 20.3
  • Created 2024-06-06T22:40:11Z
  • Comments 1
  • Commands nim c --run -d:nimDebug -d:nimDebugDlOpen -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --verbosity:0 --hints:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim

:robot: Bug found in 20 minutes bisecting 644 commits at 32 commits per second

juancarlospaco commented 3 months ago

@metagn Bisect.

metagn commented 3 months ago

Can't check right now, does it work if the enum isn't pure? There was functionality that bypassed symbol lookup for enum identifiers based on the inferred type which was removed because it ignores existing local symbols. Pure enums have a lower priority in symbol lookup, if another symbol is found before them it's used instead.

juancarlospaco commented 3 months ago

I mean check this bisect https://github.com/nim-lang/Nim/issues/23689#issuecomment-2153568605 🙂 It is one of your commits maybe you have an idea about what happens.

rockcavera commented 3 months ago

Can't check right now, does it work if the enum isn't pure? There was functionality that bypassed symbol lookup for enum identifiers based on the inferred type which was removed because it ignores existing local symbols. Pure enums have a lower priority in symbol lookup, if another symbol is found before them it's used instead.

does not work without marking with the pure pragma, either in devel, 2.0.4 or 1.6.20

metagn commented 3 months ago

I mean check this bisect

I know what commit caused it, I was just explaining what the commit did.

The reason this worked since 1.6.14 is functionality that was not good, which was removed in #23588. Doing the removed functionality in a proper way is very hard. Whenever the inferred type of an identifier expression was an enum, it would immediately check the enum member list to check if the enum has a member with the same name as the identifier. This skipped local symbols with the same name, i.e. this happened:

type Foo = enum a, b
block:
  let b = a
  let c: Foo = b
  echo c # b

I've been trying to think of ways to bring the intended behavior back since the "regressions" started popping up but there's nothing that's simple and covers every case.

  1. We can only trigger it for undeclared identifiers (#23614), but that doesn't fix this issue.
  2. We can trigger it when the expected type of an identifier is an enum but lookup fails OR the lookup succeeds but the type doesn't match, this can cause a performance hit to the compiler because it's a type comparison every single time we look up an identifier with an expected enum type.
  3. We can disable type symbols in lookup when an enum type is expected similar to #23597, maybe combined with #23614 to deal with #23611. This really only fixes this issue and it's pretty arbitrary, the question of "why just enum types, which other types can type symbols never be" pops up. I'll open a PR with this but I don't know if it'll even work. (#23694)

Another thing is the fact that this only works with pure enums, normal enums give a redefinition error instead like a proc would (unless you spread the 2 types across different modules in which case normal enums work). To fix this we would probably have to make types overloadable which would be a big effort (there's no way to disambiguate type symbols in the same module), so we can't merge pure enums with normal enums yet.