better integration of tyStatic into typeRel
This commit is contained in:
parent
1d02f2ea53
commit
edab4aaad0
9 changed files with 66 additions and 58 deletions
|
|
@ -399,6 +399,7 @@ type
|
||||||
tfHasMeta, # type has "typedesc" or "expr" somewhere; or uses '|'
|
tfHasMeta, # type has "typedesc" or "expr" somewhere; or uses '|'
|
||||||
tfHasGCedMem, # type contains GC'ed memory
|
tfHasGCedMem, # type contains GC'ed memory
|
||||||
tfGenericTypeParam
|
tfGenericTypeParam
|
||||||
|
tfHasStatic
|
||||||
|
|
||||||
TTypeFlags* = set[TTypeFlag]
|
TTypeFlags* = set[TTypeFlag]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ proc evalMacroCall*(c: PEvalContext, n, nOrig: PNode, sym: PSym): PNode
|
||||||
proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode
|
proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode
|
||||||
|
|
||||||
proc raiseCannotEval(c: PEvalContext, info: TLineInfo): PNode =
|
proc raiseCannotEval(c: PEvalContext, info: TLineInfo): PNode =
|
||||||
if defined(debug): writeStackTrace()
|
if defined(debug) and gVerbosity >= 3: writeStackTrace()
|
||||||
result = newNodeI(nkExceptBranch, info)
|
result = newNodeI(nkExceptBranch, info)
|
||||||
# creating a nkExceptBranch without sons
|
# creating a nkExceptBranch without sons
|
||||||
# means that it could not be evaluated
|
# means that it could not be evaluated
|
||||||
|
|
|
||||||
|
|
@ -701,23 +701,21 @@ type
|
||||||
TErrorHandling = enum doNothing, doAbort, doRaise
|
TErrorHandling = enum doNothing, doAbort, doRaise
|
||||||
|
|
||||||
proc handleError(msg: TMsgKind, eh: TErrorHandling, s: string) =
|
proc handleError(msg: TMsgKind, eh: TErrorHandling, s: string) =
|
||||||
template maybeTrace =
|
template quit =
|
||||||
if defined(debug) or gVerbosity >= 3:
|
if defined(debug) or gVerbosity >= 3: writeStackTrace()
|
||||||
writeStackTrace()
|
quit 1
|
||||||
|
|
||||||
if msg == errInternal:
|
if msg == errInternal:
|
||||||
writeStackTrace() # we always want a stack trace here
|
writeStackTrace() # we always want a stack trace here
|
||||||
if msg >= fatalMin and msg <= fatalMax:
|
if msg >= fatalMin and msg <= fatalMax:
|
||||||
maybeTrace()
|
quit()
|
||||||
quit(1)
|
|
||||||
if msg >= errMin and msg <= errMax:
|
if msg >= errMin and msg <= errMax:
|
||||||
maybeTrace()
|
|
||||||
inc(gErrorCounter)
|
inc(gErrorCounter)
|
||||||
options.gExitcode = 1'i8
|
options.gExitcode = 1'i8
|
||||||
if gErrorCounter >= gErrorMax:
|
if gErrorCounter >= gErrorMax:
|
||||||
quit(1)
|
quit()
|
||||||
elif eh == doAbort and gCmd != cmdIdeTools:
|
elif eh == doAbort and gCmd != cmdIdeTools:
|
||||||
quit(1)
|
quit()
|
||||||
elif eh == doRaise:
|
elif eh == doRaise:
|
||||||
raiseRecoverableError(s)
|
raiseRecoverableError(s)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -189,6 +189,15 @@ proc evalConstExpr(c: PContext, module: PSym, e: PNode): PNode =
|
||||||
proc evalStaticExpr(c: PContext, module: PSym, e: PNode, prc: PSym): PNode =
|
proc evalStaticExpr(c: PContext, module: PSym, e: PNode, prc: PSym): PNode =
|
||||||
result = evalConstExprAux(c.createEvalContext(emStatic), module, prc, e)
|
result = evalConstExprAux(c.createEvalContext(emStatic), module, prc, e)
|
||||||
|
|
||||||
|
proc tryConstExpr(c: PContext, n: PNode): PNode =
|
||||||
|
var e = semExprWithType(c, n)
|
||||||
|
if e == nil: return
|
||||||
|
result = getConstExpr(c.module, e)
|
||||||
|
if result == nil:
|
||||||
|
result = evalConstExpr(c, c.module, e)
|
||||||
|
if result == nil or result.kind == nkEmpty:
|
||||||
|
return nil
|
||||||
|
|
||||||
proc semConstExpr(c: PContext, n: PNode): PNode =
|
proc semConstExpr(c: PContext, n: PNode): PNode =
|
||||||
var e = semExprWithType(c, n)
|
var e = semExprWithType(c, n)
|
||||||
if e == nil:
|
if e == nil:
|
||||||
|
|
@ -282,6 +291,7 @@ proc myOpen(module: PSym): PPassContext =
|
||||||
c.semConstExpr = semConstExpr
|
c.semConstExpr = semConstExpr
|
||||||
c.semExpr = semExpr
|
c.semExpr = semExpr
|
||||||
c.semTryExpr = tryExpr
|
c.semTryExpr = tryExpr
|
||||||
|
c.semTryConstExpr = tryConstExpr
|
||||||
c.semOperand = semOperand
|
c.semOperand = semOperand
|
||||||
c.semConstBoolExpr = semConstBoolExpr
|
c.semConstBoolExpr = semConstBoolExpr
|
||||||
c.semOverloadedCall = semOverloadedCall
|
c.semOverloadedCall = semOverloadedCall
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ type
|
||||||
semExpr*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.}
|
semExpr*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.}
|
||||||
semTryExpr*: proc (c: PContext, n: PNode,flags: TExprFlags = {},
|
semTryExpr*: proc (c: PContext, n: PNode,flags: TExprFlags = {},
|
||||||
bufferErrors = false): PNode {.nimcall.}
|
bufferErrors = false): PNode {.nimcall.}
|
||||||
|
semTryConstExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.}
|
||||||
semOperand*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.}
|
semOperand*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.}
|
||||||
semConstBoolExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # XXX bite the bullet
|
semConstBoolExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # XXX bite the bullet
|
||||||
semOverloadedCall*: proc (c: PContext, n, nOrig: PNode,
|
semOverloadedCall*: proc (c: PContext, n, nOrig: PNode,
|
||||||
|
|
@ -217,11 +218,15 @@ proc makeAndType*(c: PContext, t1, t2: PType): PType =
|
||||||
result = newTypeS(tyAnd, c)
|
result = newTypeS(tyAnd, c)
|
||||||
result.sons = @[t1, t2]
|
result.sons = @[t1, t2]
|
||||||
result.flags.incl tfHasMeta
|
result.flags.incl tfHasMeta
|
||||||
|
if tfHasStatic in t1.flags or tfHasStatic in t2.flags:
|
||||||
|
result.flags.incl tfHasStatic
|
||||||
|
|
||||||
proc makeOrType*(c: PContext, t1, t2: PType): PType =
|
proc makeOrType*(c: PContext, t1, t2: PType): PType =
|
||||||
result = newTypeS(tyOr, c)
|
result = newTypeS(tyOr, c)
|
||||||
result.sons = @[t1, t2]
|
result.sons = @[t1, t2]
|
||||||
result.flags.incl tfHasMeta
|
result.flags.incl tfHasMeta
|
||||||
|
if tfHasStatic in t1.flags or tfHasStatic in t2.flags:
|
||||||
|
result.flags.incl tfHasStatic
|
||||||
|
|
||||||
proc makeNotType*(c: PContext, t1: PType): PType =
|
proc makeNotType*(c: PContext, t1: PType): PType =
|
||||||
result = newTypeS(tyNot, c)
|
result = newTypeS(tyNot, c)
|
||||||
|
|
|
||||||
|
|
@ -678,12 +678,9 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
paramType.sons[i] = lifted
|
paramType.sons[i] = lifted
|
||||||
result = paramType
|
result = paramType
|
||||||
|
|
||||||
if paramType.lastSon.kind == tyTypeClass and false:
|
if result == nil:
|
||||||
result = paramType
|
result = liftingWalk(paramType.lastSon)
|
||||||
result.kind = tyParametricTypeClass
|
else:
|
||||||
result = addImplicitGeneric(copyType(result,
|
|
||||||
getCurrOwner(), false))
|
|
||||||
elif result != nil:
|
|
||||||
result.kind = tyGenericInvokation
|
result.kind = tyGenericInvokation
|
||||||
result.sons.setLen(result.sons.len - 1)
|
result.sons.setLen(result.sons.len - 1)
|
||||||
of tyTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot:
|
of tyTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot:
|
||||||
|
|
@ -1014,9 +1011,10 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
of nkVarTy: result = semVarType(c, n, prev)
|
of nkVarTy: result = semVarType(c, n, prev)
|
||||||
of nkDistinctTy: result = semDistinct(c, n, prev)
|
of nkDistinctTy: result = semDistinct(c, n, prev)
|
||||||
of nkStaticTy:
|
of nkStaticTy:
|
||||||
result = newOrPrevType(tyStatic, prev, c)
|
result = newOrPrevType(tyStatic, prev, c)
|
||||||
var base = semTypeNode(c, n.sons[0], nil)
|
var base = semTypeNode(c, n.sons[0], nil)
|
||||||
result.rawAddSon(base)
|
result.rawAddSon(base)
|
||||||
|
result.flags.incl tfHasStatic
|
||||||
of nkProcTy, nkIteratorTy:
|
of nkProcTy, nkIteratorTy:
|
||||||
if n.sonsLen == 0:
|
if n.sonsLen == 0:
|
||||||
result = newConstraint(c, tyProc)
|
result = newConstraint(c, tyProc)
|
||||||
|
|
|
||||||
|
|
@ -195,15 +195,15 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType =
|
||||||
proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
|
proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
|
||||||
result = t
|
result = t
|
||||||
if t == nil: return
|
if t == nil: return
|
||||||
|
if t.kind == tyStatic and t.sym != nil and t.sym.kind == skGenericParam:
|
||||||
|
return lookupTypeVar(cl, t)
|
||||||
|
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyTypeClass: nil
|
of tyTypeClass: nil
|
||||||
of tyGenericParam:
|
of tyGenericParam:
|
||||||
result = lookupTypeVar(cl, t)
|
result = lookupTypeVar(cl, t)
|
||||||
if result.kind == tyGenericInvokation:
|
if result.kind == tyGenericInvokation:
|
||||||
result = handleGenericInvokation(cl, result)
|
result = handleGenericInvokation(cl, result)
|
||||||
of tyStatic:
|
|
||||||
if t.sym != nil and t.sym.kind == skGenericParam:
|
|
||||||
result = lookupTypeVar(cl, t)
|
|
||||||
of tyGenericInvokation:
|
of tyGenericInvokation:
|
||||||
result = handleGenericInvokation(cl, t)
|
result = handleGenericInvokation(cl, t)
|
||||||
of tyGenericBody:
|
of tyGenericBody:
|
||||||
|
|
|
||||||
|
|
@ -753,6 +753,14 @@ proc typeRel(c: var TCandidate, f, a: PType, doBind = true): TTypeRelation =
|
||||||
result = isGeneric
|
result = isGeneric
|
||||||
else:
|
else:
|
||||||
result = typeRel(c, x, a) # check if it fits
|
result = typeRel(c, x, a) # check if it fits
|
||||||
|
|
||||||
|
of tyStatic:
|
||||||
|
if a.kind == tyStatic:
|
||||||
|
result = typeRel(c, f.lastSon, a.lastSon)
|
||||||
|
if result != isNone: put(c.bindings, f, a)
|
||||||
|
else:
|
||||||
|
result = isNone
|
||||||
|
|
||||||
of tyTypeDesc:
|
of tyTypeDesc:
|
||||||
var prev = PType(idTableGet(c.bindings, f))
|
var prev = PType(idTableGet(c.bindings, f))
|
||||||
if prev == nil:
|
if prev == nil:
|
||||||
|
|
@ -904,40 +912,28 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
|
||||||
proc ParamTypesMatchAux(m: var TCandidate, f, argType: PType,
|
proc ParamTypesMatchAux(m: var TCandidate, f, argType: PType,
|
||||||
argSemantized, argOrig: PNode): PNode =
|
argSemantized, argOrig: PNode): PNode =
|
||||||
var
|
var
|
||||||
r: TTypeRelation
|
|
||||||
arg = argSemantized
|
|
||||||
|
|
||||||
let
|
|
||||||
c = m.c
|
|
||||||
a0 = if c.InTypeClass > 0: argType.skipTypes({tyTypeDesc})
|
|
||||||
else: argType
|
|
||||||
a = if a0 != nil: a0.skipTypes({tyStatic}) else: a0
|
|
||||||
fMaybeStatic = f.skipTypes({tyDistinct})
|
fMaybeStatic = f.skipTypes({tyDistinct})
|
||||||
|
arg = argSemantized
|
||||||
|
c = m.c
|
||||||
|
argType = argType
|
||||||
|
|
||||||
|
if tfHasStatic in fMaybeStatic.flags:
|
||||||
|
# XXX: When implicit statics are the default
|
||||||
|
# this will be done earlier - we just have to
|
||||||
|
# make sure that static types enter here
|
||||||
|
var evaluated = c.semTryConstExpr(c, arg)
|
||||||
|
if evaluated != nil:
|
||||||
|
arg.typ = newTypeS(tyStatic, c)
|
||||||
|
arg.typ.sons = @[evaluated.typ]
|
||||||
|
arg.typ.n = evaluated
|
||||||
|
argType = arg.typ
|
||||||
|
|
||||||
|
var
|
||||||
|
r: TTypeRelation
|
||||||
|
a = if c.InTypeClass > 0: argType.skipTypes({tyTypeDesc})
|
||||||
|
else: argType
|
||||||
|
|
||||||
case fMaybeStatic.kind
|
case fMaybeStatic.kind
|
||||||
of tyStatic:
|
|
||||||
if a.kind == tyStatic:
|
|
||||||
InternalAssert a.len > 0
|
|
||||||
r = typeRel(m, f.lastSon, a.lastSon)
|
|
||||||
else:
|
|
||||||
r = typeRel(m, fMaybeStatic, a)
|
|
||||||
if r != isNone:
|
|
||||||
# XXX: Ideally, this should happen much earlier somewhere near
|
|
||||||
# semOpAux, but to do that, we need to be able to query the
|
|
||||||
# overload set to determine whether compile-time value is expected
|
|
||||||
# for the param before entering the full-blown sigmatch algorithm.
|
|
||||||
# This is related to the immediate pragma since querying the
|
|
||||||
# overload set could help there too.
|
|
||||||
var evaluated = c.semConstExpr(c, arg)
|
|
||||||
if evaluated != nil:
|
|
||||||
r = isGeneric
|
|
||||||
arg.typ = newTypeS(tyStatic, c)
|
|
||||||
arg.typ.sons = @[evaluated.typ]
|
|
||||||
arg.typ.n = evaluated
|
|
||||||
|
|
||||||
if r == isGeneric:
|
|
||||||
put(m.bindings, f, arg.typ)
|
|
||||||
|
|
||||||
of tyTypeClass, tyParametricTypeClass:
|
of tyTypeClass, tyParametricTypeClass:
|
||||||
if fMaybeStatic.n != nil:
|
if fMaybeStatic.n != nil:
|
||||||
let match = matchUserTypeClass(c, m, arg, fMaybeStatic, a)
|
let match = matchUserTypeClass(c, m, arg, fMaybeStatic, a)
|
||||||
|
|
|
||||||
|
|
@ -434,10 +434,10 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||||
add(result, ']')
|
add(result, ']')
|
||||||
of tyTypeDesc:
|
of tyTypeDesc:
|
||||||
if t.len == 0: result = "typedesc"
|
if t.len == 0: result = "typedesc"
|
||||||
else: result = "typedesc[" & typeToString(t) & "]"
|
else: result = "typedesc[" & typeToString(t.sons[0]) & "]"
|
||||||
of tyStatic:
|
of tyStatic:
|
||||||
InternalAssert t.len > 0
|
InternalAssert t.len > 0
|
||||||
result = "static[" & typeToString(t) & "]"
|
result = "static[" & typeToString(t.sons[0]) & "]"
|
||||||
of tyTypeClass:
|
of tyTypeClass:
|
||||||
InternalAssert t.sym != nil and t.sym.owner != nil
|
InternalAssert t.sym != nil and t.sym.owner != nil
|
||||||
return t.sym.owner.name.s
|
return t.sym.owner.name.s
|
||||||
|
|
@ -450,8 +450,8 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||||
of tyNot:
|
of tyNot:
|
||||||
result = "not " & typeToString(t.sons[0])
|
result = "not " & typeToString(t.sons[0])
|
||||||
of tyExpr:
|
of tyExpr:
|
||||||
if t.len == 0: result = "expr"
|
InternalAssert t.len == 0
|
||||||
else: result = "expr[" & typeToString(t) & "]"
|
result = "expr"
|
||||||
of tyArray:
|
of tyArray:
|
||||||
if t.sons[0].kind == tyRange:
|
if t.sons[0].kind == tyRange:
|
||||||
result = "array[" & rangeToStr(t.sons[0].n) & ", " &
|
result = "array[" & rangeToStr(t.sons[0].n) & ", " &
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue