Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[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 opened this issue Jun 6, 2024 · 7 comments · Fixed by #23976

Comments

@rockcavera
Copy link
Contributor

rockcavera commented Jun 6, 2024

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: 8f5ae28
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
Copy link
Collaborator

!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

Copy link
Contributor

github-actions bot commented Jun 6, 2024

🐧 Linux bisect by @juancarlospaco (collaborator)
devel 👎 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)

Stats

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

AST

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 👍 OK

Output

MyEnum
true

IR

Compiled filesize 91.14 Kb (93,328 bytes)
#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 👍 OK

Output

MyEnum
true

IR

Compiled filesize 91.14 Kb (93,328 bytes)
#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 👍 OK

Output

MyEnum
true

IR

Compiled filesize 91.14 Kb (93,328 bytes)
#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 👍 OK

Output

MyEnum
true

IR

Compiled filesize 96.23 Kb (98,544 bytes)
#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 👎 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 <type B> but expected 'MyEnum = enum'

IR

Compiled filesize 96.23 Kb (98,544 bytes)
#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

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 👎 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)
#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

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 👎 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)
#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

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 ➡️ 🐛

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

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

@juancarlospaco
Copy link
Collaborator

@metagn Bisect.

@metagn
Copy link
Collaborator

metagn commented Jun 7, 2024

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
Copy link
Collaborator

I mean check this bisect #23689 (comment) 🙂
It is one of your commits maybe you have an idea about what happens.

@rockcavera
Copy link
Contributor Author

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
Copy link
Collaborator

metagn commented Jun 7, 2024

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 (add back enum ident inference, only on 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 ignore modules when looking up symbol with expected type #23597, maybe combined with add back enum ident inference, only on undeclared identifiers #23614 to deal with Regression from 2.0 to devel with dirty template #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. (ignore type symbols in lookup when enum type is expected #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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants