diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index f75642bcb9a83..4f00c76fcbac4 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -2153,6 +2153,15 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = result[0] = newSymNode(s, n[0].info) result[1] = semAddrArg(c, n[1], s.name.s == "unsafeAddr") result.typ = makePtrType(c, result[1].typ) + of mBitandI: # somehow, not mAnd + if c.inStaticContext > 0: # TODO: if c.inStaticContext == c.inStaticContextForConst + 1 ? + result = newTree(nkCall) + result.add newIdentNode(getIdent(c.cache, "nimInternalAndVMM"), n.info) + result.add n[1] + result.add n[2] + result = semExpr(c, result) + else: + result = semDirectOp(c, n, flags) of mTypeOf: markUsed(c, n.info, s) result = semTypeOf(c, n) diff --git a/lib/system/basic_types.nim b/lib/system/basic_types.nim index a6bf69ebc2f5d..04909d4206ef6 100644 --- a/lib/system/basic_types.nim +++ b/lib/system/basic_types.nim @@ -50,6 +50,13 @@ proc `and`*(x, y: bool): bool {.magic: "And", noSideEffect.} ## are true). ## ## Evaluation is lazy: if ``x`` is false, ``y`` will not even be evaluated. + ## Semantic check is lazy in VM, to allow `when declared(Foo) and T is Foo` + +template nimInternalAndVM*(x: bool, y: untyped): bool = + ## Internal lowering used by `and` in VM + when x: y + else: false + proc `or`*(x, y: bool): bool {.magic: "Or", noSideEffect.} ## Boolean ``or``; returns true if ``not (not x and not y)`` (if any of ## the arguments is true).