Skip to content

Commit

Permalink
major simplification
Browse files Browse the repository at this point in the history
  • Loading branch information
metagn committed Jan 16, 2024
1 parent 5af0343 commit 887fa73
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 56 deletions.
8 changes: 0 additions & 8 deletions compiler/semstmts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1819,15 +1819,7 @@ proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode =
#incl(s.flags, sfFromGeneric)
#s.owner = original

let originalReturnType = n.typ[0]
n = replaceTypesInBody(c, pt, n, original)
if originalReturnType != nil and originalReturnType.kind == tyAnything:
# the return type should not be set to a previous binding of `auto`
# this could alternatively be done by changing tyAnything to
# differentiate based on which place it's inferring the type of
# (i.e. a unique instance of tyAnything for every reference to `auto`),
# but for now this is sufficient as we only care to infer return types
n.typ[0] = originalReturnType
result = n
s.ast = result
n[namePos].sym = s
Expand Down
3 changes: 2 additions & 1 deletion compiler/semtypes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1436,7 +1436,8 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
"' is only valid for macros and templates")
# 'auto' as a return type does not imply a generic:
elif r.kind == tyAnything:
discard
r = copyType(r, c.idgen, r.owner)
r.flags.incl tfRetType
elif r.kind == tyStatic:
# type allowed should forbid this type
discard
Expand Down
7 changes: 6 additions & 1 deletion compiler/semtypinst.nim
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,9 @@ proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym, t: PType): PSym =
result.ast = replaceTypeVarsN(cl, s.ast)

proc lookupTypeVar(cl: var TReplTypeVars, t: PType): PType =
if tfRetType in t.flags and t.kind == tyAnything:
# don't bind `auto` return type to a previous binding of `auto`
return nil
result = cl.typeMap.lookup(t)
if result == nil:
if cl.allowMetaTypes or tfRetType in t.flags: return
Expand Down Expand Up @@ -551,7 +554,9 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
result = t
if t == nil: return

if t.kind in {tyStatic, tyGenericParam, tyConcept} + tyTypeClasses:
const lookupMetas = {tyStatic, tyGenericParam, tyConcept} + tyTypeClasses - {tyAnything}
if t.kind in lookupMetas or
(t.kind == tyAnything and tfRetType notin t.flags):
let lookup = cl.typeMap.lookup(t)
if lookup != nil: return lookup

Expand Down
85 changes: 39 additions & 46 deletions compiler/sigmatch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2182,34 +2182,33 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
else:
return argSemantized # argOrig

# If r == isBothMetaConvertible then we rerun typeRel.
# bothMetaCounter is for safety to avoid any infinite loop,
# I don't have any example when it is needed.
# lastBindingsLenth is used to check whether m.bindings remains the same,
# because in that case there is no point in continuing.
var bothMetaCounter = 0
var lastBindingsLength = -1
while r in {isBothMetaConvertible, isInferred, isInferredConvertible} and
(lastBindingsLength != m.bindings.counter or
(arg.typ[0] != nil and arg.typ[0].kind == tyAnything)) and
bothMetaCounter < 100:
lastBindingsLength = m.bindings.counter
inc(bothMetaCounter)
if arg.kind in {nkProcDef, nkFuncDef, nkIteratorDef} + nkLambdaKinds:
result = c.semInferredLambda(c, m.bindings, arg)
elif arg.kind != nkSym:
return nil
elif arg.sym.kind in {skMacro, skTemplate}:
return nil
else:
if arg.sym.ast == nil:
block instantiateGenericRoutine:
# In the case where the matched value is a generic proc, we need to
# fully instantiate it and then rerun typeRel to make sure it matches.
# bothMetaCounter is for safety to avoid any infinite loop,
# I don't have any example when it is needed.
# lastBindingsLenth is used to check whether m.bindings remains the same,
# because in that case there is no point in continuing.
var instantiationCounter = 0
var lastBindingsLength = -1
while r in {isBothMetaConvertible, isInferred, isInferredConvertible} and
lastBindingsLength != m.bindings.counter and
instantiationCounter < 100:
lastBindingsLength = m.bindings.counter
inc(instantiationCounter)
if arg.kind in {nkProcDef, nkFuncDef, nkIteratorDef} + nkLambdaKinds:
result = c.semInferredLambda(c, m.bindings, arg)
elif arg.kind != nkSym:
return nil
let inferred = c.semGenerateInstance(c, arg.sym, m.bindings, arg.info)
result = newSymNode(inferred, arg.info)
if r == isBothMetaConvertible: # ???
inc(m.convMatches)
arg = result
r = typeRel(m, f, arg.typ)
elif arg.sym.kind in {skMacro, skTemplate}:
return nil
else:
if arg.sym.ast == nil:
return nil
let inferred = c.semGenerateInstance(c, arg.sym, m.bindings, arg.info)
result = newSymNode(inferred, arg.info)
arg = result
r = typeRel(m, f, arg.typ)

case r
of isConvertible:
Expand All @@ -2236,23 +2235,15 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
result = arg
else:
result = implicitConv(nkHiddenStdConv, f, arg, m, c)
of isInferred, isInferredConvertible:
if arg.kind in {nkProcDef, nkFuncDef, nkIteratorDef} + nkLambdaKinds:
result = c.semInferredLambda(c, m.bindings, arg)
elif arg.kind != nkSym:
return nil
elif arg.sym.kind in {skMacro, skTemplate}:
return nil
else:
if arg.sym.ast == nil:
return nil
let inferred = c.semGenerateInstance(c, arg.sym, m.bindings, arg.info)
result = newSymNode(inferred, arg.info)
if r == isInferredConvertible:
inc(m.convMatches)
result = implicitConv(nkHiddenStdConv, f, result, m, c)
else:
inc(m.genericMatches)
of isInferred:
# result should be set in above while loop:
assert result != nil
inc(m.genericMatches)
of isInferredConvertible:
# result should be set in above while loop:
assert result != nil
inc(m.convMatches)
result = implicitConv(nkHiddenStdConv, f, result, m, c)
of isGeneric:
inc(m.genericMatches)
if arg.typ == nil:
Expand All @@ -2266,8 +2257,10 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
else:
result = arg
of isBothMetaConvertible:
# This is the result for the 101th time.
result = nil
# result should be set in above while loop:
assert result != nil
inc(m.convMatches)
result = arg
of isFromIntLit:
# too lazy to introduce another ``*matches`` field, so we conflate
# ``isIntConv`` and ``isIntLit`` here:
Expand Down

0 comments on commit 887fa73

Please sign in to comment.