diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/semexprs.nim | 1 | ||||
-rw-r--r-- | compiler/semtypes.nim | 9 | ||||
-rw-r--r-- | compiler/semtypinst.nim | 5 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 20 |
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: |