fix is with generic types; fix genericHead(Foo[T]) (#13303)

* fix #9855, fix #9855, fix genericHead
* render TTypeKind via toHumanStr
This commit is contained in:
Timothee Cour 2020-02-09 04:48:55 -08:00 • committed by GitHub
commit 7939319379
7 changed files with 94 additions and 20 deletions

View file

@ -121,6 +121,11 @@ proc uninstantiate(t: PType): PType =
of tyCompositeTypeClass: uninstantiate t[1]
else: t
proc getTypeDescNode(typ: PType, sym: PSym, info: TLineInfo): PNode =
var resType = newType(tyTypeDesc, sym)
rawAddSon(resType, typ)
result = toNode(resType, info)
proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym): PNode =
const skippedTypes = {tyTypeDesc, tyAlias, tySink}
let trait = traitCall[0]
@ -161,13 +166,16 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym)
result.typ = newType(tyInt, context)
result.info = traitCall.info
of "genericHead":
var res = uninstantiate(operand)
if res == operand and res.kind notin tyMagicGenerics:
localError(c.config, traitCall.info,
"genericHead expects a generic type. The given type was " &
typeToString(operand))
return newType(tyError, context).toNode(traitCall.info)
result = res.base.toNode(traitCall.info)
var arg = operand
case arg.kind
of tyGenericInst:
result = getTypeDescNode(arg.base, operand.owner, traitCall.info)
# of tySequence: # this doesn't work
# var resType = newType(tySequence, operand.owner)
# result = toNode(resType, traitCall.info) # doesn't work yet
else:
localError(c.config, traitCall.info, "expected generic type, got: type $2 of kind $1" % [arg.kind.toHumanStr, typeToString(operand)])
result = newType(tyError, context).toNode(traitCall.info)
of "stripGenericParams":
result = uninstantiate(operand).toNode(traitCall.info)
of "supportsCopyMem":
@ -185,9 +193,7 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym)
while arg.kind == tyDistinct:
arg = arg.base
arg = arg.skipTypes(skippedTypes + {tyGenericInst})
var resType = newType(tyTypeDesc, operand.owner)
rawAddSon(resType, arg)
result = toNode(resType, traitCall.info)
result = getTypeDescNode(arg, operand.owner, traitCall.info)
else:
localError(c.config, traitCall.info,
"distinctBase expects a distinct type as argument. The given type was " & typeToString(operand))