summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authormetagn <metagngn@gmail.com>2023-03-30 16:34:42 +0300
committerGitHub <noreply@github.com>2023-03-30 15:34:42 +0200
commitecf9efa3977f95aed5229ab79cd6ac4799a32a4c (patch)
tree4416d5c0109d308f861afc6d43fb28a168bcc18f /compiler
parent51ced0d68477e4d2ae5fa8183579922ec47cd318 (diff)
downloadNim-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.nim27
-rw-r--r--compiler/semtypes.nim13
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)