summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authormetagn <metagngn@gmail.com>2024-09-08 23:49:27 +0300
committerGitHub <noreply@github.com>2024-09-08 22:49:27 +0200
commitca28c256f3b5214b59700d0be260f700459c19d0 (patch)
tree77cb144a1d3b8a2cae3041965a68708216e2c7be /compiler
parentebcfd96ae1ba10cdf31cb3167a12d4d76d75a8c9 (diff)
downloadNim-ca28c256f3b5214b59700d0be260f700459c19d0.tar.gz
fix subscript in generics, typeof, `lent` with bracket (#24067)
fixes #15959

Another followup of #22029 and #24005, subscript expressions now
recognize when their parameters are generic types, then generating
tyFromExpr. `typeof` also now properly sets `tfNonConstExpr` to make it
usable in proc signatures. `lent` with brackets like `lent[T]` is also
now allowed.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/semmagic.nim11
-rw-r--r--compiler/semtypes.nim10
2 files changed, 21 insertions, 0 deletions
diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim
index 524c9a0ab..360d23477 100644
--- a/compiler/semmagic.nim
+++ b/compiler/semmagic.nim
@@ -53,6 +53,8 @@ proc semTypeOf(c: PContext; n: PNode): PNode =
   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,6 +70,15 @@ proc semArrGet(c: PContext; n: PNode; flags: TExprFlags): PNode =
   if result.isNil:
     let x = copyTree(n)
     x[0] = newIdentNode(getIdent(c.cache, "[]"), n.info)
+    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)
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index d51cafe0c..5faefc9aa 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -1864,6 +1864,8 @@ proc semTypeOf(c: PContext; n: PNode; prev: PType): PType =
   closeScope(c)
   fixupTypeOf(c, prev, t)
   result = t.typ
+  if result.kind == tyFromExpr:
+    result.flags.incl tfNonConstExpr
 
 proc semTypeOf2(c: PContext; n: PNode; prev: PType): PType =
   openScope(c)
@@ -1880,6 +1882,8 @@ proc semTypeOf2(c: PContext; n: PNode; prev: PType): PType =
   closeScope(c)
   fixupTypeOf(c, prev, t)
   result = t.typ
+  if result.kind == tyFromExpr:
+    result.flags.incl tfNonConstExpr
 
 proc semTypeIdent(c: PContext, n: PNode): PSym =
   if n.kind == nkSym:
@@ -2116,6 +2120,12 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
     of mRef: result = semAnyRef(c, n, tyRef, prev)
     of mPtr: result = semAnyRef(c, n, tyPtr, prev)
     of mTuple: result = semTuple(c, n, prev)
+    of mBuiltinType:
+      case s.name.s
+      of "lent": result = semAnyRef(c, n, tyLent, prev)
+      of "sink": result = semAnyRef(c, n, tySink, prev)
+      of "owned": result = semAnyRef(c, n, tyOwned, prev)
+      else: result = semGeneric(c, n, s, prev)
     else: result = semGeneric(c, n, s, prev)
   of nkDotExpr:
     let typeExpr = semExpr(c, n)