mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-27 09:01:37 +00:00
clarify the meaning of the 'auto' metatype; 'auto' is now bind-multiple; fixes #3224
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
##
|
||||
|
||||
@@ -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 =
|
||||
|
||||
20
tests/types/tauto_excessive.nim
Normal file
20
tests/types/tauto_excessive.nim
Normal file
@@ -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")
|
||||
53
web/news.txt
53
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>`_)
|
||||
|
||||
Reference in New Issue
Block a user