improvements for the is operator; implemented the type lifting rule in user-defined type classes

This commit is contained in:
Zahary Karadjov 2013-11-17 16:28:42 +02:00
commit 4cea15d274
3 changed files with 32 additions and 12 deletions

View file

@ -60,6 +60,7 @@ type
threadEntries*: TSymSeq # list of thread entries to check threadEntries*: TSymSeq # list of thread entries to check
AmbiguousSymbols*: TIntSet # ids of all ambiguous symbols (cannot AmbiguousSymbols*: TIntSet # ids of all ambiguous symbols (cannot
# store this info in the syms themselves!) # 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 InGenericContext*: int # > 0 if we are in a generic type
InUnrolledContext*: int # > 0 if we are unrolling a loop InUnrolledContext*: int # > 0 if we are unrolling a loop
InCompilesContext*: int # > 0 if we are in a ``compiles`` magic InCompilesContext*: int # > 0 if we are in a ``compiles`` magic

View file

@ -321,10 +321,19 @@ proc isOpImpl(c: PContext, n: PNode): PNode =
else: else:
var match: bool var match: bool
let t2 = n[2].typ let t2 = n[2].typ
if t2.kind == tyTypeClass: case t2.kind
of tyTypeClass:
var m: TCandidate var m: TCandidate
InitCandidate(m, t2) InitCandidate(m, t2)
match = matchUserTypeClass(c, m, emptyNode, t2, t1) != nil 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: else:
match = sameType(t1, t2) match = sameType(t1, t2)
@ -763,7 +772,8 @@ proc afterCallActions(c: PContext; n, orig: PNode, flags: TExprFlags): PNode =
analyseIfAddressTakenInCall(c, result) analyseIfAddressTakenInCall(c, result)
if callee.magic != mNone: if callee.magic != mNone:
result = magicsAfterOverloadResolution(c, result, flags) 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 = proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
# this seems to be a hotspot in the compiler! # this seems to be a hotspot in the compiler!

View file

@ -202,7 +202,7 @@ proc describeArgs*(c: PContext, n: PNode, startIdx = 1): string =
add(result, argTypeToString(arg)) add(result, argTypeToString(arg))
if i != sonsLen(n) - 1: add(result, ", ") 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 = proc concreteType(c: TCandidate, t: PType): PType =
case t.kind case t.kind
of tyArrayConstr: of tyArrayConstr:
@ -750,6 +750,11 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
# pushInfoContext(arg.info) # pushInfoContext(arg.info)
openScope(c) openScope(c)
inc c.InTypeClass
finally:
dec c.InTypeClass
closeScope(c)
for param in f.n[0]: for param in f.n[0]:
var var
@ -764,7 +769,7 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
dummyType = a dummyType = a
InternalAssert dummyName.kind == nkIdent 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 dummyParam.typ = dummyType
addDecl(c, dummyParam) addDecl(c, dummyParam)
@ -780,23 +785,27 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
of nkTypeSection: nil of nkTypeSection: nil
of nkConstDef: nil of nkConstDef: nil
else: else:
if e.typ.kind == tyBool: if e.typ != nil and e.typ.kind == tyBool:
let verdict = c.semConstExpr(c, e) let verdict = c.semConstExpr(c, e)
if verdict.intVal == 0: if verdict.intVal == 0:
let expStr = renderTree(stmt, {renderNoComments}) let expStr = renderTree(stmt, {renderNoComments})
m.errors.safeAdd(expStr & " doesn't hold for " & a.typeToString) m.errors.safeAdd(expStr & " doesn't hold for " & a.typeToString)
return nil return nil
closeScope(c)
result = arg result = arg
put(m.bindings, f, a) 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 = argSemantized, argOrig: PNode): PNode =
var arg = argSemantized var
var r: TTypeRelation r: TTypeRelation
let fMaybeExpr = f.skipTypes({tyDistinct}) arg = argSemantized
let
a = if c.InTypeClass > 0: argType.skipTypes({tyTypeDesc})
else: argType
fMaybeExpr = f.skipTypes({tyDistinct})
case fMaybeExpr.kind case fMaybeExpr.kind
of tyExpr: of tyExpr:
if fMaybeExpr.sonsLen == 0: if fMaybeExpr.sonsLen == 0: