summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/semdata.nim1
-rw-r--r--compiler/semexprs.nim14
-rw-r--r--compiler/sigmatch.nim29
3 files changed, 32 insertions, 12 deletions
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index 121bf297d..31d2ce6bd 100644
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -60,6 +60,7 @@ type
     threadEntries*: TSymSeq    # list of thread entries to check
     AmbiguousSymbols*: TIntSet # ids of all ambiguous symbols (cannot
                                # store this info in the syms themselves!)
+    InTypeClass*: int          # > 0 if we are in a user-defined type class
     InGenericContext*: int     # > 0 if we are in a generic type
     InUnrolledContext*: int    # > 0 if we are unrolling a loop
     InCompilesContext*: int    # > 0 if we are in a ``compiles`` magic
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index fdc050260..2cb6f2047 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -321,10 +321,19 @@ proc isOpImpl(c: PContext, n: PNode): PNode =
   else:
     var match: bool
     let t2 = n[2].typ
-    if t2.kind == tyTypeClass:
+    case t2.kind
+    of tyTypeClass:
       var m: TCandidate
       InitCandidate(m, t2)
       match = matchUserTypeClass(c, m, emptyNode, t2, t1) != nil
+    of tyOrdinal:
+      var m: TCandidate
+      InitCandidate(m, t2)
+      match = isOrdinalType(t1)
+    of tySequence, tyArray, tySet:
+      var m: TCandidate
+      InitCandidate(m, t2)
+      match = typeRel(m, t2, t1) != isNone
     else:
       match = sameType(t1, t2)
  
@@ -763,7 +772,8 @@ proc afterCallActions(c: PContext; n, orig: PNode, flags: TExprFlags): PNode =
     analyseIfAddressTakenInCall(c, result)
     if callee.magic != mNone:
       result = magicsAfterOverloadResolution(c, result, flags)
-  result = evalAtCompileTime(c, result)
+  if c.InTypeClass == 0:
+    result = evalAtCompileTime(c, result)
 
 proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = 
   # this seems to be a hotspot in the compiler!
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 78ae61d0f..1d502a205 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -202,7 +202,7 @@ proc describeArgs*(c: PContext, n: PNode, startIdx = 1): string =
     add(result, argTypeToString(arg))
     if i != sonsLen(n) - 1: add(result, ", ")
 
-proc typeRel(c: var TCandidate, f, a: PType): TTypeRelation
+proc typeRel*(c: var TCandidate, f, a: PType): TTypeRelation
 proc concreteType(c: TCandidate, t: PType): PType = 
   case t.kind
   of tyArrayConstr: 
@@ -750,6 +750,11 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
 
   # pushInfoContext(arg.info)
   openScope(c)
+  inc c.InTypeClass
+
+  finally:
+    dec c.InTypeClass
+    closeScope(c)
 
   for param in f.n[0]:
     var
@@ -764,7 +769,7 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
       dummyType = a
 
     InternalAssert dummyName.kind == nkIdent
-    var dummyParam = newSym(skParam, dummyName.ident, f.sym, f.sym.info)
+    var dummyParam = newSym(skType, dummyName.ident, f.sym, f.sym.info)
     dummyParam.typ = dummyType
     addDecl(c, dummyParam)
 
@@ -780,23 +785,27 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
     of nkTypeSection: nil
     of nkConstDef: nil
     else:
-      if e.typ.kind == tyBool:
+      if e.typ != nil and e.typ.kind == tyBool:
         let verdict = c.semConstExpr(c, e)
         if verdict.intVal == 0:
           let expStr = renderTree(stmt, {renderNoComments})
           m.errors.safeAdd(expStr & " doesn't hold for " & a.typeToString)
           return nil
-
-  closeScope(c)
-
+  
   result = arg
   put(m.bindings, f, a)
 
-proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType, 
+proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, argType: PType,
                         argSemantized, argOrig: PNode): PNode =
-  var arg = argSemantized
-  var r: TTypeRelation
-  let fMaybeExpr = f.skipTypes({tyDistinct})
+  var
+    r: TTypeRelation
+    arg = argSemantized
+
+  let
+    a = if c.InTypeClass > 0: argType.skipTypes({tyTypeDesc})
+        else: argType
+    fMaybeExpr = f.skipTypes({tyDistinct})
+
   case fMaybeExpr.kind
   of tyExpr:
     if fMaybeExpr.sonsLen == 0: