diff options
-rw-r--r-- | changelogs/changelog_2_0_0.md | 3 | ||||
-rw-r--r-- | compiler/ccgstmts.nim | 2 | ||||
-rw-r--r-- | compiler/commands.nim | 2 | ||||
-rw-r--r-- | compiler/lineinfos.nim | 2 | ||||
-rw-r--r-- | compiler/lowerings.nim | 3 | ||||
-rw-r--r-- | compiler/nversion.nim | 2 | ||||
-rw-r--r-- | compiler/semexprs.nim | 33 | ||||
-rw-r--r-- | compiler/semtypes.nim | 2 | ||||
-rw-r--r-- | compiler/suggest.nim | 2 | ||||
-rw-r--r-- | compiler/vmgen.nim | 3 | ||||
-rw-r--r-- | doc/sets_fragment.txt | 9 | ||||
-rw-r--r-- | lib/pure/httpcore.nim | 10 | ||||
-rw-r--r-- | lib/std/sysrand.nim | 4 | ||||
-rw-r--r-- | lib/system/setops.nim | 4 | ||||
-rw-r--r-- | tests/sets/thugeset.nim | 10 |
15 files changed, 59 insertions, 32 deletions
diff --git a/changelogs/changelog_2_0_0.md b/changelogs/changelog_2_0_0.md index 89759d34e..779eec529 100644 --- a/changelogs/changelog_2_0_0.md +++ b/changelogs/changelog_2_0_0.md @@ -219,6 +219,9 @@ replacement of the `nnkFormalParams` node as well as having child nodes unlike other type class AST. +- Signed integer literals in `set` literals now default to a range type of + `0..255` instead of `0..65535` (the maximum size of sets). + ## Standard library additions and changes [//]: # "Changes:" diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index db86af3b0..63fb17527 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -653,7 +653,7 @@ proc genParForStmt(p: BProc, t: PNode) = #initLoc(forLoopVar.loc, locLocalVar, forLoopVar.typ, onStack) #discard mangleName(forLoopVar) let call = t[1] - assert(call.len in {4, 5}) + assert(call.len == 4 or call.len == 5) initLocExpr(p, call[1], rangeA) initLocExpr(p, call[2], rangeB) diff --git a/compiler/commands.nim b/compiler/commands.nim index 4ed21d282..c31476b45 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -876,7 +876,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; of "verbosity": expectArg(conf, switch, arg, pass, info) let verbosity = parseInt(arg) - if verbosity notin {0..3}: + if verbosity notin 0..3: localError(conf, info, "invalid verbosity level: '$1'" % arg) conf.verbosity = verbosity var verb = NotesVerbosity[conf.verbosity] diff --git a/compiler/lineinfos.nim b/compiler/lineinfos.nim index 532478e4b..44e9cb716 100644 --- a/compiler/lineinfos.nim +++ b/compiler/lineinfos.nim @@ -84,6 +84,7 @@ type warnPtrToCstringConv = "PtrToCstringConv", warnEffect = "Effect", warnCastSizes = "CastSizes" + warnAboveMaxSizeSet = "AboveMaxSizeSet", warnImplicitTemplateRedefinition = "ImplicitTemplateRedefinition", warnUnnamedBreak = "UnnamedBreak", warnStmtListLambda = "StmtListLambda", @@ -186,6 +187,7 @@ const warnPtrToCstringConv: "unsafe conversion to 'cstring' from '$1'; this will become a compile time error in the future", warnEffect: "$1", warnCastSizes: "$1", + warnAboveMaxSizeSet: "$1", warnImplicitTemplateRedefinition: "template '$1' is implicitly redefined; this is deprecated, add an explicit .redefine pragma", warnUnnamedBreak: "Using an unnamed break in a block is deprecated; Use a named block with a named break instead", warnStmtListLambda: "statement list expression assumed to be anonymous proc; this is deprecated, use `do (): ...` or `proc () = ...` instead", diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index fc66fc9fa..54a59c80a 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -347,7 +347,8 @@ proc genDeref*(n: PNode; k = nkHiddenDeref): PNode = proc callCodegenProc*(g: ModuleGraph; name: string; info: TLineInfo = unknownLineInfo; - arg1, arg2, arg3, optionalArgs: PNode = nil): PNode = + arg1: PNode = nil, arg2: PNode = nil, + arg3: PNode = nil, optionalArgs: PNode = nil): PNode = result = newNodeI(nkCall, info) let sym = magicsys.getCompilerProc(g, name) if sym == nil: diff --git a/compiler/nversion.nim b/compiler/nversion.nim index 2da39b138..811008989 100644 --- a/compiler/nversion.nim +++ b/compiler/nversion.nim @@ -12,6 +12,8 @@ const MaxSetElements* = 1 shl 16 # (2^16) to support unicode character sets? + DefaultSetElements* = 1 shl 8 + ## assumed set element count when using int literals VersionAsString* = system.NimVersion RodFileVersion* = "1223" # modify this if the rod-format changes! diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 848874810..e5d5498a8 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -2563,34 +2563,39 @@ proc semSetConstr(c: PContext, n: PNode, expectedType: PType = nil): PNode = # only semantic checking for all elements, later type checking: var typ: PType = nil for i in 0..<n.len: + let doSetType = typ == nil if isRange(n[i]): checkSonsLen(n[i], 3, c.config) n[i][1] = semExprWithType(c, n[i][1], {efTypeAllowed}, expectedElementType) n[i][2] = semExprWithType(c, n[i][2], {efTypeAllowed}, expectedElementType) - if typ == nil: + if doSetType: typ = skipTypes(n[i][1].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal, tyAlias, tySink}) - if expectedElementType == nil: - expectedElementType = typ n[i].typ = n[i][2].typ # range node needs type too elif n[i].kind == nkRange: # already semchecked - if typ == nil: + if doSetType: typ = skipTypes(n[i][0].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal, tyAlias, tySink}) - if expectedElementType == nil: - expectedElementType = typ else: n[i] = semExprWithType(c, n[i], {efTypeAllowed}, expectedElementType) - if typ == nil: + if doSetType: typ = skipTypes(n[i].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal, tyAlias, tySink}) - if expectedElementType == nil: - expectedElementType = typ - if not isOrdinalType(typ, allowEnumWithHoles=true): - localError(c.config, n.info, errOrdinalTypeExpected % typeToString(typ, preferDesc)) - typ = makeRangeType(c, 0, MaxSetElements-1, n.info) - elif lengthOrd(c.config, typ) > MaxSetElements: - typ = makeRangeType(c, 0, MaxSetElements-1, n.info) + if doSetType: + if not isOrdinalType(typ, allowEnumWithHoles=true): + localError(c.config, n.info, errOrdinalTypeExpected % typeToString(typ, preferDesc)) + typ = makeRangeType(c, 0, MaxSetElements-1, n.info) + elif isIntLit(typ): + # set of int literal, use a default range smaller than the max range + typ = makeRangeType(c, 0, DefaultSetElements-1, n.info) + elif lengthOrd(c.config, typ) > MaxSetElements: + message(c.config, n.info, warnAboveMaxSizeSet, "type '" & + typeToString(typ, preferDesc) & "' is too big to be a `set` element, " & + "assuming a range of 0.." & $(MaxSetElements - 1) & + ", explicitly write this range to get rid of warning") + typ = makeRangeType(c, 0, MaxSetElements-1, n.info) + if expectedElementType == nil: + expectedElementType = typ addSonSkipIntLit(result.typ, typ, c.idgen) for i in 0..<n.len: var m: PNode diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index d82748883..cd742c90a 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -1843,7 +1843,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result = semTypeExpr(c, n, prev) else: let op = considerQuotedIdent(c, n[0]) - if op.id in {ord(wAnd), ord(wOr)} or op.s == "|": + if op.id == ord(wAnd) or op.id == ord(wOr) or op.s == "|": checkSonsLen(n, 3, c.config) var t1 = semTypeNode(c, n[1], nil) diff --git a/compiler/suggest.nim b/compiler/suggest.nim index 384ceb271..8407670ba 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -213,7 +213,7 @@ proc `$`*(suggest: Suggest): string = result.add(sep) when defined(nimsuggest) and not defined(noDocgen) and not defined(leanCompiler): result.add(suggest.doc.escape) - if suggest.version in {0, 3}: + if suggest.version == 0 or suggest.version == 3: result.add(sep) result.add($suggest.quality) if suggest.section == ideSug: diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index aa4a83900..5183f2def 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -115,7 +115,8 @@ proc echoCode*(c: PCtx; start=0; last = -1) {.deprecated.} = codeListing(c, buf, start, last) echo buf -proc gABC(ctx: PCtx; n: PNode; opc: TOpcode; a, b, c: TRegister = 0) = +proc gABC(ctx: PCtx; n: PNode; opc: TOpcode; + a: TRegister = 0, b: TRegister = 0, c: TRegister = 0) = ## Takes the registers `b` and `c`, applies the operation `opc` to them, and ## stores the result into register `a` ## The node is needed for debug information diff --git a/doc/sets_fragment.txt b/doc/sets_fragment.txt index fba98db2d..6e0991a9e 100644 --- a/doc/sets_fragment.txt +++ b/doc/sets_fragment.txt @@ -5,10 +5,13 @@ only be an ordinal type of a certain size, namely: * `uint8`/`byte`-`uint16` * `char` * `enum` +* Ordinal subrange types, i.e. `range[-10..10]` -or equivalent. For signed integers the set's base type is defined to be in the -range `0 .. MaxSetElements-1` where `MaxSetElements` is currently always -2^16. +or equivalent. When constructing a set with signed integer literals, the set's +base type is defined to be in the range `0 .. DefaultSetElements-1` where +`DefaultSetElements` is currently always 2^8. The maximum range length for the +base type of a set is `MaxSetElements` which is currently always 2^16. Types +with a bigger range length are coerced into the range `0 .. MaxSetElements-1`. The reason is that sets are implemented as high performance bit vectors. Attempting to declare a set with a larger type will result in an error: diff --git a/lib/pure/httpcore.nim b/lib/pure/httpcore.nim index d639bef05..3b5cbc3cf 100644 --- a/lib/pure/httpcore.nim +++ b/lib/pure/httpcore.nim @@ -348,20 +348,20 @@ func is1xx*(code: HttpCode): bool {.inline, since: (1, 5).} = runnableExamples: doAssert is1xx(HttpCode(103)) - code.int in {100 .. 199} + code.int in 100 .. 199 func is2xx*(code: HttpCode): bool {.inline.} = ## Determines whether `code` is a 2xx HTTP status code. - code.int in {200 .. 299} + code.int in 200 .. 299 func is3xx*(code: HttpCode): bool {.inline.} = ## Determines whether `code` is a 3xx HTTP status code. - code.int in {300 .. 399} + code.int in 300 .. 399 func is4xx*(code: HttpCode): bool {.inline.} = ## Determines whether `code` is a 4xx HTTP status code. - code.int in {400 .. 499} + code.int in 400 .. 499 func is5xx*(code: HttpCode): bool {.inline.} = ## Determines whether `code` is a 5xx HTTP status code. - code.int in {500 .. 599} + code.int in 500 .. 599 diff --git a/lib/std/sysrand.nim b/lib/std/sysrand.nim index eeaa23d72..b5f61372a 100644 --- a/lib/std/sysrand.nim +++ b/lib/std/sysrand.nim @@ -194,8 +194,8 @@ elif defined(linux) and not defined(nimNoGetRandom) and not defined(emscripten): elif readBytes > 0: inc(result, readBytes) else: - if osLastError().int in {EINTR, EAGAIN}: - discard + case osLastError().int + of EINTR, EAGAIN: discard else: result = -1 break diff --git a/lib/system/setops.nim b/lib/system/setops.nim index b42c8b4a8..67aa3097a 100644 --- a/lib/system/setops.nim +++ b/lib/system/setops.nim @@ -26,9 +26,9 @@ func excl*[T](x: var set[T], y: T) {.magic: "Excl".} = ## ## This is the same as `x = x - {y}`, but it might be more efficient. runnableExamples: - var b = {2, 3, 5, 6, 12, 545} + var b = {2, 3, 5, 6, 12, 54} b.excl(5) - assert b == {2, 3, 6, 12, 545} + assert b == {2, 3, 6, 12, 54} template excl*[T](x: var set[T], y: set[T]) {.callsite.} = ## Excludes the set `y` from the set `x`. diff --git a/tests/sets/thugeset.nim b/tests/sets/thugeset.nim new file mode 100644 index 000000000..1d82ebede --- /dev/null +++ b/tests/sets/thugeset.nim @@ -0,0 +1,10 @@ +let x = 20_000 +let s = {x, 123} #[tt.Warning + ^ type 'int' is too big to be a `set` element, assuming a range of 0..65535, explicitly write this range to get rid of warning [AboveMaxSizeSet]]# +doAssert x in s +doAssert 20_000 in s +{.push warningAsError[AboveMaxSizeSet]: on.} +let s2 = {range[0..65535](x), 123} +doAssert x in s +doAssert 20_000 in s +{.pop.} |