introduce a pre-processing pass for the concept bodies
fixes #4982 fixes #3805 close #3414
This commit is contained in:
parent
30ccadfe4c
commit
cd02561368
13 changed files with 138 additions and 60 deletions
|
|
@ -607,14 +607,24 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
|
|||
var
|
||||
typeClass = ff.skipTypes({tyUserTypeClassInst})
|
||||
body = typeClass.n[3]
|
||||
if c.inTypeClass > 4:
|
||||
localError(body.info, $body & " too nested for type matching")
|
||||
return nil
|
||||
matchedConceptContext: TMatchedConcept
|
||||
prevMatchedConcept = c.matchedConcept
|
||||
prevCandidateType = typeClass[0][0]
|
||||
|
||||
if prevMatchedConcept != nil:
|
||||
matchedConceptContext.prev = prevMatchedConcept
|
||||
matchedConceptContext.depth = prevMatchedConcept.depth + 1
|
||||
if prevMatchedConcept.depth > 4:
|
||||
localError(body.info, $body & " too nested for type matching")
|
||||
return nil
|
||||
|
||||
openScope(c)
|
||||
inc c.inTypeClass
|
||||
matchedConceptContext.candidateType = a
|
||||
typeClass[0].sons[0] = a
|
||||
c.matchedConcept = addr(matchedConceptContext)
|
||||
defer:
|
||||
dec c.inTypeClass
|
||||
c.matchedConcept = prevMatchedConcept
|
||||
typeClass[0].sons[0] = prevCandidateType
|
||||
closeScope(c)
|
||||
|
||||
var typeParams: seq[(PSym, PType)]
|
||||
|
|
@ -658,33 +668,6 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
|
|||
|
||||
addDecl(c, param)
|
||||
|
||||
for param in typeClass.n[0]:
|
||||
var
|
||||
dummyName: PNode
|
||||
dummyType: PType
|
||||
|
||||
let modifier = case param.kind
|
||||
of nkVarTy: tyVar
|
||||
of nkRefTy: tyRef
|
||||
of nkPtrTy: tyPtr
|
||||
of nkStaticTy: tyStatic
|
||||
of nkTypeOfExpr: tyTypeDesc
|
||||
else: tyNone
|
||||
|
||||
if modifier != tyNone:
|
||||
dummyName = param[0]
|
||||
dummyType = c.makeTypeWithModifier(modifier, a)
|
||||
if modifier == tyTypeDesc: dummyType.flags.incl tfExplicit
|
||||
else:
|
||||
dummyName = param
|
||||
dummyType = a
|
||||
|
||||
internalAssert dummyName.kind == nkIdent
|
||||
var dummyParam = newSym(if modifier == tyTypeDesc: skType else: skVar,
|
||||
dummyName.ident, typeClass.sym, typeClass.sym.info)
|
||||
dummyParam.typ = dummyType
|
||||
addDecl(c, dummyParam)
|
||||
|
||||
var
|
||||
oldWriteHook: type(writelnHook)
|
||||
diagnostics: seq[string]
|
||||
|
|
@ -826,7 +809,7 @@ proc inferStaticParam*(c: var TCandidate, lhs: PNode, rhs: BiggestInt): bool =
|
|||
var inferred = newTypeWithSons(c.c, tyStatic, lhs.typ.sons)
|
||||
inferred.n = newIntNode(nkIntLit, rhs)
|
||||
put(c, lhs.typ, inferred)
|
||||
if c.c.inTypeClass > 0:
|
||||
if c.c.matchedConcept != nil:
|
||||
# inside concepts, binding is currently done with
|
||||
# direct mutation of the involved types:
|
||||
lhs.typ.n = inferred.n
|
||||
|
|
@ -916,7 +899,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
|||
assert(aOrig != nil)
|
||||
|
||||
var
|
||||
useTypeLoweringRuleInTypeClass = c.c.inTypeClass > 0 and
|
||||
useTypeLoweringRuleInTypeClass = c.c.matchedConcept != nil and
|
||||
not c.isNoCall and
|
||||
f.kind != tyTypeDesc and
|
||||
tfExplicit notin aOrig.flags
|
||||
|
|
@ -965,7 +948,10 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
|||
# for example, but unfortunately `prepareOperand` is not called in certain
|
||||
# situation when nkDotExpr are rotated to nkDotCalls
|
||||
|
||||
if a.kind in {tyGenericInst, tyAlias} and
|
||||
if aOrig.kind == tyAlias:
|
||||
return typeRel(c, f, lastSon(aOrig))
|
||||
|
||||
if a.kind == tyGenericInst and
|
||||
skipTypes(f, {tyVar}).kind notin {
|
||||
tyGenericBody, tyGenericInvocation,
|
||||
tyGenericInst, tyGenericParam} + tyTypeClasses:
|
||||
|
|
@ -1106,7 +1092,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
|||
|
||||
if fRange.rangeHasUnresolvedStatic:
|
||||
return inferStaticsInRange(c, fRange, a)
|
||||
elif c.c.inTypeClass > 0 and aRange.rangeHasUnresolvedStatic:
|
||||
elif c.c.matchedConcept != nil and aRange.rangeHasUnresolvedStatic:
|
||||
return inferStaticsInRange(c, aRange, f)
|
||||
else:
|
||||
if lengthOrd(fRange) != lengthOrd(aRange):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue