Open arnetheduck opened 6 months ago
Changing varargs[typedesc]
to varargs[untyped]
(and expecting nnkArgList and not nnkBracket) works, E
probably doesn't match typedesc
and something goes wrong trying to delay the macro evaluation. This is new behavior in 2.0, previously generic parameters matched every type including typedesc
.
You probably don't want the macro evaluation delayed anyway because then we would have to explicitly instantiate X
every time since we don't know anything about its structure to match it to anything. The error message is still weird.
This also works without the last 2 lines in the example which forces the delayed macro evaluation because of #23406:
type X[E] = Raising(Future[void], E)
But then actually calling f
fails because delaying is bad, this also gives a worse error message.
The reason we don't want unresolved generic parameters to match typedesc
is because of stuff like:
proc foo(x: typedesc): int =
sizeof(x)
My expectation would have been that varargs[typedesc]
would give a better error message if one does something like ...Raising([42])
, a situation we want to avoid.
Btw, like so?
import std/[sequtils, macros]
type
Future[T] = object
InternalRaisesFuture[T, E] = object
macro Raising2*[T](F: typedesc[Future[T]], E: varargs[untyped]): untyped =
E.expectKind(nnkArgList)
let raises = nnkTupleConstr.newTree(E.mapIt(it))
nnkBracketExpr.newTree(
ident "InternalRaisesFuture",
nnkDotExpr.newTree(F, ident"T"),
raises
)
type Abc = object
field: Future[void].Raising2([ValueError])
gives:
testit.nim(46, 3) Error: '(array[0..0, typedesc[ValueError]],)' is not a concrete type
testit.nim(46, 3) Error: '(array[0..0, typedesc[ValueError]],)' is not a concrete type
Because of [ValueError]
, removing the brackets works. Could also unwrap the bracket in the macro.
Also varargs[typed]
instead of varargs[untyped]
doesn't use nnkArgList
but also doesn't unwrap the brackets.
A workaround could be using varargs[typed]
and just checking the type of Nodes manually, like so:
import std/[sequtils, macros]
type
Future[T] = object
InternalRaisesFuture[T, E] = object
macro Raising*[T](F: typedesc[Future[T]], E: varargs[typed]): untyped =
## Given a Future type instance, return a type storing `{.raises.}`
## information
##
## Note; this type may change in the future
E.expectKind(nnkBracket)
for typ in E:
if typ.getTypeInst.typeKind != ntyTypeDesc:
error("Expected typedesc, but got: '" & typ.repr & "'.", typ)
let raises = nnkTupleConstr.newTree(E.mapIt(it))
nnkBracketExpr.newTree(
ident "InternalRaisesFuture",
nnkDotExpr.newTree(F, ident"T"),
raises
)
type X[E] = Future[void].Raising(E)
proc f(x: X) = discard
var v: Future[void].Raising(ValueError, 42)
f(v)
@beef331 thanks for the workaround, the final version ended up looking like this: https://github.com/status-im/nim-chronos/pull/526 - there are some limitations but the outcome is more or less consistent with how it worked in 1.6, at least for the use cases we had already.
Of course, it's sad to have to manually implement a poor version of what the compiler should be doing already better - worth considering in the next round of macro changes ;)
!nim c
import std/[sequtils, macros]
type
Future[T] = object
InternalRaisesFuture[T, E] = object
macro Raising*[T](F: typedesc[Future[T]], E: varargs[typedesc]): untyped =
## Given a Future type instance, return a type storing `{.raises.}`
## information
##
## Note; this type may change in the future
E.expectKind(nnkBracket)
let raises = nnkTupleConstr.newTree(E.mapIt(it))
nnkBracketExpr.newTree(
ident "InternalRaisesFuture",
nnkDotExpr.newTree(F, ident"T"),
raises
)
type X[E] = Future[void].Raising(E)
proc f(x: X) = discard
var v: Future[void].Raising([ValueError])
f(v)
0 bytes (0 bytes)
```cpp
```
2024-03-25T10:23:34
2024-03-25T10:23:34
0 bytes (0 bytes)
```cpp
```
2024-03-25T10:23:35
2024-03-25T10:23:35
0 bytes (0 bytes)
```cpp
```
2024-03-25T10:23:35
2024-03-25T10:23:36
95.41 Kb (97,696 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 tyObject_InternalRaisesFuture__joXl9brPglJfwBVacGXd5yg tyObject_InternalRaisesFuture__joXl9brPglJfwBVacGXd5yg;
struct tyObject_InternalRaisesFuture__joXl9brPglJfwBVacGXd5yg {
char dummy;
};
N_LIB_PRIVATE N_NIMCALL(void, f__temp_76)(tyObject_InternalRaisesFuture__joXl9brPglJfwBVacGXd5yg x);
static N_INLINE(void, nimFrame)(TFrame* s);
N_LIB_PRIVATE N_NOINLINE(void, callDepthLimitReached__system_2997)(void);
static N_INLINE(void, popFrame)(void);
static N_INLINE(void, initStackBottomWith)(void* locals);
N_LIB_PRIVATE N_NOINLINE(void, nimGC_setStackBottom)(void* theStackBottom);
N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus1dot6dot14atslibatssystemdotnim_DatInit000)(void);
N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus1dot6dot14atslibatssystemdotnim_Init000)(void);
N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void);
N_LIB_PRIVATE tyObject_InternalRaisesFuture__joXl9brPglJfwBVacGXd5yg v__temp_75;
extern TFrame* framePtr__system_2564;
extern TFrame* framePtr__system_2564;
extern TFrame* framePtr__system_2564;
extern TFrame* framePtr__system_2564;
extern TFrame* framePtr__system_2564;
extern TFrame* framePtr__system_2564;
static N_INLINE(void, nimFrame)(TFrame* s) {
{
if (!(framePtr__system_2564 == ((TFrame*) NIM_NIL))) goto LA3_;
(*s).calldepth = ((NI16) 0);
}
goto LA1_;
LA3_: ;
{
(*s).calldepth = (NI16)((*framePtr__system_2564).calldepth + ((NI16) 1));
}
LA1_: ;
(*s).prev = framePtr__system_2564;
framePtr__system_2564 = s;
{
if (!((*s).calldepth == ((NI16) 2000))) goto LA8_;
callDepthLimitReached__system_2997();
}
LA8_: ;
}
static N_INLINE(void, popFrame)(void) {
framePtr__system_2564 = (*framePtr__system_2564).prev;
}
N_LIB_PRIVATE N_NIMCALL(void, f__temp_76)(tyObject_InternalRaisesFuture__joXl9brPglJfwBVacGXd5yg x) {
nimfr_("f", "/home/runner/work/Nim/Nim/temp.nim");
popFrame();
}
static N_INLINE(void, initStackBottomWith)(void* locals) {
nimGC_setStackBottom(locals);
}
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;
atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus1dot6dot14atslibatssystemdotnim_DatInit000();
initStackBottomWith((void *)&inner);
atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminus1dot6dot14atslibatssystemdotnim_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");
f__temp_76(v__temp_75);
popFrame();
}
}
```
2024-03-25T10:23:38
2024-03-25T10:23:39
91.30 Kb (93,496 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 tyObject_InternalRaisesFuture__SoZdjWYx5qf9aGd4M3pBJdg tyObject_InternalRaisesFuture__SoZdjWYx5qf9aGd4M3pBJdg;
struct tyObject_InternalRaisesFuture__SoZdjWYx5qf9aGd4M3pBJdg {
char dummy;
};
N_LIB_PRIVATE N_NIMCALL(void, f__Qr2Z0OouGgYw3QfhyalszA)(tyObject_InternalRaisesFuture__SoZdjWYx5qf9aGd4M3pBJdg x);
static N_INLINE(void, nimFrame)(TFrame* s);
N_LIB_PRIVATE N_NOINLINE(void, callDepthLimitReached__mMRdr4sgmnykA9aWeM9aDZlw)(void);
static N_INLINE(void, popFrame)(void);
static N_INLINE(void, initStackBottomWith)(void* locals);
N_LIB_PRIVATE N_NOINLINE(void, nimGC_setStackBottom)(void* theStackBottom);
N_LIB_PRIVATE N_NIMCALL(void, systemDatInit000)(void);
N_LIB_PRIVATE N_NIMCALL(void, systemInit000)(void);
N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void);
N_LIB_PRIVATE tyObject_InternalRaisesFuture__SoZdjWYx5qf9aGd4M3pBJdg v__ZBo9advJ7u8QecSF0Bd4bHA;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
static N_INLINE(void, nimFrame)(TFrame* s) {
{
if (!(framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw == ((TFrame*) NIM_NIL))) goto LA3_;
(*s).calldepth = ((NI16) 0);
}
goto LA1_;
LA3_: ;
{
(*s).calldepth = (NI16)((*framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw).calldepth + ((NI16) 1));
}
LA1_: ;
(*s).prev = framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw = s;
{
if (!((*s).calldepth == ((NI16) 2000))) goto LA8_;
callDepthLimitReached__mMRdr4sgmnykA9aWeM9aDZlw();
}
LA8_: ;
}
static N_INLINE(void, popFrame)(void) {
framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw = (*framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw).prev;
}
N_LIB_PRIVATE N_NIMCALL(void, f__Qr2Z0OouGgYw3QfhyalszA)(tyObject_InternalRaisesFuture__SoZdjWYx5qf9aGd4M3pBJdg x) {
nimfr_("f", "/home/runner/work/Nim/Nim/temp.nim");
popFrame();
}
static N_INLINE(void, initStackBottomWith)(void* locals) {
nimGC_setStackBottom(locals);
}
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;
systemDatInit000();
initStackBottomWith((void *)&inner);
systemInit000();
(*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");
f__Qr2Z0OouGgYw3QfhyalszA(v__ZBo9advJ7u8QecSF0Bd4bHA);
popFrame();
}
}
```
2024-03-25T10:23:42
2024-03-25T10:23:42
87.03 Kb (89,120 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 tyObject_InternalRaisesFuture__Er05yBj9atIFRAN6fCwoRwQ tyObject_InternalRaisesFuture__Er05yBj9atIFRAN6fCwoRwQ;
struct tyObject_InternalRaisesFuture__Er05yBj9atIFRAN6fCwoRwQ {
char dummy;
};
N_LIB_PRIVATE N_NIMCALL(void, f__7BqHdHV1GTsUzckBHACG6Q)(tyObject_InternalRaisesFuture__Er05yBj9atIFRAN6fCwoRwQ x);
static N_INLINE(void, nimFrame)(TFrame* s);
N_LIB_PRIVATE N_NOINLINE(void, callDepthLimitReached__mMRdr4sgmnykA9aWeM9aDZlw)(void);
static N_INLINE(void, popFrame)(void);
static N_INLINE(void, initStackBottomWith)(void* locals);
N_LIB_PRIVATE N_NOINLINE(void, nimGC_setStackBottom)(void* theStackBottom);
N_LIB_PRIVATE N_NIMCALL(void, systemDatInit000)(void);
N_LIB_PRIVATE N_NIMCALL(void, systemInit000)(void);
N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void);
N_LIB_PRIVATE tyObject_InternalRaisesFuture__Er05yBj9atIFRAN6fCwoRwQ v__ZBo9advJ7u8QecSF0Bd4bHA;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
static N_INLINE(void, nimFrame)(TFrame* s) {
{
if (!(framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw == NIM_NIL)) goto LA3_;
(*s).calldepth = ((NI16) 0);
}
goto LA1_;
LA3_: ;
{
(*s).calldepth = (NI16)((*framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw).calldepth + ((NI16) 1));
}
LA1_: ;
(*s).prev = framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw = s;
{
if (!((*s).calldepth == ((NI16) (((NI) 2000))))) goto LA8_;
callDepthLimitReached__mMRdr4sgmnykA9aWeM9aDZlw();
}
LA8_: ;
}
static N_INLINE(void, popFrame)(void) {
framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw = (*framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw).prev;
}
N_LIB_PRIVATE N_NIMCALL(void, f__7BqHdHV1GTsUzckBHACG6Q)(tyObject_InternalRaisesFuture__Er05yBj9atIFRAN6fCwoRwQ x) {
nimfr_("f", "/home/runner/work/Nim/Nim/temp.nim");
popFrame();
}
static N_INLINE(void, initStackBottomWith)(void* locals) {
nimGC_setStackBottom(locals);
}
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;
systemDatInit000();
initStackBottomWith((void *)&inner);
systemInit000();
(*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");
f__7BqHdHV1GTsUzckBHACG6Q(v__ZBo9advJ7u8QecSF0Bd4bHA);
popFrame();
}
}
```
2024-03-25T10:23:44
2024-03-25T10:23:45
86.13 Kb (88,192 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 tyObject_InternalRaisesFuture__Er05yBj9atIFRAN6fCwoRwQ tyObject_InternalRaisesFuture__Er05yBj9atIFRAN6fCwoRwQ;
struct tyObject_InternalRaisesFuture__Er05yBj9atIFRAN6fCwoRwQ {
char dummy;
};
N_LIB_PRIVATE N_NIMCALL(void, f__7BqHdHV1GTsUzckBHACG6Q)(tyObject_InternalRaisesFuture__Er05yBj9atIFRAN6fCwoRwQ x);
static N_INLINE(void, nimFrame)(TFrame* s);
N_LIB_PRIVATE N_NOINLINE(void, callDepthLimitReached__mMRdr4sgmnykA9aWeM9aDZlw)(void);
static N_INLINE(void, popFrame)(void);
static N_INLINE(void, initStackBottomWith)(void* locals);
N_NOINLINE(void, nimGC_setStackBottom)(void* theStackBottom);
N_LIB_PRIVATE N_NIMCALL(void, systemDatInit000)(void);
N_LIB_PRIVATE N_NIMCALL(void, systemInit000)(void);
N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void);
tyObject_InternalRaisesFuture__Er05yBj9atIFRAN6fCwoRwQ v__ZBo9advJ7u8QecSF0Bd4bHA;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
static N_INLINE(void, nimFrame)(TFrame* s) { NI T1_;
T1_ = (NI)0;
{
if (!(framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw == NIM_NIL)) goto LA4_;
T1_ = ((NI) 0);
}
goto LA2_;
LA4_: ;
{
T1_ = ((NI) ((NI16)((*framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw).calldepth + ((NI16) 1))));
}
LA2_: ;
(*s).calldepth = ((NI16) (T1_));
(*s).prev = framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw = s;
{
if (!((*s).calldepth == ((NI16) (((NI) 2000))))) goto LA9_;
callDepthLimitReached__mMRdr4sgmnykA9aWeM9aDZlw();
}
LA9_: ;
}
static N_INLINE(void, popFrame)(void) { framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw = (*framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw).prev;
}
N_LIB_PRIVATE N_NIMCALL(void, f__7BqHdHV1GTsUzckBHACG6Q)(tyObject_InternalRaisesFuture__Er05yBj9atIFRAN6fCwoRwQ x) { nimfr_("f", "/home/runner/work/Nim/Nim/temp.nim");
popFrame();
}
static N_INLINE(void, initStackBottomWith)(void* locals) { nimGC_setStackBottom(locals);
}
void PreMainInner(void) {
}
int cmdCount;
char** cmdLine;
char** gEnv;
void PreMain(void) {
void (*volatile inner)(void);
inner = PreMainInner;
systemDatInit000();
initStackBottomWith((void *)&inner);
systemInit000();
(*inner)();
}
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");
f__7BqHdHV1GTsUzckBHACG6Q(v__ZBo9advJ7u8QecSF0Bd4bHA);
popFrame();
}
}
```
2024-03-25T10:23:46
2024-03-25T10:23:47
11.4.0
14.0.0
19.1
2024-03-25T10:23:06Z
6
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 49 minutes
bisecting 2147
commits at 43
commits per second
Should have mentioned the origin is more than likely #22029
To be clear this isn't just a simple regression but needs a design choice:
typedesc
param, but the macro has to be early evaluated here because otherwise we would have no information about the structure of X
which is terrible for generic inference (I'm not even sure if this is implemented correctly). E
as a typedesc
param, which is normally illegal (i.e. a regular proc needs a concrete type for a typedesc
param). So maybe we need to whitelist unresolved generic params (tyGenericParam
) matching typedesc
only for macros/templates. Would be an obscure rule but makes sense practically.You probably don't want the macro evaluation delayed anyway because then we would have to explicitly instantiate X every time since we don't know anything about its structure to match it to anything.
I've been thinking about this, and I wonder if there's room for post-monomorphization macros somewhere in the language - when thinking about this problem, that's what I actually wanted.
Going further back in my reasoning around Raising
, I actually wanted type classes (if I remember the nim name right) that understand inheritance, covariance and contravariance, because what we're actually trying to mimic here is the type arithmetic of {.raises.}
, but early on, I couldn't get it to work for reasons I did not bother to investigate. I guess part of it is that the raises
effect itself for some reason does not work with a type class.
Sorry, after looking into it more it seems like some code even depends on typedesc
not matching generic types early, there is this test for it and the union library seems to depend on it. The only reason #23438 passes CI is both these cases use normal call syntax which always delays the instantiation (see #23406, these were discovered trying to fix it in #23411).
I still understand the need for better type safety than just typed
here, so maybe we could introduce a typeclass that matches expressions that have a typedesc
type rather than just concrete typedescs, like typed{typedesc}
. To also check if it's a fitting type for raises
, we would need a constraint-checking mechanism that is delayed until instantiation unlike the expression-forming mechanism that is the macro. In this case a constraint on the parameter of InternalRaisesFuture
should do it (ignoring current bugs with generic constraints) but I don't know if an intermediary generic type is always applicable.
Description
Nim Version
works in 1.6, broken in 2.0, devel
Current Output
Expected Output
No response
Possible Solution
No response
Additional Information
No response