Skip to content

Commit f7145dd

Browse files
committed
Revert "leave type section symbols unchanged on resem, fix overly general double semcheck for forward types (nim-lang#24888)"
This reverts commit cfe8909.
1 parent 1db543e commit f7145dd

File tree

6 files changed

+37
-141
lines changed

6 files changed

+37
-141
lines changed

compiler/semdata.nim

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,7 @@ type
172172
sideEffects*: Table[int, seq[(TLineInfo, PSym)]] # symbol.id index
173173
inUncheckedAssignSection*: int
174174
importModuleLookup*: Table[int, seq[int]] # (module.ident.id, [module.id])
175-
forwardTypeUpdates*: seq[(PType, PNode)]
176-
# types that need to be updated in a type section
177-
# due to containing forward types, and their corresponding nodes
175+
skipTypes*: seq[PNode] # used to skip types between passes in type section. So far only used for inheritance, sets and generic bodies.
178176
inTypeofContext*: int
179177

180178
semAsgnOpr*: proc (c: PContext; n: PNode; k: TNodeKind): PNode {.nimcall.}

compiler/semstmts.nim

Lines changed: 28 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,13 +1460,8 @@ proc typeDefLeftSidePass(c: PContext, typeSection: PNode, i: int) =
14601460
else:
14611461
s = semIdentDef(c, name, skType)
14621462
onDef(name.info, s)
1463-
if s.typ != nil:
1464-
# name node is a symbol with a type already, probably in resem, don't touch it
1465-
discard
1466-
else:
1467-
s.typ = newTypeS(tyForward, c)
1468-
s.typ.sym = s
1469-
# process pragmas:
1463+
s.typ = newTypeS(tyForward, c)
1464+
s.typ.sym = s # process pragmas:
14701465
if name.kind == nkPragmaExpr:
14711466
let rewritten = applyTypeSectionPragmas(c, name[1], typeDef)
14721467
if rewritten != nil:
@@ -1604,26 +1599,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
16041599
localError(c.config, a.info, errImplOfXexpected % s.name.s)
16051600
if s.magic != mNone: processMagicType(c, s)
16061601
let oldFlags = s.typ.flags
1607-
let preserveSym = s.typ != nil and s.typ.kind != tyForward and sfForward notin s.flags and
1608-
s.magic == mNone # magic might have received type above but still needs processing
1609-
if preserveSym:
1610-
# symbol already has a type, probably in resem, do not modify it
1611-
# but still semcheck the RHS to handle any defined symbols
1612-
# nominal type nodes are still ignored in semtypes
1613-
if a[1].kind != nkEmpty:
1614-
openScope(c)
1615-
pushOwner(c, s)
1616-
a[1] = semGenericParamList(c, a[1], nil)
1617-
inc c.inGenericContext
1618-
discard semTypeNode(c, a[2], s.typ)
1619-
dec c.inGenericContext
1620-
popOwner(c)
1621-
closeScope(c)
1622-
elif a[2].kind != nkEmpty:
1623-
pushOwner(c, s)
1624-
discard semTypeNode(c, a[2], s.typ)
1625-
popOwner(c)
1626-
elif a[1].kind != nkEmpty:
1602+
if a[1].kind != nkEmpty:
16271603
# We have a generic type declaration here. In generic types,
16281604
# symbol lookup needs to be done here.
16291605
openScope(c)
@@ -1713,7 +1689,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
17131689
localError(c.config, name.info, "only a 'distinct' type can borrow `.`")
17141690
let aa = a[2]
17151691
if aa.kind in {nkRefTy, nkPtrTy} and aa.len == 1 and
1716-
aa[0].kind == nkObjectTy and not preserveSym:
1692+
aa[0].kind == nkObjectTy:
17171693
# give anonymous object a dummy symbol:
17181694
var st = s.typ
17191695
if st.kind == tyGenericBody: st = st.typeBodyImpl
@@ -1754,6 +1730,9 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
17541730
obj.flags.incl sfPure
17551731
obj.typ = objTy
17561732
objTy.sym = obj
1733+
for sk in c.skipTypes:
1734+
discard semTypeNode(c, sk, nil)
1735+
c.skipTypes = @[]
17571736

17581737
proc checkForMetaFields(c: PContext; n: PNode; hasError: var bool) =
17591738
proc checkMeta(c: PContext; n: PNode; t: PType; hasError: var bool; parent: PType) =
@@ -1789,15 +1768,6 @@ proc checkForMetaFields(c: PContext; n: PNode; hasError: var bool) =
17891768
internalAssert c.config, false
17901769

17911770
proc typeSectionFinalPass(c: PContext, n: PNode) =
1792-
for (typ, typeNode) in c.forwardTypeUpdates:
1793-
# types that need to be updated due to containing forward types
1794-
# and their corresponding type nodes
1795-
# for example generic invocations of forward types end up here
1796-
var reified = semTypeNode(c, typeNode, nil)
1797-
assert reified != nil
1798-
assignType(typ, reified)
1799-
typ.itemId = reified.itemId # same id
1800-
c.forwardTypeUpdates = @[]
18011771
for i in 0..<n.len:
18021772
var a = n[i]
18031773
if a.kind == nkCommentStmt: continue
@@ -1824,15 +1794,29 @@ proc typeSectionFinalPass(c: PContext, n: PNode) =
18241794
else:
18251795
while x.kind in {nkStmtList, nkStmtListExpr} and x.len > 0:
18261796
x = x.lastSon
1797+
# we need the 'safeSkipTypes' here because illegally recursive types
1798+
# can enter at this point, see bug #13763
1799+
if x.kind notin {nkObjectTy, nkDistinctTy, nkEnumTy, nkEmpty} and
1800+
s.typ.safeSkipTypes(abstractPtrs).kind notin {tyObject, tyEnum}:
1801+
# type aliases are hard:
1802+
var t = semTypeNode(c, x, nil)
1803+
assert t != nil
1804+
if s.typ != nil and s.typ.kind notin {tyAlias, tySink}:
1805+
if t.kind in {tyProc, tyGenericInst} and not t.isMetaType:
1806+
assignType(s.typ, t)
1807+
s.typ.itemId = t.itemId
1808+
elif t.kind in {tyObject, tyEnum, tyDistinct}:
1809+
assert s.typ != nil
1810+
assignType(s.typ, t)
1811+
s.typ.itemId = t.itemId # same id
18271812
var hasError = false
1828-
if x.kind in {nkObjectTy, nkTupleTy} or
1813+
let baseType = s.typ.safeSkipTypes(abstractPtrs)
1814+
if baseType.kind in {tyObject, tyTuple} and not baseType.n.isNil and
1815+
(x.kind in {nkObjectTy, nkTupleTy} or
18291816
(x.kind in {nkRefTy, nkPtrTy} and x.len == 1 and
1830-
x[0].kind in {nkObjectTy, nkTupleTy}):
1831-
# we need the 'safeSkipTypes' here because illegally recursive types
1832-
# can enter at this point, see bug #13763
1833-
let baseType = s.typ.safeSkipTypes(abstractPtrs)
1834-
if baseType.kind in {tyObject, tyTuple} and not baseType.n.isNil:
1835-
checkForMetaFields(c, baseType.n, hasError)
1817+
x[0].kind in {nkObjectTy, nkTupleTy})
1818+
):
1819+
checkForMetaFields(c, baseType.n, hasError)
18361820
if not hasError:
18371821
checkConstructedType(c.config, s.info, s.typ)
18381822
#instAllTypeBoundOp(c, n.info)

compiler/semtypes.nim

Lines changed: 3 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -59,31 +59,11 @@ proc newConstraint(c: PContext, k: TTypeKind): PType =
5959
result.flags.incl tfCheckedForDestructor
6060
result.addSonSkipIntLit(newTypeS(k, c), c.idgen)
6161

62-
proc skipGenericPrev(prev: PType): PType =
63-
result = prev
64-
if prev.kind == tyGenericBody and prev.last.kind != tyNone:
65-
result = prev.last
66-
67-
proc prevIsKind(prev: PType, kind: TTypeKind): bool {.inline.} =
68-
result = prev != nil and skipGenericPrev(prev).kind == kind
69-
7062
proc semEnum(c: PContext, n: PNode, prev: PType): PType =
7163
if n.len == 0: return newConstraint(c, tyEnum)
7264
elif n.len == 1:
7365
# don't create an empty tyEnum; fixes #3052
7466
return errorType(c)
75-
if prevIsKind(prev, tyEnum):
76-
# the symbol already has an enum type (likely resem), don't define a new enum
77-
# but add the enum fields to scope from the original type
78-
let isPure = sfPure in prev.sym.flags
79-
for enumField in prev.n:
80-
assert enumField.kind == nkSym
81-
let e = enumField.sym
82-
if not isPure:
83-
addInterfaceOverloadableSymAt(c, c.currentScope, e)
84-
else:
85-
declarePureEnumField(c, e)
86-
return prev
8767
var
8868
counter, x: BiggestInt = 0
8969
e: PSym = nil
@@ -217,7 +197,7 @@ proc semSet(c: PContext, n: PNode, prev: PType): PType =
217197
if base.kind in {tyGenericInst, tyAlias, tySink}: base = skipModifier(base)
218198
if base.kind notin {tyGenericParam, tyGenericInvocation}:
219199
if base.kind == tyForward:
220-
c.forwardTypeUpdates.add (base, n[1])
200+
c.skipTypes.add n
221201
elif not isOrdinalType(base, allowEnumWithHoles = true):
222202
localError(c.config, n.info, errOrdinalTypeExpected % typeToString(base, preferDesc))
223203
elif lengthOrd(c.config, base) > MaxSetElements:
@@ -327,9 +307,6 @@ proc addSonSkipIntLitChecked(c: PContext; father, son: PType; it: PNode, id: IdG
327307

328308
proc semDistinct(c: PContext, n: PNode, prev: PType): PType =
329309
if n.len == 0: return newConstraint(c, tyDistinct)
330-
if prevIsKind(prev, tyDistinct):
331-
# the symbol already has a distinct type (likely resem), don't create a new type
332-
return skipGenericPrev(prev)
333310
result = newOrPrevType(tyDistinct, prev, c)
334311
addSonSkipIntLitChecked(c, result, semTypeNode(c, n[0], nil), n[0], c.idgen)
335312
if n.len > 1: result.n = n[1]
@@ -1017,15 +994,11 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType; flags: TTypeFlags): PType
1017994
result = nil
1018995
if n.len == 0:
1019996
return newConstraint(c, tyObject)
1020-
if prevIsKind(prev, tyObject) and sfForward notin prev.sym.flags:
1021-
# the symbol already has an object type (likely resem), don't create a new type
1022-
return skipGenericPrev(prev)
1023997
var check = initIntSet()
1024998
var pos = 0
1025999
var base, realBase: PType = nil
10261000
# n[0] contains the pragmas (if any). We process these later...
10271001
checkSonsLen(n, 3, c.config)
1028-
var needsForwardUpdate = false
10291002
if n[1].kind != nkEmpty:
10301003
realBase = semTypeNode(c, n[1][0], nil)
10311004
base = skipTypesOrNil(realBase, skipPtrs)
@@ -1047,7 +1020,7 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType; flags: TTypeFlags): PType
10471020
return newType(tyError, c.idgen, result.owner)
10481021

10491022
elif concreteBase.kind == tyForward:
1050-
needsForwardUpdate = true
1023+
c.skipTypes.add n #we retry in the final pass
10511024
else:
10521025
if concreteBase.kind != tyError:
10531026
localError(c.config, n[1].info, "inheritance only works with non-final objects; " &
@@ -1057,10 +1030,6 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType; flags: TTypeFlags): PType
10571030
realBase = nil
10581031
if n.kind != nkObjectTy: internalError(c.config, n.info, "semObjectNode")
10591032
result = newOrPrevType(tyObject, prev, c)
1060-
if needsForwardUpdate:
1061-
# if the inherited object is a forward type,
1062-
# the entire object needs to be checked again
1063-
c.forwardTypeUpdates.add (result, n) #we retry in the final pass
10641033
rawAddSon(result, realBase)
10651034
if realBase == nil and tfInheritable in flags:
10661035
result.flags.incl tfInheritable
@@ -1087,9 +1056,6 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType =
10871056
if n.len < 1:
10881057
result = newConstraint(c, kind)
10891058
else:
1090-
if prevIsKind(prev, kind) and tfRefsAnonObj in prev.skipTypes({tyGenericBody}).flags:
1091-
# the symbol already has an object type (likely resem), don't create a new type
1092-
return skipGenericPrev(prev)
10931059
let isCall = int ord(n.kind in nkCallKinds+{nkBracketExpr})
10941060
let n = if n[0].kind == nkBracket: n[0] else: n
10951061
checkMinSonsLen(n, 1, c.config)
@@ -1698,7 +1664,6 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
16981664
for i in 1..<n.len:
16991665
var elem = semGenericParamInInvocation(c, n[i])
17001666
addToResult(elem, true)
1701-
c.forwardTypeUpdates.add (result, n)
17021667
return
17031668
elif t.kind != tyGenericBody:
17041669
# we likely got code of the form TypeA[TypeB] where TypeA is
@@ -1747,7 +1712,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
17471712
localError(c.config, n.info, errCannotInstantiateX % s.name.s)
17481713
result = newOrPrevType(tyError, prev, c)
17491714
elif containsGenericInvocationWithForward(n[0]):
1750-
c.forwardTypeUpdates.add (result, n) #fixes 1500
1715+
c.skipTypes.add n #fixes 1500
17511716
else:
17521717
result = instGenericContainer(c, n.info, result,
17531718
allowMetaTypes = false)

compiler/types.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
526526
let t = typ
527527
if t == nil: return
528528
if prefer in preferToResolveSymbols and t.sym != nil and
529-
sfAnon notin t.sym.flags and t.kind notin {tySequence, tyInferred}:
529+
sfAnon notin t.sym.flags and t.kind != tySequence:
530530
if t.kind == tyInt and isIntLit(t):
531531
if prefer == preferInlayHint:
532532
result = t.sym.name.s

nimsuggest/tests/ttype_highlight.nim

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,8 @@ highlight;;skType;;4;;33;;3
2020
highlight;;skType;;5;;13;;1
2121
highlight;;skType;;6;;25;;5
2222
highlight;;skType;;6;;34;;3
23+
highlight;;skType;;2;;10;;3
24+
highlight;;skType;;3;;11;;3
25+
highlight;;skType;;4;;33;;3
26+
highlight;;skType;;6;;34;;3
2327
"""

tests/types/tresemtypesection.nim

Lines changed: 0 additions & 55 deletions
This file was deleted.

0 commit comments

Comments
 (0)