bugfix: overloading resolution for typeof

This commit is contained in:
Araq 2011-09-27 00:27:51 +02:00
commit da6046dcba
7 changed files with 98 additions and 81 deletions

View file

@ -35,7 +35,7 @@ proc semStmtScope(c: PContext, n: PNode): PNode
type type
TExprFlag = enum TExprFlag = enum
efAllowType, efLValue, efWantIterator efAllowType, efLValue, efWantIterator, efInTypeof
TExprFlags = set[TExprFlag] TExprFlags = set[TExprFlag]
proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode

View file

@ -35,6 +35,8 @@ proc semDirectCallWithBinding(c: PContext, n, f: PNode, filter: TSymKinds,
z.calleeSym = sym z.calleeSym = sym
matches(c, n, z) matches(c, n, z)
if z.state == csMatch: 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 case x.state
of csEmpty, csNoMatch: x = z of csEmpty, csNoMatch: x = z
of csMatch: of csMatch:

View file

@ -446,11 +446,13 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) =
proc semDirectCallAnalyseEffects(c: PContext, n: PNode, proc semDirectCallAnalyseEffects(c: PContext, n: PNode,
flags: TExprFlags): PNode = flags: TExprFlags): PNode =
var symflags = {skProc, skMethod, skConverter}
if efWantIterator in flags: if efWantIterator in flags:
# for ``type countup(1,3)``, see ``tests/ttoseq``. result = semDirectCall(c, n, {skIterator})
symflags = {skIterator} elif efInTypeOf in flags:
result = semDirectCall(c, n, symflags) # 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 != nil:
if result.sons[0].kind != nkSym: if result.sons[0].kind != nkSym:
InternalError("semDirectCallAnalyseEffects") InternalError("semDirectCallAnalyseEffects")

View file

@ -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) if s.ast == nil: GlobalError(n.info, errCannotInstantiateX, s.name.s)
result = instGenericContainer(c, n, result) 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 = proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
result = nil result = nil
if gCmd == cmdIdeTools: suggestExpr(c, n) if gCmd == cmdIdeTools: suggestExpr(c, n)
case n.kind case n.kind
of nkEmpty: nil of nkEmpty: nil
of nkTypeOfExpr: of nkTypeOfExpr:
# for ``type countup(1,3)``, see ``tests/ttoseq``. # for ``type(countup(1,3))``, see ``tests/ttoseq``.
# XXX We should find a better solution.
checkSonsLen(n, 1) checkSonsLen(n, 1)
result = semExprWithType(c, n.sons[0], {efWantIterator}).typ result = semExprWithType(c, n.sons[0], {efInTypeof}).typ
of nkPar: of nkPar:
if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev) if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev)
else: GlobalError(n.info, errTypeExpected) else: GlobalError(n.info, errTypeExpected)

View file

@ -18,7 +18,7 @@ type
TCandidateState* = enum TCandidateState* = enum
csEmpty, csMatch, csNoMatch csEmpty, csMatch, csNoMatch
TCandidate* {.final.} = object TCandidate* {.final.} = object
exactMatches: int exactMatches*: int
subtypeMatches: int subtypeMatches: int
intConvMatches: int # conversions to int are not as expensive intConvMatches: int # conversions to int are not as expensive
convMatches: int convMatches: int

View file

@ -1460,7 +1460,8 @@ statements always have to be intended::
complexStmt ::= ifStmt | whileStmt | caseStmt | tryStmt | forStmt complexStmt ::= ifStmt | whileStmt | caseStmt | tryStmt | forStmt
| blockStmt | asmStmt | blockStmt | asmStmt
| procDecl | iteratorDecl | macroDecl | templateDecl | procDecl | iteratorDecl | macroDecl | templateDecl
| constSection | typeSection | whenStmt | varSection | constSection | letSection
| typeSection | whenStmt | varSection
@ -2430,6 +2431,18 @@ be used to get the type of an expression:
var x = 0 var x = 0
var y: type(x) # y has type int var y: type(x) # y has type int
If ``type`` is used to determine the result type of a proc/iterator/converter
call ``c(X)`` (where ``X`` stands for a possibly empty list of arguments), the
interpretation where ``c`` is an iterator is preferred over the
other interpretations:
.. code-block:: nimrod
import strutils
# strutils contains both a ``split`` proc and iterator, but since an
# an iterator is the preferred interpretation, `y` has the type ``string``:
var y: type("a b c".split)
Type constraints Type constraints
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
@ -3308,6 +3321,7 @@ Memory allocation requires no lock at all! This design easily scales to massive
multicore processors that will become the norm in the future. multicore processors that will become the norm in the future.
Thread pragma Thread pragma
------------- -------------

View file

@ -10,3 +10,10 @@ template toSeq*(iter: expr): expr =
for x in items(toSeq(countup(2, 6))): for x in items(toSeq(countup(2, 6))):
stdout.write(x) stdout.write(x)
import strutils
var y: type("a b c".split)
y = "xzy"