summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/parampatterns.nim41
-rw-r--r--compiler/sigmatch.nim21
2 files changed, 28 insertions, 34 deletions
diff --git a/compiler/parampatterns.nim b/compiler/parampatterns.nim
index 8db786a25..58b5c5681 100644
--- a/compiler/parampatterns.nim
+++ b/compiler/parampatterns.nim
@@ -24,7 +24,7 @@ type
     ppEof = 1, # end of compiled pattern
     ppOr,      # we could short-cut the evaluation for 'and' and 'or',
     ppAnd,     # but currently we don't
-    ppNot, 
+    ppNot,
     ppSym,
     ppAtom,
     ppLit,
@@ -56,7 +56,7 @@ proc whichAlias*(p: PSym): TAliasRequest =
 proc compileConstraints(p: PNode, result: var TPatternCode) =
   case p.kind
   of nkCallKinds:
-    if p.sons[0].kind != nkIdent: 
+    if p.sons[0].kind != nkIdent:
       patternError(p.sons[0])
       return
     let op = p.sons[0].ident
@@ -168,8 +168,8 @@ proc checkForSideEffects(n: PNode): TSideEffectAnalysis =
       elif ret == seUnknown and result == seNoSideEffect:
         result = seUnknown
 
-type 
-  TAssignableResult* = enum 
+type
+  TAssignableResult* = enum
     arNone,                   # no l-value and no discriminant
     arLValue,                 # is an l-value
     arLocalLValue,            # is an l-value, but local var; must not escape
@@ -183,26 +183,26 @@ proc isAssignable*(owner: PSym, n: PNode): TAssignableResult =
   of nkSym:
     # don't list 'skLet' here:
     if n.sym.kind in {skVar, skResult, skTemp}:
-      if owner != nil and owner.id == n.sym.owner.id and 
+      if owner != nil and owner.id == n.sym.owner.id and
           sfGlobal notin n.sym.flags:
         result = arLocalLValue
       else:
         result = arLValue
-  of nkDotExpr: 
-    if skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc}).kind in 
-        {tyVar, tyPtr, tyRef}: 
+  of nkDotExpr:
+    if skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc}).kind in
+        {tyVar, tyPtr, tyRef}:
       result = arLValue
     else:
       result = isAssignable(owner, n.sons[0])
-    if result != arNone and sfDiscriminant in n.sons[1].sym.flags: 
+    if result != arNone and sfDiscriminant in n.sons[1].sym.flags:
       result = arDiscriminant
-  of nkBracketExpr: 
+  of nkBracketExpr:
     if skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc}).kind in
-        {tyVar, tyPtr, tyRef}: 
+        {tyVar, tyPtr, tyRef}:
       result = arLValue
     else:
       result = isAssignable(owner, n.sons[0])
-  of nkHiddenStdConv, nkHiddenSubConv, nkConv: 
+  of nkHiddenStdConv, nkHiddenSubConv, nkConv:
     # Object and tuple conversions are still addressable, so we skip them
     # XXX why is 'tyOpenArray' allowed here?
     if skipTypes(n.typ, abstractPtrs-{tyTypeDesc}).kind in
@@ -211,9 +211,9 @@ proc isAssignable*(owner: PSym, n: PNode): TAssignableResult =
     elif compareTypes(n.typ, n.sons[1].typ, dcEqIgnoreDistinct):
       # types that are equal modulo distinction preserve l-value:
       result = isAssignable(owner, n.sons[1])
-  of nkHiddenDeref, nkDerefExpr: 
+  of nkHiddenDeref, nkDerefExpr, nkHiddenAddr:
     result = arLValue
-  of nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr: 
+  of nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr:
     result = isAssignable(owner, n.sons[0])
   of nkCallKinds:
     # builtin slice keeps lvalue-ness:
@@ -221,24 +221,27 @@ proc isAssignable*(owner: PSym, n: PNode): TAssignableResult =
   else:
     discard
 
+proc isLValue*(n: PNode): bool =
+  isAssignable(nil, n) in {arLValue, arLocalLValue}
+
 proc matchNodeKinds*(p, n: PNode): bool =
-  # matches the parameter constraint 'p' against the concrete AST 'n'. 
+  # matches the parameter constraint 'p' against the concrete AST 'n'.
   # Efficiency matters here.
   var stack {.noinit.}: array[0..MaxStackSize, bool]
   # empty patterns are true:
   stack[0] = true
   var sp = 1
-  
+
   template push(x: bool) =
     stack[sp] = x
     inc sp
-  
+
   let code = p.strVal
   var pc = 1
   while true:
     case TOpcode(code[pc])
     of ppEof: break
-    of ppOr: 
+    of ppOr:
       stack[sp-2] = stack[sp-1] or stack[sp-2]
       dec sp
     of ppAnd:
@@ -264,4 +267,4 @@ proc matchNodeKinds*(p, n: PNode): bool =
     of ppNoSideEffect: push checkForSideEffects(n) != seSideEffect
     inc pc
   result = stack[sp-1]
-  
+
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index f1fd84326..e56d82a5b 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -191,21 +191,6 @@ proc complexDisambiguation(a, b: PType): int =
     for i in 1 .. <a.len: x += a.sons[i].sumGeneric
     for i in 1 .. <b.len: y += b.sons[i].sumGeneric
     result = x - y
-  when false:
-    proc betterThan(a, b: PType): bool {.inline.} = a.sumGeneric > b.sumGeneric
-
-    if a.len > 1 and b.len > 1:
-      let aa = a.sons[1].sumGeneric
-      let bb = b.sons[1].sumGeneric
-      var a = a
-      var b = b
-
-      if aa < bb: swap(a, b)
-      # all must be better
-      for i in 2 .. <min(a.len, b.len):
-        if not a.sons[i].betterThan(b.sons[i]): return 0
-      # a must be longer or of the same length as b:
-      result = a.len - b.len
 
 proc cmpCandidates*(a, b: TCandidate): int =
   result = a.exactMatches - b.exactMatches
@@ -1463,6 +1448,12 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
       else:
         m.state = csNoMatch
         return
+    if formal.typ.kind == tyVar:
+      if n.isLValue:
+        inc(m.genericMatches, 100)
+      else:
+        m.state = csNoMatch
+        return
 
   var
     # iterates over formal parameters