Skip to content

Compiler crash with SuspendException happening during PostTyper #18517

Closed
@smarter

Description

@smarter

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 ?

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions