summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-09-14 20:25:52 +0200
committerAraq <rumpf_a@web.de>2015-09-14 20:25:52 +0200
commit0aa908c86c84c62bae52618b91d5f1cba4c0dea1 (patch)
tree81ad6c0b9fccf744c544896606486c7165f1d1eb
parentf79ec6cdf5a33afc1de4b638149a1ed30d9b8656 (diff)
downloadNim-0aa908c86c84c62bae52618b91d5f1cba4c0dea1.tar.gz
clarify the meaning of the 'auto' metatype; 'auto' is now bind-multiple; fixes #3224
-rw-r--r--compiler/semtypes.nim20
-rw-r--r--doc/manual/generics.txt11
-rw-r--r--doc/manual/types.txt24
-rw-r--r--lib/system.nim16
-rw-r--r--tests/metatype/ttypedesc1.nim2
-rw-r--r--tests/types/tauto_excessive.nim20
-rw-r--r--web/news.txt53
7 files changed, 91 insertions, 55 deletions
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 4ff2081ec..1cfbc368b 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -718,12 +718,12 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
   if paramType == nil: return # (e.g. proc return type)
 
   proc addImplicitGenericImpl(typeClass: PType, typId: PIdent): PType =
-    let finalTypId = if typId != nil: typId
-                     else: getIdent(paramName & ":type")
     if genericParams == nil:
       # This happens with anonymous proc types appearing in signatures
       # XXX: we need to lift these earlier
       return
+    let finalTypId = if typId != nil: typId
+                     else: getIdent(paramName & ":type")
     # is this a bindOnce type class already present in the param list?
     for i in countup(0, genericParams.len - 1):
       if genericParams.sons[i].sym.name.id == finalTypId.id:
@@ -757,7 +757,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
 
   case paramType.kind:
   of tyAnything:
-    result = addImplicitGeneric(newTypeS(tyGenericParam, c))
+    result = addImplicitGenericImpl(newTypeS(tyGenericParam, c), nil)
 
   of tyStatic:
     # proc(a: expr{string}, b: expr{nkLambda})
@@ -868,6 +868,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
   of tyExpr:
     if procKind notin {skMacro, skTemplate}:
       result = addImplicitGeneric(newTypeS(tyAnything, c))
+      #result = addImplicitGenericImpl(newTypeS(tyGenericParam, c), nil)
 
   of tyGenericParam:
     markUsed(info, paramType.sym)
@@ -977,7 +978,11 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
     # compiler only checks for 'nil':
     if skipTypes(r, {tyGenericInst}).kind != tyEmpty:
       # 'auto' as a return type does not imply a generic:
-      if r.kind != tyExpr:
+      if r.kind == tyAnything:
+        # 'p(): auto' and 'p(): expr' are equivalent, but the rest of the
+        # compiler is hardly aware of 'auto':
+        r = newTypeS(tyExpr, c)
+      elif r.kind != tyExpr:
         if r.sym == nil or sfAnon notin r.sym.flags:
           let lifted = liftParamType(c, kind, genericParams, r, "result",
                                      n.sons[0].info)
@@ -1346,8 +1351,11 @@ proc processMagicType(c: PContext, m: PSym) =
   of mIntSetBaseType: setMagicType(m, tyRange, intSize)
   of mNil: setMagicType(m, tyNil, ptrSize)
   of mExpr:
-    setMagicType(m, tyExpr, 0)
-    if m.name.s == "expr": m.typ.flags.incl tfOldSchoolExprStmt
+    if m.name.s == "auto":
+      setMagicType(m, tyAnything, 0)
+    else:
+      setMagicType(m, tyExpr, 0)
+      if m.name.s == "expr": m.typ.flags.incl tfOldSchoolExprStmt
   of mStmt:
     setMagicType(m, tyStmt, 0)
     if m.name.s == "stmt": m.typ.flags.incl tfOldSchoolExprStmt
diff --git a/doc/manual/generics.txt b/doc/manual/generics.txt
index 8f7dcd580..c6206d030 100644
--- a/doc/manual/generics.txt
+++ b/doc/manual/generics.txt
@@ -116,7 +116,7 @@ type class           matches
 ``array``            any array type
 ``set``              any set type
 ``seq``              any seq type
