diff options
-rw-r--r-- | compiler/semexprs.nim | 34 | ||||
-rw-r--r-- | compiler/semtypinst.nim | 4 | ||||
-rw-r--r-- | tests/metatype/tstaticparams.nim | 6 |
3 files changed, 29 insertions, 15 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 77ac98db7..f2c5e2854 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -885,7 +885,7 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent, of nkSym: if r.sym.name.id == field.id: result = r.sym else: illFormedAst(n) - + proc makeDeref(n: PNode): PNode = var t = skipTypes(n.typ, {tyGenericInst}) result = n @@ -899,6 +899,21 @@ proc makeDeref(n: PNode): PNode = addSon(result, a) t = skipTypes(t.sons[0], {tyGenericInst}) +proc readTypeParameter(c: PContext, ty: PType, + paramName: PIdent, info: TLineInfo): PNode = + internalAssert ty.kind == tyGenericInst + let ty = ty.skipGenericAlias + let tbody = ty.sons[0] + for s in countup(0, tbody.len-2): + let tParam = tbody.sons[s] + if tParam.sym.name == paramName: + let rawTyp = ty.sons[s + 1] + if rawTyp.kind == tyStatic: + return rawTyp.n + else: + let foundTyp = makeTypeDesc(c, rawTyp) + return newSymNode(copySym(tParam.sym).linkTo(foundTyp), info) + proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = ## returns nil if it's not a built-in field access checkSonsLen(n, 2) @@ -932,18 +947,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = markUsed(n, f) return of tyGenericInst: - assert ty.sons[0].kind == tyGenericBody - let tbody = ty.sons[0] - for s in countup(0, tbody.len-2): - let tParam = tbody.sons[s] - if tParam.sym.name == i: - let rawTyp = ty.sons[s + 1] - if rawTyp.kind == tyStatic: - return rawTyp.n - else: - let foundTyp = makeTypeDesc(c, rawTyp) - return newSymNode(copySym(tParam.sym).linkTo(foundTyp), n.info) - return + return readTypeParameter(c, ty, i, n.info) of tyObject, tyTuple: if ty.n.kind == nkRecList: for field in ty.n.sons: @@ -990,6 +994,10 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = n.typ = f.typ result = n + # we didn't find any field, let's look for a generic param + if result == nil and n.sons[0].typ.kind == tyGenericInst: + result = readTypeParameter(c, n.sons[0].typ, i, n.info) + proc dotTransformation(c: PContext, n: PNode): PNode = if isSymChoice(n.sons[1]): result = newNodeI(nkDotCall, n.info) diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 46ec31d90..4229f4797 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -181,7 +181,8 @@ proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode = of nkStaticExpr: var n = prepareNode(cl, n) n = reResolveCallsWithTypedescParams(cl, n) - result = cl.c.semExpr(cl.c, n) + result = if cl.allowMetaTypes: n + else: cl.c.semExpr(cl.c, n) else: var length = sonsLen(n) if length > 0: @@ -341,6 +342,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType = result = replaceTypeVarsT(cl, lastSon(t)) of tyFromExpr: + if cl.allowMetaTypes: return var n = prepareNode(cl, t.n) n = cl.c.semConstExpr(cl.c, n) if n.typ.kind == tyTypeDesc: diff --git a/tests/metatype/tstaticparams.nim b/tests/metatype/tstaticparams.nim index 0597325c3..e76dae23c 100644 --- a/tests/metatype/tstaticparams.nim +++ b/tests/metatype/tstaticparams.nim @@ -1,6 +1,6 @@ discard """ file: "tstaticparams.nim" - output: "abracadabra\ntest\n3\n15" + output: "abracadabra\ntest\n3\n15\4" """ type @@ -41,3 +41,7 @@ type var m: AffineTransform3D[float] echo high(m) +proc getRows(mtx: Matrix): int = + result = mtx.M + +echo getRows(m) |