diff options
author | metagn <metagngn@gmail.com> | 2023-03-30 16:34:42 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-30 15:34:42 +0200 |
commit | ecf9efa3977f95aed5229ab79cd6ac4799a32a4c (patch) | |
tree | 4416d5c0109d308f861afc6d43fb28a168bcc18f /compiler | |
parent | 51ced0d68477e4d2ae5fa8183579922ec47cd318 (diff) | |
download | Nim-ecf9efa3977f95aed5229ab79cd6ac4799a32a4c.tar.gz |
document general use of `_`, error message, fixes (#21584)
* document general use of `_`, error message, fixes fixes #20687, fixes #21435 Documentation and changelog updated to clarify new universal behavior of `_`. Also new error message for attempting to use `_`, new tests, and fixes with overloadable symbols and implicit generics. * add test for #21435
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/lookups.nim | 27 | ||||
-rw-r--r-- | compiler/semtypes.nim | 13 |
2 files changed, 24 insertions, 16 deletions
diff --git a/compiler/lookups.nim b/compiler/lookups.nim index 3f028a52f..fc84b9051 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -396,11 +396,12 @@ proc addOverloadableSymAt*(c: PContext; scope: PScope, fn: PSym) = if fn.kind notin OverloadableSyms: internalError(c.config, fn.info, "addOverloadableSymAt") return - let check = strTableGet(scope.symbols, fn.name) - if check != nil and check.kind notin OverloadableSyms: - wrongRedefinition(c, fn.info, fn.name.s, check.info) - else: - scope.addSym(fn) + if fn.name.s != "_": + let check = strTableGet(scope.symbols, fn.name) + if check != nil and check.kind notin OverloadableSyms: + wrongRedefinition(c, fn.info, fn.name.s, check.info) + else: + scope.addSym(fn) proc addInterfaceOverloadableSymAt*(c: PContext, scope: PScope, sym: PSym) = ## adds an overloadable symbol on the scope and the interface if appropriate @@ -546,12 +547,16 @@ proc errorUseQualifier*(c: PContext; info:TLineInfo; choices: PNode) = errorUseQualifier(c, info, candidates, prefix) proc errorUndeclaredIdentifier*(c: PContext; info: TLineInfo; name: string, extra = "") = - var err = "undeclared identifier: '" & name & "'" & extra - if c.recursiveDep.len > 0: - err.add "\nThis might be caused by a recursive module dependency:\n" - err.add c.recursiveDep - # prevent excessive errors for 'nim check' - c.recursiveDep = "" + var err: string + if name == "_": + err = "the special identifier '_' is ignored in declarations and cannot be used" + else: + err = "undeclared identifier: '" & name & "'" & extra + if c.recursiveDep.len > 0: + err.add "\nThis might be caused by a recursive module dependency:\n" + err.add c.recursiveDep + # prevent excessive errors for 'nim check' + c.recursiveDep = "" localError(c.config, info, errGenerated, err) proc errorUndeclaredIdentifierHint*(c: PContext; n: PNode, ident: PIdent): PSym = diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 2f485d65b..fbba4f36f 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -1359,6 +1359,10 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, for j in 0..<a.len-2: var arg = newSymG(skParam, if a[j].kind == nkPragmaExpr: a[j][0] else: a[j], c) + if arg.name.s == "_": + arg.flags.incl(sfGenSym) + elif containsOrIncl(check, arg.name.id): + localError(c.config, a[j].info, "attempt to redefine: '" & arg.name.s & "'") if a[j].kind == nkPragmaExpr: pragma(c, arg, a[j][1], paramPragmas) if not hasType and not hasDefault and kind notin {skTemplate, skMacro}: @@ -1367,8 +1371,11 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, else: localError(c.config, a.info, "parameter '$1' requires a type" % arg.name.s) typ = errorType(c) + var nameForLift = arg.name.s + if sfGenSym in arg.flags: + nameForLift.add("`gensym" & $arg.id) let lifted = liftParamType(c, kind, genericParams, typ, - arg.name.s, arg.info) + nameForLift, arg.info) let finalType = if lifted != nil: lifted else: typ.skipIntLit(c.idgen) arg.typ = finalType arg.position = counter @@ -1376,10 +1383,6 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, inc(counter) if def != nil and def.kind != nkEmpty: arg.ast = copyTree(def) - if arg.name.s == "_": - arg.flags.incl(sfGenSym) - elif containsOrIncl(check, arg.name.id): - localError(c.config, a[j].info, "attempt to redefine: '" & arg.name.s & "'") result.n.add newSymNode(arg) rawAddSon(result, finalType) addParamOrResult(c, arg, kind) |