bugfix: type converter that converts to bool in 'if' context

This commit is contained in:
Araq
2011-03-25 00:47:03 +01:00
parent 220dd54acf
commit 032599c156
11 changed files with 77 additions and 25 deletions

View File

@@ -87,6 +87,11 @@ proc new*[T](a: var ref T, finalizer: proc (x: ref T)) {.
## freeing the object. Note: The `finalizer` refers to the type `T`, not to
## the object! This means that for each object of type `T` the finalizer
## will be called!
proc reset*(obj: var T) {.magic: "Reset", noSideEffect.}
proc reset*(obj: ref T) {.noSideEffect.} = reset(obj^)
## resets an object `obj` to its initial (binary zero) value. This needs to
## be called before any possible `object branch transition`:idx:.
# for low and high the return type T may not be correct, but
# we handle that with compiler magic in SemLowHigh()

View File

@@ -361,6 +361,7 @@ proc evalAsgn(c: PEvalContext, n: PNode): PNode =
var x = result
result = evalAux(c, n.sons[1], {})
if isSpecial(result): return
when defined(system.reset): reset(x)
x.kind = result.kind
x.typ = result.typ
case x.kind

View File

@@ -114,17 +114,37 @@ proc semMacroExpr(c: PContext, n: PNode, sym: PSym,
dec(evalTemplateCounter)
include seminst, semcall
proc CheckBool(t: PNode) =
if (t.Typ == nil) or
(skipTypes(t.Typ, {tyGenericInst, tyVar, tyOrdinal}).kind != tyBool):
LocalError(t.Info, errExprMustBeBool)
proc typeMismatch(n: PNode, formal, actual: PType) =
GlobalError(n.Info, errGenerated, msgKindToString(errTypeMismatch) &
typeToString(actual) & ") " &
`%`(msgKindToString(errButExpectedX), [typeToString(formal)]))
proc fitNode(c: PContext, formal: PType, arg: PNode): PNode =
result = IndexTypesMatch(c, formal, arg.typ, arg)
if result == nil:
#debug(arg)
typeMismatch(arg, formal, arg.typ)
proc forceBool(c: PContext, n: PNode): PNode =
result = fitNode(c, getSysType(tyBool), n)
if result == nil: result = n
when false:
result = t
if (t.Typ == nil) or
(skipTypes(t.Typ, {tyGenericInst, tyVar, tyOrdinal}).kind != tyBool):
var a = ConvertTo(c, getSysType(tyBool), t)
if a != nil: result = a
else: LocalError(t.Info, errExprMustBeBool)
proc semConstBoolExpr(c: PContext, n: PNode): PNode =
result = fitNode(c, getSysType(tyBool), semExprWithType(c, n))
if result == nil:
GlobalError(n.info, errConstExprExpected)
return
result = getConstExpr(c.module, result)
if result == nil: GlobalError(n.info, errConstExprExpected)
include semtypes, semexprs, semgnrc, semstmts
proc addCodeForGenerics(c: PContext, n: PNode) =

View File

@@ -792,8 +792,7 @@ proc semIfExpr(c: PContext, n: PNode): PNode =
case it.kind
of nkElifExpr:
checkSonsLen(it, 2)
it.sons[0] = semExprWithType(c, it.sons[0])
checkBool(it.sons[0])
it.sons[0] = forceBool(c, semExprWithType(c, it.sons[0]))
it.sons[1] = semExprWithType(c, it.sons[1])
if typ == nil: typ = it.sons[1].typ
else: it.sons[1] = fitNode(c, typ, it.sons[1])

View File

@@ -38,8 +38,7 @@ proc semWhen(c: PContext, n: PNode): PNode =
case it.kind
of nkElifBranch:
checkSonsLen(it, 2)
var e = semConstExpr(c, it.sons[0])
checkBool(e)
var e = semConstBoolExpr(c, it.sons[0])
if (e.kind != nkIntLit): InternalError(n.info, "semWhen")
if (e.intVal != 0) and (result == nil):
result = semStmt(c, it.sons[1]) # do not open a new scope!
@@ -63,8 +62,7 @@ proc semIf(c: PContext, n: PNode): PNode =
of nkElifBranch:
checkSonsLen(it, 2)
openScope(c.tab)
it.sons[0] = semExprWithType(c, it.sons[0])
checkBool(it.sons[0])
it.sons[0] = forceBool(c, semExprWithType(c, it.sons[0]))
it.sons[1] = semStmt(c, it.sons[1])
closeScope(c.tab)
of nkElse:
@@ -121,8 +119,7 @@ proc semWhile(c: PContext, n: PNode): PNode =
result = n
checkSonsLen(n, 2)
openScope(c.tab)
n.sons[0] = semExprWithType(c, n.sons[0])
CheckBool(n.sons[0])
n.sons[0] = forceBool(c, semExprWithType(c, n.sons[0]))
inc(c.p.nestedLoopCounter)
n.sons[1] = semStmt(c, n.sons[1])
dec(c.p.nestedLoopCounter)
@@ -162,8 +159,7 @@ proc semCase(c: PContext, n: PNode): PNode =
of nkElifBranch:
chckCovered = false
checkSonsLen(x, 2)
x.sons[0] = semExprWithType(c, x.sons[0])
checkBool(x.sons[0])
x.sons[0] = forceBool(c, semExprWithType(c, x.sons[0]))
x.sons[1] = semStmtScope(c, x.sons[1])
of nkElse:
chckCovered = false

View File

@@ -9,12 +9,6 @@
# this module does the semantic checking of type declarations
proc fitNode(c: PContext, formal: PType, arg: PNode): PNode =
result = IndexTypesMatch(c, formal, arg.typ, arg)
if result == nil:
#debug(arg)
typeMismatch(arg, formal, arg.typ)
proc newOrPrevType(kind: TTypeKind, prev: PType, c: PContext): PType =
if prev == nil:
result = newTypeS(kind, c)
@@ -355,8 +349,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var TIntSet, pos: var int,
case it.kind
of nkElifBranch:
checkSonsLen(it, 2)
e = semConstExpr(c, it.sons[0])
checkBool(e)
e = semConstBoolExpr(c, it.sons[0])
if (e.kind != nkIntLit): InternalError(e.info, "semRecordNodeAux")
if (e.intVal != 0) and (branch == nil): branch = it.sons[1]
of nkElse:

View File

@@ -461,6 +461,7 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
var dest = c.converters[i].typ.sons[0]
if (typeRel(m.bindings, f, dest) == isEqual) and
(typeRel(m.bindings, src, a) == isEqual):
markUsed(arg, c.converters[i])
var s = newSymNode(c.converters[i])
s.typ = c.converters[i].typ
s.info = arg.info
@@ -564,6 +565,11 @@ proc IndexTypesMatch*(c: PContext, f, a: PType, arg: PNode): PNode =
initCandidate(m, f)
result = paramTypesMatch(c, m, f, a, arg)
proc ConvertTo*(c: PContext, f: PType, n: PNode): PNode =
var m: TCandidate
initCandidate(m, f)
result = paramTypesMatch(c, m, f, n.typ, n)
proc argtypeMatches*(c: PContext, f, a: PType): bool =
var m: TCandidate
initCandidate(m, f)

View File

@@ -0,0 +1,11 @@
##
## can_alias_generic Nimrod Module
##
## Created by Eric Doughty-Papassideris on 2011-02-16.
## Copyright (c) 2011 FWA. All rights reserved.
type
TGen[T] = object
TGen2[T] = TGen[T]

View File

@@ -0,0 +1,11 @@
##
## can_alias_specialised_generic Nimrod Module
##
## Created by Eric Doughty-Papassideris on 2011-02-16.
## Copyright (c) 2011 FWA. All rights reserved.
type
TGen[T] = object
TSpef = TGen[string]

View File

@@ -1,6 +1,8 @@
converter p(i: int): bool = return i != 0
if 0:
echo "foo"
if 1:
echo if 4: "foo" else: "barr"
while 0:
echo "bar"

View File

@@ -0,0 +1,8 @@
discard """
line: 6
errormsg: "Error: type mismatch: got (int) but expected 'bool'"
"""
if 1:
echo "wtf?"