You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Track type variable dependencies to guide instantiation decisions (#16042)
We now keep track of reverse type variable dependencies in constraints.
E.g. if a constraint contains a clause like
A >: List[B]
We associate with `B` info that `A` depends co-variantly on it. Or, if
A <: B => C
we associate with `B` that `A` depends co-variantly on it and with `C`
that `A` depends contra-variantly on it. Here, co-variant means that
the allowable range of `A` narrows if the referred-to variable `B`
grows, and
contra-variant means that the allowable range of `A` narrows if the
referred-to
variable `C` shrinks. If there's an invariant reference such as
A <: Array[B]
Then `A` depends both co- and contra-variantly on `B`.
These dependencies are then used to guide type variable instantiation.
If an eligible type variable does not appear in the type of a typed
expression,
we interpolate it to one of its bounds. Previously this was done in an
ad-hoc
manner where we minimized the type variable if it had a lower bound and
maximized
it otherwise. We now take reverse dependencies into account. If
maximizing a type
variable would narrow the remaining constraint we minimize, and if
minimizing
a type variable would narrow the remaining constraint we maximize. Only
if
the type variable is not referred to from the remaining constraint we
resort
to the old heuristic based on the lower bound.
Fixes#15864
Todo: This could be generalized in several directions:
- We could base the dependency tracking on type param refs instead of
type variables.
That could make the `replace` operation in a constraint more efficient.
- We could base more interpolation decisions on dependencies. E.g. we
could
interpolate a type variable only if both the type of an expression and
the enclosing
constraint agree in which direction this should be done.
valYforceSbtPhases:Setting[Boolean] =BooleanSetting("-Yforce-sbt-phases", "Run the phases used by sbt for incremental compilation (ExtractDependencies and ExtractAPI) even if the compiler is ran outside of sbt, for debugging.")
310
310
valYdumpSbtInc:Setting[Boolean] =BooleanSetting("-Ydump-sbt-inc", "For every compiled foo.scala, output the API representation and dependencies used for sbt incremental compilation in foo.inc, implies -Yforce-sbt-phases.")
311
311
valYcheckAllPatmat:Setting[Boolean] =BooleanSetting("-Ycheck-all-patmat", "Check exhaustivity and redundancy of all pattern matching (used for testing the algorithm).")
312
+
valYcheckConstraintDeps:Setting[Boolean] =BooleanSetting("-Ycheck-constraint-deps", "Check dependency tracking in constraints (used for testing the algorithm).")
312
313
valYretainTrees:Setting[Boolean] =BooleanSetting("-Yretain-trees", "Retain trees for top-level classes, accessible from ClassSymbol#tree")
313
314
valYshowTreeIds:Setting[Boolean] =BooleanSetting("-Yshow-tree-ids", "Uniquely tag all tree nodes in debugging output.")
314
315
valYfromTastyIgnoreList:Setting[List[String]] =MultiStringSetting("-Yfrom-tasty-ignore-list", "file", "List of `tasty` files in jar files that will not be loaded when using -from-tasty")
0 commit comments