Skip to content

Commit 023e01d

Browse files
authored
Merge pull request #555 from scala/backport-lts-3.3-23665
Backport "Handle assertion error in TyperState" to 3.3 LTS
2 parents 8db88af + ab25ded commit 023e01d

File tree

2 files changed

+18
-5
lines changed

2 files changed

+18
-5
lines changed

compiler/src/dotty/tools/dotc/core/TyperState.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ object TyperState {
2727

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

30+
class BadTyperStateAssertion(msg: String) extends AssertionError(msg)
31+
3032
extension (ts: TyperState)
3133
def snapshot()(using Context): Snapshot =
3234
(ts.constraint, ts.ownedVars, ts.upLevels)
@@ -42,7 +44,7 @@ object TyperState {
4244
}
4345

4446
class TyperState() {
45-
import TyperState.LevelMap
47+
import TyperState.{LevelMap, BadTyperStateAssertion}
4648

4749
private var myId: Int = _
4850
def id: Int = myId
@@ -268,8 +270,10 @@ class TyperState() {
268270
*/
269271
private def includeVar(tvar: TypeVar)(using Context): Unit =
270272
val oldState = tvar.owningState.nn.get
271-
assert(oldState == null || !oldState.isCommittable,
272-
i"$this attempted to take ownership of $tvar which is already owned by committable $oldState")
273+
274+
if oldState != null && oldState.isCommittable then
275+
throw BadTyperStateAssertion(
276+
i"$this attempted to take ownership of $tvar which is already owned by committable $oldState")
273277
tvar.owningState = new WeakReference(this)
274278
ownedVars += tvar
275279

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3869,11 +3869,20 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
38693869
// But in this case we should search with additional arguments typed only if there
38703870
// is no default argument.
38713871

3872+
// Try to constrain the result using `pt1`, but back out if a BadTyperStateAssertion
3873+
// is thrown. TODO Find out why the bad typer state arises and prevent it. The try-catch
3874+
// is a temporary hack to keep projects compiling that would fail otherwise due to
3875+
// searching more arguments to instantiate implicits (PR #23532). A failing project
3876+
// is described in issue #23609.
3877+
def tryConstrainResult(pt: Type): Boolean =
3878+
try constrainResult(tree.symbol, wtp, pt)
3879+
catch case ex: TyperState.BadTyperStateAssertion => false
3880+
38723881
arg.tpe match
38733882
case failed: SearchFailureType if canProfitFromMoreConstraints =>
38743883
val pt1 = pt.deepenProtoTrans
3875-
if (pt1 `ne` pt) && (pt1 ne sharpenedPt) && constrainResult(tree.symbol, wtp, pt1)
3876-
then return implicitArgs(formals, argIndex, pt1)
3884+
if (pt1 `ne` pt) && (pt1 ne sharpenedPt) && tryConstrainResult(pt1) then
3885+
return implicitArgs(formals, argIndex, pt1)
38773886
case _ =>
38783887

38793888
arg.tpe match

0 commit comments

Comments
 (0)