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
|
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
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue