diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/aliases.nim | 3 | ||||
-rw-r--r-- | compiler/ccgexprs.nim | 5 | ||||
-rw-r--r-- | compiler/ccgtrav.nim | 4 | ||||
-rw-r--r-- | compiler/ccgtypes.nim | 6 | ||||
-rw-r--r-- | compiler/cgen.nim | 2 | ||||
-rw-r--r-- | compiler/jsgen.nim | 2 | ||||
-rw-r--r-- | compiler/jstypes.nim | 2 | ||||
-rw-r--r-- | compiler/lowerings.nim | 4 | ||||
-rw-r--r-- | compiler/semasgn.nim | 3 | ||||
-rw-r--r-- | compiler/semexprs.nim | 6 | ||||
-rw-r--r-- | compiler/semfields.nim | 2 | ||||
-rw-r--r-- | compiler/seminst.nim | 2 | ||||
-rw-r--r-- | compiler/sempass2.nim | 2 | ||||
-rw-r--r-- | compiler/semstmts.nim | 2 | ||||
-rw-r--r-- | compiler/semtypes.nim | 8 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 25 | ||||
-rw-r--r-- | compiler/suggest.nim | 2 | ||||
-rw-r--r-- | compiler/types.nim | 12 |
18 files changed, 61 insertions, 31 deletions
diff --git a/compiler/aliases.nim b/compiler/aliases.nim index 4b592ee60..4186900ec 100644 --- a/compiler/aliases.nim +++ b/compiler/aliases.nim @@ -46,7 +46,8 @@ proc isPartOfAux(a, b: PType, marker: var IntSet): TAnalysisResult = if compareTypes(a, b, dcEqIgnoreDistinct): return arYes case a.kind of tyObject: - result = isPartOfAux(a.sons[0], b, marker) + if a.sons[0] != nil: + result = isPartOfAux(a.sons[0].skipTypes(skipPtrs), b, marker) if result == arNo: result = isPartOfAux(a.n, b, marker) of tyGenericInst, tyDistinct: result = isPartOfAux(lastSon(a), b, marker) diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 719bc195c..e1ee6f1de 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -726,6 +726,7 @@ proc lookupFieldAgain(p: BProc, ty: PType; field: PSym; r: var Rope): PSym = var ty = ty assert r != nil while ty != nil: + ty = ty.skipTypes(skipPtrs) assert(ty.kind in {tyTuple, tyObject}) result = lookupInRecord(ty.n, field.name) if result != nil: break @@ -1257,7 +1258,7 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) = if not p.module.compileToCpp: while t.kind == tyObject and t.sons[0] != nil: add(r, ~".Sup") - t = skipTypes(t.sons[0], typedescInst) + t = skipTypes(t.sons[0], skipPtrs) if isObjLackingTypeField(t): globalError(x.info, errGenerated, "no 'of' operator available for pure objects") @@ -1875,7 +1876,7 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) = if not p.module.compileToCpp: while t.kind == tyObject and t.sons[0] != nil: add(r, ".Sup") - t = skipTypes(t.sons[0], abstractInst) + t = skipTypes(t.sons[0], skipPtrs) if nilCheck != nil: linefmt(p, cpsStmts, "if ($1) #chckObj($2.m_type, $3);$n", nilCheck, r, genTypeInfo(p.module, dest)) diff --git a/compiler/ccgtrav.nim b/compiler/ccgtrav.nim index c4d47f148..a8c079b35 100644 --- a/compiler/ccgtrav.nim +++ b/compiler/ccgtrav.nim @@ -73,7 +73,9 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: Rope, typ: PType) = lineF(p, cpsStmts, "}$n", []) of tyObject: for i in countup(0, sonsLen(typ) - 1): - genTraverseProc(c, accessor.parentObj(c.p.module), typ.sons[i]) + var x = typ.sons[i] + if x != nil: x = x.skipTypes(skipPtrs) + genTraverseProc(c, accessor.parentObj(c.p.module), x) if typ.n != nil: genTraverseProc(c, accessor, typ.n) of tyTuple: let typ = getUniqueType(typ) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index e30395d2e..15fefa944 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -475,11 +475,11 @@ proc getRecordDesc(m: BModule, typ: PType, name: Rope, hasField = true elif m.compileToCpp: appcg(m, result, " : public $1 {$n", - [getTypeDescAux(m, typ.sons[0], check)]) + [getTypeDescAux(m, typ.sons[0].skipTypes(skipPtrs), check)]) hasField = true else: appcg(m, result, " {$n $1 Sup;$n", - [getTypeDescAux(m, typ.sons[0], check)]) + [getTypeDescAux(m, typ.sons[0].skipTypes(skipPtrs), check)]) hasField = true else: addf(result, " {$n", [name]) @@ -901,7 +901,7 @@ proc genObjectInfo(m: BModule, typ, origType: PType, name: Rope) = addf(m.s[cfsTypeInit3], "$1.node = &$2;$n", [name, tmp]) var t = typ.sons[0] while t != nil: - t = t.skipTypes(abstractInst) + t = t.skipTypes(skipPtrs) t.flags.incl tfObjHasKids t = t.sons[0] diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 42883b590..4a3113edf 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -246,7 +246,7 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc, if not p.module.compileToCpp: while (s.kind == tyObject) and (s.sons[0] != nil): add(r, ".Sup") - s = skipTypes(s.sons[0], abstractInst) + s = skipTypes(s.sons[0], skipPtrs) linefmt(p, section, "$1.m_type = $2;$n", r, genTypeInfo(p.module, t)) of frEmbedded: # worst case for performance: diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 3e56e2f41..d17f5580e 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -1364,7 +1364,7 @@ proc createObjInitList(p: PProc, typ: PType, excludedFieldIDs: IntSet, output: v if output.len > 0: output.add(", ") addf(output, "m_type: $1" | "'m_type' => $#", [genTypeInfo(p, t)]) while t != nil: - createRecordVarAux(p, t.n, excludedFieldIDs, output) + createRecordVarAux(p, t.skipTypes(skipPtrs).n, excludedFieldIDs, output) t = t.sons[0] proc arrayTypeForElemType(typ: PType): string = diff --git a/compiler/jstypes.nim b/compiler/jstypes.nim index cf1679ee4..0aaf93579 100644 --- a/compiler/jstypes.nim +++ b/compiler/jstypes.nim @@ -76,7 +76,7 @@ proc genObjectInfo(p: PProc, typ: PType, name: Rope) = addf(p.g.typeInfo, "$1.node = NNI$2;$n", [name, rope(typ.id)]) if (typ.kind == tyObject) and (typ.sons[0] != nil): addf(p.g.typeInfo, "$1.base = $2;$n", - [name, genTypeInfo(p, typ.sons[0])]) + [name, genTypeInfo(p, typ.sons[0].skipTypes(skipPtrs))]) proc genTupleFields(p: PProc, typ: PType): Rope = var s: Rope = nil diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index 36eb24653..9db4383f6 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -172,7 +172,7 @@ proc indirectAccess*(a: PNode, b: string, info: TLineInfo): PNode = if field != nil: break t = t.sons[0] if t == nil: break - t = t.skipTypes(abstractInst) + t = t.skipTypes(skipPtrs) #if field == nil: # echo "FIELD ", b # debug deref.typ @@ -193,7 +193,7 @@ proc getFieldFromObj*(t: PType; v: PSym): PSym = if result != nil: break t = t.sons[0] if t == nil: break - t = t.skipTypes(abstractInst) + t = t.skipTypes(skipPtrs) proc indirectAccess*(a: PNode, b: PSym, info: TLineInfo): PNode = # returns a[].b as a node diff --git a/compiler/semasgn.nim b/compiler/semasgn.nim index 9702128ba..2e925e386 100644 --- a/compiler/semasgn.nim +++ b/compiler/semasgn.nim @@ -203,7 +203,8 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) = defaultOp(c, t, body, x, y) of tyObject, tyDistinct: if not considerOverloadedOp(c, t, body, x, y): - if t.sons[0] != nil: liftBodyAux(c, t.sons[0], body, x, y) + if t.sons[0] != nil: + liftBodyAux(c, t.sons[0].skipTypes(skipPtrs), body, x, y) if t.kind == tyObject: liftBodyObj(c, t.n, body, x, y) of tyTuple: liftBodyTup(c, t, body, x, y) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 274bb15b9..5c29530b8 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1070,7 +1070,7 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = result = check return result if ty.sons[0] == nil: break - ty = skipTypes(ty.sons[0], {tyGenericInst}) + ty = skipTypes(ty.sons[0], skipPtrs) # old code, not sure if it's live code: markUsed(n.info, s) styleCheckUse(n.info, s) @@ -1148,7 +1148,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = f = lookupInRecordAndBuildCheck(c, n, ty.n, i, check) if f != nil: break if ty.sons[0] == nil: break - ty = skipTypes(ty.sons[0], {tyGenericInst}) + ty = skipTypes(ty.sons[0], skipPtrs) if f != nil: if fieldVisible(c, f): # is the access to a public field or in the same module or in a friend? @@ -2108,7 +2108,7 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = f = lookupInRecordAndBuildCheck(c, it, t.n, id, check) if f != nil: break if t.sons[0] == nil: break - t = skipTypes(t.sons[0], {tyGenericInst}) + t = skipTypes(t.sons[0], skipPtrs) if f != nil and fieldVisible(c, f): it.sons[0] = newSymNode(f) e = fitNode(c, f.typ, e) diff --git a/compiler/semfields.nim b/compiler/semfields.nim index 2e6c6c3ea..9d8cea862 100644 --- a/compiler/semfields.nim +++ b/compiler/semfields.nim @@ -152,7 +152,7 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode = while t.kind == tyObject: semForObjectFields(fc, t.n, n, stmts) if t.sons[0] == nil: break - t = skipTypes(t.sons[0], abstractPtrs) + t = skipTypes(t.sons[0], skipPtrs) dec(c.p.nestedLoopCounter) # for TR macros this 'while true: ...; break' loop is pretty bad, so # we avoid it now if we can: diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 498ebc3fb..d7cad6a2f 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -47,7 +47,7 @@ proc rawHandleSelf(c: PContext; owner: PSym) = while t.kind == tyObject: addObjFieldsToLocalScope(c, t.n) if t.sons[0] == nil: break - t = t.sons[0].skipTypes(abstractPtrs) + t = t.sons[0].skipTypes(skipPtrs) proc pushProcCon*(c: PContext; owner: PSym) = rawPushProcCon(c, owner) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 3908fa26e..df9b3f69c 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -131,7 +131,7 @@ proc guardDotAccess(a: PEffects; n: PNode) = if field != nil: break ty = ty.sons[0] if ty == nil: break - ty = ty.skipTypes(abstractPtrs) + ty = ty.skipTypes(skipPtrs) if field == nil: localError(n.info, errGenerated, "invalid guard field: " & g.name.s) return diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index cd96600ec..97c3b6ddd 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -659,7 +659,7 @@ proc semRaise(c: PContext, n: PNode): PNode = if n.sons[0].kind != nkEmpty: n.sons[0] = semExprWithType(c, n.sons[0]) var typ = n.sons[0].typ - if typ.kind != tyRef or typ.sons[0].kind != tyObject: + if typ.kind != tyRef or typ.lastSon.kind != tyObject: localError(n.info, errExprCannotBeRaised) proc addGenericParamListToScope(c: PContext, n: PNode) = diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 3834d0b51..ed576f85e 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -661,11 +661,12 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType): PType = if n.sonsLen == 0: return newConstraint(c, tyObject) var check = initIntSet() var pos = 0 - var base: PType = nil + var base, realBase: PType = nil # n.sons[0] contains the pragmas (if any). We process these later... checkSonsLen(n, 3) if n.sons[1].kind != nkEmpty: - base = skipTypesOrNil(semTypeNode(c, n.sons[1].sons[0], nil), skipPtrs) + realBase = semTypeNode(c, n.sons[1].sons[0], nil) + base = skipTypesOrNil(realBase, skipPtrs) if base.isNil: localError(n.info, errIllegalRecursionInTypeX, "object") else: @@ -676,9 +677,10 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType): PType = if concreteBase.kind != tyError: localError(n.sons[1].info, errInheritanceOnlyWithNonFinalObjects) base = nil + realBase = nil if n.kind != nkObjectTy: internalError(n.info, "semObjectNode") result = newOrPrevType(tyObject, prev, c) - rawAddSon(result, base) + rawAddSon(result, realBase) if result.n.isNil: result.n = newNodeI(nkRecList, n.info) else: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 1abfaab69..90435f9c0 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -352,18 +352,28 @@ proc handleFloatRange(f, a: PType): TTypeRelation = else: result = isIntConv else: result = isNone -proc isObjectSubtype(a, f: PType): int = +proc isObjectSubtype(c: var TCandidate; a, f, fGenericOrigin: PType): int = var t = a assert t.kind == tyObject var depth = 0 + var last = a while t != nil and not sameObjectTypes(f, t): assert t.kind == tyObject t = t.sons[0] if t == nil: break - t = skipTypes(t, {tyGenericInst}) + last = t + t = skipTypes(t, skipPtrs) inc depth if t != nil: + if fGenericOrigin != nil and last.kind == tyGenericInst and + last.len-1 == fGenericOrigin.len: + for i in countup(1, sonsLen(fGenericOrigin) - 1): + let x = PType(idTableGet(c.bindings, fGenericOrigin.sons[i])) + if x == nil: + put(c, fGenericOrigin.sons[i], last.sons[i]) result = depth + else: + result = -1 type SkippedPtr = enum skippedNone, skippedRef, skippedPtr @@ -896,7 +906,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = result = isEqual # elif tfHasMeta in f.flags: result = recordRel(c, f, a) else: - var depth = isObjectSubtype(a, f) + var depth = isObjectSubtype(c, a, f, nil) if depth > 0: inc(c.inheritancePenalty, depth) result = isSubtype @@ -1012,6 +1022,15 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = result = isGeneric else: let genericBody = f.sons[0] + var askip = skippedNone + var fskip = skippedNone + let aobj = x.skipToObject(askip) + let fobj = genericBody.lastSon.skipToObject(fskip) + if fobj != nil and aobj != nil and askip == fskip: + let depth = isObjectSubtype(c, aobj, fobj, f) + if depth >= 0: + c.inheritancePenalty += depth + return if depth == 0: isGeneric else: isSubtype result = typeRel(c, genericBody, x) if result != isNone: # see tests/generics/tgeneric3.nim for an example that triggers this diff --git a/compiler/suggest.nim b/compiler/suggest.nim index c127b968c..f331fce69 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -273,7 +273,7 @@ proc suggestFieldAccess(c: PContext, n: PNode, outputs: var int) = while true: suggestObject(c, t.n, outputs) if t.sons[0] == nil: break - t = skipTypes(t.sons[0], {tyGenericInst}) + t = skipTypes(t.sons[0], skipPtrs) suggestOperations(c, n, typ, outputs) elif typ.kind == tyTuple and typ.n != nil: suggestSymList(c, typ.n, outputs) diff --git a/compiler/types.nim b/compiler/types.nim index 4690d5a1f..3db0c4507 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -94,7 +94,8 @@ proc invalidGenericInst(f: PType): bool = proc isPureObject(typ: PType): bool = var t = typ - while t.kind == tyObject and t.sons[0] != nil: t = t.sons[0] + while t.kind == tyObject and t.sons[0] != nil: + t = t.sons[0].skipTypes(skipPtrs) result = t.sym != nil and sfPure in t.sym.flags proc getOrdValue(n: PNode): BiggestInt = @@ -228,7 +229,8 @@ proc searchTypeForAux(t: PType, predicate: TTypePredicate, if result: return case t.kind of tyObject: - result = searchTypeForAux(t.sons[0], predicate, marker) + if t.sons[0] != nil: + result = searchTypeForAux(t.sons[0].skipTypes(skipPtrs), predicate, marker) if not result: result = searchTypeNodeForAux(t.n, predicate, marker) of tyGenericInst, tyDistinct: result = searchTypeForAux(lastSon(t), predicate, marker) @@ -265,7 +267,9 @@ proc analyseObjectWithTypeFieldAux(t: PType, if searchTypeNodeForAux(t.n, isObjectWithTypeFieldPredicate, marker): return frEmbedded for i in countup(0, sonsLen(t) - 1): - res = analyseObjectWithTypeFieldAux(t.sons[i], marker) + var x = t.sons[i] + if x != nil: x = x.skipTypes(skipPtrs) + res = analyseObjectWithTypeFieldAux(x, marker) if res == frEmbedded: return frEmbedded if res == frHeader: result = frHeader @@ -1293,7 +1297,7 @@ proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt = a = maxAlign of tyObject: if typ.sons[0] != nil: - result = computeSizeAux(typ.sons[0], a) + result = computeSizeAux(typ.sons[0].skipTypes(skipPtrs), a) if result < 0: return maxAlign = a elif isObjectWithTypeFieldPredicate(typ): |