-``auto``             any type
+``any``              any type
 ==================   ===================================================
 
 Furthermore, every generic type automatically creates a type class of the same
@@ -163,15 +163,6 @@ module to illustrate this:
 Alternatively, the ``distinct`` type modifier can be applied to the type class
 to allow each param matching the type class to bind to a different type.
 
-If a proc param doesn't have a type specified, Nim will use the
-``distinct auto`` type class (also known as ``any``). Note this behavior is
-deprecated for procs; templates, however, support them:
-
-.. code-block:: nim
-  # allow any combination of param types
-  proc concat(a, b): string = $a & $b # deprecated
-  proc concat(a, b: any): string = $a & $b # preferred
-
 Procs written with the implicitly generic style will often need to refer to the
 type parameters of the matched generic type. They can be easily accessed using
 the dot syntax:
diff --git a/doc/manual/types.txt b/doc/manual/types.txt
index 44a20d093..c9ac6f062 100644
--- a/doc/manual/types.txt
+++ b/doc/manual/types.txt
@@ -1228,3 +1228,27 @@ However, a ``void`` type cannot be inferred in generic code:
 
 The ``void`` type is only valid for parameters and return types; other symbols
 cannot have the type ``void``.
+
+
+Auto type
+---------
+
+The ``auto`` type can only be used for return types and parameters. For return
+types it causes the compiler to infer the type from the routine body:
+
+.. code-block:: nim
+  proc returnsInt(): auto = 1984
+
+For parameters it currently creates implicitly generic routines:
+
+.. code-block:: nim
+  proc foo(a, b: auto) = discard
+
+Is the same as:
+
+.. code-block:: nim
+  proc foo[T1, T2](a: T1, b: T2) = discard
+
+However later versions of the language might change this to mean "infer the
+parameters' types from the body". Then the above ``foo`` would be rejected as
+the parameters' types can not be infered from an empty ``discard`` statement.
diff --git a/lib/system.nim b/lib/system.nim
index cd94cfeaf..27c23e0bc 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -78,7 +78,7 @@ type
   stmt* {.magic: Stmt.} ## meta type to denote a statement (for templates)
   typedesc* {.magic: TypeDesc.} ## meta type to denote a type description
   void* {.magic: "VoidType".}   ## meta type to denote the absence of any type
-  auto* = expr ## meta type for automatic type determination
+  auto* {.magic: Expr.} ## meta type for automatic type determination
   any* = distinct auto ## meta type for any supported type
   untyped* {.magic: Expr.} ## meta type to denote an expression that
                            ## is not resolved (for templates)
@@ -104,7 +104,7 @@ type
   SomeNumber* = SomeInteger|SomeReal
     ## type class matching all number types
 
-proc defined*(x: expr): bool {.magic: "Defined", noSideEffect.}
+proc defined*(x: expr): bool {.magic: "Defined", noSideEffect, compileTime.}
   ## Special compile-time procedure that checks whether `x` is
   ## defined.
   ## `x` is an external symbol introduced through the compiler's
@@ -125,7 +125,7 @@ when defined(nimalias):
     TNumber: SomeNumber,
     TOrdinal: SomeOrdinal].}
 
-proc declared*(x: expr): bool {.magic: "Defined", noSideEffect.}
+proc declared*(x: expr): bool {.magic: "Defined", noSideEffect, compileTime.}
   ## Special compile-time procedure that checks whether `x` is
   ## declared. `x` has to be an identifier or a qualified identifier.
   ## This can be used to check whether a library provides a certain
@@ -140,11 +140,11 @@ when defined(useNimRtl):
   {.deadCodeElim: on.}
 
 proc definedInScope*(x: expr): bool {.
-  magic: "DefinedInScope", noSideEffect, deprecated.}
+  magic: "DefinedInScope", noSideEffect, deprecated, compileTime.}
   ## **Deprecated since version 0.9.6**: Use ``declaredInScope`` instead.
 
 proc declaredInScope*(x: expr): bool {.
-  magic: "DefinedInScope", noSideEffect.}
+  magic: "DefinedInScope", noSideEffect, compileTime.}
   ## Special compile-time procedure that checks whether `x` is
   ## declared in the current scope. `x` has to be an identifier.
 
