fixes #5430
This commit is contained in:
parent
d91d338d03
commit
2589d69ed2
12 changed files with 58 additions and 42 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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`.
|
||||||
|
|
|
||||||
15
tests/errmsgs/tshow_asgn.nim
Normal file
15
tests/errmsgs/tshow_asgn.nim
Normal 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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue