From 3159137d9a3110edb4024145ce0ba778975de40e Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Fri, 25 Aug 2023 00:04:33 +0200 Subject: [PATCH] workaround codegen error for `Base10.decode` (#111) Calling `Base10.decode` may lead to different structures being generated for use with `uint64`. The one normally generated is: ``` struct tyObject_Result__559ckyoL0ZZBsNFIYXjaoeg {NIM_BOOL o; union{ struct {NCSTRING e; } _o_1; struct {unsigned long long v; } _o_2; }; ``` But sometimes, it may be generated as: ``` struct tyObject_Result__xZhi1m1g75ioXsKjx9bN5bg {NIM_BOOL o; union{ struct {NCSTRING e; } _o_1; struct {NU64 v; } _o_2; }; ``` When the latter is generated, the compiler throws with: ``` error: passing 'tyObject_Result__xZhi1m1g75ioXsKjx9bN5bg' (aka 'struct tyObject_Result__xZhi1m1g75ioXsKjx9bN5bg') to parameter of incompatible type 'tyObject_Result__559ckyoL0ZZBsNFIYXjaoeg' (aka 'struct tyObject_Result__559ckyoL0ZZBsNFIYXjaoeg') ``` for ``` proc getInt*(ht: HttpTables, key: string): uint64 = let res = Base10.decode(uint64, ht.getString(key)) if res.isOk(): res.get() # This line may lead to the compiler error above else: 0'u64 ``` By passing the type as a generic param, the `unsigned long long` version gets consistently generated / used regardless of include order. Minimal POC to trigger the bug, from `nimbus-eth2` root: ``` echo 'import beacon_chain/conf, beacon_chain/sync/sync_manager' >x.nim nim c -d:"libp2p_pki_schemes=secp256k1" -r x ``` Swapping include order (`conf` after `sync_manager`) works. --- stew/base10.nim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stew/base10.nim b/stew/base10.nim index f335a8d..39de452 100644 --- a/stew/base10.nim +++ b/stew/base10.nim @@ -39,8 +39,9 @@ type data*: array[maxLen(Base10, T), byte] len*: int8 # >= 1 when holding valid unsigned integer -proc decode*[A: byte|char](B: typedesc[Base10], T: typedesc[SomeUnsignedInt], - src: openArray[A]): Result[T, cstring] = +proc decode*[A: byte|char, T: SomeUnsignedInt]( + B: typedesc[Base10], t: typedesc[T], + src: openArray[A]): Result[T, cstring] = ## Convert base10 encoded string or array of bytes to unsigned integer. const MaxValue = T(high(T) div 10)