diff --git a/changelog.md b/changelog.md index 73d7e7d9b0..cc57a91881 100644 --- a/changelog.md +++ b/changelog.md @@ -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 diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index aba36d24d2..9f802a10e9 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -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: diff --git a/doc/manual/generics.txt b/doc/manual/generics.txt index 30055f0359..4c908fefeb 100644 --- a/doc/manual/generics.txt +++ b/doc/manual/generics.txt @@ -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`` diff --git a/tests/generics/tspecial_numeric_inference.nim b/tests/generics/tspecial_numeric_inference.nim index d93544ba45..41a84a5e9e 100644 --- a/tests/generics/tspecial_numeric_inference.nim +++ b/tests/generics/tspecial_numeric_inference.nim @@ -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)