summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-12-15 22:35:16 +0100
committerAraq <rumpf_a@web.de>2012-12-15 22:35:16 +0100
commita22c1f444fa76cc06fee1ae31c79986e9c3b459f (patch)
tree2226d8cc4813b7b38988d14309ff603c60ff19c2 /compiler
parentc98696d7428346b53c8998bf8fab77fe08830e2e (diff)
downloadNim-a22c1f444fa76cc06fee1ae31c79986e9c3b459f.tar.gz
fixes #271
Diffstat (limited to 'compiler')
-rwxr-xr-xcompiler/msgs.nim2
-rwxr-xr-xcompiler/sem.nim2
-rwxr-xr-xcompiler/semcall.nim40
-rwxr-xr-xcompiler/semexprs.nim1
-rwxr-xr-xcompiler/sigmatch.nim34
5 files changed, 47 insertions, 32 deletions
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index 0f795c07d..240115817 100755
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -132,7 +132,7 @@ const
     errNumberOutOfRange: "number $1 out of valid range", 
     errNnotAllowedInCharacter: "\\n not allowed in character literal", 
     errClosingBracketExpected: "closing ']' expected, but end of file reached", 
-    errMissingFinalQuote: "missing final \'", 
+    errMissingFinalQuote: "missing final \' for character literal", 
     errIdentifierExpected: "identifier expected, but found \'$1\'", 
     errNewlineExpected: "newline expected, but found \'$1\'",
     errInvalidModuleName: "invalid module name: '$1'",
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 911eafb08..c8340a139 100755
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -47,6 +47,8 @@ proc fixImmediateParams(n: PNode): PNode
 proc activate(c: PContext, n: PNode)
 proc semQuoteAst(c: PContext, n: PNode): PNode
 
+proc IndexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode
+
 proc typeMismatch(n: PNode, formal, actual: PType) = 
   if formal.kind != tyError and actual.kind != tyError: 
     LocalError(n.Info, errGenerated, msgKindToString(errTypeMismatch) &
diff --git a/compiler/semcall.nim b/compiler/semcall.nim
index 962e4d3cc..0a5f19822 100755
--- a/compiler/semcall.nim
+++ b/compiler/semcall.nim
@@ -84,15 +84,34 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
         getProcHeader(best.calleeSym), getProcHeader(alt.calleeSym),
         args])
 
-proc instantiateGenericConverters(c: PContext, n: PNode, x: TCandidate) {.
-                                  noinline.}=
-  for i in 1 .. <n.len:
-    var a = n.sons[i]
-    if a.kind == nkHiddenCallConv and a.sons[0].kind == nkSym and
-        isGenericRoutine(a.sons[0].sym):
-      let finalCallee = generateInstance(c, a.sons[0].sym, x.bindings, n.info)
-      a.sons[0].sym = finalCallee
-      a.sons[0].typ = finalCallee.typ
+
+proc instGenericConvertersArg*(c: PContext, a: PNode, x: TCandidate) =
+  if a.kind == nkHiddenCallConv and a.sons[0].kind == nkSym and
+      isGenericRoutine(a.sons[0].sym):
+    let finalCallee = generateInstance(c, a.sons[0].sym, x.bindings, a.info)
+    a.sons[0].sym = finalCallee
+    a.sons[0].typ = finalCallee.typ
+    #a.typ = finalCallee.typ.sons[0]
+
+proc instGenericConvertersSons*(c: PContext, n: PNode, x: TCandidate) =
+  assert n.kind in nkCallKinds
+  if x.genericConverter:
+    for i in 1 .. <n.len:
+      instGenericConvertersArg(c, n.sons[i], x)
+
+proc IndexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode = 
+  var m: TCandidate
+  initCandidate(m, f)
+  result = paramTypesMatch(c, m, f, a, arg, nil)
+  if m.genericConverter and result != nil:
+    instGenericConvertersArg(c, result, m)
+
+proc ConvertTo*(c: PContext, f: PType, n: PNode): PNode = 
+  var m: TCandidate
+  initCandidate(m, f)
+  result = paramTypesMatch(c, m, f, n.typ, n, nil)
+  if m.genericConverter and result != nil:
+    instGenericConvertersArg(c, result, m)
 
 proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode =
   assert x.state == csMatch
@@ -111,8 +130,7 @@ proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode =
       if ContainsGenericType(result.typ): result.typ = errorType(c)
       return
   result = x.call
-  if x.genericConverter:
-    instantiateGenericConverters(c, result, x)
+  instGenericConvertersSons(c, result, x)
   result.sons[0] = newSymNode(finalCallee, result.sons[0].info)
   result.typ = finalCallee.typ.sons[0]
 
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 7b37987ee..d0fbcab6f 100755
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -664,6 +664,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
       result = nil
     else:
       result = m.call
+      instGenericConvertersSons(c, result, m)
     # we assume that a procedure that calls something indirectly 
     # has side-effects:
     if tfNoSideEffect notin t.flags: incl(c.p.owner.flags, sfSideEffect)
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 1f2511694..2fecda427 100755
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -594,7 +594,7 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
       addSon(result, copyTree(arg))
       inc(m.convMatches)
       m.genericConverter = srca == isGeneric or destIsGeneric
-      return
+      return result
 
 proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType, 
                     arg: PNode): PNode = 
@@ -705,8 +705,8 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType,
         else:
           result = userConvMatch(c, m, base(f), a, arg)
 
-proc ParamTypesMatch(c: PContext, m: var TCandidate, f, a: PType, 
-                     arg, argOrig: PNode): PNode =
+proc ParamTypesMatch*(c: PContext, m: var TCandidate, f, a: PType, 
+                      arg, argOrig: PNode): PNode =
   if arg == nil or arg.kind notin nkSymChoices:
     result = ParamTypesMatchAux(c, m, f, a, arg, argOrig)
   else: 
@@ -752,27 +752,12 @@ proc ParamTypesMatch(c: PContext, m: var TCandidate, f, a: PType,
       result = ParamTypesMatchAux(c, m, f, arg.sons[best].typ, arg.sons[best],
                                   argOrig)
 
-proc IndexTypesMatch*(c: PContext, f, a: PType, arg: PNode): PNode = 
-  var m: TCandidate
-  initCandidate(m, f)
-  result = paramTypesMatch(c, m, f, a, arg, nil)
-
-proc ConvertTo*(c: PContext, f: PType, n: PNode): PNode = 
-  var m: TCandidate
-  initCandidate(m, f)
-  result = paramTypesMatch(c, m, f, n.typ, n, nil)
-
-proc argtypeMatches*(c: PContext, f, a: PType): bool = 
-  var m: TCandidate
-  initCandidate(m, f)
-  result = paramTypesMatch(c, m, f, a, ast.emptyNode, nil) != nil  
-
 proc setSon(father: PNode, at: int, son: PNode) = 
   if sonsLen(father) <= at: setlen(father.sons, at + 1)
   father.sons[at] = son
 
-proc matchesAux*(c: PContext, n, nOrig: PNode,
-                 m: var TCandidate, marker: var TIntSet) = 
+proc matchesAux(c: PContext, n, nOrig: PNode,
+                m: var TCandidate, marker: var TIntSet) = 
   template checkConstraint(n: expr) {.immediate, dirty.} =
     if not formal.constraint.isNil:
       if matchNodeKinds(formal.constraint, n):
@@ -904,4 +889,13 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
         setSon(m.call, formal.position + 1, copyTree(formal.ast))
     inc(f)
 
+proc argtypeMatches*(c: PContext, f, a: PType): bool = 
+  var m: TCandidate
+  initCandidate(m, f)
+  let res = paramTypesMatch(c, m, f, a, ast.emptyNode, nil)
+  #instantiateGenericConverters(c, res, m)
+  # XXX this is used by patterns.nim too; I think it's better to not
+  # instantiate generic converters for that
+  result = res != nil
+
 include suggest