bugfix: overloading resolution for typeof
This commit is contained in:
parent
7c34357856
commit
da6046dcba
7 changed files with 98 additions and 81 deletions
|
|
@ -35,7 +35,7 @@ proc semStmtScope(c: PContext, n: PNode): PNode
|
|||
|
||||
type
|
||||
TExprFlag = enum
|
||||
efAllowType, efLValue, efWantIterator
|
||||
efAllowType, efLValue, efWantIterator, efInTypeof
|
||||
TExprFlags = set[TExprFlag]
|
||||
|
||||
proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ proc semDirectCallWithBinding(c: PContext, n, f: PNode, filter: TSymKinds,
|
|||
z.calleeSym = sym
|
||||
matches(c, n, z)
|
||||
if z.state == csMatch:
|
||||
# little hack so that iterators are preferred over everything else:
|
||||
if sym.kind == skIterator: inc(z.exactMatches, 200)
|
||||
case x.state
|
||||
of csEmpty, csNoMatch: x = z
|
||||
of csMatch:
|
||||
|
|
@ -48,7 +50,7 @@ proc semDirectCallWithBinding(c: PContext, n, f: PNode, filter: TSymKinds,
|
|||
# do not generate an error yet; the semantic checking will check for
|
||||
# an overloaded () operator
|
||||
elif y.state == csMatch and cmpCandidates(x, y) == 0 and
|
||||
not sameMethodDispatcher(x.calleeSym, y.calleeSym):
|
||||
not sameMethodDispatcher(x.calleeSym, y.calleeSym):
|
||||
if x.state != csMatch:
|
||||
InternalError(n.info, "x.state is not csMatch")
|
||||
LocalError(n.Info, errGenerated, msgKindToString(errAmbiguousCallXYZ) % [
|
||||
|
|
|
|||
|
|
@ -445,13 +445,15 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) =
|
|||
n.sons[i] = analyseIfAddressTaken(c, n.sons[i])
|
||||
|
||||
proc semDirectCallAnalyseEffects(c: PContext, n: PNode,
|
||||
flags: TExprFlags): PNode =
|
||||
var symflags = {skProc, skMethod, skConverter}
|
||||
flags: TExprFlags): PNode =
|
||||
if efWantIterator in flags:
|
||||
# for ``type countup(1,3)``, see ``tests/ttoseq``.
|
||||
symflags = {skIterator}
|
||||
result = semDirectCall(c, n, symflags)
|
||||
if result != nil:
|
||||
result = semDirectCall(c, n, {skIterator})
|
||||
elif efInTypeOf in flags:
|
||||
# for ``type(countup(1,3))``, see ``tests/ttoseq``.
|
||||
result = semDirectCall(c, n, {skIterator, skProc, skMethod, skConverter})
|
||||
else:
|
||||
result = semDirectCall(c, n, {skProc, skMethod, skConverter})
|
||||
if result != nil:
|
||||
if result.sons[0].kind != nkSym:
|
||||
InternalError("semDirectCallAnalyseEffects")
|
||||
var callee = result.sons[0].sym
|
||||
|
|
|
|||
|
|
@ -625,23 +625,15 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
|||
if s.ast == nil: GlobalError(n.info, errCannotInstantiateX, s.name.s)
|
||||
result = instGenericContainer(c, n, result)
|
||||
|
||||
proc FixupRemainingGenericInvokations(c: PContext, n: PNode,
|
||||
typ: PType): PType =
|
||||
if typ.kind == tyGenericInvokation:
|
||||
nil
|
||||
else:
|
||||
result = typ
|
||||
|
||||
proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||
result = nil
|
||||
if gCmd == cmdIdeTools: suggestExpr(c, n)
|
||||
case n.kind
|
||||
of nkEmpty: nil
|
||||
of nkTypeOfExpr:
|
||||
# for ``type countup(1,3)``, see ``tests/ttoseq``.
|
||||
# XXX We should find a better solution.
|
||||
of nkTypeOfExpr:
|
||||
# for ``type(countup(1,3))``, see ``tests/ttoseq``.
|
||||
checkSonsLen(n, 1)
|
||||
result = semExprWithType(c, n.sons[0], {efWantIterator}).typ
|
||||
result = semExprWithType(c, n.sons[0], {efInTypeof}).typ
|
||||
of nkPar:
|
||||
if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev)
|
||||
else: GlobalError(n.info, errTypeExpected)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ type
|
|||
TCandidateState* = enum
|
||||
csEmpty, csMatch, csNoMatch
|
||||
TCandidate* {.final.} = object
|
||||
exactMatches: int
|
||||
exactMatches*: int
|
||||
subtypeMatches: int
|
||||
intConvMatches: int # conversions to int are not as expensive
|
||||
convMatches: int
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue