From ee876aee28a93d45f95ae605199b19274eee92c2 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Mon, 6 Dec 2021 20:38:23 +0100 Subject: [PATCH] allow `HSlice` bounded by constants of distinct types (#19219) [backport:1.2] When creating heterogenous slices of distinct types, the compiler does not initialize the internal type's `size` before accessing it. This then leads to this crash message: ``` compiler/int128.nim(594, 11) `false` masking only implemented for 1, 2, 4 and 8 bytes [AssertionError] ``` This patch initializes the `size` properly, fixing the problem. (cherry picked from commit 0213c7313b2edf8e8ec9d81764685744e874ef84) --- compiler/semfold.nim | 16 ++++++++-------- tests/slice/tdistinct.nim | 2 ++ 2 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 tests/slice/tdistinct.nim diff --git a/compiler/semfold.nim b/compiler/semfold.nim index 1f8efc4de0..4cf659d63d 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -133,7 +133,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; idgen: IdGenerator; g: ModuleGraph): P of mCard: result = newIntNodeT(toInt128(nimsets.cardSet(g.config, a)), n, idgen, g) of mBitnotI: if n.typ.isUnsigned: - result = newIntNodeT(bitnot(getInt(a)).maskBytes(int(n.typ.size)), n, idgen, g) + result = newIntNodeT(bitnot(getInt(a)).maskBytes(int(getSize(g.config, n.typ))), n, idgen, g) else: result = newIntNodeT(bitnot(getInt(a)), n, idgen, g) of mLengthArray: result = newIntNodeT(lengthOrd(g.config, a.typ), n, idgen, g) @@ -248,23 +248,23 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; idgen: IdGenerator; g: ModuleGraph): P of mBitorI, mOr: result = newIntNodeT(bitor(getInt(a), getInt(b)), n, idgen, g) of mBitxorI, mXor: result = newIntNodeT(bitxor(getInt(a), getInt(b)), n, idgen, g) of mAddU: - let val = maskBytes(getInt(a) + getInt(b), int(n.typ.size)) + let val = maskBytes(getInt(a) + getInt(b), int(getSize(g.config, n.typ))) result = newIntNodeT(val, n, idgen, g) of mSubU: - let val = maskBytes(getInt(a) - getInt(b), int(n.typ.size)) + let val = maskBytes(getInt(a) - getInt(b), int(getSize(g.config, n.typ))) result = newIntNodeT(val, n, idgen, g) # echo "subU: ", val, " n: ", n, " result: ", val of mMulU: - let val = maskBytes(getInt(a) * getInt(b), int(n.typ.size)) + let val = maskBytes(getInt(a) * getInt(b), int(getSize(g.config, n.typ))) result = newIntNodeT(val, n, idgen, g) of mModU: - let argA = maskBytes(getInt(a), int(a.typ.size)) - let argB = maskBytes(getInt(b), int(a.typ.size)) + let argA = maskBytes(getInt(a), int(getSize(g.config, a.typ))) + let argB = maskBytes(getInt(b), int(getSize(g.config, a.typ))) if argB != Zero: result = newIntNodeT(argA mod argB, n, idgen, g) of mDivU: - let argA = maskBytes(getInt(a), int(a.typ.size)) - let argB = maskBytes(getInt(b), int(a.typ.size)) + let argA = maskBytes(getInt(a), int(getSize(g.config, a.typ))) + let argB = maskBytes(getInt(b), int(getSize(g.config, a.typ))) if argB != Zero: result = newIntNodeT(argA div argB, n, idgen, g) of mLeSet: result = newIntNodeT(toInt128(ord(containsSets(g.config, a, b))), n, idgen, g) diff --git a/tests/slice/tdistinct.nim b/tests/slice/tdistinct.nim new file mode 100644 index 0000000000..d99b529a72 --- /dev/null +++ b/tests/slice/tdistinct.nim @@ -0,0 +1,2 @@ +type Foo = distinct uint64 +const slice = 0 ..< 42.Foo