improvements for the is operator; implemented the type lifting rule in user-defined type classes
This commit is contained in:
parent
31dd66acbf
commit
4cea15d274
3 changed files with 32 additions and 12 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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!
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue