Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

semtypinst: remove the "meta-types allowed" mode #866

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions compiler/sem/seminst.nim
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,7 @@ proc sideEffectsCheck(c: PContext, s: PSym) =
{sfNoSideEffect, sfSideEffect}:
localReport(s.info, errXhasSideEffects, s.name.s)

proc instGenericContainer(c: PContext, info: TLineInfo, header: PType,
allowMetaTypes = false): PType =
proc instGenericContainer(c: PContext, info: TLineInfo, header: PType): PType =
internalAssert(
c.config,
header.kind == tyGenericInvocation,
Expand All @@ -157,7 +156,6 @@ proc instGenericContainer(c: PContext, info: TLineInfo, header: PType,

cl.info = info
cl.c = c
cl.allowMetaTypes = allowMetaTypes

# We must add all generic params in scope, because the generic body
# may include tyFromExpr nodes depending on these generic params.
Expand Down
3 changes: 1 addition & 2 deletions compiler/sem/semtypes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1744,8 +1744,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =

result = newOrPrevType(tyError, prev, c)
else:
result = instGenericContainer(c, n.info, result,
allowMetaTypes = false)
result = instGenericContainer(c, n.info, result)

# special check for generic object with
# generic/partial specialized parent
Expand Down
51 changes: 13 additions & 38 deletions compiler/sem/semtypinst.nim
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,9 @@ type
typeMap*: LayeredIdTable # map PType to PType
symMap*: TIdTable # map PSym to PSym
localCache*: TIdTable # local cache for remembering already replaced
# types during instantiation of meta types
# (they are not stored in the global cache)
# types. Used as a work-around for instantiation
# cache issues
Comment on lines +108 to +109
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

excellent, emphasizes that it needs to be fixed rather than actually required.

info*: TLineInfo
allowMetaTypes*: bool # allow types such as seq[Number]
# i.e. the result contains unresolved generics
skipTypedesc*: bool # whether we should skip typeDescs
isReturnType*: bool
owner*: PSym # where this instantiation comes from
Expand Down Expand Up @@ -141,8 +139,7 @@ template put(typeMap: LayeredIdTable, key, value: PType) =

template checkMetaInvariants(cl: TReplTypeVars, t: PType) = # noop code
when false:
if t != nil and tfHasMeta in t.flags and
cl.allowMetaTypes == false:
if t != nil and tfHasMeta in t.flags:
echo "UNEXPECTED META ", t.id, " ", instantiationInfo(-1)
debug t
writeStackTrace()
Expand Down Expand Up @@ -365,10 +362,8 @@ proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode; start=0): PNode =
of nkStaticExpr:
var n = prepareNode(cl, n)
n = reResolveCallsWithTypedescParams(cl.c, n)
result = if cl.allowMetaTypes: n
else: cl.c.semExpr(cl.c, n)
if not cl.allowMetaTypes:
assert result.kind notin nkCallKinds
result = cl.c.semExpr(cl.c, n)
assert result.kind notin nkCallKinds
else:
if n.len > 0:
newSons(result, n.len)
Expand Down Expand Up @@ -425,37 +420,27 @@ proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym =
proc lookupTypeVar(cl: var TReplTypeVars, t: PType): PType =
result = cl.typeMap.lookup(t)
if result == nil:
if cl.allowMetaTypes or tfRetType in t.flags: return
if tfRetType in t.flags: return
cl.c.config.localReport(t.sym.info, reportTyp(rsemCannotInstantiate, t))
result = errorType(cl.c)
# In order to prevent endless recursions, we must remember
# this bad lookup and replace it with errorType everywhere.
# These code paths are only active in "nim check"
cl.typeMap.put(t, result)
elif result.kind == tyGenericParam and not cl.allowMetaTypes:
elif result.kind == tyGenericParam:
cl.c.config.internalError("substitution with generic parameter")

proc instCopyType*(cl: var TReplTypeVars, t: PType): PType =
# XXX: relying on allowMetaTypes is a kludge
if cl.allowMetaTypes:
result = t.exactReplica
else:
if true:
result = copyType(t, nextTypeId(cl.c.idgen), t.owner)
copyTypeProps(cl.c.graph, cl.c.idgen.module, result, t)
#cl.typeMap.topLayer.idTablePut(result, t)

if cl.allowMetaTypes: return
result.flags.incl tfFromGeneric
if not (t.kind in tyMetaTypes or
(t.kind == tyStatic and t.n == nil)):
result.flags.excl tfInstClearedFlags
else:
result.flags.excl tfHasAsgn
when false:
if newDestructors:
result.assignment = nil
result.destructor = nil
result.sink = nil

proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
# tyGenericInvocation[A, tyGenericInvocation[A, B]]
Expand All @@ -464,10 +449,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
cl.c.config.internalAssert(body.kind == tyGenericBody, cl.info, "no generic body")
var header = t
# search for some instantiation here:
if cl.allowMetaTypes:
result = PType(idTableGet(cl.localCache, t))
else:
result = searchInstTypes(cl.c.graph, t)
result = searchInstTypes(cl.c.graph, t)

if result != nil and sameFlags(result, t):
when defined(reportCacheHits):
Expand Down Expand Up @@ -502,10 +484,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
# ugh need another pass for deeply recursive generic types (e.g. PActor)
# we need to add the candidate here, before it's fully instantiated for
# recursive instantions:
if not cl.allowMetaTypes:
cacheTypeInst(cl.c, result)
else:
idTablePut(cl.localCache, t, result)
cacheTypeInst(cl.c, result)

let oldSkipTypedesc = cl.skipTypedesc
cl.skipTypedesc = true
Expand Down Expand Up @@ -543,7 +522,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
if newbody.isGenericAlias: newbody = newbody.skipGenericAlias
rawAddSon(result, newbody)
checkPartialConstructedType(cl.c.config, cl.info, newbody)
if not cl.allowMetaTypes:
if true:
let dc = cl.c.graph.getAttachedOp(newbody, attachedDeepCopy)
if dc != nil and sfFromGeneric notin dc.flags:
# 'deepCopy' needs to be instantiated for
Expand Down Expand Up @@ -659,7 +638,6 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
#result = replaceTypeVarsT(cl, lastSon(t))

of tyFromExpr:
if cl.allowMetaTypes: return
# This assert is triggered when a tyFromExpr was created in a cyclic
# way. You should break the cycle at the point of creation by introducing
# a call such as: `n.typ = makeTypeFromExpr(c, n.copyTree)`
Expand Down Expand Up @@ -712,18 +690,15 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
propagateToOwner(result, result.lastSon)

of tyGenericInst:
# do nothing for ``tyGenericInst`` instances. Concrete ones don't need any
# replacing, and meta ones are handled at the callsite
doAssert(cl.allowMetaTypes or not containsGenericType(t))
# this must be a fully resolved concrete type
doAssert(not containsGenericType(t))
result = t

else:
if containsGenericType(t):
#if not cl.allowMetaTypes:
bailout()
result = instCopyType(cl, t)
result.size = -1 # needs to be recomputed
#if not cl.allowMetaTypes:
idTablePut(cl.localCache, t, result)

for i in 0..<result.len:
Expand Down
Loading