Skip to content

Commit

Permalink
Fix resetInst logic
Browse files Browse the repository at this point in the history
The previous way never reset any type variable since it traversed `ownedVars`, and
instantiated TypeVars are no longer in the ownedVars of their owning TyperState.
  • Loading branch information
odersky committed Aug 21, 2022
1 parent ec2b5d6 commit 86f249c
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 10 deletions.
18 changes: 8 additions & 10 deletions compiler/src/dotty/tools/dotc/core/TyperState.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,19 @@ object TyperState {

type LevelMap = SimpleIdentityMap[TypeVar, Integer]

opaque type Snapshot = (Constraint, TypeVars, TypeVars, LevelMap)
opaque type Snapshot = (Constraint, TypeVars, LevelMap)

extension (ts: TyperState)
def snapshot()(using Context): Snapshot =
var previouslyInstantiated: TypeVars = SimpleIdentitySet.empty
for tv <- ts.ownedVars do if tv.inst.exists then previouslyInstantiated += tv
(ts.constraint, ts.ownedVars, previouslyInstantiated, ts.upLevels)
(ts.constraint, ts.ownedVars, ts.upLevels)

def resetTo(state: Snapshot)(using Context): Unit =
val (c, tvs, previouslyInstantiated, upLevels) = state
for tv <- tvs do
if tv.inst.exists && !previouslyInstantiated.contains(tv) then
val (constraint, ownedVars, upLevels) = state
for tv <- ownedVars do
if !ts.ownedVars.contains(tv) then // tv has been instantiated
tv.resetInst(ts)
ts.ownedVars = tvs
ts.constraint = c
ts.constraint = constraint
ts.ownedVars = ownedVars
ts.upLevels = upLevels
}

Expand Down Expand Up @@ -190,7 +188,7 @@ class TyperState() {
if level < targetState.nestingLevel(tv) then
targetState.setNestingLevel(tv, level)
}

targetState.gc()
isCommitted = true
ownedVars = SimpleIdentitySet.empty
Expand Down
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4524,6 +4524,7 @@ object Types {
owningState = null // no longer needed; null out to avoid a memory leak

private[core] def resetInst(ts: TyperState): Unit =
assert(myInst.exists)
myInst = NoType
owningState = new WeakReference(ts)

Expand Down

0 comments on commit 86f249c

Please sign in to comment.