summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2014-09-04 23:50:00 +0300
committerZahary Karadjov <zahary@gmail.com>2014-09-04 23:50:00 +0300
commit9a3963f51b6e5ed25befa766270b1bbf5155e090 (patch)
tree5e60bfeeb0039d3cd7b5d520c44129ea62c1c425
parentc7116cc121b4e6344f3daf5f6c2823a4e7e51371 (diff)
downloadNim-9a3963f51b6e5ed25befa766270b1bbf5155e090.tar.gz
fix #959
Variable declarations using a type class will be subject to type inference similar to the one
already present in type coercions and the return type inference.
-rw-r--r--compiler/semstmts.nim11
-rw-r--r--doc/manual.txt11
-rw-r--r--tests/metatype/typeclassinference.nim11
3 files changed, 27 insertions, 6 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/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
+