Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiler crash with SuspendException happening during PostTyper #18517

Closed
smarter opened this issue Sep 5, 2023 · 5 comments · Fixed by #21651
Closed

Compiler crash with SuspendException happening during PostTyper #18517

smarter opened this issue Sep 5, 2023 · 5 comments · Fixed by #21651
Assignees
Labels
Milestone

Comments

@smarter
Copy link
Member

smarter commented Sep 5, 2023

Compiler version

3.4.0-RC1-bin-20230901-89e8dba-NIGHTLY

Minimized code

Caller.scala:

package dummy

trait BG {
	val   description: { type Structure }
	type  Structure =  description.Structure
}

abstract class Caller extends BG {
	type Foo >: this.type <: this.type

	transparent inline def generate2() =
		${Macro.impl() }

	final val description = {
		generate2()
	}
}

Macro.scala:

package dummy

import scala.quoted.*

object Macro:
	def impl()(using quotes:Quotes) : Expr[Any] =
	  '{ null }

User.scala:

package dummy

trait User:
        final def bar(cell:Any) : Unit =
                (cell : cell.type) match
                        case c: (Caller & cell.type) => ()

Output (click arrow to expand)

Exception in thread "main" dotty.tools.dotc.CompilationUnit$SuspendException

No stack trace is shown since SuspendException extends NoStackTrace, if we remove that parent then we get:

        at dotty.tools.dotc.CompilationUnit.suspend(CompilationUnit.scala:97)
        at dotty.tools.dotc.typer.Namer$SuspendCompleter.complete(Namer.scala:1639)
        at dotty.tools.dotc.core.SymDenotations$SymDenotation.completeFrom(SymDenotations.scala:174)
        at dotty.tools.dotc.core.Denotations$Denotation.completeInfo$1(Denotations.scala:187)
        at dotty.tools.dotc.core.Denotations$Denotation.info(Denotations.scala:189)
        at dotty.tools.dotc.core.Denotations$SingleDenotation.signature(Denotations.scala:619)
        at dotty.tools.dotc.core.Denotations$SingleDenotation.matchesLoosely(Denotations.scala:1027)
        at dotty.tools.dotc.core.Denotations$SingleDenotation.matches(Denotations.scala:1011)
        at dotty.tools.dotc.core.Denotations$SingleDenotation.filterDisjoint(Denotations.scala:1061)
        at dotty.tools.dotc.core.Denotations$SingleDenotation.mapInherited(Denotations.scala:1056)
        at dotty.tools.dotc.core.Denotations$SingleDenotation.mapInherited(Denotations.scala:1053)
        at dotty.tools.dotc.core.SymDenotations$ClassDenotation.collect$1(SymDenotations.scala:2160)
        at dotty.tools.dotc.core.SymDenotations$ClassDenotation.collect$1(SymDenotations.scala:2156)
        at dotty.tools.dotc.core.SymDenotations$ClassDenotation.addInherited(SymDenotations.scala:2165)
        at dotty.tools.dotc.core.SymDenotations$ClassDenotation.computeMembersNamed(SymDenotations.scala:2150)
        at dotty.tools.dotc.core.SymDenotations$ClassDenotation.membersNamed(SymDenotations.scala:2117)
        at dotty.tools.dotc.core.SymDenotations$ClassDenotation.membersNamedNoShadowingBasedOnFlags(SymDenotations.scala:2140)
        at dotty.tools.dotc.core.SymDenotations$ClassDenotation.nonPrivateMembersNamed(SymDenotations.scala:2130)
        at dotty.tools.dotc.core.SymDenotations$ClassDenotation.findMember(SymDenotations.scala:2168)
        at dotty.tools.dotc.core.Types$Type.go$1(Types.scala:741)
        at dotty.tools.dotc.core.Types$Type.goThis$1(Types.scala:847)
        at dotty.tools.dotc.core.Types$Type.go$1(Types.scala:758)
        at dotty.tools.dotc.core.Types$Type.findMember(Types.scala:920)
        at dotty.tools.dotc.core.Types$Type.memberBasedOnFlags(Types.scala:714)
        at dotty.tools.dotc.core.Types$Type.nonPrivateMember(Types.scala:704)
        at dotty.tools.dotc.core.Types$NamedType.memberDenot(Types.scala:2474)
        at dotty.tools.dotc.core.Types$NamedType.reload$1(Types.scala:2807)
        at dotty.tools.dotc.core.Types$NamedType.withPrefix(Types.scala:2822)
        at dotty.tools.dotc.core.Types$NamedType.derivedSelect(Types.scala:2755)
        at dotty.tools.dotc.core.Types$TypeMap.derivedSelect(Types.scala:5755)
        at dotty.tools.dotc.core.Types$ApproximatingTypeMap.derivedSelect(Types.scala:6075)
        at dotty.tools.dotc.core.TypeOps$AsSeenFromMap.apply(TypeOps.scala:103)
        at dotty.tools.dotc.core.TypeOps$AsSeenFromMap.op$proxy2$1(TypeOps.scala:103)
        at dotty.tools.dotc.core.TypeOps$AsSeenFromMap.apply(TypeOps.scala:103)
        at dotty.tools.dotc.core.Types$TypeMap.op$proxy19$1(Types.scala:5839)
        at dotty.tools.dotc.core.Types$TypeMap.mapOver(Types.scala:5839)
        at dotty.tools.dotc.core.TypeOps$AsSeenFromMap.apply(TypeOps.scala:111)
        at dotty.tools.dotc.core.TypeOps$.asSeenFrom(TypeOps.scala:56)
        at dotty.tools.dotc.core.Types$Type.asSeenFrom(Types.scala:1074)
        at dotty.tools.dotc.core.Denotations$SingleDenotation.derived$1(Denotations.scala:1094)
        at dotty.tools.dotc.core.Denotations$SingleDenotation.computeAsSeenFrom(Denotations.scala:1121)
        at dotty.tools.dotc.core.Denotations$SingleDenotation.computeAsSeenFrom(Denotations.scala:1074)
        at dotty.tools.dotc.core.Denotations$PreDenotation.asSeenFrom(Denotations.scala:134)
        at dotty.tools.dotc.core.Denotations$SingleDenotation.mapInherited(Denotations.scala:1055)
        at dotty.tools.dotc.core.Denotations$SingleDenotation.mapInherited(Denotations.scala:1053)
        at dotty.tools.dotc.core.SymDenotations$ClassDenotation.collect$1(SymDenotations.scala:2160)
        at dotty.tools.dotc.core.SymDenotations$ClassDenotation.collect$1(SymDenotations.scala:2156)
        at dotty.tools.dotc.core.SymDenotations$ClassDenotation.addInherited(SymDenotations.scala:2165)
        at dotty.tools.dotc.core.SymDenotations$ClassDenotation.computeMembersNamed(SymDenotations.scala:2150)
        at dotty.tools.dotc.core.SymDenotations$ClassDenotation.membersNamed(SymDenotations.scala:2117)
        at dotty.tools.dotc.core.SymDenotations$ClassDenotation.findMember(SymDenotations.scala:2168)
        at dotty.tools.dotc.core.Types$Type.go$1(Types.scala:741)
        at dotty.tools.dotc.core.Types$Type.goThis$1(Types.scala:847)
        at dotty.tools.dotc.core.Types$Type.go$1(Types.scala:758)
        at dotty.tools.dotc.core.Types$Type.findMember(Types.scala:920)
        at dotty.tools.dotc.core.Types$Type.memberBasedOnFlags(Types.scala:714)
        at dotty.tools.dotc.core.Types$Type.member(Types.scala:698)
        at dotty.tools.dotc.core.Types$nonClassTypeNameFilter$.apply(Types.scala:6574)
        at dotty.tools.dotc.core.SymDenotations$ClassDenotation.maybeAdd$1(SymDenotations.scala:2346)
        at dotty.tools.dotc.core.SymDenotations$ClassDenotation.computeMemberNames$$anonfun$1$$anonfun$1(SymDenotations.scala:2352)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.immutable.Set$Set1.foreach(Set.scala:168)
        at dotty.tools.dotc.core.SymDenotations$ClassDenotation.computeMemberNames$$anonfun$1(SymDenotations.scala:2352)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.immutable.List.foreach(List.scala:333)
        at dotty.tools.dotc.core.SymDenotations$ClassDenotation.computeMemberNames(SymDenotations.scala:2352)
        at dotty.tools.dotc.core.SymDenotations$MemberNamesImpl.apply(SymDenotations.scala:2944)
        at dotty.tools.dotc.core.SymDenotations$ClassDenotation.memberNames(SymDenotations.scala:2341)
        at dotty.tools.dotc.core.Types$Type.memberNames(Types.scala:949)
        at dotty.tools.dotc.core.Types$Type.memberDenots(Types.scala:966)
        at dotty.tools.dotc.core.Types$Type.nonClassTypeMembers(Types.scala:1013)
        at dotty.tools.dotc.core.CheckRealizable.dotty$tools$dotc$core$CheckRealizable$$boundsRealizability(CheckRealizable.scala:154)
        at dotty.tools.dotc.core.CheckRealizable.realizability(CheckRealizable.scala:128)
        at dotty.tools.dotc.core.CheckRealizable$.realizability(CheckRealizable.scala:47)
        at dotty.tools.dotc.core.Types$Type.isStable(Types.scala:186)
        at dotty.tools.dotc.core.TypeOps$.isLegalPrefix(TypeOps.scala:127)
        at dotty.tools.dotc.core.TypeOps$AsSeenFromMap.toPrefix$1(TypeOps.scala:85)
        at dotty.tools.dotc.core.TypeOps$AsSeenFromMap.apply(TypeOps.scala:107)
        at dotty.tools.dotc.core.Types$TypeMap.mapOver(Types.scala:5843)
        at dotty.tools.dotc.core.TypeOps$AsSeenFromMap.apply(TypeOps.scala:111)
        at dotty.tools.dotc.core.TypeOps$.asSeenFrom(TypeOps.scala:56)
        at dotty.tools.dotc.core.Types$Type.asSeenFrom(Types.scala:1074)
        at dotty.tools.dotc.core.Denotations$SingleDenotation.derived$1(Denotations.scala:1094)
        at dotty.tools.dotc.core.Denotations$SingleDenotation.computeAsSeenFrom(Denotations.scala:1121)
        at dotty.tools.dotc.core.Denotations$SingleDenotation.computeAsSeenFrom(Denotations.scala:1074)
        at dotty.tools.dotc.core.Denotations$PreDenotation.asSeenFrom(Denotations.scala:134)
        at dotty.tools.dotc.core.SymDenotations$ClassDenotation.findMember(SymDenotations.scala:2172)
        at dotty.tools.dotc.core.Types$Type.go$1(Types.scala:741)
        at dotty.tools.dotc.core.Types$Type.goAnd$1(Types.scala:896)
        at dotty.tools.dotc.core.Types$Type.go$1(Types.scala:775)
        at dotty.tools.dotc.core.Types$Type.findMember(Types.scala:920)
        at dotty.tools.dotc.core.Types$Type.memberBasedOnFlags(Types.scala:714)
        at dotty.tools.dotc.core.Types$Type.member(Types.scala:698)
        at dotty.tools.dotc.typer.Checking$.checkNonCyclicInherited$$anonfun$1(Checking.scala:468)
        at scala.collection.immutable.List.foreach(List.scala:333)
        at dotty.tools.dotc.typer.Checking$.checkNonCyclicInherited(Checking.scala:476)
        at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform(PostTyper.scala:450)
        at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1537)
        at dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:49)
        at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform(PostTyper.scala:476)
        at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1583)
        at dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:49)
        at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform(PostTyper.scala:439)
        at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1551)
        at dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:49)
        at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform(PostTyper.scala:287)
        at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform$$anonfun$1(Trees.scala:1635)
        at scala.collection.immutable.List.mapConserve(List.scala:472)
        at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1635)
        at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transformSub(Trees.scala:1639)
        at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1549)
        at dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:49)
        at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform(PostTyper.scala:499)
        at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1595)
        at dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:40)
        at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform$$anonfun$5(PostTyper.scala:393)
        at dotty.tools.dotc.transform.SuperAccessors.wrapDefDef(SuperAccessors.scala:229)
        at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform(PostTyper.scala:393)
        at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1250)
        at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1250)
        at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transformStats(PostTyper.scala:508)
        at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1252)
        at dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:47)
        at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform$$anonfun$4$$anonfun$1(PostTyper.scala:378)
        at dotty.tools.dotc.transform.SuperAccessors.wrapTemplate(SuperAccessors.scala:214)
        at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform$$anonfun$4(PostTyper.scala:378)
        at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.withNoCheckNews(PostTyper.scala:109)
        at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform(PostTyper.scala:380)
        at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1597)
        at dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:40)
        at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform(PostTyper.scala:435)
        at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1250)
        at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1250)
        at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transformStats(PostTyper.scala:508)
        at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1252)
        at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1608)
        at dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:40)
        at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform(PostTyper.scala:499)
        at dotty.tools.dotc.transform.MacroTransform.run(MacroTransform.scala:18)
        at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:327)
        at scala.collection.immutable.List.map(List.scala:250)
        at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:331)
        at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:246)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1321)
        at dotty.tools.dotc.Run.runPhases$1(Run.scala:262)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:270)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:279)
        at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:71)
        at dotty.tools.dotc.Run.compileUnits(Run.scala:279)
        at dotty.tools.dotc.Run.compileSources(Run.scala:194)
        at dotty.tools.dotc.Run.compile(Run.scala:179)
        at dotty.tools.dotc.Driver.doCompile(Driver.scala:37)
        at dotty.tools.dotc.Driver.process(Driver.scala:197)
        at dotty.tools.dotc.Driver.process(Driver.scala:165)
        at dotty.tools.dotc.Driver.process(Driver.scala:177)
        at dotty.tools.dotc.Driver.main(Driver.scala:207)

So a symbol is completed during PostTyper by calling SuspendCompleter#complete which throws SuspendException, but we only catch SuspendException in Typer and Inliner. Explicitly catching the exception in MacroTransform.scala fixes the error:

diff --git compiler/src/dotty/tools/dotc/transform/MacroTransform.scala compiler/src/dotty/tools/dotc/transform/MacroTransform.scala
index 7bb7ed365eb..325e32d0de6 100644
--- compiler/src/dotty/tools/dotc/transform/MacroTransform.scala
+++ compiler/src/dotty/tools/dotc/transform/MacroTransform.scala
@@ -15,7 +15,8 @@ abstract class MacroTransform extends Phase {

   override def run(using Context): Unit = {
     val unit = ctx.compilationUnit
-    unit.tpdTree = atPhase(transformPhase)(newTransformer.transform(unit.tpdTree))
+    try unit.tpdTree = atPhase(transformPhase)(newTransformer.transform(unit.tpdTree))
+    catch case _: CompilationUnit.SuspendException => ()
   }

   protected def newTransformer(using Context): Transformer

But it's not clear to me if this is a valid way to use SuspendException, wdyt @odersky ?

@odersky
Copy link
Contributor

odersky commented Oct 1, 2023

I think it's probably OK. Maybe only do it for PostTyper, and leave generral macro transforms alone?

@odersky odersky assigned smarter and unassigned odersky Oct 1, 2023
@smarter
Copy link
Member Author

smarter commented Oct 1, 2023

I would prefer to do it for all phases unless we can guarantee that SuspendCompleter will always be completed at a specific phase?

@odersky
Copy link
Contributor

odersky commented Oct 1, 2023

It should be completed after inlining, I think.

@smarter
Copy link
Member Author

smarter commented Sep 26, 2024

It should be completed after inlining, I think.

In fact it can happen later than inlining, here's a crash I just got in PruneErasedDefs#transformSym indirectly called from Mixin#tranformSym:

[error] ## Exception when compiling 17 sources to /home/smarter/forj/sw/forj_core/target/scala-3.6.0-RC1-bin-SNAPSHOT/classes
[error] dotty.tools.dotc.CompilationUnit$SuspendException
[error] dotty.tools.dotc.CompilationUnit.suspend(CompilationUnit.scala:110)
[error] dotty.tools.dotc.typer.Namer$SuspendCompleter.complete(Namer.scala:1746)
[error] dotty.tools.dotc.core.SymDenotations$SymDenotation.completeFrom(SymDenotations.scala:175)
[error] dotty.tools.dotc.core.Denotations$Denotation.completeInfo$1(Denotations.scala:190)
[error] dotty.tools.dotc.core.Denotations$Denotation.info(Denotations.scala:192)
[error] dotty.tools.dotc.core.SymDenotations$SymDenotation.ensureCompleted(SymDenotations.scala:393)
[error] dotty.tools.dotc.core.SymDenotations$SymDenotation.flags(SymDenotations.scala:66)
[error] dotty.tools.dotc.core.SymDenotations$SymDenotation.isOneOf(SymDenotations.scala:116)
[error] dotty.tools.dotc.core.SymDenotations$SymDenotation.isEffectivelyErased(SymDenotations.scala:1033)
[error] dotty.tools.dotc.transform.PruneErasedDefs.transformSym(PruneErasedDefs.scala:39)
[error] dotty.tools.dotc.core.DenotTransformers$SymTransformer.transform(DenotTransformers.scala:72)
[error] dotty.tools.dotc.core.DenotTransformers$SymTransformer.transform$(DenotTransformers.scala:67)
[error] dotty.tools.dotc.transform.PruneErasedDefs.transform(PruneErasedDefs.scala:26)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.goForward$1(Denotations.scala:838)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:884)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.goForward$1(Denotations.scala:855)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:884)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.goForward$1(Denotations.scala:855)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:884)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.goForward$1(Denotations.scala:855)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:884)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.goForward$1(Denotations.scala:855)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:884)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.goForward$1(Denotations.scala:855)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:884)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.goForward$1(Denotations.scala:855)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:884)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.goForward$1(Denotations.scala:855)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:884)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.goForward$1(Denotations.scala:855)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:884)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.goForward$1(Denotations.scala:855)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:884)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.goForward$1(Denotations.scala:855)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:884)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.goForward$1(Denotations.scala:855)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:884)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.goForward$1(Denotations.scala:855)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:884)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.goForward$1(Denotations.scala:855)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:884)
[error] dotty.tools.dotc.core.Symbols$Symbol.recomputeDenot(Symbols.scala:124)
[error] dotty.tools.dotc.core.Symbols$Symbol.computeDenot(Symbols.scala:118)
[error] dotty.tools.dotc.core.Symbols$Symbol.denot(Symbols.scala:109)
[error] dotty.tools.dotc.core.Symbols$.toDenot(Symbols.scala:544)
[error] dotty.tools.dotc.transform.Mixin.needsTraitSetter(Mixin.scala:176)
[error] dotty.tools.dotc.transform.Mixin.transformSym$$anonfun$1(Mixin.scala:155)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error] scala.collection.immutable.List.foreach(List.scala:334)
[error] dotty.tools.dotc.core.Scopes$Scope.foreach(Scopes.scala:94)
[error] dotty.tools.dotc.transform.Mixin.transformSym(Mixin.scala:159)
[error] dotty.tools.dotc.core.DenotTransformers$SymTransformer.transform(DenotTransformers.scala:72)
[error] dotty.tools.dotc.core.DenotTransformers$SymTransformer.transform$(DenotTransformers.scala:67)
[error] dotty.tools.dotc.transform.Mixin.transform(Mixin.scala:115)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.goForward$1(Denotations.scala:838)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:884)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.goForward$1(Denotations.scala:855)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:884)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.goForward$1(Denotations.scala:855)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:884)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.goForward$1(Denotations.scala:855)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:884)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.goForward$1(Denotations.scala:855)
[error] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:884)
[error] dotty.tools.dotc.core.Types$NamedType.computeDenot(Types.scala:2481)
[error] dotty.tools.dotc.core.Types$NamedType.denot(Types.scala:2444)
[error] dotty.tools.dotc.core.Types$NamedType.info(Types.scala:2433)
[error] dotty.tools.dotc.core.TypeComparer.compareNamed$1(TypeComparer.scala:306)
[error] dotty.tools.dotc.core.TypeComparer.firstTry$1(TypeComparer.scala:357)
[error] dotty.tools.dotc.core.TypeComparer.recur(TypeComparer.scala:1594)
[error] dotty.tools.dotc.core.TypeComparer.isSubType(TypeComparer.scala:229)
[error] dotty.tools.dotc.core.TypeComparer.isSubType(TypeComparer.scala:239)
[error] dotty.tools.dotc.core.TypeComparer.topLevelSubType(TypeComparer.scala:147)
[error] dotty.tools.dotc.core.TypeComparer$.topLevelSubType(TypeComparer.scala:3342)
[error] dotty.tools.dotc.core.Types$Type.$less$colon$less(Types.scala:1127)
[error] dotty.tools.dotc.ast.tpd$TreeOps$.ensureConforms$extension(tpd.scala:1047)
[error] dotty.tools.dotc.transform.Memoize.adaptToField$1(Memoize.scala:133)
[error] dotty.tools.dotc.transform.Memoize.transformDefDef(Memoize.scala:148)
[error] dotty.tools.dotc.transform.MegaPhase.goDefDef(MegaPhase.scala:1041)
[error] dotty.tools.dotc.transform.MegaPhase.goDefDef(MegaPhase.scala:1042)
[error] dotty.tools.dotc.transform.MegaPhase.goDefDef(MegaPhase.scala:1042)
[error] dotty.tools.dotc.transform.MegaPhase.goDefDef(MegaPhase.scala:1042)
[error] dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:268)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:452)
[error] dotty.tools.dotc.transform.MegaPhase.loop$1(MegaPhase.scala:465)
[error] dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:465)
[error] dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:376)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:454)
[error] dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:272)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:452)
[error] dotty.tools.dotc.transform.MegaPhase.loop$1(MegaPhase.scala:465)
[error] dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:465)
[error] dotty.tools.dotc.transform.MegaPhase.mapPackage$1(MegaPhase.scala:396)
[error] dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:399)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:454)
[error] dotty.tools.dotc.transform.MegaPhase.loop$1(MegaPhase.scala:465)
[error] dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:465)
[error] dotty.tools.dotc.transform.MegaPhase.mapPackage$1(MegaPhase.scala:396)
[error] dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:399)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:454)
[error] dotty.tools.dotc.transform.MegaPhase.transformUnit(MegaPhase.scala:481)
[error] dotty.tools.dotc.transform.MegaPhase.run(MegaPhase.scala:493)
[error] dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:380)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error] scala.collection.immutable.List.foreach(List.scala:334)
[error] dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:373)
[error] dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:343)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error] scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1323)
[error] dotty.tools.dotc.Run.runPhases$1(Run.scala:336)
[error] dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:384)
[error] dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:396)
[error] dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:69)
[error] dotty.tools.dotc.Run.compileUnits(Run.scala:396)
[error] dotty.tools.dotc.Run.compileSources(Run.scala:282)
[error] dotty.tools.dotc.Run.compile(Run.scala:267)
[error] dotty.tools.dotc.Driver.doCompile(Driver.scala:37)
[error] dotty.tools.xsbt.CompilerBridgeDriver.run(CompilerBridgeDriver.java:141)
[error] dotty.tools.xsbt.CompilerBridge.run(CompilerBridge.java:22)
[error] sbt.internal.inc.AnalyzingCompiler.compile(AnalyzingCompiler.scala:91)
[error] sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$7(MixedAnalyzingCompiler.scala:194)
[error] scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
[error] sbt.internal.inc.MixedAnalyzingCompiler.timed(MixedAnalyzingCompiler.scala:249)
[error] sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4(MixedAnalyzingCompiler.scala:184)
[error] sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4$adapted(MixedAnalyzingCompiler.scala:164)
[error] sbt.internal.inc.JarUtils$.withPreviousJar(JarUtils.scala:239)
[error] sbt.internal.inc.MixedAnalyzingCompiler.compileScala$1(MixedAnalyzingCompiler.scala:164)
[error] sbt.internal.inc.MixedAnalyzingCompiler.compile(MixedAnalyzingCompiler.scala:212)
[error] sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1(IncrementalCompilerImpl.scala:534)
[error] sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1$adapted(IncrementalCompilerImpl.scala:534)
[error] sbt.internal.inc.Incremental$.$anonfun$apply$3(Incremental.scala:178)
[error] sbt.internal.inc.Incremental$.$anonfun$apply$3$adapted(Incremental.scala:176)
[error] sbt.internal.inc.Incremental$$anon$2.run(Incremental.scala:454)
[error] sbt.internal.inc.IncrementalCommon$CycleState.next(IncrementalCommon.scala:117)
[error] sbt.internal.inc.IncrementalCommon$$anon$1.next(IncrementalCommon.scala:56)
[error] sbt.internal.inc.IncrementalCommon$$anon$1.next(IncrementalCommon.scala:52)
[error] sbt.internal.inc.IncrementalCommon.cycle(IncrementalCommon.scala:265)
[error] sbt.internal.inc.Incremental$.$anonfun$incrementalCompile$8(Incremental.scala:409)
[error] sbt.internal.inc.Incremental$.withClassfileManager(Incremental.scala:496)
[error] sbt.internal.inc.Incremental$.incrementalCompile(Incremental.scala:396)
[error] sbt.internal.inc.Incremental$.apply(Incremental.scala:170)
[error] sbt.internal.inc.IncrementalCompilerImpl.compileInternal(IncrementalCompilerImpl.scala:534)
[error] sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileIncrementally$1(IncrementalCompilerImpl.scala:488)
[error] sbt.internal.inc.IncrementalCompilerImpl.handleCompilationError(IncrementalCompilerImpl.scala:332)
[error] sbt.internal.inc.IncrementalCompilerImpl.compileIncrementally(IncrementalCompilerImpl.scala:425)
[error] sbt.internal.inc.IncrementalCompilerImpl.compile(IncrementalCompilerImpl.scala:137)
[error] sbt.Defaults$.compileIncrementalTaskImpl(Defaults.scala:2427)
[error] sbt.Defaults$.$anonfun$compileIncrementalTask$2(Defaults.scala:2377)
[error] sbt.internal.server.BspCompileTask$.$anonfun$compute$1(BspCompileTask.scala:41)
[error] sbt.internal.io.Retry$.apply(Retry.scala:47)
[error] sbt.internal.io.Retry$.apply(Retry.scala:29)
[error] sbt.internal.io.Retry$.apply(Retry.scala:24)
[error] sbt.internal.server.BspCompileTask$.compute(BspCompileTask.scala:41)
[error] sbt.Defaults$.$anonfun$compileIncrementalTask$1(Defaults.scala:2375)
[error] scala.Function1.$anonfun$compose$1(Function1.scala:49)
[error] sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:63)
[error] sbt.std.Transform$$anon$4.work(Transform.scala:69)
[error] sbt.Execute.$anonfun$submit$2(Execute.scala:283)
[error] sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:24)
[error] sbt.Execute.work(Execute.scala:292)
[error] sbt.Execute.$anonfun$submit$1(Execute.scala:283)
[error] sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:265)
[error] sbt.CompletionService$$anon$2.call(CompletionService.scala:65)
[error] java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
[error] java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
[error] java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
[error] java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
[error] java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
[error] java.base/java.lang.Thread.run(Thread.java:1583)

The change I originally proposed in MacroTransform is not enough to handle this since PruneErasedDefs is a MiniPhase, I tried catching it in Phase:

diff --git compiler/src/dotty/tools/dotc/core/Phases.scala compiler/src/dotty/tools/dotc/core/Phases.scala
index 7f925b0fc3..73fd170959 100644
--- compiler/src/dotty/tools/dotc/core/Phases.scala
+++ compiler/src/dotty/tools/dotc/core/Phases.scala
@@ -378,9 +378,11 @@ object Phases {
               ()
             else
               run
-          catch case ex: Throwable if !ctx.run.enrichedErrorMessage =>
-            println(ctx.run.enrichErrorMessage(s"unhandled exception while running $phaseName on $unit"))
-            throw ex
+          catch
+            case _: CompilationUnit.SuspendException => // this unit will be run again in `Run#compileSuspendedUnits`
+            case ex: Throwable if !ctx.run.enrichedErrorMessage =>
+              println(ctx.run.enrichErrorMessage(s"unhandled exception while running $phaseName on $unit"))
+              throw ex
           finally ctx.run.advanceUnit()
           buf += unitCtx.compilationUnit
         end if

But that seems to lead to an infinite loop in my case.

@smarter
Copy link
Member Author

smarter commented Sep 26, 2024

Ok, here's a patch that seems to do the correct thing, I'll submit a PR:

diff --git compiler/src/dotty/tools/dotc/core/Phases.scala compiler/src/dotty/tools/dotc/core/Phases.scala
index 7f925b0fc3..a438c9fcf5 100644
--- compiler/src/dotty/tools/dotc/core/Phases.scala
+++ compiler/src/dotty/tools/dotc/core/Phases.scala
@@ -378,14 +378,18 @@ object Phases {
               ()
             else
               run
-          catch case ex: Throwable if !ctx.run.enrichedErrorMessage =>
-            println(ctx.run.enrichErrorMessage(s"unhandled exception while running $phaseName on $unit"))
-            throw ex
+            buf += unitCtx.compilationUnit
+          catch
+            case _: CompilationUnit.SuspendException => // this unit will be run again in `Run#compileSuspendedUnits`
+            case ex: Throwable if !ctx.run.enrichedErrorMessage =>
+              println(ctx.run.enrichErrorMessage(s"unhandled exception while running $phaseName on $unit"))
+              throw ex
           finally ctx.run.advanceUnit()
-          buf += unitCtx.compilationUnit
         end if
       end for
-      buf.result()
+      val res = buf.result()
+      ctx.run.nn.checkSuspendedUnits(res)
+      res
     end runOn

     /** Convert a compilation unit's tree to a string; can be overridden */

smarter added a commit to smarter/dotty that referenced this issue Sep 26, 2024
It should never reach the user, but if it does because of a bug like in scala#18517,
we should have a flag to find out where it came from.
smarter added a commit to smarter/dotty that referenced this issue Sep 26, 2024
In the added test case this happens in PostTyper, but I've seen it happen in
Mixin too.

Fixes scala#18517.
smarter added a commit to dotty-staging/dotty that referenced this issue Sep 26, 2024
It should never reach the user, but if it does because of a bug like in scala#18517,
we should have a flag to find out where it came from.
smarter added a commit to dotty-staging/dotty that referenced this issue Sep 26, 2024
In the added test case this happens in PostTyper, but I've seen it happen in
Mixin too.

Fixes scala#18517.
smarter added a commit to dotty-staging/dotty that referenced this issue Sep 26, 2024
Previously we only supported suspension in Typer and Inliner. In the added test
case this happens in PostTyper, but I've seen it happen in Mixin too.

Fixes scala#18517.
smarter added a commit to dotty-staging/dotty that referenced this issue Sep 26, 2024
Previously we only supported suspension in Typer and Inliner. In the added test
case this happens in PostTyper, but I've seen it happen in Mixin too.

Fixes scala#18517.
smarter added a commit to dotty-staging/dotty that referenced this issue Sep 26, 2024
It should never reach the user, but if it does because of a bug like in scala#18517,
we should have a flag to find out where it came from.
smarter added a commit that referenced this issue Sep 27, 2024
Previously we only supported suspension in Typer and Inliner. In the
added test
case this happens in PostTyper, but I've seen it happen in Mixin too.

Fixes #18517.
@WojciechMazur WojciechMazur added this to the 3.6.0 milestone Oct 8, 2024
WojciechMazur added a commit to scala/scala3-lts that referenced this issue Dec 5, 2024
Previously we only supported suspension in Typer and Inliner. In the added test
case this happens in PostTyper, but I've seen it happen in Mixin too.

Fixes scala#18517.

[Cherry-picked bac8781][modified]
WojciechMazur added a commit that referenced this issue Dec 9, 2024
Previously we only supported suspension in Typer and Inliner. In the added test
case this happens in PostTyper, but I've seen it happen in Mixin too.

Fixes #18517.

[Cherry-picked bac8781][modified]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants