This commit is contained in:
Araq 2017-02-26 00:31:56 +01:00
commit 2589d69ed2
12 changed files with 58 additions and 42 deletions

View file

@ -84,7 +84,7 @@ proc hlo(c: PContext, n: PNode): PNode =
if isEmptyType(n.typ) and isEmptyType(result.typ): if isEmptyType(n.typ) and isEmptyType(result.typ):
discard discard
else: else:
result = fitNode(c, n.typ, result) result = fitNode(c, n.typ, result, n.info)
# optimization has been applied so check again: # optimization has been applied so check again:
result = commonOptimizations(c.module, result) result = commonOptimizations(c.module, result)
result = hlo(c, result) result = hlo(c, result)

View file

@ -514,12 +514,12 @@ proc parsePar(p: var TParser): PNode =
var a = simpleExpr(p) var a = simpleExpr(p)
if p.tok.tokType == tkEquals: if p.tok.tokType == tkEquals:
# special case: allow assignments # special case: allow assignments
let asgn = newNodeP(nkAsgn, p)
getTok(p) getTok(p)
optInd(p, result) optInd(p, result)
let b = parseExpr(p) let b = parseExpr(p)
let asgn = newNodeI(nkAsgn, a.info, 2) asgn.add a
asgn.sons[0] = a asgn.add b
asgn.sons[1] = b
result.add(asgn) result.add(asgn)
if p.tok.tokType == tkSemiColon: if p.tok.tokType == tkSemiColon:
semiStmtList(p, result) semiStmtList(p, result)
@ -1184,10 +1184,10 @@ proc parseExprStmt(p: var TParser): PNode =
#| ))? #| ))?
var a = simpleExpr(p) var a = simpleExpr(p)
if p.tok.tokType == tkEquals: if p.tok.tokType == tkEquals:
result = newNodeP(nkAsgn, p)
getTok(p) getTok(p)
optInd(p, result) optInd(p, result)
var b = parseExpr(p) var b = parseExpr(p)
result = newNodeI(nkAsgn, a.info)
addSon(result, a) addSon(result, a)
addSon(result, b) addSon(result, b)
else: else:

View file

@ -32,7 +32,7 @@ proc semExprNoType(c: PContext, n: PNode): PNode
proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
proc semProcBody(c: PContext, n: PNode): PNode proc semProcBody(c: PContext, n: PNode): PNode
proc fitNode(c: PContext, formal: PType, arg: PNode): PNode proc fitNode(c: PContext, formal: PType, arg: PNode; info: TLineInfo): PNode
proc changeType(n: PNode, newType: PType, check: bool) proc changeType(n: PNode, newType: PType, check: bool)
proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode
@ -69,7 +69,7 @@ template semIdeForTemplateOrGeneric(c: PContext; n: PNode;
# echo "passing to safeSemExpr: ", renderTree(n) # echo "passing to safeSemExpr: ", renderTree(n)
discard safeSemExpr(c, n) discard safeSemExpr(c, n)
proc fitNode(c: PContext, formal: PType, arg: PNode): PNode = proc fitNode(c: PContext, formal: PType, arg: PNode; info: TLineInfo): PNode =
if arg.typ.isNil: if arg.typ.isNil:
localError(arg.info, errExprXHasNoType, localError(arg.info, errExprXHasNoType,
renderTree(arg, {renderNoComments})) renderTree(arg, {renderNoComments}))
@ -79,7 +79,7 @@ proc fitNode(c: PContext, formal: PType, arg: PNode): PNode =
else: else:
result = indexTypesMatch(c, formal, arg.typ, arg) result = indexTypesMatch(c, formal, arg.typ, arg)
if result == nil: if result == nil:
typeMismatch(arg, formal, arg.typ) typeMismatch(info, formal, arg.typ)
# error correction: # error correction:
result = copyTree(arg) result = copyTree(arg)
result.typ = formal result.typ = formal
@ -367,7 +367,7 @@ proc semAfterMacroCall(c: PContext, n: PNode, s: PSym,
#result = symNodeFromType(c, typ, n.info) #result = symNodeFromType(c, typ, n.info)
else: else:
result = semExpr(c, result, flags) result = semExpr(c, result, flags)
result = fitNode(c, s.typ.sons[0], result) result = fitNode(c, s.typ.sons[0], result, result.info)
#GlobalError(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0])) #GlobalError(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0]))
dec(evalTemplateCounter) dec(evalTemplateCounter)
discard c.friendModules.pop() discard c.friendModules.pop()
@ -390,12 +390,12 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
popInfoContext() popInfoContext()
proc forceBool(c: PContext, n: PNode): PNode = proc forceBool(c: PContext, n: PNode): PNode =
result = fitNode(c, getSysType(tyBool), n) result = fitNode(c, getSysType(tyBool), n, n.info)
if result == nil: result = n if result == nil: result = n
proc semConstBoolExpr(c: PContext, n: PNode): PNode = proc semConstBoolExpr(c: PContext, n: PNode): PNode =
let nn = semExprWithType(c, n) let nn = semExprWithType(c, n)
result = fitNode(c, getSysType(tyBool), nn) result = fitNode(c, getSysType(tyBool), nn, nn.info)
if result == nil: if result == nil:
localError(n.info, errConstExprExpected) localError(n.info, errConstExprExpected)
return nn return nn

View file

@ -327,7 +327,7 @@ proc inferWithMetatype(c: PContext, formal: PType,
result.typ = generateTypeInstance(c, m.bindings, arg.info, result.typ = generateTypeInstance(c, m.bindings, arg.info,
formal.skipTypes({tyCompositeTypeClass})) formal.skipTypes({tyCompositeTypeClass}))
else: else:
typeMismatch(arg, formal, arg.typ) typeMismatch(arg.info, formal, arg.typ)
# error correction: # error correction:
result = copyTree(arg) result = copyTree(arg)
result.typ = formal result.typ = formal

View file

@ -194,13 +194,13 @@ proc semConv(c: PContext, n: PNode): PNode =
of convOK: of convOK:
# handle SomeProcType(SomeGenericProc) # handle SomeProcType(SomeGenericProc)
if op.kind == nkSym and op.sym.isGenericRoutine: if op.kind == nkSym and op.sym.isGenericRoutine:
result.sons[1] = fitNode(c, result.typ, result.sons[1]) result.sons[1] = fitNode(c, result.typ, result.sons[1], result.info)
elif op.kind == nkPar and targetType.kind == tyTuple: elif op.kind == nkPar and targetType.kind == tyTuple:
op = fitNode(c, targetType, op) op = fitNode(c, targetType, op, result.info)
of convNotNeedeed: of convNotNeedeed:
message(n.info, hintConvFromXtoItselfNotNeeded, result.typ.typeToString) message(n.info, hintConvFromXtoItselfNotNeeded, result.typ.typeToString)
of convNotLegal: of convNotLegal:
result = fitNode(c, result.typ, result.sons[1]) result = fitNode(c, result.typ, result.sons[1], result.info)
if result == nil: if result == nil:
localError(n.info, errGenerated, msgKindToString(errIllegalConvFromXtoY)% localError(n.info, errGenerated, msgKindToString(errIllegalConvFromXtoY)%
[op.typ.typeToString, result.typ.typeToString]) [op.typ.typeToString, result.typ.typeToString])
@ -445,7 +445,7 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
x = n.sons[i] x = n.sons[i]
if x.kind == nkExprColonExpr and sonsLen(x) == 2: if x.kind == nkExprColonExpr and sonsLen(x) == 2:
var idx = semConstExpr(c, x.sons[0]) var idx = semConstExpr(c, x.sons[0])
idx = fitNode(c, indexType, idx) idx = fitNode(c, indexType, idx, x.info)
if lastIndex+1 != getOrdValue(idx): if lastIndex+1 != getOrdValue(idx):
localError(x.info, errInvalidOrderInArrayConstructor) localError(x.info, errInvalidOrderInArrayConstructor)
x = x.sons[1] x = x.sons[1]
@ -458,7 +458,7 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
inc(lastIndex) inc(lastIndex)
addSonSkipIntLit(result.typ, typ) addSonSkipIntLit(result.typ, typ)
for i in 0 .. <result.len: for i in 0 .. <result.len:
result.sons[i] = fitNode(c, typ, result.sons[i]) result.sons[i] = fitNode(c, typ, result.sons[i], result.sons[i].info)
result.typ.sons[0] = makeRangeType(c, 0, sonsLen(result) - 1, n.info) result.typ.sons[0] = makeRangeType(c, 0, sonsLen(result) - 1, n.info)
proc fixAbstractType(c: PContext, n: PNode) = proc fixAbstractType(c: PContext, n: PNode) =
@ -1393,9 +1393,9 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
c.p.resultSym.typ = rhs.typ c.p.resultSym.typ = rhs.typ
c.p.owner.typ.sons[0] = rhs.typ c.p.owner.typ.sons[0] = rhs.typ
else: else:
typeMismatch(n, lhs.typ, rhs.typ) typeMismatch(n.info, lhs.typ, rhs.typ)
n.sons[1] = fitNode(c, le, rhs) n.sons[1] = fitNode(c, le, rhs, n.info)
if tfHasAsgn in lhs.typ.flags and not lhsIsResult and if tfHasAsgn in lhs.typ.flags and not lhsIsResult and
mode != noOverloadedAsgn: mode != noOverloadedAsgn:
return overloadedAsgn(c, lhs, n.sons[1]) return overloadedAsgn(c, lhs, n.sons[1])
@ -1494,7 +1494,7 @@ proc semYield(c: PContext, n: PNode): PNode =
let restype = iterType.sons[0] let restype = iterType.sons[0]
if restype != nil: if restype != nil:
if restype.kind != tyExpr: if restype.kind != tyExpr:
n.sons[0] = fitNode(c, restype, n.sons[0]) n.sons[0] = fitNode(c, restype, n.sons[0], n.info)
if n.sons[0].typ == nil: internalError(n.info, "semYield") if n.sons[0].typ == nil: internalError(n.info, "semYield")
if resultTypeIsInferrable(restype): if resultTypeIsInferrable(restype):
@ -1929,13 +1929,14 @@ proc semSetConstr(c: PContext, n: PNode): PNode =
addSonSkipIntLit(result.typ, typ) addSonSkipIntLit(result.typ, typ)
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
var m: PNode var m: PNode
let info = n.sons[i].info
if isRange(n.sons[i]): if isRange(n.sons[i]):
m = newNodeI(nkRange, n.sons[i].info) m = newNodeI(nkRange, info)
addSon(m, fitNode(c, typ, n.sons[i].sons[1])) addSon(m, fitNode(c, typ, n.sons[i].sons[1], info))
addSon(m, fitNode(c, typ, n.sons[i].sons[2])) addSon(m, fitNode(c, typ, n.sons[i].sons[2], info))
elif n.sons[i].kind == nkRange: m = n.sons[i] # already semchecked elif n.sons[i].kind == nkRange: m = n.sons[i] # already semchecked
else: else:
m = fitNode(c, typ, n.sons[i]) m = fitNode(c, typ, n.sons[i], info)
addSon(result, m) addSon(result, m)
proc semTableConstr(c: PContext, n: PNode): PNode = proc semTableConstr(c: PContext, n: PNode): PNode =
@ -2081,7 +2082,7 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
t = skipTypes(t.sons[0], skipPtrs) t = skipTypes(t.sons[0], skipPtrs)
if f != nil and fieldVisible(c, f): if f != nil and fieldVisible(c, f):
it.sons[0] = newSymNode(f) it.sons[0] = newSymNode(f)
e = fitNode(c, f.typ, e) e = fitNode(c, f.typ, e, it.info)
# small hack here in a nkObjConstr the ``nkExprColonExpr`` node can have # small hack here in a nkObjConstr the ``nkExprColonExpr`` node can have
# 3 children the last being the field check # 3 children the last being the field check
if check != nil: if check != nil:

View file

@ -128,7 +128,7 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
for i in 1..call.len-1: for i in 1..call.len-1:
var tupleTypeB = skipTypes(call.sons[i].typ, abstractVar-{tyTypeDesc}) var tupleTypeB = skipTypes(call.sons[i].typ, abstractVar-{tyTypeDesc})
if not sameType(tupleTypeA, tupleTypeB): if not sameType(tupleTypeA, tupleTypeB):
typeMismatch(call.sons[i], tupleTypeA, tupleTypeB) typeMismatch(call.sons[i].info, tupleTypeA, tupleTypeB)
inc(c.p.nestedLoopCounter) inc(c.p.nestedLoopCounter)
if tupleTypeA.kind == tyTuple: if tupleTypeA.kind == tyTuple:

View file

@ -209,7 +209,7 @@ proc instantiateProcType(c: PContext, pt: TIdTable,
param.owner = prc param.owner = prc
param.typ = result.sons[i] param.typ = result.sons[i]
if oldParam.ast != nil: if oldParam.ast != nil:
param.ast = fitNode(c, param.typ, oldParam.ast) param.ast = fitNode(c, param.typ, oldParam.ast, oldParam.ast.info)
# don't be lazy here and call replaceTypeVarsN(cl, originalParams[i])! # don't be lazy here and call replaceTypeVarsN(cl, originalParams[i])!
result.n.sons[i] = newSymNode(param) result.n.sons[i] = newSymNode(param)

View file

@ -191,7 +191,7 @@ proc semIf(c: PContext, n: PNode): PNode =
else: else:
for it in n: for it in n:
let j = it.len-1 let j = it.len-1
it.sons[j] = fitNode(c, typ, it.sons[j]) it.sons[j] = fitNode(c, typ, it.sons[j], it.sons[j].info)
result.kind = nkIfExpr result.kind = nkIfExpr
result.typ = typ result.typ = typ
@ -257,7 +257,7 @@ proc semCase(c: PContext, n: PNode): PNode =
for i in 1..n.len-1: for i in 1..n.len-1:
var it = n.sons[i] var it = n.sons[i]
let j = it.len-1 let j = it.len-1
it.sons[j] = fitNode(c, typ, it.sons[j]) it.sons[j] = fitNode(c, typ, it.sons[j], it.sons[j].info)
result.typ = typ result.typ = typ
proc semTry(c: PContext, n: PNode): PNode = proc semTry(c: PContext, n: PNode): PNode =
@ -330,15 +330,15 @@ proc semTry(c: PContext, n: PNode): PNode =
result.typ = enforceVoidContext result.typ = enforceVoidContext
else: else:
if n.lastSon.kind == nkFinally: discardCheck(c, n.lastSon.lastSon) if n.lastSon.kind == nkFinally: discardCheck(c, n.lastSon.lastSon)
n.sons[0] = fitNode(c, typ, n.sons[0]) n.sons[0] = fitNode(c, typ, n.sons[0], n.sons[0].info)
for i in 1..last: for i in 1..last:
var it = n.sons[i] var it = n.sons[i]
let j = it.len-1 let j = it.len-1
it.sons[j] = fitNode(c, typ, it.sons[j]) it.sons[j] = fitNode(c, typ, it.sons[j], it.sons[j].info)
result.typ = typ result.typ = typ
proc fitRemoveHiddenConv(c: PContext, typ: PType, n: PNode): PNode = proc fitRemoveHiddenConv(c: PContext, typ: PType, n: PNode): PNode =
result = fitNode(c, typ, n) result = fitNode(c, typ, n, n.info)
if result.kind in {nkHiddenStdConv, nkHiddenSubConv}: if result.kind in {nkHiddenStdConv, nkHiddenSubConv}:
let r1 = result.sons[1] let r1 = result.sons[1]
if r1.kind in {nkCharLit..nkUInt64Lit} and typ.skipTypes(abstractRange).kind in {tyFloat..tyFloat128}: if r1.kind in {nkCharLit..nkUInt64Lit} and typ.skipTypes(abstractRange).kind in {tyFloat..tyFloat128}:
@ -492,7 +492,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
else: else:
# BUGFIX: ``fitNode`` is needed here! # BUGFIX: ``fitNode`` is needed here!
# check type compatibility between def.typ and typ # check type compatibility between def.typ and typ
def = fitNode(c, typ, def) def = fitNode(c, typ, def, def.info)
#changeType(def.skipConv, typ, check=true) #changeType(def.skipConv, typ, check=true)
else: else:
typ = skipIntLit(def.typ) typ = skipIntLit(def.typ)

View file

@ -449,8 +449,8 @@ proc semBranchRange(c: PContext, t, a, b: PNode, covered: var BiggestInt): PNode
checkMinSonsLen(t, 1) checkMinSonsLen(t, 1)
let ac = semConstExpr(c, a) let ac = semConstExpr(c, a)
let bc = semConstExpr(c, b) let bc = semConstExpr(c, b)
let at = fitNode(c, t.sons[0].typ, ac).skipConvTakeType let at = fitNode(c, t.sons[0].typ, ac, ac.info).skipConvTakeType
let bt = fitNode(c, t.sons[0].typ, bc).skipConvTakeType let bt = fitNode(c, t.sons[0].typ, bc, bc.info).skipConvTakeType
result = newNodeI(nkRange, a.info) result = newNodeI(nkRange, a.info)
result.add(at) result.add(at)
@ -472,7 +472,7 @@ proc semCaseBranchSetElem(c: PContext, t, b: PNode,
checkSonsLen(b, 2) checkSonsLen(b, 2)
result = semBranchRange(c, t, b.sons[0], b.sons[1], covered) result = semBranchRange(c, t, b.sons[0], b.sons[1], covered)
else: else:
result = fitNode(c, t.sons[0].typ, b) result = fitNode(c, t.sons[0].typ, b, b.info)
inc(covered) inc(covered)
proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int, proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int,
@ -493,7 +493,7 @@ proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int,
return return
elif r.kind notin {nkCurly, nkBracket} or len(r) == 0: elif r.kind notin {nkCurly, nkBracket} or len(r) == 0:
checkMinSonsLen(t, 1) checkMinSonsLen(t, 1)
branch.sons[i] = skipConv(fitNode(c, t.sons[0].typ, r)) branch.sons[i] = skipConv(fitNode(c, t.sons[0].typ, r, r.info))
inc(covered) inc(covered)
else: else:
# first element is special and will overwrite: branch.sons[i]: # first element is special and will overwrite: branch.sons[i]:
@ -947,7 +947,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
# example code that triggers it: # example code that triggers it:
# proc sort[T](cmp: proc(a, b: T): int = cmp) # proc sort[T](cmp: proc(a, b: T): int = cmp)
if not containsGenericType(typ): if not containsGenericType(typ):
def = fitNode(c, typ, def) def = fitNode(c, typ, def, def.info)
if not hasType and not hasDefault: if not hasType and not hasDefault:
if isType: localError(a.info, "':' expected") if isType: localError(a.info, "':' expected")
if kind in {skTemplate, skMacro}: if kind in {skTemplate, skMacro}:
@ -1479,7 +1479,7 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode =
# from manyloc/named_argument_bug/triengine: # from manyloc/named_argument_bug/triengine:
def.typ = def.typ.skipTypes({tyTypeDesc}) def.typ = def.typ.skipTypes({tyTypeDesc})
if not containsGenericType(def.typ): if not containsGenericType(def.typ):
def = fitNode(c, typ, def) def = fitNode(c, typ, def, def.info)
if typ == nil: if typ == nil:
typ = newTypeS(tyGenericParam, c) typ = newTypeS(tyGenericParam, c)

View file

@ -1515,7 +1515,7 @@ proc skipHiddenSubConv*(n: PNode): PNode =
else: else:
result = n result = n
proc typeMismatch*(n: PNode, formal, actual: PType) = proc typeMismatch*(info: TLineInfo, formal, actual: PType) =
if formal.kind != tyError and actual.kind != tyError: if formal.kind != tyError and actual.kind != tyError:
let named = typeToString(formal) let named = typeToString(formal)
let desc = typeToString(formal, preferDesc) let desc = typeToString(formal, preferDesc)
@ -1537,4 +1537,4 @@ proc typeMismatch*(n: PNode, formal, actual: PType) =
msg.add "\n.tag effect is 'any tag allowed'" msg.add "\n.tag effect is 'any tag allowed'"
of efLockLevelsDiffer: of efLockLevelsDiffer:
msg.add "\nlock levels differ" msg.add "\nlock levels differ"
localError(n.info, errGenerated, msg) localError(info, errGenerated, msg)

View file

@ -95,7 +95,7 @@ proc random*(max: float): float {.benign.} =
proc random*[T](x: Slice[T]): T = proc random*[T](x: Slice[T]): T =
## For a slice `a .. b` returns a value in the range `a .. b-1`. ## For a slice `a .. b` returns a value in the range `a .. b-1`.
result = random(x.b - x.a) + x.a result = T(random(x.b - x.a)) + x.a
proc random*[T](a: openArray[T]): T = proc random*[T](a: openArray[T]): T =
## returns a random element from the openarray `a`. ## returns a random element from the openarray `a`.

View file

@ -0,0 +1,15 @@
discard """
errormsg: "type mismatch: got (int) but expected 'cshort = int16'"
line: 12
column: 10
file: "tshow_asgn.nim"
"""
# bug #5430
proc random*[T](x: Slice[T]): T =
## For a slice `a .. b` returns a value in the range `a .. b-1`.
result = int(x.b - x.a) + x.a
let slice = 10.cshort..15.cshort
discard slice.random