summary refs log tree commit diff stats
diff options
context:
space:
mode:
authormetagn <metagngn@gmail.com>2023-06-05 11:53:40 +0300
committerGitHub <noreply@github.com>2023-06-05 10:53:40 +0200
commit0a212f97a5dd4d5dd1ea84f370bd27abe55a818e (patch)
treecc44556eb8f56b15e2b3d06b17aba9a4b6890bb8
parentc7c3362cc818a660806d7247da51cd45d9660258 (diff)
downloadNim-0a212f97a5dd4d5dd1ea84f370bd27abe55a818e.tar.gz
properly disallow unresolved generic proc values (#22005)
* properly disallow unresolved generic proc values

* mirrors semoperand

* shallow efTypeAllowed, add back special case
-rw-r--r--compiler/semexprs.nim14
-rw-r--r--compiler/semstmts.nim1
-rw-r--r--tests/errmsgs/tunresolvedinnerproc.nim (renamed from tests/misc/tnoinst.nim)10
3 files changed, 15 insertions, 10 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 44a73cf10..6b4e27394 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -116,7 +116,7 @@ proc ambiguousSymChoice(c: PContext, orig, n: PNode): PNode =
     result = n
 
 proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}, expectedType: PType = nil): PNode =
-  result = semExprCheck(c, n, flags, expectedType)
+  result = semExprCheck(c, n, flags-{efTypeAllowed}, expectedType)
   if result.typ == nil and efInTypeof in flags:
     result.typ = c.voidType
   elif (result.typ == nil or result.typ.kind == tyNone) and
@@ -130,6 +130,18 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}, expectedType
   elif result.typ.kind == tyError:
     # associates the type error to the current owner
     result.typ = errorType(c)
+  elif efTypeAllowed in flags and result.typ.kind == tyProc and
+      hasUnresolvedParams(result, {}):
+    # mirrored with semOperand but only on efTypeAllowed
+    let owner = result.typ.owner
+    let err =
+      # consistent error message with evaltempl/semMacroExpr
+      if owner != nil and owner.kind in {skTemplate, skMacro}:
+        errMissingGenericParamsForTemplate % n.renderTree
+      else:
+        errProcHasNoConcreteType % n.renderTree
+    localError(c.config, n.info, err)
+    result.typ = errorType(c)
   else:
     if result.typ.kind in {tyVar, tyLent}: result = newDeref(result)
 
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 6cf9c6f7a..647d5d108 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -681,7 +681,6 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
         if hasEmpty(typ):
           localError(c.config, def.info, errCannotInferTypeOfTheLiteral % typ.kind.toHumanStr)
         elif typ.kind == tyProc and def.kind == nkSym and isGenericRoutine(def.sym.ast):
-          # tfUnresolved in typ.flags:
           let owner = typ.owner
           let err =
             # consistent error message with evaltempl/semMacroExpr
diff --git a/tests/misc/tnoinst.nim b/tests/errmsgs/tunresolvedinnerproc.nim
index 85db1e8e7..7655a5a41 100644
--- a/tests/misc/tnoinst.nim
+++ b/tests/errmsgs/tunresolvedinnerproc.nim
@@ -1,16 +1,10 @@
-discard """
-  errormsg: "instantiate 'notConcrete' explicitly"
-  line: 12
-  disabled: "true"
-"""
-
 proc wrap[T]() =
   proc notConcrete[T](x, y: int): int =
     var dummy: T
     result = x - y
 
   var x: proc (x, y: T): int
-  x = notConcrete
-
+  x = notConcrete #[tt.Error
+      ^ 'notConcrete' doesn't have a concrete type, due to unspecified generic parameters.]#
 
 wrap[int]()