summary refs log tree commit diff stats
diff options
context:
space:
mode:
authormetagn <metagngn@gmail.com>2022-09-14 19:30:15 +0300
committerGitHub <noreply@github.com>2022-09-14 18:30:15 +0200
commita73ae3e066caecb7a891de87cf7c004805f96ff0 (patch)
tree2cc5172af6584e6546c9f314abfbd908806ac266
parent2140d05f34f7976ed7f7058baa952490ee3fb859 (diff)
downloadNim-a73ae3e066caecb7a891de87cf7c004805f96ff0.tar.gz
minor improvements to follow up recent PRs (#20342)
put mOpenArrayToSeq in compile-time evaluation whitelist
(it was mNone before which was whitelisted), homogenize
"ordinal type expected" errors, put overloadable enums
in non-experimental manual
-rw-r--r--compiler/ast.nim2
-rw-r--r--compiler/semexprs.nim2
-rw-r--r--compiler/semmagic.nim2
-rw-r--r--compiler/semtypes.nim16
-rw-r--r--doc/manual.md32
-rw-r--r--doc/manual_experimental.md38
-rw-r--r--tests/errmsgs/t9908_01.nim2
-rw-r--r--tests/errmsgs/t9908_02.nim2
8 files changed, 45 insertions, 51 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index d569fee7b..d6e812f39 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -738,7 +738,7 @@ const
     mEqStr, mLeStr, mLtStr,
     mEqSet, mLeSet, mLtSet, mMulSet, mPlusSet, mMinusSet,
     mConStrStr, mAppendStrCh, mAppendStrStr, mAppendSeqElem,
-    mInSet, mRepr}
+    mInSet, mRepr, mOpenArrayToSeq}
   
   generatedMagics* = {mNone, mIsolate, mFinished, mOpenArrayToSeq}
     ## magics that are generated as normal procs in the backend
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 29a5c787b..39ee6134c 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -2504,7 +2504,7 @@ proc semSetConstr(c: PContext, n: PNode, expectedType: PType = nil): PNode =
           if expectedElementType == nil:
             expectedElementType = typ
     if not isOrdinalType(typ, allowEnumWithHoles=true):
-      localError(c.config, n.info, errOrdinalTypeExpected)
+      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)
diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim
index d3e12670b..f7edc5592 100644
--- a/compiler/semmagic.nim
+++ b/compiler/semmagic.nim
@@ -212,7 +212,7 @@ proc semOrd(c: PContext, n: PNode): PNode =
   if isOrdinalType(parType, allowEnumWithHoles=true):
     discard
   else:
-    localError(c.config, n.info, errOrdinalTypeExpected)
+    localError(c.config, n.info, errOrdinalTypeExpected % typeToString(parType, preferDesc))
     result.typ = errorType(c)
 
 proc semBindSym(c: PContext, n: PNode): PNode =
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index eefcd3069..7d077ab5a 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -16,7 +16,7 @@ const
   errIntLiteralExpected = "integer literal expected"
   errWrongNumberOfVariables = "wrong number of variables"
   errInvalidOrderInEnumX = "invalid order in enum '$1'"
-  errOrdinalTypeExpected = "ordinal type expected"
+  errOrdinalTypeExpected = "ordinal type expected; given: $1"
   errSetTooBig = "set is too large; use `std/sets` for ordinal types with more than 2^16 elements"
   errBaseTypeMustBeOrdinal = "base type of a set must be an ordinal"
   errInheritanceOnlyWithNonFinalObjects = "inheritance only works with non-final objects"
@@ -95,7 +95,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
           strVal = v[1] # second tuple part is the string value
           if skipTypes(strVal.typ, abstractInst).kind in {tyString, tyCstring}:
             if not isOrdinalType(v[0].typ, allowEnumWithHoles=true):
-              localError(c.config, v[0].info, errOrdinalTypeExpected & "; given: " & typeToString(v[0].typ, preferDesc))
+              localError(c.config, v[0].info, errOrdinalTypeExpected % typeToString(v[0].typ, preferDesc))
             x = toInt64(getOrdValue(v[0])) # first tuple part is the ordinal
             n[i][1][0] = newIntTypeNode(x, getSysType(c.graph, unknownLineInfo, tyInt))
           else:
@@ -107,7 +107,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
         x = counter
       else:
         if not isOrdinalType(v.typ, allowEnumWithHoles=true):
-          localError(c.config, v.info, errOrdinalTypeExpected & "; given: " & typeToString(v.typ, preferDesc))
+          localError(c.config, v.info, errOrdinalTypeExpected % typeToString(v.typ, preferDesc))
         x = toInt64(getOrdValue(v))
         n[i][1] = newIntTypeNode(x, getSysType(c.graph, unknownLineInfo, tyInt))
       if i != 1:
@@ -163,7 +163,7 @@ proc semSet(c: PContext, n: PNode, prev: PType): PType =
     if base.kind in {tyGenericInst, tyAlias, tySink}: base = lastSon(base)
     if base.kind notin {tyGenericParam, tyGenericInvocation}:
       if not isOrdinalType(base, allowEnumWithHoles = true):
-        localError(c.config, n.info, errOrdinalTypeExpected)
+        localError(c.config, n.info, errOrdinalTypeExpected % typeToString(base, preferDesc))
       elif lengthOrd(c.config, base) > MaxSetElements:
         localError(c.config, n.info, errSetTooBig)
   else:
@@ -331,12 +331,12 @@ proc semArrayIndex(c: PContext, n: PNode): PType =
         return semArrayIndex(c, e.sym.ast)
       if not isOrdinalType(e.typ.lastSon):
         let info = if n.safeLen > 1: n[1].info else: n.info
-        localError(c.config, info, errOrdinalTypeExpected)
+        localError(c.config, info, errOrdinalTypeExpected % typeToString(e.typ, preferDesc))
       result = makeRangeWithStaticExpr(c, e)
       if c.inGenericContext > 0: result.flags.incl tfUnresolved
     elif e.kind in (nkCallKinds + {nkBracketExpr}) and hasUnresolvedArgs(c, e):
       if not isOrdinalType(e.typ.skipTypes({tyStatic, tyAlias, tyGenericInst, tySink})):
-        localError(c.config, n[1].info, errOrdinalTypeExpected)
+        localError(c.config, n[1].info, errOrdinalTypeExpected % typeToString(e.typ, preferDesc))
       # This is an int returning call, depending on an
       # yet unknown generic param (see tgenericshardcases).
       # We are going to construct a range type that will be
@@ -365,7 +365,7 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType =
       if indxB.skipTypes({tyRange}).kind in {tyUInt, tyUInt64}:
         discard
       elif not isOrdinalType(indxB):
-        localError(c.config, n[1].info, errOrdinalTypeExpected)
+        localError(c.config, n[1].info, errOrdinalTypeExpected % typeToString(indxB, preferDesc))
       elif enumHasHoles(indxB):
         localError(c.config, n[1].info, "enum '$1' has holes" %
                    typeToString(indxB.skipTypes({tyRange})))
@@ -395,7 +395,7 @@ proc semOrdinal(c: PContext, n: PNode, prev: PType): PType =
     var base = semTypeNode(c, n[1], nil)
     if base.kind != tyGenericParam:
       if not isOrdinalType(base):
-        localError(c.config, n[1].info, errOrdinalTypeExpected)
+        localError(c.config, n[1].info, errOrdinalTypeExpected % typeToString(base, preferDesc))
     addSonSkipIntLit(result, base, c.idgen)
   else:
     localError(c.config, n.info, errXExpectsOneTypeParam % "ordinal")
diff --git a/doc/manual.md b/doc/manual.md
index 06930780e..6d92a6dca 100644
--- a/doc/manual.md
+++ b/doc/manual.md
@@ -1313,6 +1313,38 @@ as `MyEnum.value`:
   echo MyEnum.amb # OK.
   ```
 
+Enum value names are overloadable, much like routines. If both of the enums
+`T` and `U` have a member named `foo`, then the identifier `foo` corresponds
+to a choice between `T.foo` and `U.foo`. During overload resolution,
+the correct type of `foo` is decided from the context. If the type of `foo` is
+ambiguous, a static error will be produced.
+
+  ```nim  test = "nim c $1"
+
+  type
+    E1 = enum
+      value1,
+      value2
+    E2 = enum
+      value1,
+      value2 = 4
+
+  const
+    Lookuptable = [
+      E1.value1: "1",
+      # no need to qualify value2, known to be E1.value2
+      value2: "2"
+    ]
+
+  proc p(e: E1) =
+    # disambiguation in 'case' statements:
+    case e
+    of value1: echo "A"
+    of value2: echo "B"
+
+  p value2
+  ```
+
 To implement bit fields with enums see [Bit fields].
 
 
diff --git a/doc/manual_experimental.md b/doc/manual_experimental.md
index ede2ba02b..9dd44ab3b 100644
--- a/doc/manual_experimental.md
+++ b/doc/manual_experimental.md
@@ -86,44 +86,6 @@ No Unicode normalization step is performed.
   pragma `{.experimental: "unicodeOperators".}` reliably.
 
 
-Overloadable enum value names
-=============================
-
-Enum value names are overloadable, much like routines. If both of the enums
-`T` and `U` have a member named `foo`, then the identifier `foo` corresponds
-to a choice between `T.foo` and `U.foo`. During overload resolution,
-the correct type of `foo` is decided from the context. If the type of `foo` is
-ambiguous, a static error will be produced.
-
-  ```nim  test = "nim c $1"
-
-  type
-    E1 = enum
-      value1,
-      value2
-    E2 = enum
-      value1,
-      value2 = 4
-
-  const
-    Lookuptable = [
-      E1.value1: "1",
-      # no need to qualify value2, known to be E1.value2
-      value2: "2"
-    ]
-
-  proc p(e: E1) =
-    # disambiguation in 'case' statements:
-    case e
-    of value1: echo "A"
-    of value2: echo "B"
-
-  p value2
-  ```
-
-Previously required `{.experimental: "overloadableEnums".}` to enable,
-now always enabled.
-
 Top-down type inference
 =======================
 
diff --git a/tests/errmsgs/t9908_01.nim b/tests/errmsgs/t9908_01.nim
index b9d37b67b..99bc8237d 100644
--- a/tests/errmsgs/t9908_01.nim
+++ b/tests/errmsgs/t9908_01.nim
@@ -1,5 +1,5 @@
 discard """
-errormsg: "ordinal type expected"
+errormsg: "ordinal type expected; given: string"
 line: 10
 """
 
diff --git a/tests/errmsgs/t9908_02.nim b/tests/errmsgs/t9908_02.nim
index 7ff3d1ff7..4fc60b3df 100644
--- a/tests/errmsgs/t9908_02.nim
+++ b/tests/errmsgs/t9908_02.nim
@@ -1,5 +1,5 @@
 discard """
-errormsg: "ordinal type expected"
+errormsg: "ordinal type expected; given: float"
 line: 10
 """