decent error message for 'var T' problems
This commit is contained in:
parent
50e3ca9f36
commit
995727ffd0
2 changed files with 16 additions and 15 deletions
|
|
@ -69,7 +69,7 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode,
|
||||||
# gDebug = true
|
# gDebug = true
|
||||||
matches(c, n, orig, z)
|
matches(c, n, orig, z)
|
||||||
if errors != nil:
|
if errors != nil:
|
||||||
errors.safeAdd(sym)
|
errors.safeAdd((sym, int z.mutabilityProblem))
|
||||||
if z.errors != nil:
|
if z.errors != nil:
|
||||||
for err in z.errors:
|
for err in z.errors:
|
||||||
errors.add(err)
|
errors.add(err)
|
||||||
|
|
@ -111,7 +111,7 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) =
|
||||||
let proto = describeArgs(c, n, 1, preferName)
|
let proto = describeArgs(c, n, 1, preferName)
|
||||||
|
|
||||||
var prefer = preferName
|
var prefer = preferName
|
||||||
for err in errors:
|
for err, mut in items(errors):
|
||||||
var errProto = ""
|
var errProto = ""
|
||||||
let n = err.typ.n
|
let n = err.typ.n
|
||||||
for i in countup(1, n.len - 1):
|
for i in countup(1, n.len - 1):
|
||||||
|
|
@ -123,18 +123,21 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) =
|
||||||
if errProto == proto:
|
if errProto == proto:
|
||||||
prefer = preferModuleInfo
|
prefer = preferModuleInfo
|
||||||
break
|
break
|
||||||
|
|
||||||
# now use the information stored in 'prefer' to produce a nice error message:
|
# now use the information stored in 'prefer' to produce a nice error message:
|
||||||
var result = msgKindToString(errTypeMismatch)
|
var result = msgKindToString(errTypeMismatch)
|
||||||
add(result, describeArgs(c, n, 1, prefer))
|
add(result, describeArgs(c, n, 1, prefer))
|
||||||
add(result, ')')
|
add(result, ')')
|
||||||
var candidates = ""
|
var candidates = ""
|
||||||
for err in errors:
|
for err, mut in items(errors):
|
||||||
if err.kind in routineKinds and err.ast != nil:
|
if err.kind in routineKinds and err.ast != nil:
|
||||||
add(candidates, renderTree(err.ast,
|
add(candidates, renderTree(err.ast,
|
||||||
{renderNoBody, renderNoComments,renderNoPragmas}))
|
{renderNoBody, renderNoComments,renderNoPragmas}))
|
||||||
else:
|
else:
|
||||||
add(candidates, err.getProcHeader(prefer))
|
add(candidates, err.getProcHeader(prefer))
|
||||||
add(candidates, "\n")
|
add(candidates, "\n")
|
||||||
|
if mut != 0 and mut < n.len:
|
||||||
|
add(candidates, "for a 'var' type a variable needs to be passed, but '" & renderTree(n[mut]) & "' is immutable\n")
|
||||||
if candidates != "":
|
if candidates != "":
|
||||||
add(result, "\n" & msgKindToString(errButExpected) & "\n" & candidates)
|
add(result, "\n" & msgKindToString(errButExpected) & "\n" & candidates)
|
||||||
if c.compilesContextId > 0 and optReportConceptFailures in gGlobalOptions:
|
if c.compilesContextId > 0 and optReportConceptFailures in gGlobalOptions:
|
||||||
|
|
@ -158,8 +161,6 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
|
||||||
template pickBest(headSymbol) =
|
template pickBest(headSymbol) =
|
||||||
pickBestCandidate(c, headSymbol, n, orig, initialBinding,
|
pickBestCandidate(c, headSymbol, n, orig, initialBinding,
|
||||||
filter, result, alt, errors)
|
filter, result, alt, errors)
|
||||||
|
|
||||||
|
|
||||||
pickBest(f)
|
pickBest(f)
|
||||||
|
|
||||||
let overloadsState = result.state
|
let overloadsState = result.state
|
||||||
|
|
@ -230,7 +231,6 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
|
||||||
#notFoundError(c, n, errors)
|
#notFoundError(c, n, errors)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if alt.state == csMatch and cmpCandidates(result, alt) == 0 and
|
if alt.state == csMatch and cmpCandidates(result, alt) == 0 and
|
||||||
not sameMethodDispatcher(result.calleeSym, alt.calleeSym):
|
not sameMethodDispatcher(result.calleeSym, alt.calleeSym):
|
||||||
internalAssert result.state == csMatch
|
internalAssert result.state == csMatch
|
||||||
|
|
@ -299,8 +299,7 @@ proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode =
|
||||||
var finalCallee = x.calleeSym
|
var finalCallee = x.calleeSym
|
||||||
markUsed(n.sons[0].info, finalCallee)
|
markUsed(n.sons[0].info, finalCallee)
|
||||||
styleCheckUse(n.sons[0].info, finalCallee)
|
styleCheckUse(n.sons[0].info, finalCallee)
|
||||||
if finalCallee.ast == nil:
|
assert finalCallee.ast != nil
|
||||||
internalError(n.info, "calleeSym.ast is nil") # XXX: remove this check!
|
|
||||||
if x.hasFauxMatch:
|
if x.hasFauxMatch:
|
||||||
result = x.call
|
result = x.call
|
||||||
result.sons[0] = newSymNode(finalCallee, result.sons[0].info)
|
result.sons[0] = newSymNode(finalCallee, result.sons[0].info)
|
||||||
|
|
@ -319,12 +318,12 @@ proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode =
|
||||||
# are added as normal params.
|
# are added as normal params.
|
||||||
for s in instantiateGenericParamList(c, gp, x.bindings):
|
for s in instantiateGenericParamList(c, gp, x.bindings):
|
||||||
case s.kind
|
case s.kind
|
||||||
of skConst:
|
of skConst:
|
||||||
x.call.add s.ast
|
x.call.add s.ast
|
||||||
of skType:
|
of skType:
|
||||||
x.call.add newSymNode(s, n.info)
|
x.call.add newSymNode(s, n.info)
|
||||||
else:
|
else:
|
||||||
internalAssert false
|
internalAssert false
|
||||||
|
|
||||||
result = x.call
|
result = x.call
|
||||||
instGenericConvertersSons(c, result, x)
|
instGenericConvertersSons(c, result, x)
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ type
|
||||||
TCandidateState* = enum
|
TCandidateState* = enum
|
||||||
csEmpty, csMatch, csNoMatch
|
csEmpty, csMatch, csNoMatch
|
||||||
|
|
||||||
CandidateErrors* = seq[PSym]
|
CandidateErrors* = seq[(PSym,int)]
|
||||||
TCandidate* = object
|
TCandidate* = object
|
||||||
c*: PContext
|
c*: PContext
|
||||||
exactMatches*: int # also misused to prefer iters over procs
|
exactMatches*: int # also misused to prefer iters over procs
|
||||||
|
|
@ -49,6 +49,7 @@ type
|
||||||
# a distrinct type
|
# a distrinct type
|
||||||
typedescMatched*: bool
|
typedescMatched*: bool
|
||||||
isNoCall*: bool # misused for generic type instantiations C[T]
|
isNoCall*: bool # misused for generic type instantiations C[T]
|
||||||
|
mutabilityProblem*: uint8 # tyVar mismatch
|
||||||
inheritancePenalty: int # to prefer closest father object type
|
inheritancePenalty: int # to prefer closest father object type
|
||||||
errors*: CandidateErrors # additional clarifications to be displayed to the
|
errors*: CandidateErrors # additional clarifications to be displayed to the
|
||||||
# user if overload resolution fails
|
# user if overload resolution fails
|
||||||
|
|
@ -1579,6 +1580,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
|
||||||
if formal.typ.kind == tyVar:
|
if formal.typ.kind == tyVar:
|
||||||
if not n.isLValue:
|
if not n.isLValue:
|
||||||
m.state = csNoMatch
|
m.state = csNoMatch
|
||||||
|
m.mutabilityProblem = uint8(f-1)
|
||||||
return
|
return
|
||||||
|
|
||||||
var
|
var
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue