summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2017-03-29 16:15:30 +0300
committerZahary Karadjov <zahary@gmail.com>2017-03-29 16:15:30 +0300
commita74ad869e905737f144037f4ad5000eaed7a5bd2 (patch)
tree4c53830221f679e6d03f5d8aef6b3de904cc7c1a /compiler
parent01207b6cfda148c513d5b3fe7db024d1b5881a95 (diff)
downloadNim-a74ad869e905737f144037f4ad5000eaed7a5bd2.tar.gz
requested code review changes
Diffstat (limited to 'compiler')
-rw-r--r--compiler/semcall.nim30
-rw-r--r--compiler/semstmts.nim17
-rw-r--r--compiler/semtypes.nim2
-rw-r--r--compiler/sigmatch.nim24
4 files changed, 43 insertions, 30 deletions
diff --git a/compiler/semcall.nim b/compiler/semcall.nim
index e1f09c3d5..f707fc844 100644
--- a/compiler/semcall.nim
+++ b/compiler/semcall.nim
@@ -99,7 +99,10 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode,
           if cmp < 0: best = z   # x is better than the best so far
           elif cmp == 0: alt = z # x is as good as the best so far
       elif errors != nil or z.diagnostics != nil:
-        errors.safeAdd((sym, int z.mutabilityProblem, z.diagnostics))
+        errors.safeAdd(CandidateError(
+          sym: sym,
+          unmatchedVarParam: int z.mutabilityProblem,
+          diagnostics: z.diagnostics))
     else:
       # Symbol table has been modified. Restart and pre-calculate all syms
       # before any further candidate init and compare. SLOW, but rare case.
@@ -126,9 +129,9 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors):
   # we do a pre-analysis. If all types produce the same string, we will add
   # module information.
   let proto = describeArgs(c, n, 1, preferName)
-  for err, mut, diagnostics in items(errors):
+  for err in errors:
     var errProto = ""
-    let n = err.typ.n
+    let n = err.sym.typ.n
     for i in countup(1, n.len - 1):
       var p = n.sons[i]
       if p.kind == nkSym:
@@ -140,16 +143,17 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors):
       break
 
   var candidates = ""
-  for err, mut, diagnostics in items(errors):
-    if err.kind in routineKinds and err.ast != nil:
-      add(candidates, renderTree(err.ast,
+  for err in errors:
+    if err.sym.kind in routineKinds and err.sym.ast != nil:
+      add(candidates, renderTree(err.sym.ast,
             {renderNoBody, renderNoComments, renderNoPragmas}))
     else:
-      add(candidates, err.getProcHeader(prefer))
+      add(candidates, err.sym.getProcHeader(prefer))
     add(candidates, "\n")
-    if mut != 0 and mut < n.len:
-      add(candidates, "for a 'var' type a variable needs to be passed, but '" & renderTree(n[mut]) & "' is immutable\n")
-    for diag in diagnostics:
+    if err.unmatchedVarParam != 0 and err.unmatchedVarParam < n.len:
+      add(candidates, "for a 'var' type a variable needs to be passed, but '" &
+                      renderTree(n[err.unmatchedVarParam]) & "' is immutable\n")
+    for diag in err.diagnostics:
       add(candidates, diag & "\n")
   
   result = (prefer, candidates)
@@ -180,7 +184,9 @@ proc bracketNotFoundError(c: PContext; n: PNode) =
   var symx = initOverloadIter(o, c, headSymbol)
   while symx != nil:
     if symx.kind in routineKinds:
-      errors.add((symx, 0, nil))
+      errors.add(CandidateError(sym: symx,
+                                unmatchedVarParam: 0,
+                                diagnostics: nil))
     symx = nextOverloadIter(o, c, headSymbol)
   if errors.len == 0:
     localError(n.info, "could not resolve: " & $n)
@@ -405,7 +411,7 @@ proc semOverloadedCall(c: PContext, n, nOrig: PNode,
       n.sons[1] = n.sons[1].sons[0]
       notFoundError(c, n, errors)
   else:
-    if efExplain notin flags:
+    if efExplain notin flags and c.compilesContextId == 0:
       # repeat the overload resolution,
       # this time enabling all the diagnostic output (this should fail again)
       discard semOverloadedCall(c, n, nOrig, filter, flags + {efExplain})
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 12391a9cd..a678311bf 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -1555,9 +1555,14 @@ proc usesResult(n: PNode): bool =
       for c in n:
         if usesResult(c): return true
 
-proc inferConceptStaticParam(c: PContext, typ: PType, n: PNode) =
+proc inferConceptStaticParam(c: PContext, inferred, n: PNode) =
+  var typ = inferred.typ
   let res = semConstExpr(c, n)
-  if not sameType(res.typ, typ.base): localError(n.info, "")
+  if not sameType(res.typ, typ.base):
+    localError(n.info,
+      "cannot infer the concept parameter '%s', due to a type mismatch. " &
+      "attempt to equate '%s' and '%s'.",
+      [inferred.renderTree, $res.typ, $typ.base])
   typ.n = res
 
 proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
@@ -1616,12 +1621,14 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
       if c.inTypeClass > 0 and expr.typ != nil:
         case expr.typ.kind
         of tyBool:
-          if expr.kind == nkInfix and expr[0].sym.name.s == "==":
+          if expr.kind == nkInfix and
+             expr[0].kind == nkSym and
+             expr[0].sym.name.s == "==":
             if expr[1].typ.isUnresolvedStatic:
-              inferConceptStaticParam(c, expr[1].typ, expr[2])
+              inferConceptStaticParam(c, expr[1], expr[2])
               continue
             elif expr[2].typ.isUnresolvedStatic:
-              inferConceptStaticParam(c, expr[2].typ, expr[1])
+              inferConceptStaticParam(c, expr[2], expr[1])
               continue
             
           let verdict = semConstExpr(c, n[i])
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 02166f0aa..422d2f0fa 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -1235,7 +1235,7 @@ proc symFromExpectedTypeNode(c: PContext, n: PNode): PSym =
   if n.kind == nkType:
     result = symFromType(n.typ, n.info)
   else:
-    localError(n.info, "xx")
+    localError(n.info, errTypeExpected)
     result = errorSym(c, n)
 
 proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index bbcf25903..ff7b0ae72 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -22,10 +22,10 @@ type
   TCandidateState* = enum
     csEmpty, csMatch, csNoMatch
 
-  CandidateError = tuple
-    sym: PSym
-    unmatchedVarParam: int
-    diagnostics: seq[string]
+  CandidateError* = object
+    sym*: PSym
+    unmatchedVarParam*: int
+    diagnostics*: seq[string]
   
   CandidateErrors* = seq[CandidateError]
 
@@ -589,8 +589,8 @@ proc typeRangeRel(f, a: PType): TTypeRelation {.noinline.} =
 proc matchUserTypeClass*(c: PContext, m: var TCandidate,
                          ff, a: PType): PType =
   var
-    Concept = ff.skipTypes({tyUserTypeClassInst})
-    body = Concept.n[3]
+    typeClass = ff.skipTypes({tyUserTypeClassInst})
+    body = typeClass.n[3]
   if c.inTypeClass > 4:
     localError(body.info, $body & " too nested for type matching")
     return nil
@@ -611,7 +611,7 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
         param: PSym
 
       template paramSym(kind): untyped =
-        newSym(kind, typeParamName, Concept.sym, Concept.sym.info)
+        newSym(kind, typeParamName, typeClass.sym, typeClass.sym.info)
 
       block addTypeParam:
         for prev in typeParams:
@@ -642,7 +642,7 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
       
       addDecl(c, param)
 
-  for param in Concept.n[0]:
+  for param in typeClass.n[0]:
     var
       dummyName: PNode
       dummyType: PType
@@ -665,7 +665,7 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
 
     internalAssert dummyName.kind == nkIdent
     var dummyParam = newSym(if modifier == tyTypeDesc: skType else: skVar,
-                            dummyName.ident, Concept.sym, Concept.sym.info)
+                            dummyName.ident, typeClass.sym, typeClass.sym.info)
     dummyParam.typ = dummyType
     addDecl(c, dummyParam)
 
@@ -675,7 +675,7 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
     errorPrefix: string
     flags: TExprFlags = {}
     collectDiagnostics = m.diagnostics != nil or
-                         sfExplain in Concept.sym.flags
+                         sfExplain in typeClass.sym.flags
   
   if collectDiagnostics:
     oldWriteHook = writelnHook
@@ -684,7 +684,7 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
     diagnostics = @[]
     flags = {efExplain}
     writelnHook = proc (s: string) =
-      if errorPrefix == nil: errorPrefix = Concept.sym.name.s & ":"
+      if errorPrefix == nil: errorPrefix = typeClass.sym.name.s & ":"
       let msg = s.replace("Error:", errorPrefix)
       if oldWriteHook != nil: oldWriteHook msg
       diagnostics.add msg
@@ -704,7 +704,7 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
     put(m, p[1], p[0].typ)
 
   if ff.kind == tyUserTypeClassInst:
-    result = generateTypeInstance(c, m.bindings, Concept.sym.info, ff)
+    result = generateTypeInstance(c, m.bindings, typeClass.sym.info, ff)
   else:
     result = copyType(ff, ff.owner, true)