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 when deriving enums #15183

Closed
WojciechMazur opened this issue May 13, 2022 · 4 comments · Fixed by #15333
Closed

Compiler crash when deriving enums #15183

WojciechMazur opened this issue May 13, 2022 · 4 comments · Fixed by #15333
Labels
area:typer itype:bug itype:crash regression This worked in a previous version but doesn't anymore

Comments

@WojciechMazur
Copy link
Contributor

WojciechMazur commented May 13, 2022

Compiler version

3.1.2
Fails with 3.2.0-RC1-bin-20220512-9dbe2d3-NIGHTLY
Works with 3.1.1

Minimized code

Based on:

decoder.scala

import scala.deriving._

sealed trait Decoder[T]
object Decoder {
  given Decoder[Double] = ???

  inline given summonEmptyTuple[H]: Tuple.Map[EmptyTuple.type, Decoder] =
    EmptyTuple

  inline given summonTuple[H, T <: Tuple](using hd: Decoder[H], td: Tuple.Map[T, Decoder]): Tuple.Map[H *: T, Decoder] =
    hd *: td

  inline given derived[T](using m: Mirror.Of[T], d: Tuple.Map[m.MirroredElemTypes, Decoder]): Decoder[T] = ???
}

test.scala

//> using scala "3.1.1"
// Fails in each cases below
enum Env derives Decoder:
  case Local,Sit,Prod

enum Env2 derives Decoder:
  case Local()
  case Sit()
  case Prod()

enum Shape derives Decoder:
  case Rectangle(width: Double, height: Double)
  case Circle(radius: Double)

decoder.scala and test.scala needs to be compiled seperetly

scalac decoder.scala
scalac test.scala

Output (click arrow to expand)

  dotty git:(main)  ./bin/scalac test.scala 
exception occurred while typechecking test.scala
exception occurred while compiling test.scala
java.lang.NullPointerException while compiling test.scala
Exception in thread "main" java.lang.NullPointerException
        at dotty.tools.dotc.core.TypeOps$.simplify(TypeOps.scala:148)
        at dotty.tools.dotc.core.Types$Type.simplified(Types.scala:1894)
        at dotty.tools.dotc.core.ConstraintHandling.instanceType(ConstraintHandling.scala:557)
        at dotty.tools.dotc.core.ConstraintHandling.instanceType$(ConstraintHandling.scala:27)
        at dotty.tools.dotc.core.TypeComparer.instanceType(TypeComparer.scala:30)
        at dotty.tools.dotc.core.TypeComparer$.instanceType(TypeComparer.scala:2817)
        at dotty.tools.dotc.core.Types$TypeVar.instantiate(Types.scala:4753)
        at dotty.tools.dotc.typer.Inferencing$IsFullyDefinedAccumulator.instantiate(Inferencing.scala:167)
        at dotty.tools.dotc.typer.Inferencing$IsFullyDefinedAccumulator.apply(Inferencing.scala:189)
        at dotty.tools.dotc.typer.Inferencing$IsFullyDefinedAccumulator.apply(Inferencing.scala:174)
        at dotty.tools.dotc.core.Types$TypeAccumulator.op$proxy23$1(Types.scala:6019)
        at dotty.tools.dotc.core.Types$TypeAccumulator.foldArgs$3(Types.scala:6019)
        at dotty.tools.dotc.core.Types$TypeAccumulator.foldOver(Types.scala:6023)
        at dotty.tools.dotc.typer.Inferencing$IsFullyDefinedAccumulator.apply(Inferencing.scala:199)
        at dotty.tools.dotc.typer.Inferencing$IsFullyDefinedAccumulator.process(Inferencing.scala:210)
        at dotty.tools.dotc.typer.Inferencing$.isFullyDefined(Inferencing.scala:34)
        at dotty.tools.dotc.core.TypeOps$.simplify(TypeOps.scala:142)
        at dotty.tools.dotc.core.TypeOps$.mapArgs$1(TypeOps.scala:145)
        at dotty.tools.dotc.core.TypeOps$.mapArgs$1(TypeOps.scala:145)
        at dotty.tools.dotc.core.TypeOps$.simplify(TypeOps.scala:145)
        at dotty.tools.dotc.core.Types$Type.simplified(Types.scala:1894)
        at dotty.tools.dotc.core.TrackingTypeComparer.matchCase$1(TypeComparer.scala:2932)
        at dotty.tools.dotc.core.TrackingTypeComparer.recur$2(TypeComparer.scala:2947)
        at dotty.tools.dotc.core.TrackingTypeComparer.op$proxy73$1(TypeComparer.scala:2977)
        at dotty.tools.dotc.core.TrackingTypeComparer.matchCases(TypeComparer.scala:2978)
        at dotty.tools.dotc.core.Types$MatchType.matchCases$1(Types.scala:4870)
        at dotty.tools.dotc.core.Types$MatchType.reduced$$anonfun$1(Types.scala:4879)
        at dotty.tools.dotc.core.TypeComparer.inSubComparer(TypeComparer.scala:2683)
        at dotty.tools.dotc.core.TypeComparer.tracked(TypeComparer.scala:2693)
        at dotty.tools.dotc.core.TypeComparer$.tracked(TypeComparer.scala:2850)
        at dotty.tools.dotc.core.Types$MatchType.reduced(Types.scala:4879)
        at dotty.tools.dotc.core.Types$MatchType.tryNormalize(Types.scala:4828)
        at dotty.tools.dotc.core.Types$Type.normalized(Types.scala:1430)
        at dotty.tools.dotc.core.Types$AppliedType.superType(Types.scala:4161)
        at dotty.tools.dotc.core.TypeComparer.$anonfun$4(TypeComparer.scala:1120)
        at scala.Function0.apply$mcZ$sp(Function0.scala:39)
        at dotty.tools.dotc.core.TypeComparer.tryAlso(TypeComparer.scala:1669)
        at dotty.tools.dotc.core.TypeComparer.loop$1(TypeComparer.scala:1120)
        at dotty.tools.dotc.core.TypeComparer.isMatchingApply$1(TypeComparer.scala:1137)
        at dotty.tools.dotc.core.TypeComparer.compareAppliedType2$1(TypeComparer.scala:1207)
        at dotty.tools.dotc.core.TypeComparer.thirdTry$1(TypeComparer.scala:571)
        at dotty.tools.dotc.core.TypeComparer.secondTry$1(TypeComparer.scala:504)
        at dotty.tools.dotc.core.TypeComparer.firstTry$1(TypeComparer.scala:381)
        at dotty.tools.dotc.core.TypeComparer.recur(TypeComparer.scala:1335)
        at dotty.tools.dotc.core.TypeComparer.isSubType(TypeComparer.scala:192)
        at dotty.tools.dotc.core.TypeComparer.isSubType(TypeComparer.scala:202)
        at dotty.tools.dotc.core.TypeComparer.topLevelSubType(TypeComparer.scala:126)
        at dotty.tools.dotc.core.TypeComparer.necessarySubType(TypeComparer.scala:137)
        at dotty.tools.dotc.core.TypeComparer$.necessarySubType(TypeComparer.scala:2750)
        at dotty.tools.dotc.typer.ProtoTypes$Compatibility.necessarilyCompatible(ProtoTypes.scala:46)
        at dotty.tools.dotc.typer.ProtoTypes$Compatibility.necessarilyCompatible$(ProtoTypes.scala:25)
        at dotty.tools.dotc.typer.Typer.necessarilyCompatible(Typer.scala:117)
        at dotty.tools.dotc.typer.ProtoTypes$Compatibility.constrainResult(ProtoTypes.scala:96)
        at dotty.tools.dotc.typer.ProtoTypes$Compatibility.constrainResult$(ProtoTypes.scala:25)
        at dotty.tools.dotc.typer.Typer.constrainResult(Typer.scala:117)
        at dotty.tools.dotc.typer.ProtoTypes$Compatibility.constrainResult(ProtoTypes.scala:113)
        at dotty.tools.dotc.typer.ProtoTypes$Compatibility.constrainResult$(ProtoTypes.scala:25)
        at dotty.tools.dotc.typer.Typer.constrainResult(Typer.scala:117)
        at dotty.tools.dotc.typer.Typer.adaptNoArgs$1(Typer.scala:3807)
        at dotty.tools.dotc.typer.Typer.adapt1(Typer.scala:4043)
        at dotty.tools.dotc.typer.Typer.adapt(Typer.scala:3377)
        at dotty.tools.dotc.typer.Typer.readapt$1(Typer.scala:3388)
        at dotty.tools.dotc.typer.Typer.adapt1(Typer.scala:4030)
        at dotty.tools.dotc.typer.Typer.adapt(Typer.scala:3377)
        at dotty.tools.dotc.typer.Implicits.typedImplicit(Implicits.scala:1053)
        at dotty.tools.dotc.typer.Implicits.typedImplicit$(Implicits.scala:785)
        at dotty.tools.dotc.typer.Typer.typedImplicit(Typer.scala:117)
        at dotty.tools.dotc.typer.Implicits$ImplicitSearch.tryImplicit(Implicits.scala:1173)
        at dotty.tools.dotc.typer.Implicits$ImplicitSearch.rank$1(Implicits.scala:1272)
        at dotty.tools.dotc.typer.Implicits$ImplicitSearch.searchImplicit(Implicits.scala:1442)
        at dotty.tools.dotc.typer.Implicits$ImplicitSearch.searchImplicit(Implicits.scala:1470)
        at dotty.tools.dotc.typer.Implicits$ImplicitSearch.searchImplicit(Implicits.scala:1478)
        at dotty.tools.dotc.typer.Implicits$ImplicitSearch.bestImplicit(Implicits.scala:1503)
        at dotty.tools.dotc.typer.Implicits.inferImplicit(Implicits.scala:997)
        at dotty.tools.dotc.typer.Implicits.inferImplicit$(Implicits.scala:785)
        at dotty.tools.dotc.typer.Typer.inferImplicit(Typer.scala:117)
        at dotty.tools.dotc.typer.Implicits.inferImplicitArg(Implicits.scala:851)
        at dotty.tools.dotc.typer.Implicits.inferImplicitArg$(Implicits.scala:785)
        at dotty.tools.dotc.typer.Typer.inferImplicitArg(Typer.scala:117)
        at dotty.tools.dotc.typer.Typer.implicitArgs$1(Typer.scala:3499)
        at dotty.tools.dotc.typer.Typer.inferArgsAfter$1(Typer.scala:3497)
        at dotty.tools.dotc.typer.Typer.implicitArgs$1(Typer.scala:3532)
        at dotty.tools.dotc.typer.Typer.addImplicitArgs$1(Typer.scala:3535)
        at dotty.tools.dotc.typer.Typer.adaptNoArgsImplicitMethod$1(Typer.scala:3611)
        at dotty.tools.dotc.typer.Typer.adaptNoArgs$1(Typer.scala:3809)
        at dotty.tools.dotc.typer.Typer.adapt1(Typer.scala:4043)
        at dotty.tools.dotc.typer.Typer.adapt(Typer.scala:3377)
        at dotty.tools.dotc.typer.Typer.readapt$1(Typer.scala:3388)
        at dotty.tools.dotc.typer.Typer.adapt1(Typer.scala:4030)
        at dotty.tools.dotc.typer.Typer.adapt(Typer.scala:3377)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2994)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2998)
        at dotty.tools.dotc.typer.Deriving$Deriver.typeclassInstance$1$$anonfun$1(Deriving.scala:295)
        at dotty.tools.dotc.typer.Deriving$Deriver.syntheticDef$1(Deriving.scala:301)
        at dotty.tools.dotc.typer.Deriving$Deriver.syntheticDefs$$anonfun$1(Deriving.scala:304)
        at scala.collection.StrictOptimizedIterableOps.map(StrictOptimizedIterableOps.scala:100)
        at scala.collection.StrictOptimizedIterableOps.map$(StrictOptimizedIterableOps.scala:87)
        at scala.collection.mutable.ListBuffer.map(ListBuffer.scala:39)
        at dotty.tools.dotc.typer.Deriving$Deriver.syntheticDefs(Deriving.scala:304)
        at dotty.tools.dotc.typer.Deriving$Deriver.finalize(Deriving.scala:309)
        at dotty.tools.dotc.typer.Typer.finalize$1(Typer.scala:3064)
        at dotty.tools.dotc.typer.Typer.$anonfun$65(Typer.scala:3071)
        at scala.collection.immutable.List.mapConserve(List.scala:472)
        at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3071)
        at dotty.tools.dotc.typer.Typer.typedPackageDef(Typer.scala:2636)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2898)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2929)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2994)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2998)
        at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3114)
        at dotty.tools.dotc.typer.TyperPhase.typeCheck$$anonfun$1(TyperPhase.scala:43)
        at dotty.tools.dotc.typer.TyperPhase.typeCheck$$anonfun$adapted$1(TyperPhase.scala:50)
        at scala.Function0.apply$mcV$sp(Function0.scala:39)
        at dotty.tools.dotc.core.Phases$Phase.monitor(Phases.scala:414)
        at dotty.tools.dotc.typer.TyperPhase.typeCheck(TyperPhase.scala:50)
        at dotty.tools.dotc.typer.TyperPhase.runOn$$anonfun$3(TyperPhase.scala:84)
        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.typer.TyperPhase.runOn(TyperPhase.scala:84)
        at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:225)
        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:1328)
        at dotty.tools.dotc.Run.runPhases$1(Run.scala:236)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:244)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:253)
        at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:68)
        at dotty.tools.dotc.Run.compileUnits(Run.scala:253)
        at dotty.tools.dotc.Run.compileSources(Run.scala:186)
        at dotty.tools.dotc.Run.compile(Run.scala:170)
        at dotty.tools.dotc.Driver.doCompile(Driver.scala:35)
        at dotty.tools.dotc.Driver.process(Driver.scala:195)
        at dotty.tools.dotc.Driver.process(Driver.scala:163)
        at dotty.tools.dotc.Driver.process(Driver.scala:175)
        at dotty.tools.dotc.Driver.main(Driver.scala:205)
        at dotty.tools.dotc.Main.main(Main.scala)
@WojciechMazur WojciechMazur added itype:bug itype:crash stat:needs triage Every issue needs to have an "area" and "itype" label labels May 13, 2022
@griggt
Copy link
Contributor

griggt commented May 13, 2022

This errors (but does not crash) on 3.1.2. The errors started with 3ab18a9.

The crashing started with #15036, which was backported to 3.1.3-RC3, so it crashes there as well.

@Kordyjan Kordyjan added this to the 3.1.3 milestone May 16, 2022
@prolativ
Copy link
Contributor

Minimized further:

//> using scala "3.2.0-RC1-bin-20220512-9dbe2d3-NIGHTLY"

import scala.deriving._

enum Env:
  case Local,Sit,Prod

sealed trait Decoder[T]
object Decoder:
  given summonTuple[H, T <: Tuple]: Tuple.Map[H *: T, Decoder] = ???
  def derived(using m: Mirror.Of[Env], d: Tuple.Map[m.MirroredElemTypes, Decoder]): Decoder[Env] = ???

val x = Decoder.derived

@prolativ prolativ added area:typer and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels May 16, 2022
@Kordyjan Kordyjan removed this from the 3.1.3 milestone May 24, 2022
griggt added a commit to griggt/dotty that referenced this issue May 30, 2022
@griggt
Copy link
Contributor