@@ -160,7 +160,7 @@ proc unsafeAddr*[T](x: var T): ptr T {.magic: "Addr", noSideEffect.} =
   ## Cannot be overloaded.
   discard
 
-proc `type`*(x: expr): typeDesc {.magic: "TypeOf", noSideEffect.} =
+proc `type`*(x: expr): typeDesc {.magic: "TypeOf", noSideEffect, compileTime.} =
   ## Builtin 'type' operator for accessing the type of an expression.
   ## Cannot be overloaded.
   discard
@@ -3392,7 +3392,7 @@ when hasAlloc:
       x[j+i] = item[j]
       inc(j)
 
-proc compiles*(x: expr): bool {.magic: "Compiles", noSideEffect.} =
+proc compiles*(x: expr): bool {.magic: "Compiles", noSideEffect, compileTime.} =
   ## Special compile-time procedure that checks whether `x` can be compiled
   ## without any semantic error.
   ## This can be used to check whether a type supports some operation:
@@ -3456,7 +3456,7 @@ when hasAlloc and not defined(nimscript) and not defined(JS):
 
   include "system/deepcopy"
 
-proc procCall*(x: expr) {.magic: "ProcCall".} =
+proc procCall*(x: expr) {.magic: "ProcCall", compileTime.} =
   ## special magic to prohibit dynamic binding for `method`:idx: calls.
   ## This is similar to `super`:idx: in ordinary OO languages.
   ##
diff --git a/tests/metatype/ttypedesc1.nim b/tests/metatype/ttypedesc1.nim
index 19072d966..d78c62a94 100644
--- a/tests/metatype/ttypedesc1.nim
+++ b/tests/metatype/ttypedesc1.nim
@@ -7,7 +7,7 @@ type
 
 proc getTypeName(t: typedesc): string = t.name
 
-proc foo(T: typedesc[float], a: expr): string =
+proc foo(T: typedesc[float], a: auto): string =
   result = "float " & $(a.len > 5)
 
 proc foo(T: typedesc[TFoo], a: int): string =
diff --git a/tests/types/tauto_excessive.nim b/tests/types/tauto_excessive.nim
new file mode 100644
index 000000000..2626b0cf4
--- /dev/null
+++ b/tests/types/tauto_excessive.nim
@@ -0,0 +1,20 @@
+discard """
+  output: '''10
+10.0
+1.0hiho'''
+"""
+
+# bug #3224
+proc f(x: auto): auto =
+  result = $(x+10)
+
+proc f(x, y: auto): auto =
+  result = $(x+y)
+
+
+echo f(0)     # prints 10
+echo f(0.0)  # prints 10.0
+
+proc `+`(a, b: string): string = a & b
+
+echo f(0.7, 0.3), f("hi", "ho")
diff --git a/web/news.txt b/web/news.txt
index 2aeaeeaed..9f533de8e 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -3,7 +3,7 @@ News
 ====
 
 ..
-  2015-05-05 Version 0.11.4 released
+  2015-09-14 Version 0.11.4 released
   ==================================
 
   Changes affecting backwards compatibility
@@ -58,7 +58,7 @@ News
     of all the DLLs the standard library needs. This means that the following
     DLLs are now split into 32 and 64 versions:
 
-    * ``prce.dll``: Split into ``prce32.dll`` and ``prce64.dll``.
+    * ``pcre.dll``: Split into ``pcre32.dll`` and ``pcre64.dll``.
     * ``pdcurses.dll``: Split into ``pdcurses32.dll`` and ``pdcurses64.dll``.
     * ``sqlite3.dll``: Split into ``sqlite3_32.dll`` and ``sqlite3_64.dll``.
     * ``ssleay32.dll``: Split into ``ssleay32.dll`` and ``ssleay64.dll``.
@@ -75,6 +75,13 @@ News
     with Unix's ``#!``.
   - An implicit return type for an iterator is now deprecated. Use ``auto`` if
     you want more type inference.
+  - The type ``auto`` is now a "multi-bind" metatype, so the following compiles:
+
+    .. code-block:: nim
+      proc f(x, y: auto): auto =
+        result = $x & y
+
+      echo f(0, "abc")
 
 
   Library Additions
