diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ast.nim | 1 | ||||
-rw-r--r-- | compiler/cgmeth.nim | 4 | ||||
-rw-r--r-- | compiler/pragmas.nim | 2 | ||||
-rw-r--r-- | compiler/semdata.nim | 2 | ||||
-rw-r--r-- | compiler/semexprs.nim | 10 | ||||
-rw-r--r-- | compiler/semstmts.nim | 16 | ||||
-rw-r--r-- | compiler/semtypinst.nim | 13 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 9 | ||||
-rw-r--r-- | compiler/suggest.nim | 2 | ||||
-rw-r--r-- | compiler/types.nim | 2 |
10 files changed, 44 insertions, 17 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 9ec88ba8e..4c98219f9 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -850,6 +850,7 @@ type # see instantiateDestructor in semdestruct.nim deepCopy*: PSym # overriden 'deepCopy' operation assignment*: PSym # overriden '=' operator + methods*: seq[(int,PSym)] # attached methods size*: BiggestInt # the size of the type in bytes # -1 means that the size is unkwown align*: int16 # the type's alignment requirements diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim index 3dbd4f815..624c5b183 100644 --- a/compiler/cgmeth.nim +++ b/compiler/cgmeth.nim @@ -63,7 +63,7 @@ proc sameMethodBucket(a, b: PSym): MethodResult = while true: aa = skipTypes(aa, {tyGenericInst}) bb = skipTypes(bb, {tyGenericInst}) - if (aa.kind == bb.kind) and (aa.kind in {tyVar, tyPtr, tyRef}): + if aa.kind == bb.kind and aa.kind in {tyVar, tyPtr, tyRef}: aa = aa.lastSon bb = bb.lastSon else: @@ -187,7 +187,7 @@ proc cmpSignatures(a, b: PSym, relevantCols: IntSet): int = var aa = skipTypes(a.typ.sons[col], skipPtrs) var bb = skipTypes(b.typ.sons[col], skipPtrs) var d = inheritanceDiff(aa, bb) - if (d != high(int)): + if (d != high(int)) and d != 0: return d proc sortBucket(a: var TSymSeq, relevantCols: IntSet) = diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index c15794b99..d7d1ed838 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -68,7 +68,7 @@ const letPragmas* = varPragmas procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideeffect, wThread, wRaises, wLocks, wTags, wGcSafe} - allRoutinePragmas* = procPragmas + iteratorPragmas + lambdaPragmas + allRoutinePragmas* = methodPragmas + iteratorPragmas + lambdaPragmas proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) # implementation diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 52b5dc274..30b6e261d 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -104,7 +104,7 @@ type hloLoopDetector*: int # used to prevent endless loops in the HLO inParallelStmt*: int instTypeBoundOp*: proc (c: PContext; dc: PSym; t: PType; info: TLineInfo; - op: TTypeAttachedOp): PSym {.nimcall.} + op: TTypeAttachedOp; col: int): PSym {.nimcall.} selfName*: PIdent signatures*: TStrTable diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 9f0696252..d76bd791e 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -191,10 +191,6 @@ proc semConv(c: PContext, n: PNode): PNode = case status of convOK: # handle SomeProcType(SomeGenericProc) - # XXX: This needs fixing. checkConvertible uses typeRel internally, but - # doesn't bother to perform the work done in paramTypeMatchAux/fitNode - # so we are redoing the typeRel work here. Why does semConv exist as a - # separate proc from fitNode? if op.kind == nkSym and op.sym.isGenericRoutine: result.sons[1] = fitNode(c, result.typ, result.sons[1]) elif op.kind == nkPar and targetType.kind == tyTuple: @@ -202,8 +198,10 @@ proc semConv(c: PContext, n: PNode): PNode = of convNotNeedeed: message(n.info, hintConvFromXtoItselfNotNeeded, result.typ.typeToString) of convNotLegal: - localError(n.info, errGenerated, msgKindToString(errIllegalConvFromXtoY)% - [op.typ.typeToString, result.typ.typeToString]) + result = fitNode(c, result.typ, result.sons[1]) + if result == nil: + localError(n.info, errGenerated, msgKindToString(errIllegalConvFromXtoY)% + [op.typ.typeToString, result.typ.typeToString]) else: for i in countup(0, sonsLen(op) - 1): let it = op.sons[i] diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 79581e4cb..f59acd7be 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1352,7 +1352,21 @@ proc semMethod(c: PContext, n: PNode): PNode = # macros can transform methods to nothing: if namePos >= result.safeLen: return result var s = result.sons[namePos].sym - if not isGenericRoutine(s): + if isGenericRoutine(s): + let tt = s.typ + var foundObj = false + # we start at 1 for now so that tparsecombnum continues to compile. + # XXX Revisit this problem later. + for col in countup(1, sonsLen(tt)-1): + let t = tt.sons[col] + if t != nil and t.kind == tyGenericInvocation: + var x = skipTypes(t.sons[0], {tyVar, tyPtr, tyRef, tyGenericInst, tyGenericInvocation, tyGenericBody}) + if x.kind == tyObject and t.len-1 == result.sons[genericParamsPos].len: + foundObj = true + x.methods.safeAdd((col,s)) + if not foundObj: + message(n.info, warnDeprecated, "generic method not attachable to object type") + else: # why check for the body? bug #2400 has none. Checking for sfForward makes # no sense either. # and result.sons[bodyPos].kind != nkEmpty: diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 922071ba3..076679bbf 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -289,7 +289,8 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType = # but we already raised an error! rawAddSon(result, header.sons[i]) - var newbody = replaceTypeVarsT(cl, lastSon(body)) + let bbody = lastSon body + var newbody = replaceTypeVarsT(cl, bbody) cl.skipTypedesc = oldSkipTypedesc newbody.flags = newbody.flags + (t.flags + body.flags - tfInstClearedFlags) result.flags = result.flags + newbody.flags - tfInstClearedFlags @@ -306,12 +307,18 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType = # 'deepCopy' needs to be instantiated for # generics *when the type is constructed*: newbody.deepCopy = cl.c.instTypeBoundOp(cl.c, dc, result, cl.info, - attachedDeepCopy) + attachedDeepCopy, 1) let asgn = newbody.assignment if asgn != nil and sfFromGeneric notin asgn.flags: # '=' needs to be instantiated for generics when the type is constructed: newbody.assignment = cl.c.instTypeBoundOp(cl.c, asgn, result, cl.info, - attachedAsgn) + attachedAsgn, 1) + let methods = skipTypes(bbody, abstractPtrs).methods + for col, meth in items(methods): + # we instantiate the known methods belonging to that type, this causes + # them to be registered and that's enough, so we 'discard' the result. + discard cl.c.instTypeBoundOp(cl.c, meth, result, cl.info, + attachedAsgn, col) proc eraseVoidParams*(t: PType) = # transform '(): void' into '()' because old parts of the compiler really diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 7a5aa8dbb..9a8f865a6 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1796,16 +1796,19 @@ proc argtypeMatches*(c: PContext, f, a: PType): bool = result = res != nil proc instTypeBoundOp*(c: PContext; dc: PSym; t: PType; info: TLineInfo; - op: TTypeAttachedOp): PSym {.procvar.} = + op: TTypeAttachedOp; col: int): PSym {.procvar.} = var m: TCandidate initCandidate(c, m, dc.typ) - var f = dc.typ.sons[1] + if col >= dc.typ.len: + localError(info, errGenerated, "cannot instantiate '" & dc.name.s & "'") + return nil + var f = dc.typ.sons[col] if op == attachedDeepCopy: if f.kind in {tyRef, tyPtr}: f = f.lastSon else: if f.kind == tyVar: f = f.lastSon if typeRel(m, f, t) == isNone: - localError(info, errGenerated, "cannot instantiate 'deepCopy'") + localError(info, errGenerated, "cannot instantiate '" & dc.name.s & "'") else: result = c.semGenerateInstance(c, dc, m.bindings, info) assert sfFromGeneric in result.flags diff --git a/compiler/suggest.nim b/compiler/suggest.nim index bcab6b04a..f35ff2142 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -393,6 +393,8 @@ proc suggestSym*(info: TLineInfo; s: PSym; isDecl=true) {.inline.} = proc markUsed(info: TLineInfo; s: PSym) = incl(s.flags, sfUsed) + if s.kind == skEnumField and s.owner != nil: + incl(s.owner.flags, sfUsed) if {sfDeprecated, sfError} * s.flags != {}: if sfDeprecated in s.flags: message(info, warnDeprecated, s.name.s) if sfError in s.flags: localError(info, errWrongSymbolX, s.name.s) diff --git a/compiler/types.nim b/compiler/types.nim index a87f9470f..5fbab85b9 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -803,6 +803,8 @@ proc sameTuple(a, b: PType, c: var TSameTypeClosure): bool = result = x.name.id == y.name.id if not result: break else: internalError(a.n.info, "sameTuple") + elif a.n != b.n and (a.n == nil or b.n == nil) and IgnoreTupleFields notin c.flags: + result = false template ifFastObjectTypeCheckFailed(a, b: PType, body: stmt) {.immediate.} = if tfFromGeneric notin a.flags + b.flags: |