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.
This commit is contained in:
metagn
2024-09-08 23:49:27 +03:00
committed by GitHub
parent ebcfd96ae1
commit ca28c256f3
3 changed files with 41 additions and 0 deletions

View File

@@ -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)

View File

@@ -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)