summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--changelogs/changelog_2_0_0.md3
-rw-r--r--compiler/ccgstmts.nim2
-rw-r--r--compiler/commands.nim2
-rw-r--r--compiler/lineinfos.nim2
-rw-r--r--compiler/lowerings.nim3
-rw-r--r--compiler/nversion.nim2
-rw-r--r--compiler/semexprs.nim33
-rw-r--r--compiler/semtypes.nim2
-rw-r--r--compiler/suggest.nim2
-rw-r--r--compiler/vmgen.nim3
-rw-r--r--doc/sets_fragment.txt9
-rw-r--r--lib/pure/httpcore.nim10
-rw-r--r--lib/std/sysrand.nim4
-rw-r--r--lib/system/setops.nim4
-rw-r--r--tests/sets/thugeset.nim10
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.}