diff options
-rw-r--r-- | changelog.md | 1 | ||||
-rw-r--r-- | compiler/semmagic.nim | 13 | ||||
-rw-r--r-- | lib/pure/typetraits.nim | 14 | ||||
-rw-r--r-- | tests/metatype/ttypetraits.nim | 2 |
4 files changed, 14 insertions, 16 deletions
diff --git a/changelog.md b/changelog.md index 8221a157e..22ae9c359 100644 --- a/changelog.md +++ b/changelog.md @@ -119,6 +119,7 @@ with other backends. see #9125. Use `-d:nimLegacyJsRound` for previous behavior. - nil dereference is not allowed at compile time. `cast[ptr int](nil)[]` is rejected at compile time. +- `typetraits.distinctBase` now is identity instead of error for non distinct types. ## Compiler changes diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index d0ec1a2e9..c80e689a5 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -190,15 +190,10 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym) result = newIntNodeT(toInt128(operand.len), traitCall, c.idgen, c.graph) of "distinctBase": var arg = operand.skipTypes({tyGenericInst}) - if arg.kind == tyDistinct: - while arg.kind == tyDistinct: - arg = arg.base - arg = arg.skipTypes(skippedTypes + {tyGenericInst}) - result = getTypeDescNode(c, arg, operand.owner, traitCall.info) - else: - localError(c.config, traitCall.info, - "distinctBase expects a distinct type as argument. The given type was " & typeToString(operand)) - result = newType(tyError, nextTypeId c.idgen, context).toNode(traitCall.info) + while arg.kind == tyDistinct: + arg = arg.base + arg = arg.skipTypes(skippedTypes + {tyGenericInst}) + result = getTypeDescNode(c, arg, operand.owner, traitCall.info) else: localError(c.config, traitCall.info, "unknown trait: " & s) result = newNodeI(nkEmpty, traitCall.info) diff --git a/lib/pure/typetraits.nim b/lib/pure/typetraits.nim index 45e2a86c2..859a06cac 100644 --- a/lib/pure/typetraits.nim +++ b/lib/pure/typetraits.nim @@ -86,26 +86,26 @@ proc isNamedTuple*(T: typedesc): bool {.magic: "TypeTrait".} = doAssert isNamedTuple(tuple[name: string, age: int]) proc distinctBase*(T: typedesc): typedesc {.magic: "TypeTrait".} = - ## Returns the base type for distinct types. This works only - ## for distinct types and produces a compile time error otherwise. + ## Returns the base type for distinct types, or the type itself otherwise. ## ## **See also:** ## * `distinctBase template <#distinctBase.t,T>`_ runnableExamples: type MyInt = distinct int - doAssert distinctBase(MyInt) is int - doAssert not compiles(distinctBase(int)) + doAssert distinctBase(int) is int since (1, 1): template distinctBase*[T](a: T): untyped = ## Overload of `distinctBase <#distinctBase,typedesc>`_ for values. runnableExamples: type MyInt = distinct int - doAssert 12.MyInt.distinctBase == 12 - - distinctBase(type(a))(a) + doAssert 12.distinctBase == 12 + when T is distinct: + distinctBase(type(a))(a) + else: # avoids hint ConvFromXtoItselfNotNeeded + a proc tupleLen*(T: typedesc[tuple]): int {.magic: "TypeTrait".} = ## Returns the number of elements of the tuple type `T`. diff --git a/tests/metatype/ttypetraits.nim b/tests/metatype/ttypetraits.nim index 32cdd2871..3ff5c5ea6 100644 --- a/tests/metatype/ttypetraits.nim +++ b/tests/metatype/ttypetraits.nim @@ -90,6 +90,8 @@ block distinctBase: Foo[T] = distinct seq[T] var a: Foo[int] doAssert a.type.distinctBase is seq[int] + doAssert seq[int].distinctBase is seq[int] + doAssert "abc".distinctBase == "abc" block: # simplified from https://github.com/nim-lang/Nim/pull/8531#issuecomment-410436458 |