mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-04 20:17:42 +00:00
better integration of tyStatic into typeRel
This commit is contained in:
@@ -399,6 +399,7 @@ type
|
||||
tfHasMeta, # type has "typedesc" or "expr" somewhere; or uses '|'
|
||||
tfHasGCedMem, # type contains GC'ed memory
|
||||
tfGenericTypeParam
|
||||
tfHasStatic
|
||||
|
||||
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 raiseCannotEval(c: PEvalContext, info: TLineInfo): PNode =
|
||||
if defined(debug): writeStackTrace()
|
||||
if defined(debug) and gVerbosity >= 3: writeStackTrace()
|
||||
result = newNodeI(nkExceptBranch, info)
|
||||
# creating a nkExceptBranch without sons
|
||||
# means that it could not be evaluated
|
||||
|
||||
@@ -701,23 +701,21 @@ type
|
||||
TErrorHandling = enum doNothing, doAbort, doRaise
|
||||
|
||||
proc handleError(msg: TMsgKind, eh: TErrorHandling, s: string) =
|
||||
template maybeTrace =
|
||||
if defined(debug) or gVerbosity >= 3:
|
||||
writeStackTrace()
|
||||
template quit =
|
||||
if defined(debug) or gVerbosity >= 3: writeStackTrace()
|
||||
quit 1
|
||||
|
||||
if msg == errInternal:
|
||||
writeStackTrace() # we always want a stack trace here
|
||||
if msg >= fatalMin and msg <= fatalMax:
|
||||
maybeTrace()
|
||||
quit(1)
|
||||
quit()
|
||||
if msg >= errMin and msg <= errMax:
|
||||
maybeTrace()
|
||||
inc(gErrorCounter)
|
||||
options.gExitcode = 1'i8
|
||||
if gErrorCounter >= gErrorMax:
|
||||
quit(1)
|
||||
quit()
|
||||
elif eh == doAbort and gCmd != cmdIdeTools:
|
||||
quit(1)
|
||||
quit()
|
||||
elif eh == doRaise:
|
||||
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 =
|
||||
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 =
|
||||
var e = semExprWithType(c, n)
|
||||
if e == nil:
|
||||
@@ -282,6 +291,7 @@ proc myOpen(module: PSym): PPassContext =
|
||||
c.semConstExpr = semConstExpr
|
||||
c.semExpr = semExpr
|
||||
c.semTryExpr = tryExpr
|
||||
c.semTryConstExpr = tryConstExpr
|
||||
c.semOperand = semOperand
|
||||
c.semConstBoolExpr = semConstBoolExpr
|
||||
c.semOverloadedCall = semOverloadedCall
|
||||
|
||||
@@ -75,6 +75,7 @@ type
|
||||
semExpr*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.}
|
||||
semTryExpr*: proc (c: PContext, n: PNode,flags: TExprFlags = {},
|
||||
bufferErrors = false): PNode {.nimcall.}
|
||||
semTryConstExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.}
|
||||
semOperand*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.}
|
||||
semConstBoolExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # XXX bite the bullet
|
||||
semOverloadedCall*: proc (c: PContext, n, nOrig: PNode,
|
||||
@@ -217,11 +218,15 @@ proc makeAndType*(c: PContext, t1, t2: PType): PType =
|
||||
result = newTypeS(tyAnd, c)
|
||||
result.sons = @[t1, t2]
|
||||
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 =
|
||||
result = newTypeS(tyOr, c)
|
||||
result.sons = @[t1, t2]
|
||||
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 =
|
||||
result = newTypeS(tyNot, c)
|
||||
|
||||
@@ -678,12 +678,9 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||
paramType.sons[i] = lifted
|
||||
result = paramType
|
||||
|
||||
if paramType.lastSon.kind == tyTypeClass and false:
|
||||
result = paramType
|
||||
result.kind = tyParametricTypeClass
|
||||
result = addImplicitGeneric(copyType(result,
|
||||
getCurrOwner(), false))
|
||||
elif result != nil:
|
||||
if result == nil:
|
||||
result = liftingWalk(paramType.lastSon)
|
||||
else:
|
||||
result.kind = tyGenericInvokation
|
||||
result.sons.setLen(result.sons.len - 1)
|
||||
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 nkDistinctTy: result = semDistinct(c, n, prev)
|
||||
of nkStaticTy:
|
||||
result = newOrPrevType(tyStatic, prev, c)
|
||||
var base = semTypeNode(c, n.sons[0], nil)
|
||||
result.rawAddSon(base)
|
||||
result = newOrPrevType(tyStatic, prev, c)
|
||||
var base = semTypeNode(c, n.sons[0], nil)
|
||||
result.rawAddSon(base)
|
||||
result.flags.incl tfHasStatic
|
||||
of nkProcTy, nkIteratorTy:
|
||||
if n.sonsLen == 0:
|
||||
result = newConstraint(c, tyProc)
|
||||
|
||||
@@ -194,16 +194,16 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType =
|
||||
|
||||
proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
|
||||
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
|
||||
of tyTypeClass: nil
|
||||
of tyGenericParam:
|
||||
result = lookupTypeVar(cl, t)
|
||||
if result.kind == tyGenericInvokation:
|
||||
result = handleGenericInvokation(cl, result)
|
||||
of tyStatic:
|
||||
if t.sym != nil and t.sym.kind == skGenericParam:
|
||||
result = lookupTypeVar(cl, t)
|
||||
of tyGenericInvokation:
|
||||
result = handleGenericInvokation(cl, t)
|
||||
of tyGenericBody:
|
||||
|
||||
@@ -753,6 +753,14 @@ proc typeRel(c: var TCandidate, f, a: PType, doBind = true): TTypeRelation =
|
||||
result = isGeneric
|
||||
else:
|
||||
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:
|
||||
var prev = PType(idTableGet(c.bindings, f))
|
||||
if prev == nil:
|
||||
@@ -904,40 +912,28 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
|
||||
proc ParamTypesMatchAux(m: var TCandidate, f, argType: PType,
|
||||
argSemantized, argOrig: PNode): PNode =
|
||||
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})
|
||||
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
|
||||
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:
|
||||
if fMaybeStatic.n != nil:
|
||||
let match = matchUserTypeClass(c, m, arg, fMaybeStatic, a)
|
||||
@@ -955,7 +951,7 @@ proc ParamTypesMatchAux(m: var TCandidate, f, argType: PType,
|
||||
r = typeRel(m, f, a)
|
||||
|
||||
case r
|
||||
of isConvertible:
|
||||
of isConvertible:
|
||||
inc(m.convMatches)
|
||||
result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c)
|
||||
of isIntConv:
|
||||
|
||||
@@ -434,10 +434,10 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||
add(result, ']')
|
||||
of tyTypeDesc:
|
||||
if t.len == 0: result = "typedesc"
|
||||
else: result = "typedesc[" & typeToString(t) & "]"
|
||||
else: result = "typedesc[" & typeToString(t.sons[0]) & "]"
|
||||
of tyStatic:
|
||||
InternalAssert t.len > 0
|
||||
result = "static[" & typeToString(t) & "]"
|
||||
result = "static[" & typeToString(t.sons[0]) & "]"
|
||||
of tyTypeClass:
|
||||
InternalAssert t.sym != nil and t.sym.owner != nil
|
||||
return t.sym.owner.name.s
|
||||
@@ -450,8 +450,8 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||
of tyNot:
|
||||
result = "not " & typeToString(t.sons[0])
|
||||
of tyExpr:
|
||||
if t.len == 0: result = "expr"
|
||||
else: result = "expr[" & typeToString(t) & "]"
|
||||
InternalAssert t.len == 0
|
||||
result = "expr"
|
||||
of tyArray:
|
||||
if t.sons[0].kind == tyRange:
|
||||
result = "array[" & rangeToStr(t.sons[0].n) & ", " &
|
||||
|
||||
Reference in New Issue
Block a user