Skip to content

Commit

Permalink
minor improvements to follow up recent PRs (nim-lang#20342)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
metagn authored Sep 14, 2022
1 parent 2140d05 commit a73ae3e
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 51 deletions.
2 changes: 1 addition & 1 deletion compiler/ast.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion compiler/semexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion compiler/semmagic.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
16 changes: 8 additions & 8 deletions compiler/semtypes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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})))
Expand Down Expand Up @@ -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")
Expand Down
32 changes: 32 additions & 0 deletions doc/manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -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].


Expand Down
38 changes: 0 additions & 38 deletions doc/manual_experimental.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
=======================

Expand Down
2 changes: 1 addition & 1 deletion tests/errmsgs/t9908_01.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
discard """
errormsg: "ordinal type expected"
errormsg: "ordinal type expected; given: string"
line: 10
"""

Expand Down
2 changes: 1 addition & 1 deletion tests/errmsgs/t9908_02.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
discard """
errormsg: "ordinal type expected"
errormsg: "ordinal type expected; given: float"
line: 10
"""

Expand Down

0 comments on commit a73ae3e

Please sign in to comment.