top-down type inference, implements rfc 149 (#20091)
* micro implementation of rfc 149 refs https://github.com/nim-lang/RFCs/issues/149 * number/array/seq literals, more statements * try fix number literal alias issue * renew expectedType with if/case/try branch types * fix (nerf) index type handling and float typed int * use typeAllowed * tweaks + const test (tested locally) [skip ci] * fill out more of the checklist * more literals, change @ order, type conversions Not copying the full call tree before the typedesc call check in `semIndirectOp` is also a small performance improvement. * disable self-conversion warning * revert type conversions (maybe separate op later) * deal with CI for now (seems unrelated), try enums * workaround CI different way * proper fix * again * see sizes * lol * overload selection, simplify int literal -> float * range, new @ solution, try use fitNode for nil * use new magic * try fix ranges, new magic, deal with #20193 * add documentation, support templates Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
parent
2dcfd73260
commit
0014b9c48e
17 changed files with 599 additions and 199 deletions
|
|
@ -27,11 +27,11 @@ when not defined(leanCompiler):
|
|||
|
||||
# implementation
|
||||
|
||||
proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
|
||||
proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
|
||||
proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}, expectedType: PType = nil): PNode
|
||||
proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}, expectedType: PType = nil): PNode
|
||||
proc semExprNoType(c: PContext, n: PNode): PNode
|
||||
proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
|
||||
proc semProcBody(c: PContext, n: PNode): PNode
|
||||
proc semProcBody(c: PContext, n: PNode; expectedType: PType = nil): PNode
|
||||
|
||||
proc fitNode(c: PContext, formal: PType, arg: PNode; info: TLineInfo): PNode
|
||||
proc changeType(c: PContext; n: PNode, newType: PType, check: bool)
|
||||
|
|
@ -48,7 +48,7 @@ proc semQuoteAst(c: PContext, n: PNode): PNode
|
|||
proc finishMethod(c: PContext, s: PSym)
|
||||
proc evalAtCompileTime(c: PContext, n: PNode): PNode
|
||||
proc indexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode
|
||||
proc semStaticExpr(c: PContext, n: PNode): PNode
|
||||
proc semStaticExpr(c: PContext, n: PNode; expectedType: PType = nil): PNode
|
||||
proc semStaticType(c: PContext, childNode: PNode, prev: PType): PType
|
||||
proc semTypeOf(c: PContext; n: PNode): PNode
|
||||
proc computeRequiresInit(c: PContext, t: PType): bool
|
||||
|
|
@ -269,12 +269,12 @@ proc paramsTypeCheck(c: PContext, typ: PType) {.inline.} =
|
|||
typeAllowedCheck(c, typ.n.info, typ, skProc)
|
||||
|
||||
proc expectMacroOrTemplateCall(c: PContext, n: PNode): PSym
|
||||
proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode
|
||||
proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType = nil): PNode
|
||||
proc semWhen(c: PContext, n: PNode, semCheck: bool = true): PNode
|
||||
proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
|
||||
flags: TExprFlags = {}): PNode
|
||||
flags: TExprFlags = {}; expectedType: PType = nil): PNode
|
||||
proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
|
||||
flags: TExprFlags = {}): PNode
|
||||
flags: TExprFlags = {}; expectedType: PType = nil): PNode
|
||||
|
||||
proc symFromType(c: PContext; t: PType, info: TLineInfo): PSym =
|
||||
if t.sym != nil: return t.sym
|
||||
|
|
@ -334,8 +334,8 @@ proc fixupTypeAfterEval(c: PContext, evaluated, eOrig: PNode): PNode =
|
|||
isArrayConstr(arg):
|
||||
arg.typ = eOrig.typ
|
||||
|
||||
proc tryConstExpr(c: PContext, n: PNode): PNode =
|
||||
var e = semExprWithType(c, n)
|
||||
proc tryConstExpr(c: PContext, n: PNode; expectedType: PType = nil): PNode =
|
||||
var e = semExprWithType(c, n, expectedType = expectedType)
|
||||
if e == nil: return
|
||||
|
||||
result = getConstExpr(c.module, e, c.idgen, c.graph)
|
||||
|
|
@ -365,8 +365,8 @@ proc tryConstExpr(c: PContext, n: PNode): PNode =
|
|||
const
|
||||
errConstExprExpected = "constant expression expected"
|
||||
|
||||
proc semConstExpr(c: PContext, n: PNode): PNode =
|
||||
var e = semExprWithType(c, n)
|
||||
proc semConstExpr(c: PContext, n: PNode; expectedType: PType = nil): PNode =
|
||||
var e = semExprWithType(c, n, expectedType = expectedType)
|
||||
if e == nil:
|
||||
localError(c.config, n.info, errConstExprExpected)
|
||||
return n
|
||||
|
|
@ -388,14 +388,14 @@ proc semConstExpr(c: PContext, n: PNode): PNode =
|
|||
else:
|
||||
result = fixupTypeAfterEval(c, result, e)
|
||||
|
||||
proc semExprFlagDispatched(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
proc semExprFlagDispatched(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType = nil): PNode =
|
||||
if efNeedStatic in flags:
|
||||
if efPreferNilResult in flags:
|
||||
return tryConstExpr(c, n)
|
||||
return tryConstExpr(c, n, expectedType)
|
||||
else:
|
||||
return semConstExpr(c, n)
|
||||
return semConstExpr(c, n, expectedType)
|
||||
else:
|
||||
result = semExprWithType(c, n, flags)
|
||||
result = semExprWithType(c, n, flags, expectedType)
|
||||
if efPreferStatic in flags:
|
||||
var evaluated = getConstExpr(c.module, result, c.idgen, c.graph)
|
||||
if evaluated != nil: return evaluated
|
||||
|
|
@ -414,7 +414,7 @@ proc resetSemFlag(n: PNode) =
|
|||
resetSemFlag(n[i])
|
||||
|
||||
proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
|
||||
s: PSym, flags: TExprFlags): PNode =
|
||||
s: PSym, flags: TExprFlags; expectedType: PType = nil): PNode =
|
||||
## Semantically check the output of a macro.
|
||||
## This involves processes such as re-checking the macro output for type
|
||||
## coherence, making sure that variables declared with 'let' aren't
|
||||
|
|
@ -438,10 +438,10 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
|
|||
case retType.kind
|
||||
of tyUntyped:
|
||||
# Not expecting a type here allows templates like in ``tmodulealias.in``.
|
||||
result = semExpr(c, result, flags)
|
||||
result = semExpr(c, result, flags, expectedType)
|
||||
of tyTyped:
|
||||
# More restrictive version.
|
||||
result = semExprWithType(c, result, flags)
|
||||
result = semExprWithType(c, result, flags, expectedType)
|
||||
of tyTypeDesc:
|
||||
if result.kind == nkStmtList: result.transitionSonsKind(nkStmtListType)
|
||||
var typ = semTypeNode(c, result, nil)
|
||||
|
|
@ -465,7 +465,7 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
|
|||
retType = generateTypeInstance(c, paramTypes,
|
||||
macroResult.info, retType)
|
||||
|
||||
result = semExpr(c, result, flags)
|
||||
result = semExpr(c, result, flags, expectedType)
|
||||
result = fitNode(c, retType, result, result.info)
|
||||
#globalError(s.info, errInvalidParamKindX, typeToString(s.typ[0]))
|
||||
dec(c.config.evalTemplateCounter)
|
||||
|
|
@ -476,7 +476,7 @@ const
|
|||
errFloatToString = "cannot convert '$1' to '$2'"
|
||||
|
||||
proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
|
||||
flags: TExprFlags = {}): PNode =
|
||||
flags: TExprFlags = {}; expectedType: PType = nil): PNode =
|
||||
rememberExpansion(c, nOrig.info, sym)
|
||||
pushInfoContext(c.config, nOrig.info, sym.detailedInfo)
|
||||
|
||||
|
|
@ -496,7 +496,7 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
|
|||
# c.evalContext = c.createEvalContext(emStatic)
|
||||
result = evalMacroCall(c.module, c.idgen, c.graph, c.templInstCounter, n, nOrig, sym)
|
||||
if efNoSemCheck notin flags:
|
||||
result = semAfterMacroCall(c, n, result, sym, flags)
|
||||
result = semAfterMacroCall(c, n, result, sym, flags, expectedType)
|
||||
if c.config.macrosToExpand.hasKey(sym.name.s):
|
||||
message(c.config, nOrig.info, hintExpandMacro, renderTree(result))
|
||||
result = wrapInComesFrom(nOrig.info, sym, result)
|
||||
|
|
@ -507,7 +507,7 @@ proc forceBool(c: PContext, n: PNode): PNode =
|
|||
if result == nil: result = n
|
||||
|
||||
proc semConstBoolExpr(c: PContext, n: PNode): PNode =
|
||||
result = forceBool(c, semConstExpr(c, n))
|
||||
result = forceBool(c, semConstExpr(c, n, getSysType(c.graph, n.info, tyBool)))
|
||||
if result.kind != nkIntLit:
|
||||
localError(c.config, n.info, errConstExprExpected)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue