diff options
author | Araq <rumpf_a@web.de> | 2015-09-14 20:25:52 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2015-09-14 20:25:52 +0200 |
commit | 0aa908c86c84c62bae52618b91d5f1cba4c0dea1 (patch) | |
tree | 81ad6c0b9fccf744c544896606486c7165f1d1eb | |
parent | f79ec6cdf5a33afc1de4b638149a1ed30d9b8656 (diff) | |
download | Nim-0aa908c86c84c62bae52618b91d5f1cba4c0dea1.tar.gz |
clarify the meaning of the 'auto' metatype; 'auto' is now bind-multiple; fixes #3224
-rw-r--r-- | compiler/semtypes.nim | 20 | ||||
-rw-r--r-- | doc/manual/generics.txt | 11 | ||||
-rw-r--r-- | doc/manual/types.txt | 24 | ||||
-rw-r--r-- | lib/system.nim | 16 | ||||
-rw-r--r-- | tests/metatype/ttypedesc1.nim | 2 | ||||
-rw-r--r-- | tests/types/tauto_excessive.nim | 20 | ||||
-rw-r--r-- | web/news.txt | 53 |
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>`_) |