diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ast.nim | 6 | ||||
-rw-r--r-- | compiler/condsyms.nim | 1 | ||||
-rw-r--r-- | compiler/jsgen.nim | 2 | ||||
-rw-r--r-- | compiler/liftdestructors.nim | 2 | ||||
-rw-r--r-- | compiler/linter.nim | 2 | ||||
-rw-r--r-- | compiler/semcall.nim | 10 | ||||
-rw-r--r-- | compiler/semdata.nim | 2 | ||||
-rw-r--r-- | compiler/semexprs.nim | 9 | ||||
-rw-r--r-- | compiler/semtypes.nim | 13 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 31 | ||||
-rw-r--r-- | compiler/typeallowed.nim | 3 | ||||
-rw-r--r-- | compiler/types.nim | 11 | ||||
-rw-r--r-- | compiler/vmdeps.nim | 1 |
13 files changed, 71 insertions, 22 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index fffe08cb7..155af6375 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -440,10 +440,12 @@ type tyVoid # now different from tyEmpty, hurray! + tyIterable static: # remind us when TTypeKind stops to fit in a single 64-bit word - assert TTypeKind.high.ord <= 63 + # assert TTypeKind.high.ord <= 63 + discard const tyPureObject* = tyTuple @@ -664,7 +666,7 @@ type mDefault, mUnown, mIsolate, mAccessEnv, mReset, mArray, mOpenArray, mRange, mSet, mSeq, mVarargs, mRef, mPtr, mVar, mDistinct, mVoid, mTuple, - mOrdinal, + mOrdinal, mIterableType, mInt, mInt8, mInt16, mInt32, mInt64, mUInt, mUInt8, mUInt16, mUInt32, mUInt64, mFloat, mFloat32, mFloat64, mFloat128, diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index 9ba97a8ed..bdecd7e53 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -132,3 +132,4 @@ proc initDefines*(symbols: StringTableRef) = defineSymbol("nimHasSpellSuggest") defineSymbol("nimHasCustomLiterals") defineSymbol("nimHasUnifiedTuple") + defineSymbol("nimHasIterable") diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 3fc7708bf..ca716b1c0 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -211,7 +211,7 @@ proc mapType(typ: PType): TJSTypeKind = else: result = etyNone of tyProc: result = etyProc of tyCString: result = etyString - of tyConcept: doAssert false + of tyConcept, tyIterable: doAssert false proc mapType(p: PProc; typ: PType): TJSTypeKind = result = mapType(typ) diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim index bb24fed34..436665827 100644 --- a/compiler/liftdestructors.nim +++ b/compiler/liftdestructors.nim @@ -908,7 +908,7 @@ proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) = of tyOrdinal, tyRange, tyInferred, tyGenericInst, tyAlias, tySink: fillBody(c, lastSon(t), body, x, y) - of tyConcept: doAssert false + of tyConcept, tyIterable: doAssert false proc produceSymDistinctType(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp; info: TLineInfo; diff --git a/compiler/linter.nim b/compiler/linter.nim index 9af4f468e..83dd84699 100644 --- a/compiler/linter.nim +++ b/compiler/linter.nim @@ -40,7 +40,7 @@ proc beautifyName(s: string, k: TSymKind): string = "pointer", "float", "csize", "csize_t", "cdouble", "cchar", "cschar", "cshort", "cu", "nil", "typedesc", "auto", "any", "range", "openarray", "varargs", "set", "cfloat", "ref", "ptr", - "untyped", "typed", "static", "sink", "lent", "type", "owned"]: + "untyped", "typed", "static", "sink", "lent", "type", "owned", "iterable"]: result.add s[i] else: result.add toUpperAscii(s[i]) diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 99979c382..8f29bdf32 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -62,7 +62,7 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode, best, alt: var TCandidate, errors: var CandidateErrors, diagnosticsFlag: bool, - errorsEnabled: bool) = + errorsEnabled: bool, flags: TExprFlags) = var o: TOverloadIter var sym = initOverloadIter(o, c, headSymbol) var scope = o.lastOverloadScope @@ -95,7 +95,11 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode, matches(c, n, orig, z) if z.state == csMatch: # little hack so that iterators are preferred over everything else: - if sym.kind == skIterator: inc(z.exactMatches, 200) + if sym.kind == skIterator: + if not (efWantIterator notin flags and efWantIterable in flags): + inc(z.exactMatches, 200) + else: + dec(z.exactMatches, 200) case best.state of csEmpty, csNoMatch: best = z of csMatch: @@ -356,7 +360,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode, template pickBest(headSymbol) = pickBestCandidate(c, headSymbol, n, orig, initialBinding, filter, result, alt, errors, efExplain in flags, - errorsEnabled) + errorsEnabled, flags) pickBest(f) let overloadsState = result.state diff --git a/compiler/semdata.nim b/compiler/semdata.nim index c655047e2..51b2cdea1 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -54,7 +54,7 @@ type inst*: PInstantiation TExprFlag* = enum - efLValue, efWantIterator, efInTypeof, + efLValue, efWantIterator, efWantIterable, efInTypeof, efNeedStatic, # Use this in contexts where a static value is mandatory efPreferStatic, diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index c0aa168ef..256c008c9 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -853,7 +853,7 @@ proc semStaticExpr(c: PContext, n: PNode): PNode = proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode, flags: TExprFlags): PNode = - if flags*{efInTypeof, efWantIterator} != {}: + if flags*{efInTypeof, efWantIterator, efWantIterable} != {}: # consider: 'for x in pReturningArray()' --> we don't want the restriction # to 'skIterator' anymore; skIterator is preferred in sigmatch already # for typeof support. @@ -877,6 +877,11 @@ proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode, # error correction, prevents endless for loop elimination in transf. # See bug #2051: result[0] = newSymNode(errorSym(c, n)) + elif callee.kind == skIterator: + if efWantIterable in flags: + let typ = newTypeS(tyIterable, c) + rawAddSon(typ, result.typ) + result.typ = typ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode @@ -1364,7 +1369,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = onUse(n[1].info, s) return - n[0] = semExprWithType(c, n[0], flags+{efDetermineType}) + n[0] = semExprWithType(c, n[0], flags+{efDetermineType, efWantIterable}) #restoreOldStyleType(n[0]) var i = considerQuotedIdent(c, n[1], n) var ty = n[0].typ diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index b34dc36e3..34a90a3f2 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -356,6 +356,15 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType = localError(c.config, n.info, errArrayExpectsTwoTypeParams) result = newOrPrevType(tyError, prev, c) +proc semIterableType(c: PContext, n: PNode, prev: PType): PType = + result = newOrPrevType(tyIterable, prev, c) + if n.len == 2: + let base = semTypeNode(c, n[1], nil) + addSonSkipIntLit(result, base, c.idgen) + else: + localError(c.config, n.info, errXExpectsOneTypeParam % "iterable") + result = newOrPrevType(tyError, prev, c) + proc semOrdinal(c: PContext, n: PNode, prev: PType): PType = result = newOrPrevType(tyOrdinal, prev, c) if n.len == 2: @@ -1844,6 +1853,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = of mRange: result = semRange(c, n, prev) of mSet: result = semSet(c, n, prev) of mOrdinal: result = semOrdinal(c, n, prev) + of mIterableType: result = semIterableType(c, n, prev) of mSeq: result = semContainer(c, n, tySequence, "seq", prev) if optSeqDestructors in c.config.globalOptions: @@ -2067,6 +2077,9 @@ proc processMagicType(c: PContext, m: PSym) = of mOrdinal: setMagicIntegral(c.config, m, tyOrdinal, szUncomputedSize) rawAddSon(m.typ, newTypeS(tyNone, c)) + of mIterableType: + setMagicIntegral(c.config, m, tyIterable, 0) + rawAddSon(m.typ, newTypeS(tyNone, c)) of mPNimrodNode: incl m.typ.flags, tfTriggersCompileTime incl m.typ.flags, tfCheckedForDestructor diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 87f7c273b..767f34dda 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1119,6 +1119,8 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, return if x >= isGeneric: isGeneric else: x return isNone + of tyIterable: + if f.kind != tyIterable: return isNone of tyNot: case f.kind of tyNot: @@ -1421,6 +1423,15 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, of tyAlias, tySink: result = typeRel(c, lastSon(f), a, flags) + of tyIterable: + if a.kind == tyIterable: + if f.len == 1: + result = typeRel(c, lastSon(f), lastSon(a), flags) + else: + # f.len = 3, for some reason + result = isGeneric + else: + result = isNone of tyGenericInst: var prev = PType(idTableGet(c.bindings, f)) let origF = f @@ -2270,14 +2281,18 @@ proc prepareOperand(c: PContext; formal: PType; a: PNode): PNode = # a.typ == nil is valid result = a elif a.typ.isNil: - # XXX This is unsound! 'formal' can differ from overloaded routine to - # overloaded routine! - let flags = {efDetermineType, efAllowStmt} - #if formal.kind == tyIter: {efDetermineType, efWantIterator} - #else: {efDetermineType, efAllowStmt} - #elif formal.kind == tyTyped: {efDetermineType, efWantStmt} - #else: {efDetermineType} - result = c.semOperand(c, a, flags) + if formal.kind == tyIterable: + let flags = {efDetermineType, efAllowStmt, efWantIterator, efWantIterable} + result = c.semOperand(c, a, flags) + else: + # XXX This is unsound! 'formal' can differ from overloaded routine to + # overloaded routine! + let flags = {efDetermineType, efAllowStmt} + #if formal.kind == tyIterable: {efDetermineType, efWantIterator} + #else: {efDetermineType, efAllowStmt} + #elif formal.kind == tyTyped: {efDetermineType, efWantStmt} + #else: {efDetermineType} + result = c.semOperand(c, a, flags) else: result = a considerGenSyms(c, result) diff --git a/compiler/typeallowed.nim b/compiler/typeallowed.nim index 9075d9e38..270e7c028 100644 --- a/compiler/typeallowed.nim +++ b/compiler/typeallowed.nim @@ -97,6 +97,9 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, result = nil of tyUntyped, tyTyped: if kind notin {skParam, skResult} or taNoUntyped in flags: result = t + of tyIterable: + if kind notin {skParam} or taNoUntyped in flags: result = t + # tyIterable is only for templates and macros. of tyStatic: if kind notin {skParam}: result = t of tyVoid: diff --git a/compiler/types.nim b/compiler/types.nim index 1dbbc3261..ce4812506 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -460,8 +460,8 @@ const "lent ", "varargs[$1]", "UncheckedArray[$1]", "Error Type", "BuiltInTypeClass", "UserTypeClass", "UserTypeClassInst", "CompositeTypeClass", "inferred", - "and", "or", "not", "any", "static", "TypeFromExpr", "out ", - "void"] + "and", "or", "not", "any", "static", "TypeFromExpr", "concept", # xxx bugfix + "void", "iterable"] const preferToResolveSymbols = {preferName, preferTypeName, preferModuleInfo, preferGenericArg, preferResolved, preferMixed} @@ -645,6 +645,11 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = of tyDistinct: result = "distinct " & typeToString(t[0], if prefer == preferModuleInfo: preferModuleInfo else: preferTypeName) + of tyIterable: + # xxx factor this pattern + result = "iterable" + if t.len > 0: + result &= "[" & typeToString(t[0]) & ']' of tyTuple: # we iterate over t.sons here, because t.n may be nil if t.n != nil: @@ -1191,7 +1196,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = result = sameTypeOrNilAux(a[0], b[0], c) and sameValue(a.n[0], b.n[0]) and sameValue(a.n[1], b.n[1]) - of tyGenericInst, tyAlias, tyInferred: + of tyGenericInst, tyAlias, tyInferred, tyIterable: cycleCheck() result = sameTypeAux(a.lastSon, b.lastSon, c) of tyNone: result = false diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index a9157bc03..6191f9459 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -287,6 +287,7 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo; of tyAnd: result = mapTypeToBracket("and", mAnd, t, info) of tyOr: result = mapTypeToBracket("or", mOr, t, info) of tyNot: result = mapTypeToBracket("not", mNot, t, info) + of tyIterable: result = mapTypeToBracket("iterable", mIterableType, t, info) of tyAnything: result = atomicType("anything", mNone) of tyInferred: assert false of tyStatic, tyFromExpr: |