status-im / nimbus-eth2

Nim implementation of the Ethereum Beacon Chain
https://nimbus.guide
Other
503 stars 210 forks source link

Compilation error when "import libp2p/multicodec" is added to sync_manager.nim #6325

Closed diegomrsantos closed 1 month ago

diegomrsantos commented 1 month ago

Describe the bug

When import libp2p/multicodec is added to sync_manager.nim, running make -j10 nimbus_beacon_node fails with error:

Building: install/usr/lib/libbacktracenim.a
Building: build/generate_makefile
src/minissdpc.c:473:6: warning: comparison of function 'clock_gettime' not equal to a null pointer is always true [-Wtautological-pointer-compare]
        if (clock_gettime != NULL) {
            ^~~~~~~~~~~~~    ~~~~
src/minissdpc.c:473:6: note: prefix with the address-of operator to silence this warning
        if (clock_gettime != NULL) {
            ^
            &
1 warning generated.
ld: warning: ignoring duplicate libraries: '-lm'
Build completed successfully: build/generate_makefile
Building: build/nimbus_beacon_node
/nimbus-eth2/vendor/nim-libp2p/libp2p/transports/tcptransport.nim(50, 57) template/generic instantiation of `async` from here
/nimbus-eth2/vendor/nim-libp2p/libp2p/transports/tcptransport.nim(103, 10) template/generic instantiation of `setResult` from here
/nimbus-eth2/vendor/nim-libp2p/libp2p/transports/tcptransport.nim(65, 20) template/generic instantiation of `async` from here
/nimbus-eth2/vendor/nim-libp2p/libp2p/transports/tcptransport.nim(89, 25) template/generic instantiation of `error` from here
/nimbus-eth2/vendor/nim-chronos/chronos/internal/raisesfutures.nim(241, 12) Warning: No exceptions possible with this operation, `error` always returns nil [User]
/nimbus-eth2/vendor/nim-libp2p/libp2p/transports/tcptransport.nim(163, 36) template/generic instantiation of `async` from here
/nimbus-eth2/vendor/nim-libp2p/libp2p/transports/tcptransport.nim(169, 17) template/generic instantiation of `checkFutures` from here
/nimbus-eth2/vendor/nim-libp2p/libp2p/errors.nim(30, 24) template/generic instantiation of `readError` from here
/nimbus-eth2/vendor/nim-chronos/chronos/internal/raisesfutures.nim(247, 12) Warning: No exceptions possible with this operation, `readError` always raises [User]
/nimbus-eth2/beacon_chain/nimbus_beacon_node.nim(1900, 44) template/generic instantiation of `async` from here
/nimbus-eth2/beacon_chain/nimbus_beacon_node.nim(1907, 22) template/generic instantiation of `start` from here
/nimbus-eth2/beacon_chain/sync/sync_manager.nim(783, 20) template/generic instantiation of `syncLoop` from here
/nimbus-eth2/beacon_chain/sync/sync_manager.nim(615, 6) template/generic instantiation of `startWorkers` from here
/nimbus-eth2/beacon_chain/sync/sync_manager.nim(568, 45) template/generic instantiation of `syncWorker` from here
/nimbus-eth2/beacon_chain/sync/sync_manager.nim(523, 16) template/generic instantiation of `syncStep` from here
/nimbus-eth2/beacon_chain/sync/sync_manager.nim(428, 25) Error: type mismatch: got <T, Slot>
but expected one of:
func `==`(a, b: Address): bool
  first type mismatch at position: 1
  required type for a: Address
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: BadProposal): bool
  first type mismatch at position: 1
  required type for a: BadProposal
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: BadVote): bool
  first type mismatch at position: 1
  required type for a: BadVote
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: BlockNumber): bool
  first type mismatch at position: 1
  required type for a: BlockNumber
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: Cipher): bool
  first type mismatch at position: 1
  required type for a: Cipher
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: Duration): bool
  first type mismatch at position: 1
  required type for a: Duration
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: Eth2Digest): bool
  first type mismatch at position: 1
  required type for a: Eth2Digest
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: ForkDigest | Version | DomainType): bool
  first type mismatch at position: 1
  required type for a: ForkDigest or Version or DomainType
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: KZG_RET): bool
  first type mismatch at position: 1
  required type for a: KZG_RET
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: Kdf): bool
  first type mismatch at position: 1
  required type for a: Kdf
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: KdfSaltKey): bool
  first type mismatch at position: 1
  required type for a: KdfSaltKey
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: KeyedBlockRef): bool
  first type mismatch at position: 1
  required type for a: KeyedBlockRef
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: KeystoreCacheItem): bool
  first type mismatch at position: 1
  required type for a: KeystoreCacheItem
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: Moment): bool
  first type mismatch at position: 1
  required type for a: Moment
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: Node): bool
  first type mismatch at position: 1
  required type for a: Node
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: PublicKey or Signature or ProofOfPossession): bool
  first type mismatch at position: 1
  required type for a: PublicKey or Signature or ProofOfPossession
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: Quantity): bool
  first type mismatch at position: 1
  required type for a: Quantity
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: Record): bool
  first type mismatch at position: 1
  required type for a: Record
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: RestValidatorIndex): bool
  first type mismatch at position: 1
  required type for a: RestValidatorIndex
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: StInt): bool
  first type mismatch at position: 1
  required type for a: StInt
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: StUint): bool
  first type mismatch at position: 1
  required type for a: StUint
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: TomlTableRef): bool
  first type mismatch at position: 1
  required type for a: TomlTableRef
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: TomlValueRef): bool
  first type mismatch at position: 1
  required type for a: TomlValueRef
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: ValidatorPrivKey): bool
  first type mismatch at position: 1
  required type for a: ValidatorPrivKey
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: ValidatorPubKey | ValidatorSig): bool
  first type mismatch at position: 1
  required type for a: ValidatorPubKey or ValidatorSig
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(a, b: ref HashedValidatorPubKeyItem): bool
  first type mismatch at position: 1
  required type for a: ref HashedValidatorPubKeyItem
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(lhs, rhs: JsonValueRef): bool
  first type mismatch at position: 1
  required type for lhs: JsonValueRef
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(lhs, rhs: PublicKey): bool
  first type mismatch at position: 1
  required type for lhs: PublicKey
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(lhs, rhs: Signature): bool
  first type mismatch at position: 1
  required type for lhs: Signature
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(lhs, rhs: SignatureNR): bool
  first type mismatch at position: 1
  required type for lhs: SignatureNR
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(lhs, rhs: SkPublicKey): bool
  first type mismatch at position: 1
  required type for lhs: SkPublicKey
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(lhs, rhs: SkRecoverableSignature): bool
  first type mismatch at position: 1
  required type for lhs: SkRecoverableSignature
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(lhs, rhs: SkSchnorrSignature): bool
  first type mismatch at position: 1
  required type for lhs: SkSchnorrSignature
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(lhs, rhs: SkSignature): bool
  first type mismatch at position: 1
  required type for lhs: SkSignature
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(lhs, rhs: SkXOnlyPublicKey): bool
  first type mismatch at position: 1
  required type for lhs: SkXOnlyPublicKey
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(x, y: Ether): bool
  first type mismatch at position: 1
  required type for x: Ether
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(x, y: Gwei): bool
  first type mismatch at position: 1
  required type for x: Gwei
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(x: Epoch; y: Epoch): bool
  first type mismatch at position: 1
  required type for x: Epoch
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(x: Epoch; y: uint64): bool
  first type mismatch at position: 1
  required type for x: Epoch
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(x: Era; y: Era): bool
  first type mismatch at position: 1
  required type for x: Era
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(x: Era; y: uint64): bool
  first type mismatch at position: 1
  required type for x: Era
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(x: Slot; y: Slot): bool
  first type mismatch at position: 1
  required type for x: Slot
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(x: Slot; y: uint64): bool
  first type mismatch at position: 1
  required type for x: Slot
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(x: SyncCommitteePeriod; y: SyncCommitteePeriod): bool
  first type mismatch at position: 1
  required type for x: SyncCommitteePeriod
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(x: SyncCommitteePeriod; y: uint64): bool
  first type mismatch at position: 1
  required type for x: SyncCommitteePeriod
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(x: uint64; y: Epoch): bool
  first type mismatch at position: 1
  required type for x: uint64
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(x: uint64; y: Era): bool
  first type mismatch at position: 1
  required type for x: uint64
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(x: uint64; y: Slot): bool
  first type mismatch at position: 1
  required type for x: uint64
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`(x: uint64; y: SyncCommitteePeriod): bool
  first type mismatch at position: 1
  required type for x: uint64
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`[E0, E1](lhs: Result[void, E0]; rhs: Result[void, E1]): bool
  first type mismatch at position: 1
  required type for lhs: Result[system.void, ==.E0]
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`[T0, T1](lhs: Result[T0, void]; rhs: Result[T1, void]): bool
  first type mismatch at position: 1
  required type for lhs: Result[==.T0, system.void]
  but expression 'copy[len(copy) - 1]' is of type: T
func `==`[T0: not void; E0: not void; T1: not void; E1: not void](
    lhs: Result[T0, E0]; rhs: Result[T1, E1]): bool
  first type mismatch at position: 1
  required type for lhs: Result[==.T0, ==.E0]
  but expression 'copy[len(copy) - 1]' is of type: T
method `==`(x, y: Collector): bool
  first type mismatch at position: 1
  required type for x: Collector
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(a, b: ContentTypeData): bool
  first type mismatch at position: 1
  required type for a: ContentTypeData
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(a, b: DateTime): bool
  first type mismatch at position: 1
  required type for a: DateTime
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(a, b: Duration): bool
  first type mismatch at position: 1
  required type for a: Duration
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(a, b: IoErrorCode): bool
  first type mismatch at position: 1
  required type for a: IoErrorCode
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(a, b: Port): bool
  first type mismatch at position: 1
  required type for a: Port
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(a, b: Time): bool
  first type mismatch at position: 1
  required type for a: Time
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(a, b: Time): bool
  first type mismatch at position: 1
  required type for a: Time
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(a: ContentTypeData; b: MediaType): bool
  first type mismatch at position: 1
  required type for a: ContentTypeData
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(a: IoErrorCode; b: cint): bool
  first type mismatch at position: 1
  required type for a: IoErrorCode
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(a: MediaType; b: ContentTypeData): bool
  first type mismatch at position: 1
  required type for a: MediaType
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(a: Opt[ContentTypeData]; b: MediaType): bool
  first type mismatch at position: 1
  required type for a: Opt[httputils.ContentTypeData]
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(err1, err2: OSErrorCode): bool
  first type mismatch at position: 1
  required type for err1: OSErrorCode
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(key1, key2: PrivateKey): bool
  first type mismatch at position: 1
  required type for key1: PrivateKey
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(key1, key2: PublicKey): bool
  first type mismatch at position: 1
  required type for key1: PublicKey
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(lhs, rhs: IpAddress): bool
  first type mismatch at position: 1
  required type for lhs: IpAddress
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(lhs, rhs: TransportAddress): bool
  first type mismatch at position: 1
  required type for lhs: TransportAddress
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(m1, m2: IpMask): bool
  first type mismatch at position: 1
  required type for m1: IpMask
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(m1: var MultiAddress; m2: MultiAddress): bool
  first type mismatch at position: 1
  required type for m1: var MultiAddress
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(n1, n2: IpNet): bool
  first type mismatch at position: 1
  required type for n1: IpNet
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(oid1: Oid; oid2: Oid): bool
  first type mismatch at position: 1
  required type for oid1: Oid
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(s1, s2: SegmentedPath): bool
  first type mismatch at position: 1
  required type for s1: SegmentedPath
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: AsyncFD): bool
  first type mismatch at position: 1
  required type for x: AsyncFD
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: MediaType): bool
  first type mismatch at position: 1
  required type for x: MediaType
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: RestStatus): bool
  first type mismatch at position: 1
  required type for x: RestStatus
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: SocketHandle): bool
  first type mismatch at position: 1
  required type for x: SocketHandle
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: bool): bool
  first type mismatch at position: 1
  required type for x: bool
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: char): bool
  first type mismatch at position: 1
  required type for x: char
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: cstring): bool
  first type mismatch at position: 1
  required type for x: cstring
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: float): bool
  first type mismatch at position: 1
  required type for x: float
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: float32): bool
  first type mismatch at position: 1
  required type for x: float32
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: int): bool
  first type mismatch at position: 1
  required type for x: int
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: int16): bool
  first type mismatch at position: 1
  required type for x: int16
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: int32): bool
  first type mismatch at position: 1
  required type for x: int32
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: int64): bool
  first type mismatch at position: 1
  required type for x: int64
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: int8): bool
  first type mismatch at position: 1
  required type for x: int8
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: pointer): bool
  first type mismatch at position: 1
  required type for x: pointer
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: string): bool
  first type mismatch at position: 1
  required type for x: string
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: uint): bool
  first type mismatch at position: 1
  required type for x: uint
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: uint16): bool
  first type mismatch at position: 1
  required type for x: uint16
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: uint32): bool
  first type mismatch at position: 1
  required type for x: uint32
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: uint64): bool
  first type mismatch at position: 1
  required type for x: uint64
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x, y: uint8): bool
  first type mismatch at position: 1
  required type for x: uint8
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x: SocketHandle; y: int): bool
  first type mismatch at position: 1
  required type for x: SocketHandle
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x: string; y: typeof(nil) | typeof(nil)): bool
  first type mismatch at position: 1
  required type for x: string
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(x: typeof(nil) | typeof(nil); y: string): bool
  first type mismatch at position: 1
  required type for x: typeof(nil) or typeof(nil)
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`(zone1, zone2: Timezone): bool
  first type mismatch at position: 1
  required type for zone1: Timezone
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[A, B](d1: MDigest[A]; d2: MDigest[B]): bool
  first type mismatch at position: 1
  required type for d1: MDigest[==.A]
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[A, B](s, t: OrderedTableRef[A, B]): bool
  first type mismatch at position: 1
  required type for s: OrderedTableRef[==.A, ==.B]
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[A, B](s, t: OrderedTable[A, B]): bool
  first type mismatch at position: 1
  required type for s: OrderedTable[==.A, ==.B]
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[A, B](s, t: TableRef[A, B]): bool
  first type mismatch at position: 1
  required type for s: TableRef[==.A, ==.B]
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[A, B](s, t: Table[A, B]): bool
  first type mismatch at position: 1
  required type for s: Table[==.A, ==.B]
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[A](s, t: CountTableRef[A]): bool
  first type mismatch at position: 1
  required type for s: CountTableRef[==.A]
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[A](s, t: CountTable[A]): bool
  first type mismatch at position: 1
  required type for s: CountTable[==.A]
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[A](s, t: HashSet[A]): bool
  first type mismatch at position: 1
  required type for s: HashSet[==.A]
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[A](s, t: OrderedSet[A]): bool
  first type mismatch at position: 1
  required type for s: OrderedSet[==.A]
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[Enum: enum](x, y: Enum): bool
  first type mismatch at position: 1
  required type for x: Enum: enum
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[I, T](x, y: array[I, T]): bool
  first type mismatch at position: 1
  required type for x: array[I, T]
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[T: proc | iterator](x, y: T): bool
  first type mismatch at position: 1
  required type for x: T: proc or proc
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[T: tuple | object](x, y: T): bool
  first type mismatch at position: 1
  required type for x: T: tuple or object
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[T](a, b: Option[T]): bool
  first type mismatch at position: 1
  required type for a: Option[==.T]
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[T](a, b: SyncRequest[T]): bool
  first type mismatch at position: 1
  required type for a: SyncRequest[==.T]
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[T](x, y: openArray[T]): bool
  first type mismatch at position: 1
  required type for x: openArray[T]
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[T](x, y: ptr T): bool
  first type mismatch at position: 1
  required type for x: ptr T
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[T](x, y: ref T): bool
  first type mismatch at position: 1
  required type for x: ref T
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[T](x, y: seq[T]): bool
  first type mismatch at position: 1
  required type for x: seq[T]
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[T](x, y: set[T]): bool
  first type mismatch at position: 1
  required type for x: set[T]
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[bits: static[int]](a`gensym32: StUint[bits]; b`gensym32: int{lit}): bool
  first type mismatch at position: 1
  required type for a`gensym32: StUint[==.bits]
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[bits: static[int]](a`gensym33: int{lit}; b`gensym33: StUint[bits]): bool
  first type mismatch at position: 1
  required type for a`gensym33: int
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[bits: static[int]](a`gensym34: StInt[bits]; b`gensym34: int{lit}): bool
  first type mismatch at position: 1
  required type for a`gensym34: StInt[==.bits]
  but expression 'copy[len(copy) - 1]' is of type: T
proc `==`[bits: static[int]](a`gensym35: int{lit}; b`gensym35: StInt[bits]): bool
  first type mismatch at position: 1
  required type for a`gensym35: int
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(a, b: BitList): bool
  first type mismatch at position: 1
  required type for a: BitList
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(a, b: BitSeq): bool
  first type mismatch at position: 1
  required type for a: BitSeq
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(a, b: HashList | HashArray): bool
  first type mismatch at position: 1
  required type for a: HashList or HashArray
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(a, b: List): bool
  first type mismatch at position: 1
  required type for a: List
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(a, b: PeerId): bool
  first type mismatch at position: 1
  required type for a: PeerId
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(a, b: PubKey0x): bool
  first type mismatch at position: 1
  required type for a: PubKey0x
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(a, b: TypedTransaction): bool
  first type mismatch at position: 1
  required type for a: TypedTransaction
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(lhs, rhs: GraffitiBytes): bool
  first type mismatch at position: 1
  required type for lhs: GraffitiBytes
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(lhs, rhs: HttpHostUri): bool
  first type mismatch at position: 1
  required type for lhs: HttpHostUri
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(lhs, rhs: JsonString): bool
  first type mismatch at position: 1
  required type for lhs: JsonString
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(lhs, rhs: WalletName): bool
  first type mismatch at position: 1
  required type for lhs: WalletName
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(x, y: JustificationBits): bool
  first type mismatch at position: 1
  required type for x: JustificationBits
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(x`gensym10, y`gensym10: SubnetId): bool
  first type mismatch at position: 1
  required type for x`gensym10: SubnetId
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(x`gensym10: SubnetId; y`gensym10: uint64): bool
  first type mismatch at position: 1
  required type for x`gensym10: SubnetId
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(x`gensym10: uint64; y`gensym10: SubnetId): bool
  first type mismatch at position: 1
  required type for x`gensym10: uint64
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(x`gensym11, y`gensym11: SyncSubcommitteeIndex): bool
  first type mismatch at position: 1
  required type for x`gensym11: SyncSubcommitteeIndex
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(x`gensym11: SyncSubcommitteeIndex; y`gensym11: uint64): bool
  first type mismatch at position: 1
  required type for x`gensym11: SyncSubcommitteeIndex
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(x`gensym11: uint64; y`gensym11: SyncSubcommitteeIndex): bool
  first type mismatch at position: 1
  required type for x`gensym11: uint64
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(x`gensym14, y`gensym14: BlobId): bool
  first type mismatch at position: 1
  required type for x`gensym14: BlobId
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(x`gensym14: BlobId; y`gensym14: uint64): bool
  first type mismatch at position: 1
  required type for x`gensym14: BlobId
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(x`gensym14: uint64; y`gensym14: BlobId): bool
  first type mismatch at position: 1
  required type for x`gensym14: uint64
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(x`gensym15, y`gensym15: IndexInSyncCommittee): bool
  first type mismatch at position: 1
  required type for x`gensym15: IndexInSyncCommittee
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(x`gensym15: IndexInSyncCommittee; y`gensym15: uint64): bool
  first type mismatch at position: 1
  required type for x`gensym15: IndexInSyncCommittee
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(x`gensym15: uint64; y`gensym15: IndexInSyncCommittee): bool
  first type mismatch at position: 1
  required type for x`gensym15: uint64
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(x`gensym21, y`gensym21: ValidatorIndex): bool
  first type mismatch at position: 1
  required type for x`gensym21: ValidatorIndex
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(x`gensym21: ValidatorIndex; y`gensym21: uint64): bool
  first type mismatch at position: 1
  required type for x`gensym21: ValidatorIndex
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(x`gensym21: uint64; y`gensym21: ValidatorIndex): bool
  first type mismatch at position: 1
  required type for x`gensym21: uint64
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(x`gensym6, y`gensym6: CommitteeIndex): bool
  first type mismatch at position: 1
  required type for x`gensym6: CommitteeIndex
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(x`gensym6: CommitteeIndex; y`gensym6: uint64): bool
  first type mismatch at position: 1
  required type for x`gensym6: CommitteeIndex
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`(x`gensym6: uint64; y`gensym6: CommitteeIndex): bool
  first type mismatch at position: 1
  required type for x`gensym6: uint64
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`[N](a, b: FixedBytes[N]): bool
  first type mismatch at position: 1
  required type for a: FixedBytes[==.N]
  but expression 'copy[len(copy) - 1]' is of type: T
