Skip to content

Commit

Permalink
Split out immutable GadtConstraint (#16602)
Browse files Browse the repository at this point in the history
This change eagerly allocates a GadtConstraint whenever its state is
changed, rather than simply changing the reference(s) in, what's now
called, `GadtConstraintHandling`, such as `constraint`. Previous to a
recent change, in order to restore the GADT constraints, a fresh copy
was eagerly created in a number of cases, just so it can be used to
restore, for the cases in which it must be restored. The recent change
exposed the underlying pieces of the GADT constraint and allowed those
to be restored as components. Now we still do that, but as a packaged up
GadtConstraint that we created once, eagerly. That also makes sure that
invariants in components are upheld, like the mappings.
  • Loading branch information
Linyxus authored Jan 26, 2023
2 parents d63e572 + b1a035a commit 6ccdbd9
Show file tree
Hide file tree
Showing 17 changed files with 229 additions and 241 deletions.
3 changes: 3 additions & 0 deletions compiler/src/dotty/tools/dotc/core/Constraint.scala
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ abstract class Constraint extends Showable {
*/
def nonParamBounds(param: TypeParamRef)(using Context): TypeBounds

/** The current bounds of type parameter `param` */
def bounds(param: TypeParamRef)(using Context): TypeBounds

/** A new constraint which is derived from this constraint by adding
* entries for all type parameters of `poly`.
* @param tvars A list of type variables associated with the params,
Expand Down
11 changes: 1 addition & 10 deletions compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
Original file line number Diff line number Diff line change
Expand Up @@ -749,16 +749,7 @@ trait ConstraintHandling {
}

/** The current bounds of type parameter `param` */
def bounds(param: TypeParamRef)(using Context): TypeBounds = {
val e = constraint.entry(param)
if (e.exists) e.bounds
else {
// TODO: should we change the type of paramInfos to nullable?
val pinfos: List[param.binder.PInfo] | Null = param.binder.paramInfos
if (pinfos != null) pinfos(param.paramNum) // pinfos == null happens in pos/i536.scala
else TypeBounds.empty
}
}
def bounds(param: TypeParamRef)(using Context): TypeBounds = constraint.bounds(param)

/** Add type lambda `tl`, possibly with type variables `tvars`, to current constraint
* and propagate all bounds.
Expand Down
21 changes: 11 additions & 10 deletions compiler/src/dotty/tools/dotc/core/Contexts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ object Contexts {
def tree: Tree[?]
def scope: Scope
def typerState: TyperState
def gadt: GadtConstraint
def gadt: GadtConstraint = gadtState.gadt
def gadtState: GadtState
def searchHistory: SearchHistory
def source: SourceFile

Expand Down Expand Up @@ -410,7 +411,7 @@ object Contexts {
val constrCtx = outersIterator.dropWhile(_.outer.owner == owner).next()
superOrThisCallContext(owner, constrCtx.scope)
.setTyperState(typerState)
.setGadt(gadt)
.setGadtState(gadtState)
.fresh
.setScope(this.scope)
}
Expand Down Expand Up @@ -541,8 +542,8 @@ object Contexts {
private var _typerState: TyperState = uninitialized
final def typerState: TyperState = _typerState

private var _gadt: GadtConstraint = uninitialized
final def gadt: GadtConstraint = _gadt
private var _gadtState: GadtState = uninitialized
final def gadtState: GadtState = _gadtState

private var _searchHistory: SearchHistory = uninitialized
final def searchHistory: SearchHistory = _searchHistory
Expand All @@ -567,7 +568,7 @@ object Contexts {
_owner = origin.owner
_tree = origin.tree
_scope = origin.scope
_gadt = origin.gadt
_gadtState = origin.gadtState
_searchHistory = origin.searchHistory
_source = origin.source
_moreProperties = origin.moreProperties
Expand Down Expand Up @@ -624,12 +625,12 @@ object Contexts {
this._scope = typer.scope
setTypeAssigner(typer)

def setGadt(gadt: GadtConstraint): this.type =
util.Stats.record("Context.setGadt")
this._gadt = gadt
def setGadtState(gadtState: GadtState): this.type =
util.Stats.record("Context.setGadtState")
this._gadtState = gadtState
this
def setFreshGADTBounds: this.type =
setGadt(gadt.fresh)
setGadtState(gadtState.fresh)

def setSearchHistory(searchHistory: SearchHistory): this.type =
util.Stats.record("Context.setSearchHistory")
Expand Down Expand Up @@ -721,7 +722,7 @@ object Contexts {
.updated(notNullInfosLoc, Nil)
.updated(compilationUnitLoc, NoCompilationUnit)
c._searchHistory = new SearchRoot
c._gadt = GadtConstraint.empty
c._gadtState = GadtState(GadtConstraint.empty)
c
end FreshContext

Expand Down
Loading

0 comments on commit 6ccdbd9

Please sign in to comment.