diff options
Diffstat (limited to 'compiler/semtypinst.nim')
-rw-r--r-- | compiler/semtypinst.nim | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 483db0bbb..759e8e6ab 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -118,7 +118,12 @@ proc replaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType = result = replaceTypeVarsTAux(cl, t) checkMetaInvariants(cl, result) -proc prepareNode(cl: var TReplTypeVars, n: PNode): PNode = +proc prepareNode*(cl: var TReplTypeVars, n: PNode): PNode = + ## instantiates a given generic expression, not a type node + if n.kind == nkSym and n.sym.kind == skType and + n.sym.typ != nil and n.sym.typ.kind == tyGenericBody: + # generic body types are allowed as user expressions, see #24090 + return n let t = replaceTypeVarsT(cl, n.typ) if t != nil and t.kind == tyStatic and t.n != nil: return if tfUnresolved in t.flags: prepareNode(cl, t.n) @@ -147,10 +152,14 @@ proc prepareNode(cl: var TReplTypeVars, n: PNode): PNode = # exception exists for the call name being a dot expression since # dot expressions need their LHS instantiated assert n.len != 0 - let ignoreFirst = n[0].kind != nkDotExpr + # avoid instantiating generic proc symbols, refine condition if needed: + let ignoreFirst = n[0].kind notin {nkDotExpr, nkBracketExpr} + nkCallKinds let name = n[0].getPIdent let ignoreSecond = name != nil and name.s == "[]" and n.len > 1 and - (n[1].typ != nil and n[1].typ.kind == tyTypeDesc) + # generic type instantiation: + ((n[1].typ != nil and n[1].typ.kind == tyTypeDesc) or + # generic proc instantiation: + (n[1].kind == nkSym and n[1].sym.isGenericRoutineStrict)) if ignoreFirst: result.add(n[0]) else: @@ -168,7 +177,10 @@ proc prepareNode(cl: var TReplTypeVars, n: PNode): PNode = # dot expressions need their LHS instantiated assert n.len != 0 let ignoreFirst = n[0].kind != nkDotExpr and - n[0].typ != nil and n[0].typ.kind == tyTypeDesc + # generic type instantiation: + ((n[0].typ != nil and n[0].typ.kind == tyTypeDesc) or + # generic proc instantiation: + (n[0].kind == nkSym and n[0].sym.isGenericRoutineStrict)) if ignoreFirst: result.add(n[0]) else: @@ -283,7 +295,8 @@ proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode; start=0; expectedType: PT replaceTypeVarsS(cl, n.sym, result.typ) else: replaceTypeVarsS(cl, n.sym, replaceTypeVarsT(cl, n.sym.typ)) - if result.sym.typ.kind == tyVoid: + # sym type can be nil if was gensym created by macro, see #24048 + if result.sym.typ != nil and result.sym.typ.kind == tyVoid: # don't add the 'void' field result = newNodeI(nkRecList, n.info) of nkRecWhen: @@ -788,6 +801,14 @@ proc replaceTypesInBody*(p: PContext, pt: TypeMapping, n: PNode; result = replaceTypeVarsN(cl, n, expectedType = expectedType) popInfoContext(p.config) +proc prepareTypesInBody*(p: PContext, pt: TypeMapping, n: PNode; + owner: PSym = nil): PNode = + var typeMap = initLayeredTypeMap(pt) + var cl = initTypeVars(p, typeMap, n.info, owner) + pushInfoContext(p.config, n.info) + result = prepareNode(cl, n) + popInfoContext(p.config) + when false: # deadcode proc replaceTypesForLambda*(p: PContext, pt: TIdTable, n: PNode; |