template `==`[minLen, maxLen](a, b: DynamicBytes[minLen, maxLen]): bool
  first type mismatch at position: 1
  required type for a: DynamicBytes[==.minLen, ==.maxLen]
  but expression 'copy[len(copy) - 1]' is of type: T

expression: copy[len(copy) - 1] == cur
make: *** [nimbus_beacon_node] Error 1

To Reproduce Steps to reproduce the behavior:

  1. Platform details (OS, architecture): macOS M1, Nim Compiler Version 1.6.20 [MacOSX: arm64]
  2. Branch/commit used: nimbus unstable
  3. Commands being executed: make -j10 nimbus_beacon_node

Additional context

  1. Removing the proc below from multicodec.nim fixes the problem:
    proc `!=`*(a, b: MultiCodec): bool =
    ## Returns ``true`` if MultiCodecs ``a`` and ``b`` are not equal.
    int(a) != int(b) 
  2. Replacing copy[len(copy) - 1] by copy[^1] fixes the problem.
tersec commented 1 month ago

Removing

proc `!=`*(a, b: MultiCodec): bool =
  ## Returns ``true`` if MultiCodecs ``a`` and ``b`` are not equal.
  int(a) != int(b) 

is a correct, useful change anyway, so it should be done regardless.

https://nim-lang.org/docs/manual.html#templates documents that

template `!=` (a, b: untyped): untyped =
  # this definition exists in the system module
  not (a == b)

assert(5 != 6) # the compiler rewrites that to: assert(not (5 == 6))

The !=, >, >=, in, notin, isnot operators are in fact templates

and https://github.com/nim-lang/Nim/blob/version-1-6/lib/system/comparisons.nim#L128 shows this in the Nim 1.6 stdlib exactly:

template `!=`*(x, y: untyped): untyped =
  ## Unequals operator. This is a shorthand for `not (x == y)`.
  not (x == y)

So as https://github.com/vacp2p/nim-libp2p/blob/368c9765f7c48b76d3f79b47a5cf210c84ff857c/libp2p/multicodec.nim#L288-L294 already defines both the == operator:

proc `==`*(a, b: MultiCodec): bool =
  ## Returns ``true`` if MultiCodecs ``a`` and ``b`` are equal.
  int(a) == int(b)

proc `!=`*(a, b: MultiCodec): bool =
  ## Returns ``true`` if MultiCodecs ``a`` and ``b`` are not equal.
  int(a) != int(b)

the != version should be removed as the syntax sugar it is. Nim's behavior isn't well-defined if one tries to define a != which isn't the logical negation of == regardless, so in general != should not be overloaded.

If this compilation error persists/returns, it can be investigated further.

diegomrsantos commented 1 month ago

I couldn't reproduce the error with a simpler code when overloading !=.

Adding the code below instead of the import doesn't reproduce the error either:

type
  MultiCodec* = distinct int

proc `!=`*(a, b: MultiCodec): bool =
  ## Returns ``true`` if MultiCodecs ``a`` and ``b`` are not equal.
  int(a) != int(b)
tersec commented 1 month ago
type Slot = distinct uint64
func `==`(x: Slot, y: Slot): bool {.borrow.}
import libp2p/multicodec

proc syncStep(index: int | int) =   # ensure this is generic
  let acc = default(seq[Slot])
  discard acc[acc.len-1] != 0.Slot

syncStep(0)

where libp2p/multicodec consists solely of

type MultiCodec* = distinct int

proc `!=`*(a, b: MultiCodec): bool =
  ## Returns ``true`` if MultiCodecs ``a`` and ``b`` are not equal.
  int(a) != int(b)

so, no external imports left.

This reproduces it. Import libp2p/multicodec and this error appears. Don't import libp2p/multicodec and it compiles fine.

But fundamentally if it depends on libp2p's erroneous overloading of != it's not something the Nim upstream is likely to accept as a real bug, even if it's strange behavior.

So this is what I'm getting at, unless, without the != overloading which isn't even really well-defined in Nim, it's not a useful potential Nim bug report, so if it resolves the immediate issue, why not just do that.

