diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/semdata.nim | 1 | ||||
-rw-r--r-- | compiler/semstmts.nim | 5 | ||||
-rw-r--r-- | compiler/semtypes.nim | 9 |
3 files changed, 10 insertions, 5 deletions
diff --git a/compiler/semdata.nim b/compiler/semdata.nim index e92698916..bf0f73f80 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -168,6 +168,7 @@ type sideEffects*: Table[int, seq[(TLineInfo, PSym)]] # symbol.id index inUncheckedAssignSection*: int importModuleLookup*: Table[int, seq[int]] # (module.ident.id, [module.id]) + skipTypes*: seq[PNode] # used to skip types between passes in type section. So far only used for inheritance. template config*(c: PContext): ConfigRef = c.graph.config diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 48b075570..95820c939 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1498,7 +1498,9 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = obj.flags.incl sfPure obj.typ = objTy objTy.sym = obj - + for sk in c.skipTypes: + discard semTypeNode(c, sk, nil) + c.skipTypes = @[] proc checkForMetaFields(c: PContext; n: PNode) = proc checkMeta(c: PContext; n: PNode; t: PType) = if t != nil and t.isMetaType and tfGenericTypeParam notin t.flags: @@ -1565,7 +1567,6 @@ proc typeSectionFinalPass(c: PContext, n: PNode) = # fix bug #5170, bug #17162, bug #15526: ensure locally scoped types get a unique name: if s.typ.kind in {tyEnum, tyRef, tyObject} and not isTopLevel(c): incl(s.flags, sfGenSym) - #instAllTypeBoundOp(c, n.info) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index a9fc980db..b342356f8 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -865,14 +865,15 @@ proc skipGenericInvocation(t: PType): PType {.inline.} = result = lastSon(result) proc tryAddInheritedFields(c: PContext, check: var IntSet, pos: var int, - obj: PType, n: PNode, isPartial = false): bool = - if (not isPartial) and (obj.kind notin {tyObject, tyGenericParam} or tfFinal in obj.flags): + obj: PType, n: PNode, isPartial = false, innerObj: PType = nil): bool = + if ((not isPartial) and (obj.kind notin {tyObject, tyGenericParam} or tfFinal in obj.flags)) or + (innerObj != nil and obj.sym.id == innerObj.sym.id): localError(c.config, n.info, "Cannot inherit from: '" & $obj & "'") result = false elif obj.kind == tyObject: result = true if (obj.len > 0) and (obj[0] != nil): - result = result and tryAddInheritedFields(c, check, pos, obj[0].skipGenericInvocation, n) + result = result and tryAddInheritedFields(c, check, pos, obj[0].skipGenericInvocation, n, false, obj) addInheritedFieldsAux(c, check, pos, obj.n) else: result = true @@ -905,6 +906,8 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType; flags: TTypeFlags): PType if not tryAddInheritedFields(c, check, pos, concreteBase, n): return newType(tyError, nextTypeId c.idgen, result.owner) + elif concreteBase.kind == tyForward: + c.skipTypes.add n #we retry in the final pass else: if concreteBase.kind != tyError: localError(c.config, n[1].info, "inheritance only works with non-final objects; " & |