Skip to content

Selectable + opaque types cause crash #15448

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

Closed
rcano opened this issue Jun 14, 2022 · 2 comments · Fixed by #15451
Closed

Selectable + opaque types cause crash #15448

rcano opened this issue Jun 14, 2022 · 2 comments · Fixed by #15451

Comments

@rcano
Copy link

rcano commented Jun 14, 2022

Compiler version

3.1.3 as well as 3.2-nightly

Minimized code

object SelectableBreaks {
  object opaques {
    opaque type Struct = Int

    opaque type Pointer[S <: Struct] <: S = S
    object Pointer {
      implicit class PointerSelectable[S <: Struct](private val f: Pointer[S]) extends Selectable {
        def selectDynamic(name: String): Any = ???
        def applyDynamic(name: String)(): Any = ???
      }
      // extension [S <: Struct](f: Pointer[S]) {
      //   def selectDynamic(name: String): Any = ???
      //   def applyDynamic(name: String)(): Any = ???
      // }
    }
  }
  import opaques.*

  type Break = Struct {
    def boom(): Nothing
  }

  def makeBreak(): Pointer[Break] = ???

  makeBreak().boom() // <-- selecting boom() here crashes the compiler. Crashes happens whether it's select or apply dynamic.
}

Output (click arrow to expand)

exception occurred while compiling /tmp/proj/src/main/scala/proj/selectable-breaks.scala
java.lang.AssertionError: assertion failed: no owner from  <none>/ <none> in proj.SelectableBreaks.makeBreak().boom while compiling /tmp/proj/src/main/scala/proj/selectable-breaks.scala
 ## Exception when compiling 44 sources to /tmp/proj/target/scala-3.1.2/classes
 java.lang.AssertionError: assertion failed: no owner from  <none>/ <none> in proj.SelectableBreaks.makeBreak().boom
 scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
 dotty.tools.dotc.transform.Erasure$Typer.typedSelect(Erasure.scala:698)
 dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2779)
 dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2871)
 dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:121)
 dotty.tools.dotc.typer.Typer.typed(Typer.scala:2937)
 dotty.tools.dotc.typer.Typer.typed(Typer.scala:2941)
 dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3057)
 dotty.tools.dotc.transform.Erasure$Typer.typedApply(Erasure.scala:814)
 dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2809)
 dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2872)
 dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:121)
 dotty.tools.dotc.typer.Typer.typed(Typer.scala:2937)
 dotty.tools.dotc.typer.Typer.typed(Typer.scala:2941)
 dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:2990)
 dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3013)
 dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1030)
 dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:2454)
 dotty.tools.dotc.transform.Erasure$Typer.typedClassDef(Erasure.scala:1020)
 dotty.tools.dotc.typer.Typer.typedTypeOrClassDef$1(Typer.scala:2797)
 dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2801)
 dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2871)
 dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:121)
 dotty.tools.dotc.typer.Typer.typed(Typer.scala:2937)
 dotty.tools.dotc.typer.Typer.typed(Typer.scala:2941)
 dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:2963)
 dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3013)
 dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1030)
 dotty.tools.dotc.typer.Typer.typedPackageDef(Typer.scala:2581)
 dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2842)
 dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2872)
 dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:121)
 dotty.tools.dotc.typer.Typer.typed(Typer.scala:2937)
 dotty.tools.dotc.typer.Typer.typed(Typer.scala:2941)
 dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3057)
 dotty.tools.dotc.transform.Erasure.run(Erasure.scala:144)
 dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:308)
 scala.collection.immutable.List.map(List.scala:246)
 dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:309)
 dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:259)
 scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
 scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
 scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1328)
 dotty.tools.dotc.Run.runPhases$1(Run.scala:270)
 dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:278)
 scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
 dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:68)
 dotty.tools.dotc.Run.compileUnits(Run.scala:287)
 dotty.tools.dotc.Run.compileSources(Run.scala:220)
 dotty.tools.dotc.Run.compile(Run.scala:204)
 dotty.tools.dotc.Driver.doCompile(Driver.scala:39)
 dotty.tools.xsbt.CompilerBridgeDriver.run(CompilerBridgeDriver.java:88)
 dotty.tools.xsbt.CompilerBridge.run(CompilerBridge.java:22)
 sbt.internal.inc.AnalyzingCompiler.compile(AnalyzingCompiler.scala:91)
 sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$7(MixedAnalyzingCompiler.scala:192)
 scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
 sbt.internal.inc.MixedAnalyzingCompiler.timed(MixedAnalyzingCompiler.scala:247)
 sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4(MixedAnalyzingCompiler.scala:182)
 sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4$adapted(MixedAnalyzingCompiler.scala:163)
 sbt.internal.inc.JarUtils$.withPreviousJar(JarUtils.scala:239)
 sbt.internal.inc.MixedAnalyzingCompiler.compileScala$1(MixedAnalyzingCompiler.scala:163)
 sbt.internal.inc.MixedAnalyzingCompiler.compile(MixedAnalyzingCompiler.scala:210)
 sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1(IncrementalCompilerImpl.scala:528)
 sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1$adapted(IncrementalCompilerImpl.scala:528)
 sbt.internal.inc.Incremental$.$anonfun$apply$5(Incremental.scala:177)
 sbt.internal.inc.Incremental$.$anonfun$apply$5$adapted(Incremental.scala:175)
 sbt.internal.inc.Incremental$$anon$2.run(Incremental.scala:461)
 sbt.internal.inc.IncrementalCommon$CycleState.next(IncrementalCommon.scala:116)
 sbt.internal.inc.IncrementalCommon$$anon$1.next(IncrementalCommon.scala:56)
 sbt.internal.inc.IncrementalCommon$$anon$1.next(IncrementalCommon.scala:52)
 sbt.internal.inc.IncrementalCommon.cycle(IncrementalCommon.scala:263)
 sbt.internal.inc.Incremental$.$anonfun$incrementalCompile$8(Incremental.scala:416)
 sbt.internal.inc.Incremental$.withClassfileManager(Incremental.scala:503)
 sbt.internal.inc.Incremental$.incrementalCompile(Incremental.scala:403)
 sbt.internal.inc.Incremental$.apply(Incremental.scala:169)
 sbt.internal.inc.IncrementalCompilerImpl.compileInternal(IncrementalCompilerImpl.scala:528)
 sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileIncrementally$1(IncrementalCompilerImpl.scala:482)
 sbt.internal.inc.IncrementalCompilerImpl.handleCompilationError(IncrementalCompilerImpl.scala:332)
 sbt.internal.inc.IncrementalCompilerImpl.compileIncrementally(IncrementalCompilerImpl.scala:420)
 sbt.internal.inc.IncrementalCompilerImpl.compile(IncrementalCompilerImpl.scala:137)
 sbt.Defaults$.compileIncrementalTaskImpl(Defaults.scala:2366)
 sbt.Defaults$.$anonfun$compileIncrementalTask$2(Defaults.scala:2316)
 sbt.internal.server.BspCompileTask$.$anonfun$compute$1(BspCompileTask.scala:30)
 sbt.internal.io.Retry$.apply(Retry.scala:46)
 sbt.internal.io.Retry$.apply(Retry.scala:28)
 sbt.internal.io.Retry$.apply(Retry.scala:23)
 sbt.internal.server.BspCompileTask$.compute(BspCompileTask.scala:30)
 sbt.Defaults$.$anonfun$compileIncrementalTask$1(Defaults.scala:2314)
 scala.Function1.$anonfun$compose$1(Function1.scala:49)
 sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62)
 sbt.std.Transform$$anon$4.work(Transform.scala:68)
 sbt.Execute.$anonfun$submit$2(Execute.scala:282)
 sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:23)
 sbt.Execute.work(Execute.scala:291)
 sbt.Execute.$anonfun$submit$1(Execute.scala:282)
 sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:265)
 sbt.CompletionService$$anon$2.call(CompletionService.scala:64)
 java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
 java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
 java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
 java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
 java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
 java.base/java.lang.Thread.run(Thread.java:833)

Note: both options, with the implicit class or with extension methods (which is commented out) cause the same crash.

@rcano rcano added itype:bug itype:crash stat:needs triage Every issue needs to have an "area" and "itype" label labels Jun 14, 2022
@KacperFKorban
Copy link
Member

I managed to minimize it quite a bit. Turns out that it doesn't require opaque types nor Selectable.

type Pointer[S <: Int] <: S

type Break = Int {
  def boom: Unit
}

def test = {
  val ptrBreak: Pointer[Break] = ???
  ptrBreak.boom // boom crashes the compiler
}

odersky added a commit to dotty-staging/dotty that referenced this issue Jun 15, 2022
When looking at AppliedTypes, we want to go to the supertype (which is the dealiased type or upper bound),
not the underlying type (which is the type constructor).

This is the second bug in a week caused by a confusion of unerlying and supertype for AppliedTypes. We
should do an audit of the codebase to see whether there are more cases like this.

Fixes scala#15448
@odersky
Copy link
Contributor

odersky commented Jun 15, 2022

@KacperFKorban Good minimization. I verified that it gets rejected with 80364f8.

odersky added a commit to dotty-staging/dotty that referenced this issue Jun 15, 2022
When looking at AppliedTypes, we want to go to the supertype (which is the dealiased type or upper bound),
not the underlying type (which is the type constructor).

This is the second bug in a week caused by a confusion of unerlying and supertype for AppliedTypes. We
should do an audit of the codebase to see whether there are more cases like this.

Fixes scala#15448
odersky added a commit to dotty-staging/dotty that referenced this issue Jun 15, 2022
When looking at AppliedTypes, we want to go to the supertype (which is the dealiased type or upper bound),
not the underlying type (which is the type constructor).

This is the second bug in a week caused by a confusion of unerlying and supertype for AppliedTypes. We
should do an audit of the codebase to see whether there are more cases like this.

Fixes scala#15448
odersky added a commit to dotty-staging/dotty that referenced this issue Jun 15, 2022
When looking at AppliedTypes, we want to go to the supertype (which is the dealiased type or upper bound),
not the underlying type (which is the type constructor).

This is the second bug in a week caused by a confusion of unerlying and supertype for AppliedTypes. We
should do an audit of the codebase to see whether there are more cases like this.

Fixes scala#15448
@odersky odersky removed the stat:needs triage Every issue needs to have an "area" and "itype" label label Jun 15, 2022
bishabosha pushed a commit to dotty-staging/dotty that referenced this issue Oct 18, 2022
When looking at AppliedTypes, we want to go to the supertype (which is the dealiased type or upper bound),
not the underlying type (which is the type constructor).

This is the second bug in a week caused by a confusion of unerlying and supertype for AppliedTypes. We
should do an audit of the codebase to see whether there are more cases like this.

Fixes scala#15448
@Kordyjan Kordyjan added this to the 3.2.0 milestone Aug 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants