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

assertion failed: <: X[?] & Xa[?] when searching for a higher-kinded type variable with an intersection #13987

Closed
neko-kai opened this issue Nov 21, 2021 · 1 comment · Fixed by #14068
Assignees
Milestone

Comments

@neko-kai
Copy link
Contributor

Compiler version

3.1.2-RC1-bin-20211118-2b37257-NIGHTLY

Minimized code

Scastie: https://scastie.scala-lang.org/Gx3EdTaQTgSTYJQLI42dqg

sealed trait Xa[T]
sealed trait Mu[T] extends Xa[T]
object Xa {
  // bad
  implicit def convertMu[X[x] <: Xa[x], A, B](implicit t: X[A] with Xa[A]): X[B] = t.asInstanceOf[X[B]]
  // good
//  implicit def convertMu[X[x] <: Xa[x], A, B](implicit t: X[A] with Mu[A]): X[B] = t.asInstanceOf[X[B]]
}
object Mu {
  implicit def mu: Mu[Int] = new Mu[Int] {}
}

object App extends App {
  def constrain(a: Mu[Long]): Unit = println(a)
  constrain(Xa.convertMu)
}

Output

java.lang.AssertionError: assertion failed: <: X[?] & Xa[?] / TypeBounds(TypeRef(...

Stack trace
java.lang.AssertionError: assertion failed:  <: X[?] & Xa[?] / TypeBounds(TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Nothing),AppliedType(TypeParamRef(X),List(TypeBounds(TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Nothing),TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Any))))) & AppliedType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),trait Xa),List(TypeBounds(TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Nothing),TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Any))))
	at scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
	at dotty.tools.dotc.core.Types$AndType$.apply(Types.scala:3171)
	at dotty.tools.dotc.core.Types$AndType$.make(Types.scala:3206)
	at dotty.tools.dotc.core.Types$AndType.derivedAndType(Types.scala:3152)
	at dotty.tools.dotc.core.Types$TypeMap.derivedAndType(Types.scala:5376)
	at dotty.tools.dotc.core.Types$TypeMap.mapOver(Types.scala:5500)
	at dotty.tools.dotc.typer.Implicits$$anon$5.apply(Implicits.scala:476)
	at dotty.tools.dotc.typer.Implicits$NoMatchingImplicits.clarify(Implicits.scala:479)
	at dotty.tools.dotc.printing.RefinedPrinter.toTextCore(RefinedPrinter.scala:401)
	at dotty.tools.dotc.printing.RefinedPrinter.toText$$anonfun$2(RefinedPrinter.scala:714)
	at dotty.tools.dotc.printing.MessageLimiter.controlled(MessageLimiter.scala:23)
	at dotty.tools.dotc.printing.PlainPrinter.controlled(PlainPrinter.scala:35)
	at dotty.tools.dotc.printing.RefinedPrinter.toText(RefinedPrinter.scala:785)
	at dotty.tools.dotc.ast.Trees$Tree.toText(Trees.scala:189)
	at dotty.tools.dotc.printing.Printer.toText$$anonfun$1(Printer.scala:173)
	at scala.collection.immutable.List.map(List.scala:246)
	at scala.collection.immutable.List.map(List.scala:79)
	at dotty.tools.dotc.printing.Printer.toText(Printer.scala:173)
	at dotty.tools.dotc.printing.Printer.toTextGlobal$$anonfun$2(Printer.scala:181)
	at dotty.tools.dotc.printing.Printer.atPrec(Printer.scala:43)
	at dotty.tools.dotc.printing.Printer.toTextGlobal(Printer.scala:181)
	at dotty.tools.dotc.printing.RefinedPrinter.toTextCore(RefinedPrinter.scala:436)
	at dotty.tools.dotc.printing.RefinedPrinter.toText$$anonfun$2(RefinedPrinter.scala:714)
	at dotty.tools.dotc.printing.MessageLimiter.controlled(MessageLimiter.scala:23)
	at dotty.tools.dotc.printing.PlainPrinter.controlled(PlainPrinter.scala:35)
	at dotty.tools.dotc.printing.RefinedPrinter.toText(RefinedPrinter.scala:785)
	at dotty.tools.dotc.ast.Trees$Tree.toText(Trees.scala:189)
	at dotty.tools.dotc.printing.Showable.show(Showable.scala:23)
	at dotty.tools.dotc.printing.Showable.show$(Showable.scala:9)
	at dotty.tools.dotc.ast.Trees$Tree.show(Trees.scala:48)
	at dotty.tools.dotc.typer.ImplicitSearchError.formatMsg(ErrorReporting.scala:284)
	at dotty.tools.dotc.typer.ImplicitSearchError.missingArgMsg(ErrorReporting.scala:266)
	at dotty.tools.dotc.typer.Implicits.missingArgMsg(Implicits.scala:892)
	at dotty.tools.dotc.typer.Implicits.missingArgMsg$(Implicits.scala:776)
	at dotty.tools.dotc.typer.Typer.missingArgMsg(Typer.scala:113)
	at dotty.tools.dotc.typer.Typer.issueErrors$1$$anonfun$1$$anonfun$1(Typer.scala:3472)
	at dotty.tools.dotc.reporting.NoExplanation.msg(Message.scala:139)
	at dotty.tools.dotc.reporting.Message.message(Message.scala:87)
	at dotty.tools.dotc.reporting.Message.isNonSensical(Message.scala:99)
	at dotty.tools.dotc.reporting.HideNonSensicalMessages.isHidden(HideNonSensicalMessages.scala:16)
	at dotty.tools.dotc.reporting.HideNonSensicalMessages.isHidden$(HideNonSensicalMessages.scala:10)
	at dotty.tools.dotc.reporting.AbstractReporter.isHidden(AbstractReporter.scala:8)
	at dotty.tools.dotc.reporting.Reporter.issueUnconfigured(Reporter.scala:153)
	at dotty.tools.dotc.reporting.Reporter.go$1(Reporter.scala:177)
	at dotty.tools.dotc.reporting.Reporter.issueIfNotSuppressed(Reporter.scala:195)
	at dotty.tools.dotc.reporting.Reporter.report(Reporter.scala:198)
	at dotty.tools.dotc.reporting.Reporter.flush$$anonfun$1(Reporter.scala:243)
	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.reporting.Reporter.flush(Reporter.scala:243)
	at dotty.tools.dotc.core.TyperState.commit(TyperState.scala:144)
	at dotty.tools.dotc.typer.Applications.fail$1(Applications.scala:980)
	at dotty.tools.dotc.typer.Applications.realApply$1$$anonfun$4$$anonfun$1(Applications.scala:986)
	at scala.Option.getOrElse(Option.scala:201)
	at dotty.tools.dotc.typer.Applications.realApply$1$$anonfun$4(Applications.scala:987)
	at dotty.tools.dotc.typer.Typer.tryEither(Typer.scala:3059)
	at dotty.tools.dotc.typer.Applications.realApply$1(Applications.scala:988)
	at dotty.tools.dotc.typer.Applications.typedApply(Applications.scala:1026)
	at dotty.tools.dotc.typer.Applications.typedApply$(Applications.scala:317)
	at dotty.tools.dotc.typer.Typer.typedApply(Typer.scala:113)
	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2784)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2847)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2912)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2916)
	at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:2965)
	at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:2988)
	at dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:2429)
	at dotty.tools.dotc.typer.Typer.typedTypeOrClassDef$1(Typer.scala:2772)
	at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2776)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2846)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2912)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2916)
	at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:2938)
	at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:2988)
	at dotty.tools.dotc.typer.Typer.typedPackageDef(Typer.scala:2556)
	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2817)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2847)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2912)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2916)
	at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3032)
	at dotty.tools.dotc.typer.TyperPhase.liftedTree1$1(TyperPhase.scala:47)
	at dotty.tools.dotc.typer.TyperPhase.typeCheck$$anonfun$1(TyperPhase.scala:53)
	at dotty.tools.dotc.core.Phases$Phase.monitor(Phases.scala:411)
	at dotty.tools.dotc.typer.TyperPhase.typeCheck(TyperPhase.scala:54)
	at dotty.tools.dotc.typer.TyperPhase.runOn$$anonfun$3(TyperPhase.scala:88)
	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:88)
	at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:261)
	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:1323)
	at dotty.tools.dotc.Run.runPhases$1(Run.scala:272)
	at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:280)
	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
	at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:68)
	at dotty.tools.dotc.Run.compileUnits(Run.scala:289)
	at dotty.tools.dotc.Run.compileSources(Run.scala:222)
	at dotty.tools.dotc.Run.compile(Run.scala:206)
	at dotty.tools.dotc.Driver.doCompile(Driver.scala:39)
	at dotty.tools.xsbt.CompilerBridgeDriver.run(CompilerBridgeDriver.java:88)
	at dotty.tools.xsbt.CompilerBridge.run(CompilerBridge.java:22)
	at sbt.internal.inc.AnalyzingCompiler.compile(AnalyzingCompiler.scala:91)
	at sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$7(MixedAnalyzingCompiler.scala:192)
	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
	at sbt.internal.inc.MixedAnalyzingCompiler.timed(MixedAnalyzingCompiler.scala:247)
	at sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4(MixedAnalyzingCompiler.scala:182)
	at sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4$adapted(MixedAnalyzingCompiler.scala:163)
	at sbt.internal.inc.JarUtils$.withPreviousJar(JarUtils.scala:239)
	at sbt.internal.inc.MixedAnalyzingCompiler.compileScala$1(MixedAnalyzingCompiler.scala:163)
	at sbt.internal.inc.MixedAnalyzingCompiler.compile(MixedAnalyzingCompiler.scala:210)
	at sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1(IncrementalCompilerImpl.scala:528)
	at sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1$adapted(IncrementalCompilerImpl.scala:528)
	at sbt.internal.inc.Incremental$.$anonfun$apply$5(Incremental.scala:175)
	at sbt.internal.inc.Incremental$.$anonfun$apply$5$adapted(Incremental.scala:173)
	at sbt.internal.inc.Incremental$$anon$2.run(Incremental.scala:459)
	at sbt.internal.inc.IncrementalCommon$CycleState.next(IncrementalCommon.scala:116)
	at sbt.internal.inc.IncrementalCommon$$anon$1.next(IncrementalCommon.scala:56)
	at sbt.internal.inc.IncrementalCommon$$anon$1.next(IncrementalCommon.scala:52)
	at sbt.internal.inc.IncrementalCommon.cycle(IncrementalCommon.scala:263)
	at sbt.internal.inc.Incremental$.$anonfun$incrementalCompile$8(Incremental.scala:414)
	at sbt.internal.inc.Incremental$.withClassfileManager(Incremental.scala:501)
	at sbt.internal.inc.Incremental$.incrementalCompile(Incremental.scala:401)
	at sbt.internal.inc.Incremental$.apply(Incremental.scala:167)
	at sbt.internal.inc.IncrementalCompilerImpl.compileInternal(IncrementalCompilerImpl.scala:528)
	at sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileIncrementally$1(IncrementalCompilerImpl.scala:482)
	at sbt.internal.inc.IncrementalCompilerImpl.handleCompilationError(IncrementalCompilerImpl.scala:332)
	at sbt.internal.inc.IncrementalCompilerImpl.compileIncrementally(IncrementalCompilerImpl.scala:420)
	at sbt.internal.inc.IncrementalCompilerImpl.compile(IncrementalCompilerImpl.scala:137)
	at sbt.Defaults$.compileIncrementalTaskImpl(Defaults.scala:2357)
	at sbt.Defaults$.$anonfun$compileIncrementalTask$2(Defaults.scala:2314)
	at sbt.internal.io.Retry$.apply(Retry.scala:46)
	at sbt.internal.io.Retry$.apply(Retry.scala:28)
	at sbt.internal.io.Retry$.apply(Retry.scala:23)
	at sbt.internal.server.BspCompileTask$.compute(BspCompileTask.scala:31)
	at sbt.Defaults$.$anonfun$compileIncrementalTask$1(Defaults.scala:2310)
	at scala.Function1.$anonfun$compose$1(Function1.scala:49)
	at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62)
	at sbt.std.Transform$$anon$4.work(Transform.scala:68)
	at sbt.Execute.$anonfun$submit$2(Execute.scala:282)
	at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:23)
	at sbt.Execute.work(Execute.scala:291)
	at sbt.Execute.$anonfun$submit$1(Execute.scala:282)
	at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:265)
	at sbt.CompletionService$$anon$2.call(CompletionService.scala:64)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

Expectation

Expected to work, as in Scala 2: https://scastie.scala-lang.org/qpkqt46xTDOV6unUEAs2Dg

This is related to #13986 - it's a variation of the minimized code there, were an intersection is used to try to bring the implicits in Xa/Mu into implicit scope. The variation using with Xa[A] fails to bring implicits into scope AND causes the assertion failure above. Adding with Mu[A] succeeds, but shouldn't be necessary as the type variable X[x] has sufficient bounds to bring in Mu companion object regardless of the intersection (#13986)

@prolativ
Copy link
Contributor

Interestingly the compiler won't crash internally and we'll get a different compilation error if we make convertMu non-implicit:

no implicit argument of type X[A] & Xa[A] was found for parameter t of method convertMu in object Xa
 
where:     A is a type variable
           X is a type variable with constraint <: Mu
   constrain(Xa.convertMu)
                         ^

@odersky odersky self-assigned this Dec 7, 2021
odersky added a commit to dotty-staging/dotty that referenced this issue Dec 7, 2021
olsdavis pushed a commit to olsdavis/dotty that referenced this issue Apr 4, 2022
@Kordyjan Kordyjan added this to the 3.1.2 milestone Aug 2, 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