diff options
-rw-r--r-- | compiler/importer.nim | 12 | ||||
-rw-r--r-- | compiler/lookups.nim | 4 | ||||
-rw-r--r-- | compiler/semdata.nim | 4 | ||||
-rw-r--r-- | compiler/semexprs.nim | 6 | ||||
-rw-r--r-- | compiler/semgnrc.nim | 4 | ||||
-rw-r--r-- | compiler/semtypes.nim | 4 |
6 files changed, 27 insertions, 7 deletions
diff --git a/compiler/importer.nim b/compiler/importer.nim index c4861df7f..dfc9e84ba 100644 --- a/compiler/importer.nim +++ b/compiler/importer.nim @@ -60,6 +60,11 @@ proc checkModuleName*(n: PNode; doLocalError=true): int32 = else: result = fullPath.fileInfoIdx +proc importPureEnumField*(c: PContext; s: PSym) = + var check = strTableGet(c.importTable.symbols, s.name) + if check == nil: + strTableAdd(c.pureEnumFields, s) + proc rawImportSymbol(c: PContext, s: PSym) = # This does not handle stubs, because otherwise loading on demand would be # pointless in practice. So importing stubs is fine here! @@ -75,7 +80,7 @@ proc rawImportSymbol(c: PContext, s: PSym) = strTableAdd(c.importTable.symbols, s) if s.kind == skType: var etyp = s.typ - if etyp.kind in {tyBool, tyEnum} and sfPure notin s.flags: + if etyp.kind in {tyBool, tyEnum}: for j in countup(0, sonsLen(etyp.n) - 1): var e = etyp.n.sons[j].sym if e.kind != skEnumField: @@ -91,7 +96,10 @@ proc rawImportSymbol(c: PContext, s: PSym) = break check = nextIdentIter(it, c.importTable.symbols) if e != nil: - rawImportSymbol(c, e) + if sfPure notin s.flags: + rawImportSymbol(c, e) + else: + importPureEnumField(c, e) else: # rodgen assures that converters and patterns are no stubs if s.kind == skConverter: addConverter(c, s) diff --git a/compiler/lookups.nim b/compiler/lookups.nim index 5c326d10a..5a5dfc46a 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -286,7 +286,7 @@ proc lookUp*(c: PContext, n: PNode): PSym = type TLookupFlag* = enum - checkAmbiguity, checkUndeclared, checkModule + checkAmbiguity, checkUndeclared, checkModule, checkPureEnumFields proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym = const allExceptModule = {low(TSymKind)..high(TSymKind)}-{skModule,skPackage} @@ -297,6 +297,8 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym = result = searchInScopes(c, ident).skipAlias(n) else: result = searchInScopes(c, ident, allExceptModule).skipAlias(n) + if result == nil and checkPureEnumFields in flags: + result = strTableGet(c.pureEnumFields, ident) if result == nil and checkUndeclared in flags: fixSpelling(n, ident, searchInScopes) errorUndeclaredIdentifier(c, n.info, ident.s) diff --git a/compiler/semdata.nim b/compiler/semdata.nim index d422646a8..97212d2cd 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -65,7 +65,7 @@ type efWantStmt, efAllowStmt, efDetermineType, efExplain, efAllowDestructor, efWantValue, efOperand, efNoSemCheck, efNoProcvarCheck, efNoEvaluateGeneric, efInCall, efFromHlo, - + TExprFlags* = set[TExprFlag] TTypeAttachedOp* = enum @@ -112,6 +112,7 @@ type semGenerateInstance*: proc (c: PContext, fn: PSym, pt: TIdTable, info: TLineInfo): PSym includedFiles*: IntSet # used to detect recursive include files + pureEnumFields*: TStrTable # pure enum fields that can be used unambiguously userPragmas*: TStrTable evalContext*: PEvalContext unknownIdents*: IntSet # ids of all unknown identifiers to prevent @@ -210,6 +211,7 @@ proc newContext*(graph: ModuleGraph; module: PSym; cache: IdentCache): PContext result.converters = @[] result.patterns = @[] result.includedFiles = initIntSet() + initStrTable(result.pureEnumFields) initStrTable(result.userPragmas) result.generics = @[] result.unknownIdents = initIntSet() diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 65557658a..9930e127e 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -2115,8 +2115,10 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = if nfSem in n.flags: return case n.kind of nkIdent, nkAccQuoted: - let checks = if efNoEvaluateGeneric in flags: {checkUndeclared} - else: {checkUndeclared, checkModule, checkAmbiguity} + let checks = if efNoEvaluateGeneric in flags: + {checkUndeclared, checkPureEnumFields} + else: + {checkUndeclared, checkModule, checkAmbiguity, checkPureEnumFields} var s = qualifiedLookUp(c, n, checks) if c.matchedConcept == nil: semCaptureSym(s, c.p.owner) result = semSym(c, n, s, flags) diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 7e55b266a..e3d078432 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -106,6 +106,10 @@ proc lookup(c: PContext, n: PNode, flags: TSemGenericFlags, let ident = considerQuotedIdent(n) var s = searchInScopes(c, ident).skipAlias(n) if s == nil: + s = strTableGet(c.pureEnumFields, ident) + if s != nil and contains(c.ambiguousSymbols, s.id): + s = nil + if s == nil: if ident.id notin ctx.toMixin and withinMixin notin flags: errorUndeclaredIdentifier(c, n.info, ident.s) else: diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index a7c9244cc..14a6d9ed5 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -88,7 +88,9 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = if not isPure: strTableAdd(c.module.tab, e) addSon(result.n, newSymNode(e)) styleCheckDef(e) - if sfGenSym notin e.flags and not isPure: addDecl(c, e) + if sfGenSym notin e.flags: + if not isPure: addDecl(c, e) + else: importPureEnumField(c, e) if isPure and strTableIncl(symbols, e): wrongRedefinition(e.info, e.name.s) inc(counter) |