summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/semexprs.nim1
-rw-r--r--compiler/semtypes.nim9
-rw-r--r--compiler/semtypinst.nim5
-rw-r--r--compiler/sigmatch.nim20
4 files changed, 21 insertions, 14 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 238ae0194..a9258fb62 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -857,6 +857,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
     else:
       result = m.call
       instGenericConvertersSons(c, result, m)
+
   elif t != nil and t.kind == tyTypeDesc:
     if n.len == 1: return semObjConstr(c, n, flags)
     return semConv(c, n)
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index f0f22e87c..a0144500e 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -863,7 +863,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
 
   of tyStatic:
     if paramType.base.kind != tyNone and paramType.n != nil:
-      # this is a concrete type
+      # this is a concrete static value
       return
     if tfUnresolved in paramType.flags: return # already lifted
     let base = paramType.base.maybeLift
@@ -1048,7 +1048,12 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
       if typ == nil:
         typ = def.typ
         if typ.kind == tyTypeDesc:
-          # default typedesc values are mapped to the unbound typedesc type:
+          # consider a proc such as:
+          # proc takesType(T = int)
+          # a naive analysis may conclude that the proc type is type[int]
+          # which will prevent other types from matching - clearly a very
+          # surprising behavior. We must instead fix the expected type of
+          # the proc to be the unbound typedesc type:
           typ = newTypeWithSons(c, tyTypeDesc, @[newTypeS(tyNone, c)])
 
       else:
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim
index f02c45e46..22ea09af1 100644
--- a/compiler/semtypinst.nim
+++ b/compiler/semtypinst.nim
@@ -223,8 +223,9 @@ proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym =
 
   # XXX: Bound symbols in default parameter expressions may reach here.
   # We cannot process them, becase `sym.n` may point to a proc body with
-  # cyclic references that will lead to an infinite recursion. Perhaps we
-  # should not use a black-list here, but a whitelist instead.
+  # cyclic references that will lead to an infinite recursion.
+  # Perhaps we should not use a black-list here, but a whitelist instead
+  # (e.g. skGenericParam and skType).
   # Note: `s.magic` may be `mType` in an example such as:
   # proc foo[T](a: T, b = myDefault(type(a)))
   if s.kind == skProc or s.magic != mNone:
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 0bb7c4fdd..784b5c11c 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -1089,13 +1089,8 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
              else: isNone
 
   of tyAnything:
-    if f.kind in {tyAnything}:
-      return isGeneric
-
-    if tfWildCard in a.flags and f.kind == tyTypeDesc:
-      return isGeneric
-
-    return isNone
+    if f.kind == tyAnything: return isGeneric
+    else: return isNone
 
   of tyUserTypeClass, tyUserTypeClassInst:
     if c.c.matchedConcept != nil and c.c.matchedConcept.depth <= 4:
@@ -2366,6 +2361,14 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
           m.firstMismatch = f
           break
       else:
+        if formal.ast.kind == nkEmpty:
+          # The default param value is set to empty in `instantiateProcType`
+          # when the type of the default expression doesn't match the type
+          # of the instantiated proc param:
+          localError(c.config, m.call.info,
+                     ("The default parameter '$1' has incompatible type " &
+                      "with the explicitly requested proc instantiation") %
+                      formal.name.s)
         if nfDefaultRefsParam in formal.ast.flags:
           m.call.flags.incl nfDefaultRefsParam
         var def = copyTree(formal.ast)
@@ -2375,9 +2378,6 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
           put(m, formal.typ, def.typ)
         def.flags.incl nfDefaultParam
         setSon(m.call, formal.position + 1, def)
-        # XXX: Instead of setting a default value here, we may place a special
-        # marker value instead. Later, we will replace it in `semResolvedCall`.
-        # Unfortunately, this causes some breakage at the moment.
     inc(f)
   # forget all inferred types if the overload matching failed
   if m.state == csNoMatch: