diff options
author | Araq <rumpf_a@web.de> | 2014-09-05 01:17:03 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2014-09-05 01:17:03 +0200 |
commit | bd4e2294640c634027f7a15d2a07eea21808dc61 (patch) | |
tree | 98d1f66e53ac305e1fbc249da4c65e19bb10789a | |
parent | bf557a7cdb8f31aabca17d5b147a90ec155eaf23 (diff) | |
parent | 7d5e387a488200113664a3ffa60e5c63ec32c54b (diff) | |
download | Nim-bd4e2294640c634027f7a15d2a07eea21808dc61.tar.gz |
Merge branch 'bigbreak' of https://github.com/Araq/Nimrod into bigbreak
-rw-r--r-- | compiler/semstmts.nim | 11 | ||||
-rw-r--r-- | compiler/semtypinst.nim | 8 | ||||
-rw-r--r-- | compiler/types.nim | 4 | ||||
-rw-r--r-- | doc/manual.txt | 11 | ||||
-rw-r--r-- | tests/metatype/typeclassinference.nim | 11 |
5 files changed, 36 insertions, 9 deletions
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 28d062392..93a1994a7 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -350,9 +350,14 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = var def: PNode if a.sons[length-1].kind != nkEmpty: def = semExprWithType(c, a.sons[length-1], {efAllowDestructor}) - # BUGFIX: ``fitNode`` is needed here! - # check type compability between def.typ and typ: - if typ != nil: def = fitNode(c, typ, def) + if typ != nil: + if typ.isMetaType: + def = inferWithMetaType(c, typ, def) + typ = def.typ + else: + # BUGFIX: ``fitNode`` is needed here! + # check type compability between def.typ and typ + def = fitNode(c, typ, def) else: typ = skipIntLit(def.typ) if typ.kind in {tySequence, tyArray, tySet} and diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 9484bbe90..4563dc8d4 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -216,12 +216,16 @@ proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym = result.typ = replaceTypeVarsT(cl, s.typ) result.ast = replaceTypeVarsN(cl, s.ast) -proc lookupTypeVar(cl: TReplTypeVars, t: PType): PType = +proc lookupTypeVar(cl: var TReplTypeVars, t: PType): PType = result = PType(idTableGet(cl.typeMap, t)) if result == nil: if cl.allowMetaTypes or tfRetType in t.flags: return localError(t.sym.info, errCannotInstantiateX, typeToString(t)) result = errorType(cl.c) + # In order to prevent endless recursions, we must remember + # this bad lookup and replace it with errorType everywhere. + # These code paths are only active in nimrod check + idTablePut(cl.typeMap, t, result) elif result.kind == tyGenericParam and not cl.allowMetaTypes: internalError(cl.info, "substitution with generic parameter") @@ -353,7 +357,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType = of tyGenericBody: localError(cl.info, errCannotInstantiateX, typeToString(t)) - result = t + result = errorType(cl.c) #result = replaceTypeVarsT(cl, lastSon(t)) of tyFromExpr: diff --git a/compiler/types.nim b/compiler/types.nim index adc03a13e..7b59fbf20 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -913,9 +913,11 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = result = sameTypeAux(a.sons[0], b.sons[0], c) else: result = sameTypeAux(a.sons[0], b.sons[0], c) and sameFlags(a, b) - of tyEnum, tyForward, tyProxy: + of tyEnum, tyForward: # XXX generic enums do not make much sense, but require structural checking result = a.id == b.id and sameFlags(a, b) + of tyError: + result = b.kind == tyError of tyTuple: cycleCheck() result = sameTuple(a, b, c) and sameFlags(a, b) diff --git a/doc/manual.txt b/doc/manual.txt index 10fe78336..144a3b2c0 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -3671,8 +3671,8 @@ once for each tested type and any static code included within them will also be executed once. -Return Type Inference ---------------------- +Type inference with type classes +-------------------------------- If a type class is used as the return type of a proc and it won't be bound to a concrete type by some of the proc params, Nim will infer the return type @@ -3681,13 +3681,18 @@ from the proc body. This is usually used with the ``auto`` type class: .. code-block:: nim proc makePair(a, b): auto = (first: a, second: b) -The return type will be treated as additional generic param and can be +The return type will be treated as an additional generic param and can be explicitly specified at call sites as any other generic param. Future versions of Nim may also support overloading based on the return type of the overloads. In such settings, the expected result type at call sites may also influence the inferred return type. +Likewise, if a type class is used in another position where Nim expects a +concrete type (e.g. a variable declaration or a type coercion), Nim will try to +infer the concrete type by applying the sane matching algorithm also used in +overload resolution. + Symbol lookup in generics ------------------------- diff --git a/tests/metatype/typeclassinference.nim b/tests/metatype/typeclassinference.nim index 72b5aca96..2ac037ac5 100644 --- a/tests/metatype/typeclassinference.nim +++ b/tests/metatype/typeclassinference.nim @@ -1,3 +1,8 @@ +discard """ + errormsg: "type mismatch: got (string) but expected 'ptr'" + line: 20 +""" + import typetraits type @@ -8,3 +13,9 @@ var x = Vec([1, 2, 3]) static: assert x.type.name == "Vec[static[int](3), int]" +var str1: string = "hello, world!" +var ptr1: ptr = addr(str1) + +var str2: string = "hello, world!" +var ptr2: ptr = str2 + |