fix bugs with dot & call operators [backport] (#20931)
* better error messages for dot operators [backport] fixes #13063 * also fixes #7777 * fix #6981 and #9831 too * fix * minor improvement * sus test fixes * make test multiplatform lol * fix nimsuggest test, extra improvements
This commit is contained in:
parent
f31dc63169
commit
555c5ed1a7
6 changed files with 156 additions and 49 deletions
|
|
@ -287,8 +287,23 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) =
|
|||
# fail fast:
|
||||
globalError(c.config, n.info, "type mismatch")
|
||||
return
|
||||
# see getMsgDiagnostic:
|
||||
if nfExplicitCall notin n.flags and {nfDotField, nfDotSetter} * n.flags != {}:
|
||||
let ident = considerQuotedIdent(c, n[0], n).s
|
||||
let sym = n[1].typ.typSym
|
||||
var typeHint = ""
|
||||
if sym == nil:
|
||||
discard
|
||||
else:
|
||||
typeHint = " for type " & getProcHeader(c.config, sym)
|
||||
localError(c.config, n.info, errUndeclaredField % ident & typeHint)
|
||||
return
|
||||
if errors.len == 0:
|
||||
localError(c.config, n.info, "expression '$1' cannot be called" % n[0].renderTree)
|
||||
if n[0].kind in nkIdentKinds:
|
||||
let ident = considerQuotedIdent(c, n[0], n).s
|
||||
localError(c.config, n.info, errUndeclaredRoutine % ident)
|
||||
else:
|
||||
localError(c.config, n.info, "expression '$1' cannot be called" % n[0].renderTree)
|
||||
return
|
||||
|
||||
let (prefer, candidates) = presentFailedCandidates(c, n, errors)
|
||||
|
|
@ -330,7 +345,7 @@ proc getMsgDiagnostic(c: PContext, flags: TExprFlags, n, f: PNode): string =
|
|||
sym = nextOverloadIter(o, c, f)
|
||||
|
||||
let ident = considerQuotedIdent(c, f, n).s
|
||||
if {nfDotField, nfExplicitCall} * n.flags == {nfDotField}:
|
||||
if nfExplicitCall notin n.flags and {nfDotField, nfDotSetter} * n.flags != {}:
|
||||
let sym = n[1].typ.typSym
|
||||
var typeHint = ""
|
||||
if sym == nil:
|
||||
|
|
@ -363,11 +378,15 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
|
|||
else:
|
||||
initialBinding = nil
|
||||
|
||||
template pickBest(headSymbol) =
|
||||
pickBestCandidate(c, f, n, orig, initialBinding,
|
||||
filter, result, alt, errors, efExplain in flags,
|
||||
errorsEnabled, flags)
|
||||
|
||||
var dummyErrors: CandidateErrors
|
||||
template pickSpecialOp(headSymbol) =
|
||||
pickBestCandidate(c, headSymbol, n, orig, initialBinding,
|
||||
filter, result, alt, errors, efExplain in flags,
|
||||
errorsEnabled, flags)
|
||||
pickBest(f)
|
||||
filter, result, alt, dummyErrors, efExplain in flags,
|
||||
false, flags)
|
||||
|
||||
let overloadsState = result.state
|
||||
if overloadsState != csMatch:
|
||||
|
|
@ -383,7 +402,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
|
|||
let op = newIdentNode(getIdent(c.cache, x), n.info)
|
||||
n[0] = op
|
||||
orig[0] = op
|
||||
pickBest(op)
|
||||
pickSpecialOp(op)
|
||||
|
||||
if nfExplicitCall in n.flags:
|
||||
tryOp ".()"
|
||||
|
|
@ -397,26 +416,15 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
|
|||
let callOp = newIdentNode(getIdent(c.cache, ".="), n.info)
|
||||
n.sons[0..1] = [callOp, n[1], calleeName]
|
||||
orig.sons[0..1] = [callOp, orig[1], calleeName]
|
||||
pickBest(callOp)
|
||||
pickSpecialOp(callOp)
|
||||
|
||||
if overloadsState == csEmpty and result.state == csEmpty:
|
||||
if efNoUndeclared notin flags: # for tests/pragmas/tcustom_pragma.nim
|
||||
template impl() =
|
||||
result.state = csNoMatch
|
||||
if efNoDiagnostics in flags:
|
||||
return
|
||||
# xxx adapt/use errorUndeclaredIdentifierHint(c, n, f.ident)
|
||||
localError(c.config, n.info, getMsgDiagnostic(c, flags, n, f))
|
||||
if n[0].kind == nkIdent and n[0].ident.s == ".=" and n[2].kind == nkIdent:
|
||||
let sym = n[1].typ.sym
|
||||
if sym == nil:
|
||||
impl()
|
||||
else:
|
||||
let field = n[2].ident.s
|
||||
let msg = errUndeclaredField % field & " for type " & getProcHeader(c.config, sym)
|
||||
localError(c.config, orig[2].info, msg)
|
||||
else:
|
||||
impl()
|
||||
result.state = csNoMatch
|
||||
if efNoDiagnostics in flags:
|
||||
return
|
||||
# xxx adapt/use errorUndeclaredIdentifierHint(c, n, f.ident)
|
||||
localError(c.config, n.info, getMsgDiagnostic(c, flags, n, f))
|
||||
return
|
||||
elif result.state != csMatch:
|
||||
if nfExprCall in n.flags:
|
||||
|
|
@ -619,7 +627,7 @@ proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode =
|
|||
proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
|
||||
assert n.kind == nkBracketExpr
|
||||
for i in 1..<n.len:
|
||||
let e = semExpr(c, n[i])
|
||||
let e = semExprWithType(c, n[i])
|
||||
if e.typ == nil:
|
||||
n[i].typ = errorType(c)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -535,7 +535,7 @@ proc overloadedCallOpr(c: PContext, n: PNode): PNode =
|
|||
result = newNodeI(nkCall, n.info)
|
||||
result.add newIdentNode(par, n.info)
|
||||
for i in 0..<n.len: result.add n[i]
|
||||
result = semExpr(c, result)
|
||||
result = semExpr(c, result, flags = {efNoUndeclared})
|
||||
|
||||
proc changeType(c: PContext; n: PNode, newType: PType, check: bool) =
|
||||
case n.kind
|
||||
|
|
@ -993,6 +993,9 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType
|
|||
if s != nil:
|
||||
setGenericParams(c, n[0])
|
||||
return semDirectOp(c, n, flags, expectedType)
|
||||
elif isSymChoice(n[0]):
|
||||
# overloaded generic procs e.g. newSeq[int] can end up here
|
||||
return semDirectOp(c, n, flags, expectedType)
|
||||
|
||||
var t: PType = nil
|
||||
if n[0].typ != nil:
|
||||
|
|
@ -1042,10 +1045,10 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType
|
|||
instGenericConvertersSons(c, result, m)
|
||||
|
||||
else:
|
||||
result = overloadedCallOpr(c, n)
|
||||
result = overloadedCallOpr(c, n) # this uses efNoUndeclared
|
||||
# Now that nkSym does not imply an iteration over the proc/iterator space,
|
||||
# the old ``prc`` (which is likely an nkIdent) has to be restored:
|
||||
if result == nil:
|
||||
if result == nil or result.kind == nkEmpty:
|
||||
# XXX: hmm, what kind of symbols will end up here?
|
||||
# do we really need to try the overload resolution?
|
||||
n[0] = prc
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue