Skip to content

Commit 985aaa1

Browse files
Backport "Handle assertion error in TyperState" to 3.7.4 (#24028)
Backports #23665 to the 3.7.4. PR submitted by the release tooling. [skip ci]
2 parents c94cb5c + 2f053b1 commit 985aaa1

File tree

3 files changed

+19
-5
lines changed

3 files changed

+19
-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
@@ -28,6 +28,8 @@ object TyperState {
2828

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

31+
class BadTyperStateAssertion(msg: String) extends AssertionError(msg)
32+
3133
extension (ts: TyperState)
3234
def snapshot()(using Context): Snapshot =
3335
(ts.constraint, ts.ownedVars, ts.upLevels)
@@ -43,7 +45,7 @@ object TyperState {
4345
}
4446

4547
class TyperState() {
46-
import TyperState.LevelMap
48+
import TyperState.{LevelMap, BadTyperStateAssertion}
4749

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

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ trait Migrations:
162162
private def checkParentheses(tree: Tree, pt: FunProto)(using Context): Boolean =
163163
val ptSpan = pt.args.head.span
164164
ptSpan.exists
165+
&& tree.span.exists
165166
&& ctx.source.content
166167
.slice(tree.span.end, ptSpan.start)
167168
.exists(_ == '(')

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

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

4383+
// Try to constrain the result using `pt1`, but back out if a BadTyperStateAssertion
4384+
// is thrown. TODO Find out why the bad typer state arises and prevent it. The try-catch
4385+
// is a temporary hack to keep projects compiling that would fail otherwise due to
4386+
// searching more arguments to instantiate implicits (PR #23532). A failing project
4387+
// is described in issue #23609.
4388+
def tryConstrainResult(pt: Type): Boolean =
4389+
try constrainResult(tree.symbol, wtp, pt)
4390+
catch case ex: TyperState.BadTyperStateAssertion => false
4391+
43834392
arg.tpe match
43844393
case failed: SearchFailureType if canProfitFromMoreConstraints =>
43854394
val pt1 = pt.deepenProtoTrans
4386-
if (pt1 `ne` pt) && (pt1 ne sharpenedPt) && constrainResult(tree.symbol, wtp, pt1)
4387-
then return implicitArgs(formals, argIndex, pt1)
4395+
if (pt1 `ne` pt) && (pt1 ne sharpenedPt) && tryConstrainResult(pt1) then
4396+
return implicitArgs(formals, argIndex, pt1)
43884397
case _ =>
43894398

43904399
arg.tpe match

0 commit comments

Comments
 (0)