some work to make 'opt' a first class type

This commit is contained in:
Andreas Rumpf 2017-09-24 11:21:52 +02:00
commit e879da5791
13 changed files with 52 additions and 71 deletions

View file

@ -404,14 +404,8 @@ type
# instantiation and prior to this it has the potential to # instantiation and prior to this it has the potential to
# be any type. # be any type.
tyFieldAccessor tyOpt
# Expressions such as Type.field (valid in contexts such # Builtin optional type
# as the `is` operator and magics like `high` and `low`).
# Could be lifted to a single argument proc returning the
# field value.
# sons[0]: type of containing object or tuple
# sons[1]: field type
# .n: nkDotExpr storing the field name
tyVoid tyVoid
# now different from tyEmpty, hurray! # now different from tyEmpty, hurray!
@ -624,7 +618,7 @@ type
mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast, mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast,
mNewString, mNewStringOfCap, mParseBiggestFloat, mNewString, mNewStringOfCap, mParseBiggestFloat,
mReset, mReset,
mArray, mOpenArray, mRange, mSet, mSeq, mVarargs, mArray, mOpenArray, mRange, mSet, mSeq, mOpt, mVarargs,
mRef, mPtr, mVar, mDistinct, mVoid, mTuple, mRef, mPtr, mVar, mDistinct, mVoid, mTuple,
mOrdinal, mOrdinal,
mInt, mInt8, mInt16, mInt32, mInt64, mInt, mInt8, mInt16, mInt32, mInt64,

View file

@ -130,7 +130,7 @@ proc hashType(c: var MD5Context, t: PType) =
c.hashSym body.sym c.hashSym body.sym
for i in countup(1, sonsLen(t) - 2): for i in countup(1, sonsLen(t) - 2):
c.hashType t.sons[i] c.hashType t.sons[i]
of tyFromExpr, tyFieldAccessor: of tyFromExpr:
c.hashTree(t.n) c.hashTree(t.n)
of tyArray: of tyArray:
c.hashTree(t.sons[0].n) c.hashTree(t.sons[0].n)

View file

@ -100,7 +100,7 @@ proc getUniqueType*(key: PType): PType =
if result == nil: if result == nil:
gCanonicalTypes[k] = key gCanonicalTypes[k] = key
result = key result = key
of tyTypeDesc, tyTypeClasses, tyGenericParam, tyFromExpr, tyFieldAccessor: of tyTypeDesc, tyTypeClasses, tyGenericParam, tyFromExpr:
if key.isResolvedUserTypeClass: if key.isResolvedUserTypeClass:
return getUniqueType(lastSon(key)) return getUniqueType(lastSon(key))
if key.sym != nil: if key.sym != nil:
@ -126,7 +126,7 @@ proc getUniqueType*(key: PType): PType =
result = slowSearch(key, k) result = slowSearch(key, k)
of tyGenericInvocation, tyGenericBody, of tyGenericInvocation, tyGenericBody,
tyOpenArray, tyArray, tySet, tyRange, tyTuple, tyOpenArray, tyArray, tySet, tyRange, tyTuple,
tySequence, tyForward, tyVarargs, tyProxy: tySequence, tyForward, tyVarargs, tyProxy, tyOpt:
# we have to do a slow linear search because types may need # we have to do a slow linear search because types may need
# to be compared by their structure: # to be compared by their structure:
result = slowSearch(key, k) result = slowSearch(key, k)

View file

@ -187,12 +187,12 @@ proc mapType(typ: PType): TJSTypeKind =
of tyBool: result = etyBool of tyBool: result = etyBool
of tyFloat..tyFloat128: result = etyFloat of tyFloat..tyFloat128: result = etyFloat
of tySet: result = etyObject # map a set to a table of tySet: result = etyObject # map a set to a table
of tyString, tySequence: result = etySeq of tyString, tySequence, tyOpt: result = etySeq
of tyObject, tyArray, tyTuple, tyOpenArray, tyVarargs: of tyObject, tyArray, tyTuple, tyOpenArray, tyVarargs:
result = etyObject result = etyObject
of tyNil: result = etyNull of tyNil: result = etyNull
of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvocation, of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvocation,
tyNone, tyFromExpr, tyForward, tyEmpty, tyFieldAccessor, tyNone, tyFromExpr, tyForward, tyEmpty,
tyExpr, tyStmt, tyTypeDesc, tyTypeClasses, tyVoid, tyAlias: tyExpr, tyStmt, tyTypeDesc, tyTypeClasses, tyVoid, tyAlias:
result = etyNone result = etyNone
of tyInferred: of tyInferred:
@ -927,7 +927,7 @@ proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
# we don't care if it's an etyBaseIndex (global) of a string, it's # we don't care if it's an etyBaseIndex (global) of a string, it's
# still a string that needs to be copied properly: # still a string that needs to be copied properly:
if x.typ.skipTypes(abstractInst).kind in {tySequence, tyString}: if x.typ.skipTypes(abstractInst).kind in {tySequence, tyOpt, tyString}:
xtyp = etySeq xtyp = etySeq
case xtyp case xtyp
of etySeq: of etySeq:
@ -971,7 +971,7 @@ proc genFastAsgn(p: PProc, n: PNode) =
# See bug #5933. So we try to be more compatible with the C backend semantics # See bug #5933. So we try to be more compatible with the C backend semantics
# here for 'shallowCopy'. This is an educated guess and might require further # here for 'shallowCopy'. This is an educated guess and might require further
# changes later: # changes later:
let noCopy = n[0].typ.skipTypes(abstractInst).kind in {tySequence, tyString} let noCopy = n[0].typ.skipTypes(abstractInst).kind in {tySequence, tyOpt, tyString}
genAsgnAux(p, n.sons[0], n.sons[1], noCopyNeeded=noCopy) genAsgnAux(p, n.sons[0], n.sons[1], noCopyNeeded=noCopy)
proc genSwap(p: PProc, n: PNode) = proc genSwap(p: PProc, n: PNode) =
@ -1550,7 +1550,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
result = putToSeq("[null, 0]", indirect) result = putToSeq("[null, 0]", indirect)
else: else:
result = putToSeq("null", indirect) result = putToSeq("null", indirect)
of tySequence, tyString, tyCString, tyPointer, tyProc: of tySequence, tyOpt, tyString, tyCString, tyPointer, tyProc:
result = putToSeq("null", indirect) result = putToSeq("null", indirect)
of tyStatic: of tyStatic:
if t.n != nil: if t.n != nil:

View file

@ -185,7 +185,7 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
case t.kind case t.kind
of tyNone, tyEmpty, tyVoid: discard of tyNone, tyEmpty, tyVoid: discard
of tyPointer, tySet, tyBool, tyChar, tyEnum, tyInt..tyUInt64, tyCString, of tyPointer, tySet, tyBool, tyChar, tyEnum, tyInt..tyUInt64, tyCString,
tyPtr, tyString, tyRef: tyPtr, tyString, tyRef, tyOpt:
defaultOp(c, t, body, x, y) defaultOp(c, t, body, x, y)
of tyArray, tySequence: of tyArray, tySequence:
if tfHasAsgn in t.flags: if tfHasAsgn in t.flags:
@ -227,7 +227,7 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
tyTypeDesc, tyGenericInvocation, tyForward: tyTypeDesc, tyGenericInvocation, tyForward:
internalError(c.info, "assignment requested for type: " & typeToString(t)) internalError(c.info, "assignment requested for type: " & typeToString(t))
of tyOrdinal, tyRange, tyInferred, of tyOrdinal, tyRange, tyInferred,
tyGenericInst, tyFieldAccessor, tyStatic, tyVar, tyAlias: tyGenericInst, tyStatic, tyVar, tyAlias:
liftBodyAux(c, lastSon(t), body, x, y) liftBodyAux(c, lastSon(t), body, x, y)
of tyUnused, tyUnused0, tyUnused1, tyUnused2: internalError("liftBodyAux") of tyUnused, tyUnused0, tyUnused1, tyUnused2: internalError("liftBodyAux")

View file

@ -246,8 +246,7 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
localError(n.info, errXExpectsTypeOrValue, opToStr[m]) localError(n.info, errXExpectsTypeOrValue, opToStr[m])
else: else:
n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType}) n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType})
var typ = skipTypes(n.sons[1].typ, abstractVarRange + var typ = skipTypes(n.sons[1].typ, abstractVarRange + {tyTypeDesc})
{tyTypeDesc, tyFieldAccessor})
case typ.kind case typ.kind
of tySequence, tyString, tyCString, tyOpenArray, tyVarargs: of tySequence, tyString, tyCString, tyOpenArray, tyVarargs:
n.typ = getSysType(tyInt) n.typ = getSysType(tyInt)
@ -255,7 +254,7 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
n.typ = typ.sons[0] # indextype n.typ = typ.sons[0] # indextype
of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt8, tyUInt16, tyUInt32: of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt8, tyUInt16, tyUInt32:
# do not skip the range! # do not skip the range!
n.typ = n.sons[1].typ.skipTypes(abstractVar + {tyFieldAccessor}) n.typ = n.sons[1].typ.skipTypes(abstractVar)
of tyGenericParam: of tyGenericParam:
# prepare this for resolving in semtypinst: # prepare this for resolving in semtypinst:
# we must use copyTree here in order to avoid creating a cycle # we must use copyTree here in order to avoid creating a cycle
@ -279,7 +278,7 @@ proc isOpImpl(c: PContext, n: PNode, flags: TExprFlags): PNode =
n[1].typ != nil and n[1].typ.kind == tyTypeDesc and n[1].typ != nil and n[1].typ.kind == tyTypeDesc and
n[2].kind in {nkStrLit..nkTripleStrLit, nkType} n[2].kind in {nkStrLit..nkTripleStrLit, nkType}
let t1 = n[1].typ.skipTypes({tyTypeDesc, tyFieldAccessor}) let t1 = n[1].typ.skipTypes({tyTypeDesc})
if n[2].kind in {nkStrLit..nkTripleStrLit}: if n[2].kind in {nkStrLit..nkTripleStrLit}:
case n[2].strVal.normalize case n[2].strVal.normalize
@ -1087,9 +1086,6 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
if field != nil: if field != nil:
n.typ = makeTypeDesc(c, field.typ) n.typ = makeTypeDesc(c, field.typ)
return n return n
#n.typ = newTypeWithSons(c, tyFieldAccessor, @[ty, field.typ])
#n.typ.n = copyTree(n)
#return n
else: else:
tryReadingGenericParam(ty) tryReadingGenericParam(ty)
return return

View file

@ -1234,7 +1234,7 @@ proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode =
s.typ = n.typ s.typ = n.typ
for i in 1..<params.len: for i in 1..<params.len:
if params[i].typ.kind in {tyTypeDesc, tyGenericParam, if params[i].typ.kind in {tyTypeDesc, tyGenericParam,
tyFromExpr, tyFieldAccessor}+tyTypeClasses: tyFromExpr}+tyTypeClasses:
localError(params[i].info, "cannot infer type of parameter: " & localError(params[i].info, "cannot infer type of parameter: " &
params[i].sym.name.s) params[i].sym.name.s)
#params[i].sym.owner = s #params[i].sym.owner = s

View file

@ -1592,6 +1592,8 @@ proc processMagicType(c: PContext, m: PSym) =
setMagicType(m, tySet, 0) setMagicType(m, tySet, 0)
of mSeq: of mSeq:
setMagicType(m, tySequence, 0) setMagicType(m, tySequence, 0)
of mOpt:
setMagicType(m, tyOpt, 0)
of mOrdinal: of mOrdinal:
setMagicType(m, tyOrdinal, 0) setMagicType(m, tyOrdinal, 0)
rawAddSon(m.typ, newTypeS(tyNone, c)) rawAddSon(m.typ, newTypeS(tyNone, c))

View file

@ -201,7 +201,7 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
of tyRef, tyPtr, tyGenericBody, tyVar: of tyRef, tyPtr, tyGenericBody, tyVar:
c.hashType t.lastSon, flags c.hashType t.lastSon, flags
if tfVarIsPtr in t.flags: c &= ".varisptr" if tfVarIsPtr in t.flags: c &= ".varisptr"
of tyFromExpr, tyFieldAccessor: of tyFromExpr:
c.hashTree(t.n) c.hashTree(t.n)
of tyTuple: of tyTuple:
if t.n != nil and CoType notin flags: if t.n != nil and CoType notin flags:

View file

@ -936,7 +936,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
tfExplicit notin aOrig.flags tfExplicit notin aOrig.flags
aOrig = if useTypeLoweringRuleInTypeClass: aOrig = if useTypeLoweringRuleInTypeClass:
aOrig.skipTypes({tyTypeDesc, tyFieldAccessor}) aOrig.skipTypes({tyTypeDesc})
else: else:
aOrig aOrig

View file

@ -12,9 +12,6 @@
import import
intsets, ast, astalgo, trees, msgs, strutils, platform, renderer intsets, ast, astalgo, trees, msgs, strutils, platform, renderer
proc firstOrd*(t: PType): BiggestInt
proc lastOrd*(t: PType): BiggestInt
proc lengthOrd*(t: PType): BiggestInt
type type
TPreferedDesc* = enum TPreferedDesc* = enum
preferName, preferDesc, preferExported, preferModuleInfo, preferGenericArg preferName, preferDesc, preferExported, preferModuleInfo, preferGenericArg
@ -70,17 +67,6 @@ const
typedescPtrs* = abstractPtrs + {tyTypeDesc} typedescPtrs* = abstractPtrs + {tyTypeDesc}
typedescInst* = abstractInst + {tyTypeDesc} typedescInst* = abstractInst + {tyTypeDesc}
proc containsObject*(t: PType): bool
proc containsGarbageCollectedRef*(typ: PType): bool
proc containsHiddenPointer*(typ: PType): bool
proc canFormAcycle*(typ: PType): bool
proc isCompatibleToCString*(a: PType): bool
proc getOrdValue*(n: PNode): BiggestInt
proc computeSize*(typ: PType): BiggestInt
proc getSize*(typ: PType): BiggestInt
proc isPureObject*(typ: PType): bool
proc invalidGenericInst*(f: PType): bool
# for debugging
type type
TTypeFieldResult* = enum TTypeFieldResult* = enum
frNone, # type has no object type field frNone, # type has no object type field
@ -92,16 +78,16 @@ proc analyseObjectWithTypeField*(t: PType): TTypeFieldResult
# made or intializing of the type field suffices or if there is no type field # made or intializing of the type field suffices or if there is no type field
# at all in this type. # at all in this type.
proc invalidGenericInst(f: PType): bool = proc invalidGenericInst*(f: PType): bool =
result = f.kind == tyGenericInst and lastSon(f) == nil result = f.kind == tyGenericInst and lastSon(f) == nil
proc isPureObject(typ: PType): bool = proc isPureObject*(typ: PType): bool =
var t = typ var t = typ
while t.kind == tyObject and t.sons[0] != nil: while t.kind == tyObject and t.sons[0] != nil:
t = t.sons[0].skipTypes(skipPtrs) t = t.sons[0].skipTypes(skipPtrs)
result = t.sym != nil and sfPure in t.sym.flags result = t.sym != nil and sfPure in t.sym.flags
proc getOrdValue(n: PNode): BiggestInt = proc getOrdValue*(n: PNode): BiggestInt =
case n.kind case n.kind
of nkCharLit..nkUInt64Lit: result = n.intVal of nkCharLit..nkUInt64Lit: result = n.intVal
of nkNilLit: result = 0 of nkNilLit: result = 0
@ -116,14 +102,6 @@ proc isIntLit*(t: PType): bool {.inline.} =
proc isFloatLit*(t: PType): bool {.inline.} = proc isFloatLit*(t: PType): bool {.inline.} =
result = t.kind == tyFloat and t.n != nil and t.n.kind == nkFloatLit result = t.kind == tyFloat and t.n != nil and t.n.kind == nkFloatLit
proc isCompatibleToCString(a: PType): bool =
if a.kind == tyArray:
if (firstOrd(a.sons[0]) == 0) and
(skipTypes(a.sons[0], {tyRange, tyGenericInst, tyAlias}).kind in
{tyInt..tyInt64, tyUInt..tyUInt64}) and
(a.sons[1].kind == tyChar):
result = true
proc getProcHeader*(sym: PSym; prefer: TPreferedDesc = preferName): string = proc getProcHeader*(sym: PSym; prefer: TPreferedDesc = preferName): string =
result = sym.owner.name.s & '.' & sym.name.s & '(' result = sym.owner.name.s & '.' & sym.name.s & '('
var n = sym.typ.n var n = sym.typ.n
@ -252,7 +230,7 @@ proc searchTypeFor(t: PType, predicate: TTypePredicate): bool =
proc isObjectPredicate(t: PType): bool = proc isObjectPredicate(t: PType): bool =
result = t.kind == tyObject result = t.kind == tyObject
proc containsObject(t: PType): bool = proc containsObject*(t: PType): bool =
result = searchTypeFor(t, isObjectPredicate) result = searchTypeFor(t, isObjectPredicate)
proc isObjectWithTypeFieldPredicate(t: PType): bool = proc isObjectWithTypeFieldPredicate(t: PType): bool =
@ -297,7 +275,7 @@ proc isGCRef(t: PType): bool =
result = t.kind in GcTypeKinds or result = t.kind in GcTypeKinds or
(t.kind == tyProc and t.callConv == ccClosure) (t.kind == tyProc and t.callConv == ccClosure)
proc containsGarbageCollectedRef(typ: PType): bool = proc containsGarbageCollectedRef*(typ: PType): bool =
# returns true if typ contains a reference, sequence or string (all the # returns true if typ contains a reference, sequence or string (all the
# things that are garbage-collected) # things that are garbage-collected)
result = searchTypeFor(typ, isGCRef) result = searchTypeFor(typ, isGCRef)
@ -312,7 +290,7 @@ proc containsTyRef*(typ: PType): bool =
proc isHiddenPointer(t: PType): bool = proc isHiddenPointer(t: PType): bool =
result = t.kind in {tyString, tySequence} result = t.kind in {tyString, tySequence}
proc containsHiddenPointer(typ: PType): bool = proc containsHiddenPointer*(typ: PType): bool =
# returns true if typ contains a string, table or sequence (all the things # returns true if typ contains a string, table or sequence (all the things
# that need to be copied deeply) # that need to be copied deeply)
result = searchTypeFor(typ, isHiddenPointer) result = searchTypeFor(typ, isHiddenPointer)
@ -355,7 +333,7 @@ proc canFormAcycleAux(marker: var IntSet, typ: PType, startId: int): bool =
of tyProc: result = typ.callConv == ccClosure of tyProc: result = typ.callConv == ccClosure
else: discard else: discard
proc canFormAcycle(typ: PType): bool = proc canFormAcycle*(typ: PType): bool =
var marker = initIntSet() var marker = initIntSet()
result = canFormAcycleAux(marker, typ, typ.id) result = canFormAcycleAux(marker, typ, typ.id)
@ -521,7 +499,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
of tyExpr: of tyExpr:
internalAssert t.len == 0 internalAssert t.len == 0
result = "untyped" result = "untyped"
of tyFromExpr, tyFieldAccessor: of tyFromExpr:
result = renderTree(t.n) result = renderTree(t.n)
of tyArray: of tyArray:
if t.sons[0].kind == tyRange: if t.sons[0].kind == tyRange:
@ -532,6 +510,8 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
typeToString(t.sons[1]) & ']' typeToString(t.sons[1]) & ']'
of tySequence: of tySequence:
result = "seq[" & typeToString(t.sons[0]) & ']' result = "seq[" & typeToString(t.sons[0]) & ']'
of tyOpt:
result = "opt[" & typeToString(t.sons[0]) & ']'
of tyOrdinal: of tyOrdinal:
result = "ordinal[" & typeToString(t.sons[0]) & ']' result = "ordinal[" & typeToString(t.sons[0]) & ']'
of tySet: of tySet:
@ -605,7 +585,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
result = typeToStr[t.kind] result = typeToStr[t.kind]
result.addTypeFlags(t) result.addTypeFlags(t)
proc firstOrd(t: PType): BiggestInt = proc firstOrd*(t: PType): BiggestInt =
case t.kind case t.kind
of tyBool, tyChar, tySequence, tyOpenArray, tyString, tyVarargs, tyProxy: of tyBool, tyChar, tySequence, tyOpenArray, tyString, tyVarargs, tyProxy:
result = 0 result = 0
@ -630,7 +610,7 @@ proc firstOrd(t: PType): BiggestInt =
else: else:
assert(t.n.sons[0].kind == nkSym) assert(t.n.sons[0].kind == nkSym)
result = t.n.sons[0].sym.position result = t.n.sons[0].sym.position
of tyGenericInst, tyDistinct, tyTypeDesc, tyFieldAccessor, tyAlias: of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias:
result = firstOrd(lastSon(t)) result = firstOrd(lastSon(t))
of tyOrdinal: of tyOrdinal:
if t.len > 0: result = firstOrd(lastSon(t)) if t.len > 0: result = firstOrd(lastSon(t))
@ -639,7 +619,7 @@ proc firstOrd(t: PType): BiggestInt =
internalError("invalid kind for first(" & $t.kind & ')') internalError("invalid kind for first(" & $t.kind & ')')
result = 0 result = 0
proc lastOrd(t: PType): BiggestInt = proc lastOrd*(t: PType): BiggestInt =
case t.kind case t.kind
of tyBool: result = 1 of tyBool: result = 1
of tyChar: result = 255 of tyChar: result = 255
@ -666,7 +646,7 @@ proc lastOrd(t: PType): BiggestInt =
of tyEnum: of tyEnum:
assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym) assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym)
result = t.n.sons[sonsLen(t.n) - 1].sym.position result = t.n.sons[sonsLen(t.n) - 1].sym.position
of tyGenericInst, tyDistinct, tyTypeDesc, tyFieldAccessor, tyAlias: of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias:
result = lastOrd(lastSon(t)) result = lastOrd(lastSon(t))
of tyProxy: result = 0 of tyProxy: result = 0
of tyOrdinal: of tyOrdinal:
@ -676,7 +656,7 @@ proc lastOrd(t: PType): BiggestInt =
internalError("invalid kind for last(" & $t.kind & ')') internalError("invalid kind for last(" & $t.kind & ')')
result = 0 result = 0
proc lengthOrd(t: PType): BiggestInt = proc lengthOrd*(t: PType): BiggestInt =
case t.kind case t.kind
of tyInt64, tyInt32, tyInt: result = lastOrd(t) of tyInt64, tyInt32, tyInt: result = lastOrd(t)
of tyDistinct: result = lengthOrd(t.sons[0]) of tyDistinct: result = lengthOrd(t.sons[0])
@ -689,6 +669,14 @@ proc lengthOrd(t: PType): BiggestInt =
else: else:
result = lastOrd(t) - firstOrd(t) + 1 result = lastOrd(t) - firstOrd(t) + 1
proc isCompatibleToCString*(a: PType): bool =
if a.kind == tyArray:
if (firstOrd(a.sons[0]) == 0) and
(skipTypes(a.sons[0], {tyRange, tyGenericInst, tyAlias}).kind in
{tyInt..tyInt64, tyUInt..tyUInt64}) and
(a.sons[1].kind == tyChar):
result = true
# -------------- type equality ----------------------------------------------- # -------------- type equality -----------------------------------------------
type type
@ -989,7 +977,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
result = a.sym.position == b.sym.position result = a.sym.position == b.sym.position
of tyGenericInvocation, tyGenericBody, tySequence, of tyGenericInvocation, tyGenericBody, tySequence,
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyOpenArray, tySet, tyRef, tyPtr, tyVar,
tyArray, tyProc, tyVarargs, tyOrdinal, tyTypeClasses, tyFieldAccessor: tyArray, tyProc, tyVarargs, tyOrdinal, tyTypeClasses, tyOpt:
cycleCheck() cycleCheck()
if a.kind == tyUserTypeClass and a.n != nil: return a.n == b.n if a.kind == tyUserTypeClass and a.n != nil: return a.n == b.n
result = sameChildrenAux(a, b, c) and sameFlags(a, b) result = sameChildrenAux(a, b, c) and sameFlags(a, b)
@ -1144,7 +1132,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
of tyTypeClasses: of tyTypeClasses:
if not (tfGenericTypeParam in t.flags or taField notin flags): result = t if not (tfGenericTypeParam in t.flags or taField notin flags): result = t
of tyGenericBody, tyGenericParam, tyGenericInvocation, of tyGenericBody, tyGenericParam, tyGenericInvocation,
tyNone, tyForward, tyFromExpr, tyFieldAccessor: tyNone, tyForward, tyFromExpr:
result = t result = t
of tyNil: of tyNil:
if kind != skConst: result = t if kind != skConst: result = t
@ -1160,7 +1148,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
of tyOpenArray, tyVarargs: of tyOpenArray, tyVarargs:
if kind != skParam: result = t if kind != skParam: result = t
else: result = typeAllowedAux(marker, t.sons[0], skVar, flags) else: result = typeAllowedAux(marker, t.sons[0], skVar, flags)
of tySequence: of tySequence, tyOpt:
if t.sons[0].kind != tyEmpty: if t.sons[0].kind != tyEmpty:
result = typeAllowedAux(marker, t.sons[0], skVar, flags+{taHeap}) result = typeAllowedAux(marker, t.sons[0], skVar, flags+{taHeap})
of tyArray: of tyArray:
@ -1359,7 +1347,7 @@ proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt =
typ.size = result typ.size = result
typ.align = int16(a) typ.align = int16(a)
proc computeSize(typ: PType): BiggestInt = proc computeSize*(typ: PType): BiggestInt =
var a: BiggestInt = 1 var a: BiggestInt = 1
result = computeSizeAux(typ, a) result = computeSizeAux(typ, a)
@ -1368,7 +1356,7 @@ proc getReturnType*(s: PSym): PType =
assert s.kind in skProcKinds assert s.kind in skProcKinds
result = s.typ.sons[0] result = s.typ.sons[0]
proc getSize(typ: PType): BiggestInt = proc getSize*(typ: PType): BiggestInt =
result = computeSize(typ) result = computeSize(typ)
if result < 0: internalError("getSize: " & $typ.kind) if result < 0: internalError("getSize: " & $typ.kind)

View file

@ -250,6 +250,7 @@ proc mapTypeToAstX(t: PType; info: TLineInfo;
result = mapTypeToBracket("ref", mRef, t, info) result = mapTypeToBracket("ref", mRef, t, info)
of tyVar: result = mapTypeToBracket("var", mVar, t, info) of tyVar: result = mapTypeToBracket("var", mVar, t, info)
of tySequence: result = mapTypeToBracket("seq", mSeq, t, info) of tySequence: result = mapTypeToBracket("seq", mSeq, t, info)
of tyOpt: result = mapTypeToBracket("opt", mOpt, t, info)
of tyProc: of tyProc:
if inst: if inst:
result = newNodeX(nkProcTy) result = newNodeX(nkProcTy)
@ -304,7 +305,7 @@ proc mapTypeToAstX(t: PType; info: TLineInfo;
of tyNot: result = mapTypeToBracket("not", mNot, t, info) of tyNot: result = mapTypeToBracket("not", mNot, t, info)
of tyAnything: result = atomicType("anything", mNone) of tyAnything: result = atomicType("anything", mNone)
of tyInferred: internalAssert false of tyInferred: internalAssert false
of tyStatic, tyFromExpr, tyFieldAccessor: of tyStatic, tyFromExpr:
if inst: if inst:
if t.n != nil: result = t.n.copyTree if t.n != nil: result = t.n.copyTree
else: result = atomicType("void", mVoid) else: result = atomicType("void", mVoid)

View file

@ -97,7 +97,7 @@ type
ntyError, ntyError,
ntyBuiltinTypeClass, ntyUserTypeClass, ntyUserTypeClassInst, ntyBuiltinTypeClass, ntyUserTypeClass, ntyUserTypeClassInst,
ntyCompositeTypeClass, ntyInferred, ntyAnd, ntyOr, ntyNot, ntyCompositeTypeClass, ntyInferred, ntyAnd, ntyOr, ntyNot,
ntyAnything, ntyStatic, ntyFromExpr, ntyFieldAccessor, ntyVoid ntyAnything, ntyStatic, ntyFromExpr, ntyOpt, ntyVoid
TNimTypeKinds* {.deprecated.} = set[NimTypeKind] TNimTypeKinds* {.deprecated.} = set[NimTypeKind]
NimSymKind* = enum NimSymKind* = enum