This commit is contained in:
Andreas Rumpf
2018-02-23 11:28:54 +01:00
parent fb3e460f6d
commit 3dab0877da
4 changed files with 44 additions and 61 deletions

View File

@@ -241,9 +241,6 @@ styledEcho "Red on Green.", resetStyle
and it no longer raises an OS error but returns an ``osInvalidSocket`` when
creation fails.
- ``newNativeSocket`` is now named ``createNativeSocket``.
- Type inference for generic type parameters involving numeric types is now symetric. See
[Generic type inference for numeric types](https://nim-lang.org/docs/manual.html#generics-generic-type-inference-fornumeric-types)
for more information.
- The ``deprecated`` pragma now supports a user-definable warning message for procs.
```nim

View File

@@ -915,24 +915,25 @@ proc isCovariantPtr(c: var TCandidate, f, a: PType): bool =
else:
return false
proc maxNumericType(prev, candidate: PType): PType =
let c = candidate.skipTypes({tyRange})
template greater(s) =
if c.kind in s: result = c
case prev.kind
of tyInt: greater({tyInt64})
of tyInt8: greater({tyInt, tyInt16, tyInt32, tyInt64})
of tyInt16: greater({tyInt, tyInt32, tyInt64})
of tyInt32: greater({tyInt64})
when false:
proc maxNumericType(prev, candidate: PType): PType =
let c = candidate.skipTypes({tyRange})
template greater(s) =
if c.kind in s: result = c
case prev.kind
of tyInt: greater({tyInt64})
of tyInt8: greater({tyInt, tyInt16, tyInt32, tyInt64})
of tyInt16: greater({tyInt, tyInt32, tyInt64})
of tyInt32: greater({tyInt64})
of tyUInt: greater({tyUInt64})
of tyUInt8: greater({tyUInt, tyUInt16, tyUInt32, tyUInt64})
of tyUInt16: greater({tyUInt, tyUInt32, tyUInt64})
of tyUInt32: greater({tyUInt64})
of tyUInt: greater({tyUInt64})
of tyUInt8: greater({tyUInt, tyUInt16, tyUInt32, tyUInt64})
of tyUInt16: greater({tyUInt, tyUInt32, tyUInt64})
of tyUInt32: greater({tyUInt64})
of tyFloat32: greater({tyFloat64, tyFloat128})
of tyFloat64: greater({tyFloat128})
else: discard
of tyFloat32: greater({tyFloat64, tyFloat128})
of tyFloat64: greater({tyFloat128})
else: discard
proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
flags: TTypeRelFlags = {}): TTypeRelation =
@@ -1145,12 +1146,12 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
fRange = prev
let ff = f.sons[1].skipTypes({tyTypeDesc})
let aa = a.sons[1].skipTypes({tyTypeDesc})
if f.sons[0].kind != tyGenericParam and aa.kind == tyEmpty:
result = isGeneric
result = isGeneric
else:
result = typeRel(c, ff, aa)
if result < isGeneric:
if nimEnableCovariance and
trNoCovariance notin flags and
@@ -1631,13 +1632,15 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
# Special type binding rule for numeric types.
# See section "Generic type inference for numeric types" of the
# manual for further details:
let rebinding = maxNumericType(x.skipTypes({tyRange}), a)
if rebinding != nil:
put(c, f, rebinding)
result = isGeneric
else:
result = typeRel(c, x, a) # check if it fits
if result > isGeneric: result = isGeneric
when false:
let rebinding = maxNumericType(x.skipTypes({tyRange}), a)
if rebinding != nil:
put(c, f, rebinding)
result = isGeneric
else:
discard
result = typeRel(c, x, a) # check if it fits
if result > isGeneric: result = isGeneric
of tyStatic:
let prev = PType(idTableGet(c.bindings, f))
if prev == nil:

View File

@@ -713,29 +713,3 @@ definition):
But a ``bind`` is rarely useful because symbol binding from the definition
scope is the default.
Generic type inference for numeric types
----------------------------------------
A `numeric`:idx: type is any signed, unsigned integer type, floating point
type or a subrange thereof. Let ``maxNumericType(T1, T2)`` be the "greater"
type of ``T1`` and ``T2``, that is the type that uses more bits. For
example ``maxNumericType(int32, int64) == int64``. ``maxNumericType`` is only
defined for numeric types of the same class (signed, unsigned, floating point).
``maxNumericType`` strips away subranges,
``maxNumericType(subrangeof(int16), int8)`` produces ``int16`` not its
subrange. The definition ``maxNumericType`` is extended to take a variable
number of arguments in the obvious way;
``maxNumericType(x, y, z) == maxNumericType(maxNumericType(x, y), z)``.
A generic type parameter ``T`` that is bound to multiple numeric types ``N1``,
``N2``, ``N3``, ... during type checking is inferred to
be ``maxNumericType(N1, N2, N3, ...)``. This special type inference rule ensures
that the builtin arithmetic operators can be written in an intuitive way:
.. code-block:: nim
proc `@`[T: int|int16|int32](x, y: T): T
4'i32 @ 6'i64 # inferred to be of type ``int64``
4'i64 @ 6'i32 # inferred to be of type ``int64``

View File

@@ -1,12 +1,21 @@
discard """
output: '''int64
int64'''
output: '''false'''
"""
import typetraits
when false:
import typetraits
proc `@`[T: SomeInteger](x, y: T): T = x
proc `@`[T: SomeInteger](x, y: T): T = x
echo(type(5'i64 @ 6'i32))
echo(type(5'i64 @ 6'i32))
echo(type(5'i32 @ 6'i64))
echo(type(5'i32 @ 6'i64))
import sets
# bug #7247
type
n8 = range[0'i8..127'i8]
var tab = initSet[n8]()
echo tab.contains(8)