diff options
-rw-r--r-- | compiler/semmagic.nim | 11 | ||||
-rw-r--r-- | compiler/semtypes.nim | 10 | ||||
-rw-r--r-- | tests/generics/tuninstantiatedgenericcalls.nim | 20 |
3 files changed, 41 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) diff --git a/tests/generics/tuninstantiatedgenericcalls.nim b/tests/generics/tuninstantiatedgenericcalls.nim index edce48aef..9b43d18d9 100644 --- a/tests/generics/tuninstantiatedgenericcalls.nim +++ b/tests/generics/tuninstantiatedgenericcalls.nim @@ -333,6 +333,26 @@ block: # issue #24044 type MyBuf[I] = ArrayBuf[maxLen(I)] var v: MyBuf[int] +block: # issue #15959 + proc my[T](a: T): typeof(a[0]) = discard + proc my2[T](a: T): array[sizeof(a[0]), T] = discard + proc byLent2[T](a: T): lent type(a[0]) = a[0] # Error: type mismatch: got <T, int literal(0)> + proc byLent3[T](a: T): lent typeof(a[0]) = a[0] # ditto + proc byLent4[T](a: T): lent[type(a[0])] = a[0] # Error: no generic parameters allowed for lent + var x = @[1, 2, 3] + doAssert my(x) is int + doAssert my2(x) is array[sizeof(int), seq[int]] + doAssert byLent2(x) == 1 + doAssert byLent2(x) is lent int + doAssert byLent3(x) == 1 + doAssert byLent3(x) is lent int + doAssert byLent4(x) == 1 + doAssert byLent4(x) is lent int + proc fn[U](a: U): auto = a + proc my3[T](a: T, b: typeof(fn(a))) = discard + my3(x, x) + doAssert not compiles(my3(x, x[0])) + block: # issue #22342, type section version of #22607 type GenAlias[isInt: static bool] = ( when isInt: |