diff options
author | Zahary Karadjov <zahary@gmail.com> | 2013-12-29 16:08:33 +0200 |
---|---|---|
committer | Zahary Karadjov <zahary@gmail.com> | 2013-12-29 16:08:33 +0200 |
commit | 72291875bf895e8e0d22ab3f375752417b07ed25 (patch) | |
tree | 98bfd4c616465b9d98a927e742120e9303695e77 /compiler | |
parent | 66a255652572b48440b68878e99d7f5290e384b3 (diff) | |
download | Nim-72291875bf895e8e0d22ab3f375752417b07ed25.tar.gz |
integrate the logic of fixupProcType into ReplaceTypeVars
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ast.nim | 20 | ||||
-rw-r--r-- | compiler/semdata.nim | 14 | ||||
-rw-r--r-- | compiler/seminst.nim | 3 | ||||
-rw-r--r-- | compiler/semtypes.nim | 19 | ||||
-rw-r--r-- | compiler/semtypinst.nim | 42 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 15 | ||||
-rw-r--r-- | compiler/types.nim | 5 |
7 files changed, 76 insertions, 42 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 45784bbcb..92f3ce8d3 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 874e5dab4..687140ce9 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 969ff2d59..cfa099d3f 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 29fad0059..0562509db 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 1bd6e23d5..1a4bdd9e3 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 .. <result.sonsLen: + result.sons[i] = ReplaceTypeVarsT(cl, result.sons[i]) else: if t.kind == tyArray: let idxt = t.sons[0] @@ -238,15 +247,18 @@ proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType = if result.kind == tyProc and result.sons[0] != nil: if result.sons[0].kind == tyEmpty: result.sons[0] = nil - -proc generateTypeInstance*(p: PContext, pt: TIdTable, arg: PNode, - t: PType): PType = + +proc generateTypeInstance*(p: PContext, pt: TIdTable, info: TLineInfo, + t: PType): PType = var cl: TReplTypeVars InitIdTable(cl.symMap) copyIdTable(cl.typeMap, pt) - cl.info = arg.info + cl.info = info cl.c = p - pushInfoContext(arg.info) + pushInfoContext(info) result = ReplaceTypeVarsT(cl, t) popInfoContext() +template generateTypeInstance*(p: PContext, pt: TIdTable, arg: PNode, + t: PType): expr = + generateTypeInstance(p, pt, arg.info, t) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 27be1b7d5..20c348f17 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -418,7 +418,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = if a.kind == tyGenericInst and skipTypes(f, {tyVar}).kind notin { tyGenericBody, tyGenericInvokation, - tyGenericParam} + tyTypeClasses: + tyGenericInst, tyGenericParam} + tyTypeClasses: return typeRel(c, f, lastSon(a)) template bindingRet(res) = @@ -649,7 +649,14 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = if a.kind == tyEmpty: result = isEqual of tyGenericInst: - result = typeRel(c, lastSon(f), a) + if a.kind == tyGenericInst: + if a.base != f.base: return isNone + for i in 1 .. f.sonsLen-2: + result = typeRel(c, f.sons[i], a.sons[i]) + if result == isNone: return + result = isGeneric + else: + result = typeRel(c, lastSon(f), a) of tyGenericBody: if a.kind == tyGenericInst and a.sons[0] == f: @@ -937,9 +944,9 @@ proc ParamTypesMatchAux(m: var TCandidate, f, argType: PType, var fMaybeStatic = f.skipTypes({tyDistinct}) arg = argSemantized - c = m.c argType = argType - + c = m.c + if tfHasStatic in fMaybeStatic.flags: # XXX: When implicit statics are the default # this will be done earlier - we just have to diff --git a/compiler/types.nim b/compiler/types.nim index a2869f0da..f0b593996 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1220,8 +1220,9 @@ proc getSize(typ: PType): biggestInt = result = computeSize(typ) if result < 0: InternalError("getSize: " & $typ.kind) -proc containsGenericTypeIter(t: PType, closure: PObject): bool = - result = t.kind in GenericTypes +proc containsGenericTypeIter(t: PType, closure: PObject): bool = + result = t.kind in GenericTypes + tyTypeClasses + + {tyTypeDesc, tyStatic} proc containsGenericType*(t: PType): bool = result = iterOverType(t, containsGenericTypeIter, nil) |