summary refs log tree commit diff stats
path: root/compiler/semmagic.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/semmagic.nim')
-rw-r--r--compiler/semmagic.nim20
1 files changed, 16 insertions, 4 deletions
diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim
index 1e579a959..a12e933e7 100644
--- a/compiler/semmagic.nim
+++ b/compiler/semmagic.nim
@@ -50,9 +50,11 @@ proc semTypeOf(c: PContext; n: PNode): PNode =
       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: {})
-  dec c.inTypeofContext
   result.add typExpr
+  if typExpr.typ.kind == tyFromExpr:
+    typExpr.typ.flags.incl tfNonConstExpr
   result.typ = makeTypeDesc(c, typExpr.typ)
 
 type
@@ -68,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)
 
@@ -226,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)