@@ -116,24 +123,20 @@ News
   - ``when nimvm`` can now be used for compiletime versions of some code
     sections. Click `here <docs/manual.html#when-nimvm-statement>`_ for details.
   - Usage of the type ``NimNode`` in a proc now implicitly annotates the proc
-    with ``.compileTime``. This means generics work much better
-    for ``NimNode``.
+    with ``.compileTime``. This means generics work much better for ``NimNode``.
 
 
   Bugfixes
   --------
-  - Fixed "Compiler internal error on iterator it(T: typedesc[Base]) called with
- it(Child), where Child = object of Base"
+  - Fixed "Compiler internal error on iterator it(T: typedesc[Base]) called with it(Child), where Child = object of Base"
     (`#2662 <https://github.com/Araq/Nim/issues/2662>`_)
   - Fixed "repr() misses base object field in 2nd level derived object"
     (`#2749 <https://github.com/Araq/Nim/issues/2749>`_)
   - Fixed "nimsuggest doesn't work more than once on the non-main file"
     (`#2694 <https://github.com/Araq/Nim/issues/2694>`_)
-  - Fixed "JS Codegen. Passing arguments by var in certain cases leads to invali
-d JS."
+  - Fixed "JS Codegen. Passing arguments by var in certain cases leads to invalid JS."
     (`#2798 <https://github.com/Araq/Nim/issues/2798>`_)
-  - Fixed ""check" proc in unittest.nim prevents the propagation of changes to v
-ar parameters."
+  - Fixed ""check" proc in unittest.nim prevents the propagation of changes to var parameters."
     (`#964 <https://github.com/Araq/Nim/issues/964>`_)
   - Fixed "Excessive letters in integer literals are not an error"
     (`#2523 <https://github.com/Araq/Nim/issues/2523>`_)
@@ -147,8 +150,7 @@ ar parameters."
     (`#2687 <https://github.com/Araq/Nim/issues/2687>`_)
   - Fixed "Compile error using object in const array"
     (`#2774 <https://github.com/Araq/Nim/issues/2774>`_)
-  - Fixed "httpclient async requests with method httpPOST isn't sending Content-
-Length header"
+  - Fixed "httpclient async requests with method httpPOST isn't sending Content-Length header"
     (`#2884 <https://github.com/Araq/Nim/issues/2884>`_)
   - Fixed "Streams module not working with JS backend"
     (`#2148 <https://github.com/Araq/Nim/issues/2148>`_)
@@ -179,8 +181,7 @@ Length header"
     (`#2974 <https://github.com/Araq/Nim/issues/2974>`_)
   - Fixed "repr is broken"
     (`#2992 <https://github.com/Araq/Nim/issues/2992>`_)
-  - Fixed "Ipv6 devel - add IPv6 support for asyncsockets, make AF_INET6 a defau
-lt"
+  - Fixed "Ipv6 devel - add IPv6 support for asyncsockets, make AF_INET6 a default"
     (`#2976 <https://github.com/Araq/Nim/issues/2976>`_)
   - Fixed "Compilation broken on windows"
     (`#2996 <https://github.com/Araq/Nim/issues/2996>`_)
@@ -190,8 +191,7 @@ lt"
     (`#2672 <https://github.com/Araq/Nim/issues/2672>`_)
   - Fixed "Uncatched exception in async procedure on raise statement"
     (`#3014 <https://github.com/Araq/Nim/issues/3014>`_)
-  - Fixed "nim doc2 fails in Mac OS X due to system.nim (possibly related to #18
-98)"
+  - Fixed "nim doc2 fails in Mac OS X due to system.nim (possibly related to #1898)"
     (`#3005 <https://github.com/Araq/Nim/issues/3005>`_)
   - Fixed "IndexError when rebuilding Nim on iteration 2"
     (`#3018 <https://github.com/Araq/Nim/issues/3018>`_)
@@ -239,8 +239,7 @@ lt"
     (`#3054 <https://github.com/Araq/Nim/issues/3054>`_)
   - Fixed "Wrong sharing of static_t instantations"
     (`#3112 <https://github.com/Araq/Nim/issues/3112>`_)
-  - Fixed "Automatically generated proc conflicts with user-defined proc when .e
-xportc.'ed"
+  - Fixed "Automatically generated proc conflicts with user-defined proc when .exportc.'ed"
     (`#3134 <https://github.com/Araq/Nim/issues/3134>`_)
   - Fixed "getTypeInfo call crashes nim"
     (`#3099 <https://github.com/Araq/Nim/issues/3099>`_)
@@ -260,15 +259,13 @@ xportc.'ed"
     (`#3149 <https://github.com/Araq/Nim/issues/3149>`_)
   - Fixed "Inference of `static[T]` in sequences"
     (`#3144 <https://github.com/Araq/Nim/issues/3144>`_)
-  - Fixed "Argument named "closure" to proc inside template interfere with closu
-re pragma"
+  - Fixed "Argument named "closure" to proc inside template interfere with closure pragma"
     (`#3171 <https://github.com/Araq/Nim/issues/3171>`_)
   - Fixed "Internal error with aliasing inside template"
     (`#3158 <https://github.com/Araq/Nim/issues/3158>`_)
   - Fixed "Cardinality of sets prints unexpected value"
     (`#3135 <https://github.com/Araq/Nim/issues/3135>`_)
-  - Fixed "Nim crashes on const assignment from function returning var ref objec
-t"
+  - Fixed "Nim crashes on const assignment from function returning var ref object"
     (`#3103 <https://github.com/Araq/Nim/issues/3103>`_)
   - Fixed "`repr` cstring"
     (`#3080 <https://github.com/Araq/Nim/issues/3080>`_)
@@ -276,8 +273,7 @@ t"
     (`#3052 <https://github.com/Araq/Nim/issues/3052>`_)
   - Fixed "Compiler assertion when evaluating template with static[T]"
     (`#1858 <https://github.com/Araq/Nim/issues/1858>`_)
-  - Fixed "Erroneous overflow in iterators when compiler built with overflowChec
-ks enabled"
+  - Fixed "Erroneous overflow in iterators when compiler built with overflowChecks enabled"
     (`#3140 <https://github.com/Araq/Nim/issues/3140>`_)
   - Fixed "Unicode dashes as "lisp'ish" alternative to hump and snake notation"
     (`#2811 <https://github.com/Araq/Nim/issues/2811>`_)
@@ -289,8 +285,7 @@ ks enabled"
     (`#3193 <https://github.com/Araq/Nim/issues/3193>`_)
   - Fixed "VM crash when accessing array's element"
     (`#3192 <https://github.com/Araq/Nim/issues/3192>`_)
-  - Fixed "Unexpected proc invoked when different modules add procs to a type fr
-om a 3rd module"
+  - Fixed "Unexpected proc invoked when different modules add procs to a type from a 3rd module"
     (`#2664 <https://github.com/Araq/Nim/issues/2664>`_)
   - Fixed "Nim crashes on conditional declaration inside a template"
     (`#2670 <https://github.com/Araq/Nim/issues/2670>`_)
@@ -298,8 +293,7 @@ om a 3rd module"
     (`#2752 <https://github.com/Araq/Nim/issues/2752>`_)
   - Fixed "VM: Cannot assign int value to ref variable"
     (`#1329 <https://github.com/Araq/Nim/issues/1329>`_)
-  - Fixed "Incorrect code generated for tagged unions with enums not starting at
- zero"
+  - Fixed "Incorrect code generated for tagged unions with enums not starting at zero"
     (`#3096 <https://github.com/Araq/Nim/issues/3096>`_)
   - Fixed "Compile time procs using forward declarations are silently ignored"
     (`#3066 <https://github.com/Araq/Nim/issues/3066>`_)
@@ -307,8 +301,7 @@ om a 3rd module"
     (`#1965 <https://github.com/Araq/Nim/issues/1965>`_)
   - Fixed "os.getCreationTime is incorrect/impossible on Posix systems"
     (`#1058 <https://github.com/Araq/Nim/issues/1058>`_)
-  - Fixed "Improve error message for osproc.startProcess when command does not e
-xist"
+  - Fixed "Improve error message for osproc.startProcess when command does not exist"
     (`#2183 <https://github.com/Araq/Nim/issues/2183>`_)
   - Fixed "gctest segfaults with --gc:markandsweep on x86_64"
     (`#2305 <https://github.com/Araq/Nim/issues/2305>`_)