Static[T] fixes (#7333)

* fix the usage of unresolved static[T] parameters in proc signatures
* fix tsametype and tmacrogenerics
* Allow creating composite type classes with concepts and using them in type signatures
* Allow integers to be used in ident concatenations
* Support using imported C++ generic types in proc signatures
* fixes #7230
* closes #7379
* re-enable some metatype tests
This commit is contained in:
zah 2018-03-24 16:28:09 +02:00 • committed by Andreas Rumpf
commit 121b9e26fb
18 changed files with 265 additions and 26 deletions

View file

@ -884,6 +884,9 @@ const
proc readTypeParameter(c: PContext, typ: PType,
paramName: PIdent, info: TLineInfo): PNode =
# Note: This function will return emptyNode when attempting to read
# a static type parameter that is not yet resolved (e.g. this may
# happen in proc signatures such as `proc(x: T): array[T.sizeParam, U]`
if typ.kind in {tyUserTypeClass, tyUserTypeClassInst}:
for statement in typ.n:
case statement.kind
@ -914,7 +917,10 @@ proc readTypeParameter(c: PContext, typ: PType,
if tParam.sym.name.id == paramName.id:
let rawTyp = ty.sons[s + 1]
if rawTyp.kind == tyStatic:
return rawTyp.n
if rawTyp.n != nil:
return rawTyp.n
else:
return emptyNode
else:
let foundTyp = makeTypeDesc(c, rawTyp)
return newSymNode(copySym(tParam.sym).linkTo(foundTyp), info)
@ -1079,21 +1085,43 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
template tryReadingGenericParam(t: PType) =
case t.kind
of tyTypeParamsHolders:
return readTypeParameter(c, t, i, n.info)
result = readTypeParameter(c, t, i, n.info)
if result == emptyNode:
result = n
n.typ = makeTypeFromExpr(c, n.copyTree)
return
of tyUserTypeClasses:
if t.isResolvedUserTypeClass:
return readTypeParameter(c, t, i, n.info)
else:
n.typ = makeTypeFromExpr(c, copyTree(n))
return n
of tyGenericParam:
of tyGenericParam, tyAnything:
n.typ = makeTypeFromExpr(c, copyTree(n))
return n
else:
discard
if isTypeExpr(n.sons[0]) or (ty.kind == tyTypeDesc and ty.base.kind != tyNone):
if ty.kind == tyTypeDesc: ty = ty.base
var argIsType = false
if ty.kind == tyTypeDesc:
if ty.base.kind == tyNone:
# This is a still unresolved typedesc parameter.
# If this is a regular proc, then all bets are off and we must return
# tyFromExpr, but when this happen in a macro this is not a built-in
# field access and we leave the compiler to compile a normal call:
if getCurrOwner(c).kind != skMacro:
n.typ = makeTypeFromExpr(c, n.copyTree)
return n
else:
return nil
else:
ty = ty.base
argIsType = true
else:
argIsType = isTypeExpr(n.sons[0])
if argIsType:
ty = ty.skipTypes(tyDotOpTransparent)
case ty.kind
of tyEnum:
@ -2186,7 +2214,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
# because of the changed symbol binding, this does not mean that we
# don't have to check the symbol for semantics here again!
result = semSym(c, n, n.sym, flags)
of nkEmpty, nkNone, nkCommentStmt:
of nkEmpty, nkNone, nkCommentStmt, nkType:
discard
of nkNilLit:
if result.typ == nil: result.typ = getSysType(tyNil)