From 72291875bf895e8e0d22ab3f375752417b07ed25 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Sun, 29 Dec 2013 16:08:33 +0200 Subject: [PATCH] integrate the logic of fixupProcType into ReplaceTypeVars --- compiler/ast.nim | 20 ++++++++--- compiler/semdata.nim | 14 ++++---- compiler/seminst.nim | 3 +- compiler/semtypes.nim | 19 +++++++---- compiler/semtypinst.nim | 42 ++++++++++++++--------- compiler/sigmatch.nim | 15 ++++++--- compiler/types.nim | 5 +-- tests/compile/tbindtypedesc.nim | 60 ++++++++++++++++----------------- tests/reject/tenummix.nim | 2 +- tests/run/tfailedassert.nim | 2 +- 10 files changed, 108 insertions(+), 74 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 45784bbcbf..92f3ce8d37 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -351,9 +351,12 @@ const tyPureObject* = tyTuple GcTypeKinds* = {tyRef, tySequence, tyString} tyError* = tyProxy # as an errornous node should match everything + tyTypeClasses* = {tyTypeClass, tyBuiltInTypeClass, tyCompositeTypeClass, tyParametricTypeClass, tyAnd, tyOr, tyNot, tyAnything} + tyMetaTypes* = {tyGenericParam, tyTypeDesc, tyStatic, tyExpr} + tyTypeClasses + type TTypeKinds* = set[TTypeKind] @@ -397,7 +400,8 @@ type tfNeedsInit, # type constains a "not nil" constraint somewhere or some # other type so that it requires inititalization tfHasShared, # type constains a "shared" constraint modifier somewhere - tfHasMeta, # type has "typedesc" or "expr" somewhere; or uses '|' + tfHasMeta, # type contains "wildcard" sub-types such as generic params + # or other type classes tfHasGCedMem, # type contains GC'ed memory tfGenericTypeParam tfHasStatic @@ -777,9 +781,11 @@ const GenericTypes*: TTypeKinds = {tyGenericInvokation, tyGenericBody, tyGenericParam} + StructuralEquivTypes*: TTypeKinds = {tyArrayConstr, tyNil, tyTuple, tyArray, tySet, tyRange, tyPtr, tyRef, tyVar, tySequence, tyProc, tyOpenArray, tyVarargs} + ConcreteTypes*: TTypeKinds = { # types of the expr that may occur in:: # var x = expr tyBool, tyChar, tyEnum, tyArray, tyObject, @@ -1222,7 +1228,7 @@ proc newSons(father: PNode, length: int) = proc propagateToOwner*(owner, elem: PType) = const HaveTheirOwnEmpty = {tySequence, tySet} owner.flags = owner.flags + (elem.flags * {tfHasShared, tfHasMeta, - tfHasGCedMem}) + tfHasStatic, tfHasGCedMem}) if tfNotNil in elem.flags: if owner.kind in {tyGenericInst, tyGenericBody, tyGenericInvokation}: owner.flags.incl tfNotNil @@ -1235,10 +1241,14 @@ proc propagateToOwner*(owner, elem: PType) = if tfShared in elem.flags: owner.flags.incl tfHasShared - - if elem.kind in {tyExpr, tyStatic, tyTypeDesc}: + + if elem.kind in tyMetaTypes: owner.flags.incl tfHasMeta - elif elem.kind in {tyString, tyRef, tySequence} or + + if elem.kind == tyStatic: + owner.flags.incl tfHasStatic + + if elem.kind in {tyString, tyRef, tySequence} or elem.kind == tyProc and elem.callConv == ccClosure: owner.flags.incl tfHasGCedMem diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 874e5dab46..687140ce98 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -217,23 +217,21 @@ proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode = proc makeAndType*(c: PContext, t1, t2: PType): PType = result = newTypeS(tyAnd, c) result.sons = @[t1, t2] - result.flags.incl tfHasMeta - if tfHasStatic in t1.flags or tfHasStatic in t2.flags: - result.flags.incl tfHasStatic + propagateToOwner(result, t1) + propagateToOwner(result, t2) proc makeOrType*(c: PContext, t1, t2: PType): PType = result = newTypeS(tyOr, c) result.sons = @[t1, t2] - result.flags.incl tfHasMeta - if tfHasStatic in t1.flags or tfHasStatic in t2.flags: - result.flags.incl tfHasStatic + propagateToOwner(result, t1) + propagateToOwner(result, t2) proc makeNotType*(c: PContext, t1: PType): PType = result = newTypeS(tyNot, c) result.sons = @[t1] - result.flags.incl tfHasMeta + propagateToOwner(result, t1) -proc newTypeS(kind: TTypeKind, c: PContext): PType = +proc newTypeS(kind: TTypeKind, c: PContext): PType = result = newType(kind, getCurrOwner()) proc newTypeWithSons*(c: PContext, kind: TTypeKind, diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 969ff2d590..cfa099d3fe 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -310,7 +310,8 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, var entry = TInstantiation.new entry.sym = result instantiateGenericParamList(c, n.sons[genericParamsPos], pt, entry[]) - result.typ = fixupProcType(c, fn.typ, entry[]) + # let t1 = fixupProcType(c, fn.typ, entry[]) + result.typ = generateTypeInstance(c, pt, info, fn.typ) n.sons[genericParamsPos] = ast.emptyNode var oldPrc = GenericCacheGet(fn, entry[]) if oldPrc == nil: diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 29fad00599..0562509db4 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -591,6 +591,10 @@ proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) = let typedescId = getIdent"typedesc" +template shouldHaveMeta(t) = + InternalAssert tfHasMeta in result.lastSon.flags + # result.lastSon.flags.incl tfHasMeta + proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, paramType: PType, paramName: string, info: TLineInfo, anon = false): PType = @@ -615,7 +619,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, s.position = genericParams.len genericParams.addSon(newSymNode(s)) result = typeClass - + # XXX: There are codegen errors if this is turned into a nested proc template liftingWalk(typ: PType, anonFlag = false): expr = liftParamType(c, procKind, genericParams, typ, paramName, info, anonFlag) @@ -674,24 +678,22 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, result.rawAddSon(copyType(paramType.sons[i], getCurrOwner(), true)) result = instGenericContainer(c, paramType.sym.info, result, allowMetaTypes = true) - result.lastSon.flags.incl tfHasMeta + result.lastSon.shouldHaveMeta result = newTypeWithSons(c, tyCompositeTypeClass, @[paramType, result]) result = addImplicitGeneric(result) of tyGenericInst: - # XXX: It should be possible to set tfHasMeta in semtypinst, when the - # instance was generated for i in 1 .. (paramType.sons.len - 2): var lifted = liftingWalk(paramType.sons[i]) if lifted != nil: paramType.sons[i] = lifted result = paramType - paramType.lastSon.flags.incl tfHasMeta + result.lastSon.shouldHaveMeta let liftBody = liftingWalk(paramType.lastSon) if liftBody != nil: result = liftBody - result.flags.incl tfHasMeta + result.shouldHaveMeta of tyTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot: result = addImplicitGeneric(copyType(paramType, getCurrOwner(), true)) @@ -884,7 +886,10 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = when oUseLateInstantiation: result = lateInstantiateGeneric(c, result, n.info) else: - result = instGenericContainer(c, n, result) + result = instGenericContainer(c, n.info, result, + allowMetaTypes = not isConcrete) + if not isConcrete and result.kind == tyGenericInst: + result.lastSon.shouldHaveMeta proc semTypeExpr(c: PContext, n: PNode): PType = var n = semExprWithType(c, n, {efDetermineType}) diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 1bd6e23d5e..1a4bdd9e3e 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -135,7 +135,7 @@ proc ReplaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym = proc lookupTypeVar(cl: TReplTypeVars, t: PType): PType = result = PType(idTableGet(cl.typeMap, t)) if result == nil: - if cl.allowMetaTypes: return + if cl.allowMetaTypes or tfRetType in t.flags: return LocalError(t.sym.info, errCannotInstantiateX, typeToString(t)) result = errorType(cl.c) elif result.kind == tyGenericParam and not cl.allowMetaTypes: @@ -184,7 +184,7 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType = # if one of the params is not concrete, we cannot do anything # but we already raised an error! rawAddSon(result, header.sons[i]) - + var newbody = ReplaceTypeVarsT(cl, lastSon(body)) newbody.flags = newbody.flags + t.flags + body.flags result.flags = result.flags + newbody.flags @@ -205,20 +205,29 @@ proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType = return if s != nil: s else: t case t.kind - of tyTypeClass, tyBuiltInTypeClass: nil - of tyGenericParam, tyCompositeTypeClass: - result = lookupTypeVar(cl, t) - if result == nil: return t - if result.kind == tyGenericInvokation: - result = handleGenericInvokation(cl, result) - of tyGenericInvokation: + of tyGenericParam, tyTypeClasses: + let lookup = lookupTypeVar(cl, t) + if lookup != nil: + result = lookup + if result.kind == tyGenericInvokation: + result = handleGenericInvokation(cl, result) + of tyGenericInvokation: result = handleGenericInvokation(cl, t) of tyGenericBody: - InternalError(cl.info, "ReplaceTypeVarsT: tyGenericBody") + InternalError(cl.info, "ReplaceTypeVarsT: tyGenericBody" ) result = ReplaceTypeVarsT(cl, lastSon(t)) of tyInt: result = skipIntLit(t) # XXX now there are also float literals + of tyTypeDesc: + let lookup = PType(idTableGet(cl.typeMap, t)) # lookupTypeVar(cl, t) + if lookup != nil: + result = lookup + if tfUnresolved in t.flags: result = result.base + of tyGenericInst: + result = copyType(t, t.owner, true) + for i in 1 ..