diff options
Diffstat (limited to 'compiler/semmagic.nim')
-rw-r--r-- | compiler/semmagic.nim | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 8db62a9c8..a12e933e7 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -49,8 +49,12 @@ 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: + typExpr.typ.flags.incl tfNonConstExpr result.typ = makeTypeDesc(c, typExpr.typ) type @@ -66,7 +70,16 @@ proc semArrGet(c: PContext; n: PNode; flags: TExprFlags): PNode = if result.isNil: let x = copyTree(n) x[0] = newIdentNode(getIdent(c.cache, "[]"), n.info) - bracketNotFoundError(c, x) + if c.inGenericContext > 0: + for i in 0..<n.len: + let a = n[i] + if a.typ != nil and a.typ.kind in {tyGenericParam, tyFromExpr}: + # expression is compiled early in a generic body + result = semGenericStmt(c, x) + result.typ = makeTypeFromExpr(c, copyTree(result)) + result.typ.flags.incl tfNonConstExpr + return + bracketNotFoundError(c, x, flags) #localError(c.config, n.info, "could not resolve: " & $n) result = errorNode(c, n) @@ -224,8 +237,9 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym) of "rangeBase": # return the base type of a range type var arg = operand.skipTypes({tyGenericInst}) - assert arg.kind == tyRange - result = getTypeDescNode(c, arg.base, operand.owner, traitCall.info) + if arg.kind == tyRange: + arg = arg.base + result = getTypeDescNode(c, arg, operand.owner, traitCall.info) of "isCyclic": var operand = operand.skipTypes({tyGenericInst}) let isCyclic = canFormAcycle(c.graph, operand) @@ -237,7 +251,7 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym) proc semTypeTraits(c: PContext, n: PNode): PNode = checkMinSonsLen(n, 2, c.config) let t = n[1].typ - internalAssert c.config, t != nil and t.kind == tyTypeDesc + internalAssert c.config, t != nil and t.skipTypes({tyAlias}).kind == tyTypeDesc if t.len > 0: # This is either a type known to sem or a typedesc # param to a regular proc (again, known at instantiation) |