diff options
author | Zahary Karadjov <zahary@gmail.com> | 2016-08-31 02:17:14 +0300 |
---|---|---|
committer | Zahary Karadjov <zahary@gmail.com> | 2017-03-24 16:59:47 +0200 |
commit | cbf66e99a85551021d768aa81858f9d7b6f55d6f (patch) | |
tree | d7cef4972c87575a98deb57a9ddd73b22ef5080b /compiler | |
parent | 52b241fd5703034066d9c9f3c3d514162c2c809e (diff) | |
download | Nim-cbf66e99a85551021d768aa81858f9d7b6f55d6f.tar.gz |
Working test cases for the sophisticated matrix library example from the manual
Fixed the dot operator when used within return types (see tgenericdotrettype) Fixed the matching of generic concepts aliases used with the implicit generics style
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/semexprs.nim | 28 | ||||
-rw-r--r-- | compiler/semtypes.nim | 10 | ||||
-rw-r--r-- | compiler/semtypinst.nim | 2 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 46 | ||||
-rw-r--r-- | compiler/types.nim | 18 | ||||
-rw-r--r-- | compiler/vmgen.nim | 3 |
6 files changed, 67 insertions, 40 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index b5e9e6dc4..9d0f4aef1 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -911,8 +911,7 @@ proc makeDeref(n: PNode): PNode = t = skipTypes(baseTyp, {tyGenericInst, tyAlias}) const - tyTypeParamsHolders = {tyGenericInst, tyCompositeTypeClass, - tyUserTypeClass, tyUserTypeClassInst} + tyTypeParamsHolders = {tyGenericInst, tyCompositeTypeClass} tyDotOpTransparent = {tyVar, tyPtr, tyRef, tyAlias} proc readTypeParameter(c: PContext, typ: PType, @@ -1107,6 +1106,23 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = var ty = n.sons[0].typ var f: PSym = nil result = nil + + template tryReadingGenericParam(t: PType) = + case t.kind + of tyTypeParamsHolders: + return readTypeParameter(c, t, i, n.info) + of tyUserTypeClasses: + if t.isResolvedUserTypeClass: + return readTypeParameter(c, t, i, n.info) + else: + n.typ = makeTypeFromExpr(c, copyTree(n)) + return n + of tyGenericParam: + n.typ = makeTypeFromExpr(c, copyTree(n)) + return n + else: + discard + if isTypeExpr(n.sons[0]) or (ty.kind == tyTypeDesc and ty.base.kind != tyNone): if ty.kind == tyTypeDesc: ty = ty.base ty = ty.skipTypes(tyDotOpTransparent) @@ -1124,8 +1140,6 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = markUsed(n.info, f, c.graph.usageSym) styleCheckUse(n.info, f) return - of tyTypeParamsHolders: - return readTypeParameter(c, ty, i, n.info) of tyObject, tyTuple: if ty.n != nil and ty.n.kind == nkRecList: let field = lookupInRecord(ty.n, i) @@ -1134,8 +1148,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = n.typ.n = copyTree(n) return n else: - # echo "TYPE FIELD ACCESS" - # debug ty + tryReadingGenericParam(ty) return # XXX: This is probably not relevant any more # reset to prevent 'nil' bug: see "tests/reject/tenumitems.nim": @@ -1178,8 +1191,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = # we didn't find any field, let's look for a generic param if result == nil: let t = n.sons[0].typ.skipTypes(tyDotOpTransparent) - if t.kind in tyTypeParamsHolders: - result = readTypeParameter(c, t, i, n.info) + tryReadingGenericParam(t) proc dotTransformation(c: PContext, n: PNode): PNode = if isSymChoice(n.sons[1]): diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 204641b74..42ffaa5fa 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -845,9 +845,9 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, for i in 0 .. paramType.sonsLen - 2: if paramType.sons[i].kind == tyStatic: - var x = copyNode(ast.emptyNode) - x.typ = paramType.sons[i] - result.rawAddSon makeTypeFromExpr(c, x) # aka 'tyUnknown' + var staticCopy = paramType.sons[i].exactReplica + staticCopy.flags.incl tfInferrableStatic + result.rawAddSon staticCopy else: result.rawAddSon newTypeS(tyAnything, c) @@ -891,7 +891,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, allowMetaTypes = true) result = liftingWalk(expanded, true) - of tyUserTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot: + of tyUserTypeClasses, tyBuiltInTypeClass, tyAnd, tyOr, tyNot: result = addImplicitGeneric(copyType(paramType, getCurrOwner(c), true)) of tyGenericParam: @@ -1357,6 +1357,8 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = else: result = semGeneric(c, n, s, prev) of nkDotExpr: let typeExpr = semExpr(c, n) + if typeExpr.typ.kind == tyFromExpr: + return typeExpr.typ if typeExpr.typ.kind != tyTypeDesc: localError(n.info, errTypeExpected) result = errorType(c) diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index ac8a5ff82..fddcc7a24 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -404,6 +404,8 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType = case t.kind of tyGenericInvocation: result = handleGenericInvocation(cl, t) + if result.lastSon.kind == tyUserTypeClass: + result.kind = tyUserTypeClassInst of tyGenericBody: localError(cl.info, errCannotInstantiateX, typeToString(t)) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 5a6f4e015..a40f8ee66 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -613,26 +613,34 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate, template paramSym(kind): untyped = newSym(kind, typeParamName, Concept.sym, Concept.sym.info) - case typ.kind - of tyStatic: - param = paramSym skConst - param.typ = typ.exactReplica - if typ.n == nil: - param.typ.flags.incl tfInferrableStatic + block addTypeParam: + for prev in typeParams: + if prev[1].id == typ.id: + param = paramSym prev[0].kind + param.typ = prev[0].typ + break addTypeParam + + case typ.kind + of tyStatic: + param = paramSym skConst + param.typ = typ.exactReplica + if typ.n == nil: + param.typ.flags.incl tfInferrableStatic + else: + param.ast = typ.n + of tyUnknown: + param = paramSym skVar + param.typ = typ.exactReplica else: - param.ast = typ.n - of tyUnknown: - param = paramSym skVar - param.typ = typ.exactReplica - else: - param = paramSym skType - param.typ = if typ.isMetaType: - c.newTypeWithSons(tyInferred, @[typ]) - else: - makeTypeDesc(c, typ) + param = paramSym skType + param.typ = if typ.isMetaType: + c.newTypeWithSons(tyInferred, @[typ]) + else: + makeTypeDesc(c, typ) + typeParams.safeAdd((param, typ)) + addDecl(c, param) - typeParams.safeAdd((param, typ)) for param in Concept.n[0]: var @@ -682,7 +690,7 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate, diagnostics.add msg var checkedBody = c.semTryExpr(c, body.copyTree, flags) - + if collectDiagnostics: writelnHook = oldWriteHook for msg in diagnostics: m.diagnostics.safeAdd msg @@ -696,7 +704,7 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate, put(m.bindings, p[1], p[0].typ) if ff.kind == tyUserTypeClassInst: - result = generateTypeInstance(c, m.bindings, ff.sym.info, ff) + result = generateTypeInstance(c, m.bindings, Concept.sym.info, ff) else: result = copyType(ff, ff.owner, true) diff --git a/compiler/types.nim b/compiler/types.nim index 65eb6de61..3f84548a1 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -183,7 +183,7 @@ proc iterOverTypeAux(marker: var IntSet, t: PType, iter: TTypeIter, if result: return if not containsOrIncl(marker, t.id): case t.kind - of tyGenericInst, tyGenericBody, tyAlias: + of tyGenericInst, tyGenericBody, tyAlias, tyInferred: result = iterOverTypeAux(marker, lastSon(t), iter, closure) else: for i in countup(0, sonsLen(t) - 1): @@ -1320,6 +1320,9 @@ proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt = if result < 0: return if a < maxAlign: a = maxAlign result = align(result, a) + of tyInferred: + if typ.len > 1: + result = computeSizeAux(typ.lastSon, a) of tyGenericInst, tyDistinct, tyGenericBody, tyAlias: result = computeSizeAux(lastSon(typ), a) of tyTypeClasses: @@ -1351,18 +1354,17 @@ proc getSize(typ: PType): BiggestInt = if result < 0: internalError("getSize: " & $typ.kind) proc containsGenericTypeIter(t: PType, closure: RootRef): bool = - if t.kind == tyStatic: + case t.kind + of tyStatic: return t.n == nil - - if t.kind == tyTypeDesc: + of tyTypeDesc: if t.base.kind == tyNone: return true if containsGenericTypeIter(t.base, closure): return true return false - - if t.kind in GenericTypes + tyTypeClasses + {tyFromExpr}: + of GenericTypes + tyTypeClasses + {tyFromExpr}: return true - - return false + else: + return false proc containsGenericType*(t: PType): bool = result = iterOverType(t, containsGenericTypeIter, nil) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 125fe8ae0..c7d9be48c 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -1678,7 +1678,8 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) = elif sfImportc in s.flags: c.importcSym(n.info, s) genLit(c, n, dest) of skConst: - gen(c, s.ast, dest) + let constVal = if s.ast != nil: s.ast else: s.typ.n + gen(c, constVal, dest) of skEnumField: if dest < 0: dest = c.getTemp(n.typ) if s.position >= low(int16) and s.position <= high(int16): |