griggt commented May 30, 2022

This appears to have been fixed by a combination of #15310 (the NPE) and #15036 (the match type reduction failure).

It still crashes on 3.1.3-RC4 however. Is it too late to backport #15310?

@griggt griggt added the regression This worked in a previous version but doesn't anymore label May 30, 2022
bishabosha added a commit that referenced this issue May 30, 2022
griggt added a commit to griggt/dotty that referenced this issue May 31, 2022
griggt added a commit to griggt/dotty that referenced this issue May 31, 2022
bishabosha pushed a commit to dotty-staging/dotty that referenced this issue Oct 18, 2022
odersky added a commit to dotty-staging/dotty that referenced this issue Apr 3, 2024
We now try to reduce match types before computing their contributions to an implicit scope.
This avoids problems where joint and separate compilations gave different results, as in
scala#20071 and scala#15183.

Background: If a match type is reducible to a type R the compiler is free to replace the
match type with R. That should not affect the implicit scope computation. Consequently,
we have to try to reduce match types before computing their contributions to an implicit scope.

scala#20071 and scala#15183 are really the same problem. Both used to compile in sequence and both
gave an implicit not found error when two files were compiled together.

In scala#15183 a weird match type was constructed intentionally, in order to avoid an otherwise
necessary given import. That exploited a bug in the compiler which this PR fixes.
@odersky
Copy link
Contributor

odersky commented Apr 3, 2024

This will unfortunately no longer work.

odersky added a commit to dotty-staging/dotty that referenced this issue Apr 3, 2024
We now try to reduce match types before computing their contributions to an implicit scope.
This avoids problems where joint and separate compilations gave different results, as in
scala#20071 and scala#15183.

Background: If a match type is reducible to a type R the compiler is free to replace the
match type with R. That should not affect the implicit scope computation. Consequently,
we have to try to reduce match types before computing their contributions to an implicit scope.

scala#20071 and scala#15183 are really the same problem. Both used to compile in sequence and both
gave an implicit not found error when two files were compiled together.

In scala#15183 a weird match type was constructed intentionally, in order to avoid an otherwise
necessary given import. That exploited a bug in the compiler which this PR fixes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:typer itype:bug itype:crash regression This worked in a previous version but doesn't anymore
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants