diff options
-rw-r--r-- | compiler/semdata.nim | 1 | ||||
-rw-r--r-- | compiler/semexprs.nim | 14 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 29 |
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: |