diff options
author | metagn <metagngn@gmail.com> | 2022-09-14 19:30:15 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-14 18:30:15 +0200 |
commit | a73ae3e066caecb7a891de87cf7c004805f96ff0 (patch) | |
tree | 2cc5172af6584e6546c9f314abfbd908806ac266 | |
parent | 2140d05f34f7976ed7f7058baa952490ee3fb859 (diff) | |
download | Nim-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.nim | 2 | ||||
-rw-r--r-- | compiler/semexprs.nim | 2 | ||||
-rw-r--r-- | compiler/semmagic.nim | 2 | ||||
-rw-r--r-- | compiler/semtypes.nim | 16 | ||||
-rw-r--r-- | doc/manual.md | 32 | ||||
-rw-r--r-- | doc/manual_experimental.md | 38 | ||||
-rw-r--r-- | tests/errmsgs/t9908_01.nim | 2 | ||||
-rw-r--r-- | tests/errmsgs/t9908_02.nim | 2 |
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 """ |