summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authormetagn <metagngn@gmail.com>2024-08-29 17:13:06 +0300
committerGitHub <noreply@github.com>2024-08-29 16:13:06 +0200
commitb7b1313d21deb687adab2b4a162e716ba561a26b (patch)
treeb04d1718fa65cc6d03f1385cf9a2ec672cfccf6d /compiler
parentd7e77b330f3f84a9cebcca057c0697687ebe8ec3 (diff)
downloadNim-b7b1313d21deb687adab2b4a162e716ba561a26b.tar.gz
proper error message for out-of-range enum sets (#24027)
fixes #17848
Diffstat (limited to 'compiler')
-rw-r--r--compiler/semexprs.nim19
-rw-r--r--compiler/types.nim7
2 files changed, 23 insertions, 3 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 0c3691362..91e318a63 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -648,7 +648,14 @@ proc overloadedCallOpr(c: PContext, n: PNode): PNode =
 
 proc changeType(c: PContext; n: PNode, newType: PType, check: bool) =
   case n.kind
-  of nkCurly, nkBracket:
+  of nkCurly:
+    for i in 0..<n.len:
+      if n[i].kind == nkRange:
+        changeType(c, n[i][0], elemType(newType), check)
+        changeType(c, n[i][1], elemType(newType), check)
+      else:
+        changeType(c, n[i], elemType(newType), check)
+  of nkBracket:
     for i in 0..<n.len:
       changeType(c, n[i], elemType(newType), check)
   of nkPar, nkTupleConstr:
@@ -685,10 +692,16 @@ proc changeType(c: PContext; n: PNode, newType: PType, check: bool) =
       let value = n.intVal
       if value < firstOrd(c.config, newType) or value > lastOrd(c.config, newType):
         localError(c.config, n.info, "cannot convert " & $value &
-                                         " to " & typeToString(newType))
+                                         " to " & typeNameAndDesc(newType))
   of nkFloatLit..nkFloat64Lit:
     if check and not floatRangeCheck(n.floatVal, newType):
-      localError(c.config, n.info, errFloatToString % [$n.floatVal, typeToString(newType)])
+      localError(c.config, n.info, errFloatToString % [$n.floatVal, typeNameAndDesc(newType)])
+  of nkSym:
+    if check and n.sym.kind == skEnumField and not sameTypeOrNil(n.sym.typ, newType):
+      let value = n.sym.position
+      if value < firstOrd(c.config, newType) or value > lastOrd(c.config, newType):
+        localError(c.config, n.info, "cannot convert '" & n.sym.name.s &
+                                         "' to '" & typeNameAndDesc(newType) & "'")
   else: discard
   n.typ = newType
 
diff --git a/compiler/types.nim b/compiler/types.nim
index 93da2cc9b..1c434fbfa 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -1739,6 +1739,13 @@ proc processPragmaAndCallConvMismatch(msg: var string, formal, actual: PType, co
     of efTagsIllegal:
       msg.add "\n.notTag catched an illegal effect"
 
+proc typeNameAndDesc*(t: PType): string =
+  result = typeToString(t)
+  let desc = typeToString(t, preferDesc)
+  if result != desc:
+    result.add(" = ")
+    result.add(desc)
+
 proc typeMismatch*(conf: ConfigRef; info: TLineInfo, formal, actual: PType, n: PNode) =
   if formal.kind != tyError and actual.kind != tyError:
     let actualStr = typeToString(actual)