distinctBase now is identity instead of error for non distinct types (#16891)

This commit is contained in:
Timothee Cour
2021-02-01 04:10:52 -08:00
committed by GitHub
parent 25c75752d0
commit 1a74576854
4 changed files with 14 additions and 16 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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`.

View File

@@ -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