improve error message for mismatched proc types
This commit is contained in:
parent
0bb18d1821
commit
443a46b40d
2 changed files with 43 additions and 13 deletions
|
|
@ -543,7 +543,7 @@ proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation =
|
||||||
else:
|
else:
|
||||||
return isNone
|
return isNone
|
||||||
when useEffectSystem:
|
when useEffectSystem:
|
||||||
if not compatibleEffects(f, a): return isNone
|
if compatibleEffects(f, a) != efCompat: return isNone
|
||||||
|
|
||||||
of tyNil:
|
of tyNil:
|
||||||
result = f.allowsNil
|
result = f.allowsNil
|
||||||
|
|
|
||||||
|
|
@ -1377,7 +1377,16 @@ proc compatibleEffectsAux(se, re: PNode): bool =
|
||||||
return false
|
return false
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
proc compatibleEffects*(formal, actual: PType): bool =
|
type
|
||||||
|
EffectsCompat* = enum
|
||||||
|
efCompat
|
||||||
|
efRaisesDiffer
|
||||||
|
efRaisesUnknown
|
||||||
|
efTagsDiffer
|
||||||
|
efTagsUnknown
|
||||||
|
efLockLevelsDiffer
|
||||||
|
|
||||||
|
proc compatibleEffects*(formal, actual: PType): EffectsCompat =
|
||||||
# for proc type compatibility checking:
|
# for proc type compatibility checking:
|
||||||
assert formal.kind == tyProc and actual.kind == tyProc
|
assert formal.kind == tyProc and actual.kind == tyProc
|
||||||
internalAssert formal.n.sons[0].kind == nkEffectList
|
internalAssert formal.n.sons[0].kind == nkEffectList
|
||||||
|
|
@ -1393,18 +1402,21 @@ proc compatibleEffects*(formal, actual: PType): bool =
|
||||||
# 'r.msgHandler = if isNil(msgHandler): defaultMsgHandler else: msgHandler'
|
# 'r.msgHandler = if isNil(msgHandler): defaultMsgHandler else: msgHandler'
|
||||||
if not isNil(se) and se.kind != nkArgList:
|
if not isNil(se) and se.kind != nkArgList:
|
||||||
# spec requires some exception or tag, but we don't know anything:
|
# spec requires some exception or tag, but we don't know anything:
|
||||||
if real.len == 0: return false
|
if real.len == 0: return efRaisesUnknown
|
||||||
result = compatibleEffectsAux(se, real.sons[exceptionEffects])
|
let res = compatibleEffectsAux(se, real.sons[exceptionEffects])
|
||||||
if not result: return
|
if not res: return efRaisesDiffer
|
||||||
|
|
||||||
let st = spec.sons[tagEffects]
|
let st = spec.sons[tagEffects]
|
||||||
if not isNil(st) and st.kind != nkArgList:
|
if not isNil(st) and st.kind != nkArgList:
|
||||||
# spec requires some exception or tag, but we don't know anything:
|
# spec requires some exception or tag, but we don't know anything:
|
||||||
if real.len == 0: return false
|
if real.len == 0: return efTagsUnknown
|
||||||
result = compatibleEffectsAux(st, real.sons[tagEffects])
|
let res = compatibleEffectsAux(st, real.sons[tagEffects])
|
||||||
if not result: return
|
if not res: return efTagsDiffer
|
||||||
result = formal.lockLevel.ord < 0 or
|
if formal.lockLevel.ord < 0 or
|
||||||
actual.lockLevel.ord <= formal.lockLevel.ord
|
actual.lockLevel.ord <= formal.lockLevel.ord:
|
||||||
|
result = efCompat
|
||||||
|
else:
|
||||||
|
result = efLockLevelsDiffer
|
||||||
|
|
||||||
proc isCompileTimeOnly*(t: PType): bool {.inline.} =
|
proc isCompileTimeOnly*(t: PType): bool {.inline.} =
|
||||||
result = t.kind in {tyTypeDesc, tyStatic}
|
result = t.kind in {tyTypeDesc, tyStatic}
|
||||||
|
|
@ -1508,6 +1520,24 @@ proc typeMismatch*(n: PNode, formal, actual: PType) =
|
||||||
let named = typeToString(formal)
|
let named = typeToString(formal)
|
||||||
let desc = typeToString(formal, preferDesc)
|
let desc = typeToString(formal, preferDesc)
|
||||||
let x = if named == desc: named else: named & " = " & desc
|
let x = if named == desc: named else: named & " = " & desc
|
||||||
localError(n.info, errGenerated, msgKindToString(errTypeMismatch) &
|
var msg = msgKindToString(errTypeMismatch) &
|
||||||
typeToString(actual) & ") " &
|
typeToString(actual) & ") " &
|
||||||
`%`(msgKindToString(errButExpectedX), [x]))
|
msgKindToString(errButExpectedX) % [x]
|
||||||
|
|
||||||
|
if formal.kind == tyProc and actual.kind == tyProc:
|
||||||
|
case compatibleEffects(formal, actual)
|
||||||
|
of efCompat: discard
|
||||||
|
of efRaisesDiffer:
|
||||||
|
msg.add "\n.raise effects differ"
|
||||||
|
of efRaisesUnknown:
|
||||||
|
msg.add "\n.raise effect is 'can raise any'"
|
||||||
|
of efTagsDiffer:
|
||||||
|
msg.add "\n.tag effects differ"
|
||||||
|
of efTagsUnknown:
|
||||||
|
msg.add "\n.tag effect is 'any tag allowed'"
|
||||||
|
of efLockLevelsDiffer:
|
||||||
|
msg.add "\nlock levels differ"
|
||||||
|
writeStackTrace()
|
||||||
|
debug actual.n
|
||||||
|
debug formal.n
|
||||||
|
localError(n.info, errGenerated, msg)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue