bugfix: overloading resolution for typeof

This commit is contained in:
Araq
2011-09-27 00:27:51 +02:00
parent 7c34357856
commit da6046dcba
7 changed files with 98 additions and 81 deletions

View File

@@ -435,7 +435,7 @@ have no side-effect can be used in constant expressions too:
The rules for compile-time computability are:
1. Literals are compile-time computable.
1. Literals are compile-time computable.
2. Type conversions are compile-time computable.
3. Procedure calls of the form ``p(X)`` are compile-time computable if
``p`` is a proc without side-effects (see the `noSideEffect pragma`_
@@ -1294,14 +1294,14 @@ algorithm (in pseudo-code) determines type equality:
Since types are graphs which can have cycles, the above algorithm needs an
auxiliary set ``s`` to detect this case.
Type equality modulo type distinction
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The following algorithm (in pseudo-code) determines whether two types
are equal with no respect to ``distinct`` types. For brevity the cycle check
with an auxiliary set ``s`` is omitted:
The following algorithm (in pseudo-code) determines whether two types
are equal with no respect to ``distinct`` types. For brevity the cycle check
with an auxiliary set ``s`` is omitted:
.. code-block:: nimrod
proc typeEqualsOrDistinct(a, b: PType): bool =
@@ -1324,15 +1324,15 @@ with an auxiliary set ``s`` is omitted:
for i in 0..a.tupleLen-1:
if not typeEqualsOrDistinct(a[i], b[i]): return false
result = true
of distinct:
result = typeEqualsOrDistinct(a.baseType, b.baseType)
of distinct:
result = typeEqualsOrDistinct(a.baseType, b.baseType)
of object, enum:
result = a == b
of proc:
result = typeEqualsOrDistinct(a.parameterTuple, b.parameterTuple) and
typeEqualsOrDistinct(a.resultType, b.resultType) and
a.callingConvention == b.callingConvention
elif a.kind == distinct:
a.callingConvention == b.callingConvention
elif a.kind == distinct:
result = typeEqualsOrDistinct(a.baseType, b)
elif b.kind == distinct:
result = typeEqualsOrDistinct(a, b.baseType)
@@ -1413,10 +1413,10 @@ The convertible relation can be relaxed by a user-defined type
# you can use the explicit form too
x = chr.toInt
echo x # => 97
The type conversion ``T(a)`` is an L-value if ``a`` is an L-value and
The type conversion ``T(a)`` is an L-value if ``a`` is an L-value and
``typeEqualsOrDistinct(T, type(a))`` holds.
Assignment compatibility
~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1460,7 +1460,8 @@ statements always have to be intended::
complexStmt ::= ifStmt | whileStmt | caseStmt | tryStmt | forStmt
| blockStmt | asmStmt
| procDecl | iteratorDecl | macroDecl | templateDecl
| constSection | typeSection | whenStmt | varSection
| constSection | letSection
| typeSection | whenStmt | varSection
@@ -1474,26 +1475,26 @@ Syntax::
Example:
.. code-block:: nimrod
proc p(x, y: int): int {.optional.} =
return x + y
proc p(x, y: int): int {.optional.} =
return x + y
discard p(3, 4) # discard the return value of `p`
The `discard`:idx: statement evaluates its expression for side-effects and
throws the expression's resulting value away.
Ignoring the return value of a procedure without using a discard statement is
a static error.
The return value can be ignored implicitely if the called proc/iterator has
been declared with the `discardable`:idx: pragma:
.. code-block:: nimrod
proc p(x, y: int): int {.discardable.} =
return x + y
p(3, 4) # now valid
throws the expression's resulting value away.
Ignoring the return value of a procedure without using a discard statement is
a static error.
The return value can be ignored implicitely if the called proc/iterator has
been declared with the `discardable`:idx: pragma:
.. code-block:: nimrod
proc p(x, y: int): int {.discardable.} =
return x + y
p(3, 4) # now valid
Var statement
~~~~~~~~~~~~~
@@ -2430,6 +2431,18 @@ be used to get the type of an expression:
var x = 0
var y: type(x) # y has type int
If ``type`` is used to determine the result type of a proc/iterator/converter
call ``c(X)`` (where ``X`` stands for a possibly empty list of arguments), the
interpretation where ``c`` is an iterator is preferred over the
other interpretations:
.. code-block:: nimrod
import strutils
# strutils contains both a ``split`` proc and iterator, but since an
# an iterator is the preferred interpretation, `y` has the type ``string``:
var y: type("a b c".split)
Type constraints
~~~~~~~~~~~~~~~~
@@ -2979,16 +2992,16 @@ only consist of an assembler statement.
error pragma
------------
The `error`:idx: pragma is used to make the compiler output an error message
with the given content. Compilation does not necessarily abort after an error
though.
The ``error`` pragma can also be used to
annotate a symbol (like an iterator or proc). The *usage* of the symbol then
triggers a compile-time error. This is especially useful to rule out that some
operation is valid due to overloading and type conversions:
.. code-block:: nimrod
## check that underlying int values are compared and not the pointers:
with the given content. Compilation does not necessarily abort after an error
though.
The ``error`` pragma can also be used to
annotate a symbol (like an iterator or proc). The *usage* of the symbol then
triggers a compile-time error. This is especially useful to rule out that some
operation is valid due to overloading and type conversions:
.. code-block:: nimrod
## check that underlying int values are compared and not the pointers:
proc `==`(x, y: ptr int): bool {.error.}
@@ -3308,6 +3321,7 @@ Memory allocation requires no lock at all! This design easily scales to massive
multicore processors that will become the norm in the future.
Thread pragma
-------------
@@ -3402,24 +3416,24 @@ The interaction between threads and exceptions is simple: A *handled* exception
in one thread cannot affect any other thread. However, an *unhandled*
exception in one thread terminates the whole *process*!
Taint mode
==========
The Nimrod compiler and most parts of the standard library support
a `taint mode`:idx:. Input strings are declared with the `TaintedString`:idx:
string type declared in the ``system`` module.
If the taint mode is turned on (via the ``--taintMode:on`` command line
option) it is a distinct string type which helps to detect input
validation errors:
.. code-block:: nimrod
echo "your name: "
var name: TaintedString = stdin.readline
# it is safe here to output the name without any input validation, so
# we simply convert `name` to string to make the compiler happy:
echo "hi, ", name.string
If the taint mode is turned off, ``TaintedString`` is simply an alias for
``string``.
Taint mode
==========
The Nimrod compiler and most parts of the standard library support
a `taint mode`:idx:. Input strings are declared with the `TaintedString`:idx:
string type declared in the ``system`` module.
If the taint mode is turned on (via the ``--taintMode:on`` command line
option) it is a distinct string type which helps to detect input
validation errors:
.. code-block:: nimrod
echo "your name: "
var name: TaintedString = stdin.readline
# it is safe here to output the name without any input validation, so
# we simply convert `name` to string to make the compiler happy:
echo "hi, ", name.string
If the taint mode is turned off, ``TaintedString`` is simply an alias for
``string``.