diegomrsantos commented 1 month ago

Sure, I'll do it. But I'd argue that the error happening only when the operator is imported from another file and disappears when copy[^1] is used is strange enough and deserves a deeper investigation as it might be a symptom of a bigger issue.

Additionally, the overload isn't even for Slot.

tersec commented 1 month ago

Well, one can show the structure of this issue without any special Nim symbols:

import "."/multicodec
template m(x: untyped) = discard x == x
proc j(n: int | int) = m(@[0'u][0])
j(0)

and

type D = object
proc m*(a: D) = discard

i.e. it's not a manifestation of anything special about != anymore.

It also occurs in Nim 1.6, Nim 2.0, and Nim devel.

It does seem odd that the m template isn't being called on non-D types in this context. There is in general a matching priority Nim has from specific to non-specific types, and untyped is sort of the least specific possible. I don't actually know if by design nothing can coexist with a template of some name taking only untyped symbols, that at that point Nim doesn't even try to fit it in the overload-matching order.

It also occurs only when

So, yes, it's a bit strange. Will leave here for potential further investigation.

But the fundamental fix to libp2p you've already at this point made remains the same, and it's not some workaround.

tersec commented 1 month ago

Ah, indeed, https://nim-lang.org/docs/manual.html#templates-typed-vs-untyped-parameters documents that:

A template where every parameter is untyped is called an immediate template. For historical reasons, templates can be explicitly annotated with an immediate pragma and then these templates do not take part in overloading resolution and the parameters' types are ignored by the compiler.

So, this is already documented, and is a specific reason not to try to overload !=, that the existing != template does not participate in overload resolution by design because all its parameters are untyped and therefore it's immediate.

diegomrsantos commented 1 month ago

Might be related to https://github.com/nim-lang/Nim/issues/7803

This gives the same error:

type D = object
proc m*(a: D) = discard

block:
  template m(x: untyped) = discard x == x
  proc j(n: int | int) = m(@[0'u][0])
  j(0)
tersec commented 1 month ago

I think it's different, because it also happens the same way if all m are templates:

type D = object
template m(a: D) = discard

block:
  template m(x: untyped) = discard x == x
  proc j(n: int | int) = m([0][0])
  j(0)
tersec commented 1 month ago

The other weird part is, if it's really because the immediate template m isn't participating in the overloading resolution, why is the error message:

a.nim(5, 38) Error: type mismatch: got <T, T>
but expected one of:
proc `==`(x, y: bool): bool
  first type mismatch at position: 1
  required type for x: bool
  but expression '[0][0]' is of type: T
proc `==`(x, y: char): bool
  first type mismatch at position: 1
  required type for x: char
  but expression '[0][0]' is of type: T
proc `==`(x, y: cstring): bool
  first type mismatch at position: 1
  required type for x: cstring
  but expression '[0][0]' is of type: T
proc `==`(x, y: float): bool
  first type mismatch at position: 1
  required type for x: float
  but expression '[0][0]' is of type: T
proc `==`(x, y: float32): bool
  first type mismatch at position: 1
  required type for x: float32
  but expression '[0][0]' is of type: T

it can only access that if it's trying to compile discard x == x, i.e. has in fact attempted to resolve to using the immediate template m.

tersec commented 1 month ago
type D = object
template m(a: D, p: int) = discard

block:
  template m(x: untyped, i: int) = echo x
  proc j(n: int | int) = m([0][0], 0)
  j(0)

No immediate template, same issue

diegomrsantos commented 1 month ago

template m(a: RootObj, p: int) = discard is enough.

tersec commented 1 month ago

https://github.com/nim-lang/Nim/issues/23680