requested pull-request changes
This commit is contained in:
parent
31651ecd61
commit
e129466910
5 changed files with 25 additions and 18 deletions
|
|
@ -857,6 +857,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
else:
|
else:
|
||||||
result = m.call
|
result = m.call
|
||||||
instGenericConvertersSons(c, result, m)
|
instGenericConvertersSons(c, result, m)
|
||||||
|
|
||||||
elif t != nil and t.kind == tyTypeDesc:
|
elif t != nil and t.kind == tyTypeDesc:
|
||||||
if n.len == 1: return semObjConstr(c, n, flags)
|
if n.len == 1: return semObjConstr(c, n, flags)
|
||||||
return semConv(c, n)
|
return semConv(c, n)
|
||||||
|
|
|
||||||
|
|
@ -863,7 +863,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
|
|
||||||
of tyStatic:
|
of tyStatic:
|
||||||
if paramType.base.kind != tyNone and paramType.n != nil:
|
if paramType.base.kind != tyNone and paramType.n != nil:
|
||||||
# this is a concrete type
|
# this is a concrete static value
|
||||||
return
|
return
|
||||||
if tfUnresolved in paramType.flags: return # already lifted
|
if tfUnresolved in paramType.flags: return # already lifted
|
||||||
let base = paramType.base.maybeLift
|
let base = paramType.base.maybeLift
|
||||||
|
|
@ -1048,7 +1048,12 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
|
||||||
if typ == nil:
|
if typ == nil:
|
||||||
typ = def.typ
|
typ = def.typ
|
||||||
if typ.kind == tyTypeDesc:
|
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)])
|
typ = newTypeWithSons(c, tyTypeDesc, @[newTypeS(tyNone, c)])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -223,8 +223,9 @@ proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym =
|
||||||
|
|
||||||
# XXX: Bound symbols in default parameter expressions may reach here.
|
# XXX: Bound symbols in default parameter expressions may reach here.
|
||||||
# We cannot process them, becase `sym.n` may point to a proc body with
|
# 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
|
# cyclic references that will lead to an infinite recursion.
|
||||||
# should not use a black-list here, but a whitelist instead.
|
# 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:
|
# Note: `s.magic` may be `mType` in an example such as:
|
||||||
# proc foo[T](a: T, b = myDefault(type(a)))
|
# proc foo[T](a: T, b = myDefault(type(a)))
|
||||||
if s.kind == skProc or s.magic != mNone:
|
if s.kind == skProc or s.magic != mNone:
|
||||||
|
|
|
||||||
|
|
@ -1089,13 +1089,8 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
|
||||||
else: isNone
|
else: isNone
|
||||||
|
|
||||||
of tyAnything:
|
of tyAnything:
|
||||||
if f.kind in {tyAnything}:
|
if f.kind == tyAnything: return isGeneric
|
||||||
return isGeneric
|
else: return isNone
|
||||||
|
|
||||||
if tfWildCard in a.flags and f.kind == tyTypeDesc:
|
|
||||||
return isGeneric
|
|
||||||
|
|
||||||
return isNone
|
|
||||||
|
|
||||||
of tyUserTypeClass, tyUserTypeClassInst:
|
of tyUserTypeClass, tyUserTypeClassInst:
|
||||||
if c.c.matchedConcept != nil and c.c.matchedConcept.depth <= 4:
|
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
|
m.firstMismatch = f
|
||||||
break
|
break
|
||||||
else:
|
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:
|
if nfDefaultRefsParam in formal.ast.flags:
|
||||||
m.call.flags.incl nfDefaultRefsParam
|
m.call.flags.incl nfDefaultRefsParam
|
||||||
var def = copyTree(formal.ast)
|
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)
|
put(m, formal.typ, def.typ)
|
||||||
def.flags.incl nfDefaultParam
|
def.flags.incl nfDefaultParam
|
||||||
setSon(m.call, formal.position + 1, def)
|
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)
|
inc(f)
|
||||||
# forget all inferred types if the overload matching failed
|
# forget all inferred types if the overload matching failed
|
||||||
if m.state == csNoMatch:
|
if m.state == csNoMatch:
|
||||||
|
|
|
||||||
|
|
@ -5500,9 +5500,9 @@ Static params can also appear in the signatures of generic types:
|
||||||
var m2: AffineTransform2D[string] # Error, `string` is not a `Number`
|
var m2: AffineTransform2D[string] # Error, `string` is not a `Number`
|
||||||
|
|
||||||
Please note that ``static T`` is just a syntactic convenience for the
|
Please note that ``static T`` is just a syntactic convenience for the
|
||||||
underlying generic type ``static[T]``. This means that you can omit the
|
underlying generic type ``static[T]``. The type param can be omitted
|
||||||
type param to obtain the type class of all values, known at compile-time
|
to obtain the type class of all values known at compile-time. A more
|
||||||
and you can restrict the matched values by instantiating ``static`` with
|
specific type class can be created by instantiating ``static`` with
|
||||||
another type class.
|
another type class.
|
||||||
|
|
||||||
You can force the evaluation of a certain expression at compile-time by
|
You can force the evaluation of a certain expression at compile-time by
|
||||||
|
|
@ -5529,7 +5529,7 @@ generic param is ommited, ``type`` denotes the type class of all types.
|
||||||
As a syntactic convenience, you can also use ``type`` as a modifier.
|
As a syntactic convenience, you can also use ``type`` as a modifier.
|
||||||
``type int`` is considered the same as ``type[int]``.
|
``type int`` is considered the same as ``type[int]``.
|
||||||
|
|
||||||
Procs featuring ``type`` params will be considered implicitly generic.
|
Procs featuring ``type`` params are considered implicitly generic.
|
||||||
They will be instantiated for each unique combination of supplied types
|
They will be instantiated for each unique combination of supplied types
|
||||||
and within the body of the proc, the name of each param will refer to
|
and within the body of the proc, the name of each param will refer to
|
||||||
the bound concrete type:
|
the bound concrete type:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue