diff --git a/compiler/options.nim b/compiler/options.nim index b77bdd2a3371..498c8438a7e2 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -228,6 +228,7 @@ type openSym, # remove nfDisabledOpenSym when this is default # alternative to above: genericsOpenSym + genericProcCompileTime vtables LegacyFeature* = enum diff --git a/compiler/semdata.nim b/compiler/semdata.nim index ca35ddc53a6e..f4b6cb698f81 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -171,7 +171,6 @@ type inUncheckedAssignSection*: int importModuleLookup*: Table[int, seq[int]] # (module.ident.id, [module.id]) skipTypes*: seq[PNode] # used to skip types between passes in type section. So far only used for inheritance, sets and generic bodies. - inTypeofContext*: int TBorrowState* = enum bsNone, bsReturnNotMatch, bsNoDistinct, bsGeneric, bsNotSupported, bsMatch diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 6a3b401111e0..61504219f14e 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -995,8 +995,11 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode = if callee.magic notin ctfeWhitelist: return - if callee.kind notin {skProc, skFunc, skConverter, skConst} or - callee.isGenericRoutineStrict: + if callee.kind notin {skProc, skFunc, skConverter, skConst} or ( + if genericProcCompileTime in c.features: + callee.isGenericRoutineStrict + else: + callee.isGenericRoutine): return if n.typ != nil and typeAllowed(n.typ, skConst, c) != nil: return @@ -1136,7 +1139,7 @@ proc afterCallActions(c: PContext; n, orig: PNode, flags: TExprFlags; expectedTy not (result.typ.kind == tySequence and result.elementType.kind == tyEmpty): liftTypeBoundOps(c, result.typ, n.info) #result = patchResolvedTypeBoundOp(c, result) - if c.matchedConcept == nil and (c.inTypeofContext == 0 or callee.magic != mNone): + if c.matchedConcept == nil: # don't fold calls in concepts and typeof result = evalAtCompileTime(c, result) diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index a12e933e79ca..6ac8082a6fa8 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -49,8 +49,6 @@ proc semTypeOf(c: PContext; n: PNode): PNode = else: m = mode.intVal result = newNodeI(nkTypeOfExpr, n.info) - inc c.inTypeofContext - defer: dec c.inTypeofContext # compiles can raise an exception let typExpr = semExprWithType(c, n[1], if m == 1: {efInTypeof} else: {}) result.add typExpr if typExpr.typ.kind == tyFromExpr: diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 9af71ba8f244..724ad156b3e1 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -1870,8 +1870,6 @@ proc semStaticType(c: PContext, childNode: PNode, prev: PType): PType = proc semTypeOf(c: PContext; n: PNode; prev: PType): PType = openScope(c) - inc c.inTypeofContext - defer: dec c.inTypeofContext # compiles can raise an exception let t = semExprWithType(c, n, {efInTypeof}) closeScope(c) fixupTypeOf(c, prev, t) @@ -1888,8 +1886,6 @@ proc semTypeOf2(c: PContext; n: PNode; prev: PType): PType = localError(c.config, n.info, "typeof: cannot evaluate 'mode' parameter at compile-time") else: m = mode.intVal - inc c.inTypeofContext - defer: dec c.inTypeofContext # compiles can raise an exception let t = semExprWithType(c, n[1], if m == 1: {efInTypeof} else: {}) closeScope(c) fixupTypeOf(c, prev, t) diff --git a/tests/vm/tgenericcompiletimeproc.nim b/tests/vm/tgenericcompiletimeproc.nim index 08099ebbe354..f9f98bd2b13f 100644 --- a/tests/vm/tgenericcompiletimeproc.nim +++ b/tests/vm/tgenericcompiletimeproc.nim @@ -1,3 +1,15 @@ +block: + # don't fold compile time procs in typeof with experimental switch disabled + proc fail[T](x: T): T {.compileTime.} = + doAssert false + x + doAssert typeof(fail(123)) is typeof(123) + proc p(x: int): int = x + + type Foo = typeof(p(fail(123))) + +{.experimental: "genericProcCompileTime".} + block: # issue #10753 proc foo(x: int): int {.compileTime.} = x const a = foo(123) @@ -18,16 +30,6 @@ block: # issue #19365 doAssert f(123) == 246 doAssert f(1.0) == 2.0 -block: - # don't fold compile time procs in typeof - proc fail[T](x: T): T {.compileTime.} = - doAssert false - x - doAssert typeof(fail(123)) is typeof(123) - proc p(x: int): int = x - - type Foo = typeof(p(fail(123))) - block: # issue #24150, related regression proc w(T: type): T {.compileTime.} = default(ptr T)[] template y(v: auto): auto = typeof(v) is int