Skip to content

REPL regression with opaque type and extension methods #9202

Closed
@FabioPinheiro

Description

@FabioPinheiro

If we put opaque type, type parameters, and extension methods on the same object.
We got strange behavior after importing the object into the REPL.

The initial discussion on Gitter. Involve @yilinwei @som-snytt @smarter
https://gitter.im/lampepfl/dotty?at=5eeaac6be0e5673398bc888c

Both examples here have the code minimized on:
https://github.com/FabioPinheiro/cats-money/tree/dotty-repl-AssertionError

The work fine on dottyVersion 0.24.0-RC1. But have this behavior on versions "0.25.0-bin-20200609-a3b417b-NIGHTLY" and "0.26.0-bin-20200617-6b03fbd-NIGHTLY".

Example A

"exception while typing"

Minimized code

https://github.com/FabioPinheiro/cats-money/blob/dotty-repl-AssertionError/modules/core/src/main/scala/experiments/Ex2Definition.scala

In a file

object Ex2Definition {
  opaque type SomeUnrelatedOpaque = Int
  class A[T](val d: T)
  extension Ex2SameNameToBeToImport on [T] (x: A[T]) { def value: T = x.d }
}

In REPL (sbt console)

import experiments.Ex2Definition._
A(1d).value

Output (click arrow to expand)

sbt:root> core/console

scala> import experiments.Ex2Definition._

scala> A(1d).value                                                                                                                                                                                                                            
exception while typing new experiments.Ex2Definition.A of class class dotty.tools.dotc.ast.Trees$New # 1255532
exception while typing new experiments.Ex2Definition.A of class class dotty.tools.dotc.ast.Trees$Select # 1255533
exception while typing new experiments.Ex2Definition.A[Double] of class class dotty.tools.dotc.ast.Trees$TypeApply # 1255559
exception while typing new experiments.Ex2Definition.A[Double](1.0) of class class dotty.tools.dotc.ast.Trees$Apply # 1255560
exception while typing experiments.Ex2Definition.Ex2SameNameToBeToImport.value[Double](
  new experiments.Ex2Definition.A[Double](1.0)
) of class class dotty.tools.dotc.ast.Trees$Apply # 1255561
exception while typing def res0: Double = 
  experiments.Ex2Definition.Ex2SameNameToBeToImport.value[Double](
    new experiments.Ex2Definition.A[Double](1.0)
  ) of class class dotty.tools.dotc.ast.Trees$DefDef # 1255564
exception while typing @scala.annotation.internal.SourceFile("rs$line$2") final module class rs$line$2$
  (
) extends Object(), Serializable {
  private def writeReplace(): AnyRef = 
    new scala.runtime.ModuleSerializationProxy(classOf[rs$line$2.type])
  def res0: Double = 
    experiments.Ex2Definition.Ex2SameNameToBeToImport.value[Double](
      new experiments.Ex2Definition.A[Double](1.0)
    )
} of class class dotty.tools.dotc.ast.Trees$TypeDef # 1255566
exception while typing package <empty> {
  final lazy module val rs$line$2: rs$line$2$ = new rs$line$2$()
  @scala.annotation.internal.SourceFile("rs$line$2") final module class 
    rs$line$2$
  () extends Object(), Serializable {
    private def writeReplace(): AnyRef = 
      new scala.runtime.ModuleSerializationProxy(classOf[rs$line$2.type])
    def res0: Double = 
      experiments.Ex2Definition.Ex2SameNameToBeToImport.value[Double](
        new experiments.Ex2Definition.A[Double](1.0)
      )
  }
} of class class dotty.tools.dotc.ast.Trees$PackageDef # 1255567
[error] (run-main-d) java.lang.AssertionError: assertion failed: denotation module class Ex2Definition$ invalid in run 2. ValidFor: Period(1..22, run = 3)
[error] java.lang.AssertionError: assertion failed: denotation module class Ex2Definition$ invalid in run 2. ValidFor: Period(1..22, run = 3)
[error]         at dotty.DottyPredef$.assertFail(DottyPredef.scala:17)
[error]         at dotty.tools.dotc.core.Denotations$SingleDenotation.updateValidity(Denotations.scala:688)
[error]         at dotty.tools.dotc.core.Denotations$SingleDenotation.bringForward(Denotations.scala:718)
[error]         at dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:773)
[error]         at dotty.tools.dotc.core.Symbols$Symbol.recomputeDenot(Symbols.scala:498)
[error]         at dotty.tools.dotc.core.Symbols$Symbol.computeDenot(Symbols.scala:493)
[error]         at dotty.tools.dotc.core.Symbols$Symbol.denot(Symbols.scala:487)
[error]         at dotty.tools.dotc.core.SymDenotations.stillValidInOwner(SymDenotations.scala:64)
[error]         at dotty.tools.dotc.core.Contexts$Context.stillValidInOwner(Contexts.scala:79)
[error]         at dotty.tools.dotc.core.SymDenotations.stillValid(SymDenotations.scala:60)
[error]         at dotty.tools.dotc.core.Contexts$Context.stillValid(Contexts.scala:79)
[error]         at dotty.tools.dotc.core.Denotations$SingleDenotation.bringForward(Denotations.scala:718)
[error]         at dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:773)
[error]         at dotty.tools.dotc.core.Symbols$Symbol.recomputeDenot(Symbols.scala:498)
[error]         at dotty.tools.dotc.core.Symbols$Symbol.computeDenot(Symbols.scala:493)
[error]         at dotty.tools.dotc.core.Symbols$Symbol.denot(Symbols.scala:487)
[error]         at dotty.tools.dotc.core.Symbols$.toDenot(Symbols.scala:859)
[error]         at dotty.tools.dotc.core.Types$ClassInfo.force$1(Types.scala:4422)
[error]         at dotty.tools.dotc.core.Types$ClassInfo.refineSelfType$1$$anonfun$1(Types.scala:4432)
[error]         at dotty.tools.dotc.core.Types$LazyRef.ref(Types.scala:2642)
[error]         at dotty.tools.dotc.core.Types$Type.stripLazyRef(Types.scala:1064)
[error]         at dotty.tools.dotc.core.SymDenotations$SymDenotation.recur$2(SymDenotations.scala:1289)
[error]         at dotty.tools.dotc.core.SymDenotations$SymDenotation.opaqueAlias(SymDenotations.scala:1293)
[error]         at dotty.tools.dotc.transform.ElimOpaque.transform(ElimOpaque.scala:36)
[error]         at dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:800)
[error]         at dotty.tools.dotc.core.Symbols$Symbol.recomputeDenot(Symbols.scala:498)
[error]         at dotty.tools.dotc.core.Symbols$Symbol.computeDenot(Symbols.scala:493)
[error]         at dotty.tools.dotc.core.Symbols$Symbol.denot(Symbols.scala:487)
[error]         at dotty.tools.dotc.core.Symbols$Symbol.name(Symbols.scala:626)
[error]         at dotty.tools.dotc.core.Scopes$MutableScope.unlink(Scopes.scala:333)
[error]         at dotty.tools.dotc.core.Scopes$Scope.filteredScope$$anonfun$1(Scopes.scala:164)
[error]         at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error]         at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error]         at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:553)
[error]         at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:551)
[error]         at scala.collection.AbstractIterator.foreach(Iterator.scala:1279)
[error]         at dotty.tools.dotc.core.Scopes$Scope.filteredScope(Scopes.scala:165)
[error]         at dotty.tools.dotc.core.TypeErasure.dotty$tools$dotc$core$TypeErasure$$apply(TypeErasure.scala:501)
[error]         at dotty.tools.dotc.core.TypeErasure.eraseInfo(TypeErasure.scala:549)
[error]         at dotty.tools.dotc.core.TypeErasure$.transformInfo(TypeErasure.scala:202)
[error]         at dotty.tools.dotc.transform.Erasure.transform(Erasure.scala:81)
[error]         at dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:800)
[error]         at dotty.tools.dotc.core.Symbols$Symbol.recomputeDenot(Symbols.scala:498)
[error]         at dotty.tools.dotc.core.Symbols$Symbol.computeDenot(Symbols.scala:493)
[error]         at dotty.tools.dotc.core.Symbols$Symbol.denot(Symbols.scala:487)
[error]         at dotty.tools.dotc.core.Symbols$ClassSymbol.classDenot(Symbols.scala:822)
[error]         at dotty.tools.dotc.core.Symbols$.toClassDenot(Symbols.scala:862)
[error]         at dotty.tools.dotc.core.TypeOps$.makePackageObjPrefixExplicit(TypeOps.scala:463)
[error]         at dotty.tools.dotc.typer.TypeAssigner.test$1(TypeAssigner.scala:113)
[error]         at dotty.tools.dotc.typer.TypeAssigner.ensureAccessible(TypeAssigner.scala:117)
[error]         at dotty.tools.dotc.typer.Typer.ensureAccessible(Typer.scala:84)
[error]         at dotty.tools.dotc.typer.Typer.typedNew(Typer.scala:682)
[error]         at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2396)
[error]         at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2452)
[error]         at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:124)
[error]         at dotty.tools.dotc.typer.Typer.op$1(Typer.scala:2518)
[error]         at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2527)
[error]         at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2530)
[error]         at dotty.tools.dotc.transform.Erasure$Typer.typedSelect(Erasure.scala:635)
[error]         at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2362)
[error]         at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2451)
[error]         at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:124)
[error]         at dotty.tools.dotc.typer.Typer.op$1(Typer.scala:2518)
[error]         at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2527)
[error]         at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2530)
[error]         at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:2641)
[error]         at dotty.tools.dotc.transform.Erasure$Typer.typedTypeApply(Erasure.scala:724)
[error]         at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2410)
[error]         at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2452)
[error]         at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:124)
[error]         at dotty.tools.dotc.typer.Typer.op$1(Typer.scala:2518)
[error]         at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2527)
[error]         at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2530)
[error]         at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:2641)
[error]         at dotty.tools.dotc.transform.Erasure$Typer.typedApply(Erasure.scala:746)
[error]         at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2392)
[error]         at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2452)
[error]         at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:124)
[error]         at dotty.tools.dotc.typer.Typer.op$1(Typer.scala:2518)
[error]         at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2527)
[error]         at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2530)
[error]         at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:2641)
[error]         at dotty.tools.dotc.transform.Erasure$Typer.$anonfun$4(Erasure.scala:759)
[error]         at dotty.tools.dotc.core.Decorators$ListDecorator$.zipWithConserve$extension(Decorators.scala:110)
[error]         at dotty.tools.dotc.transform.Erasure$Typer.typedApply(Erasure.scala:759)
[error]         at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2392)
[error]         at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2452)
[error]         at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:124)
[error]         at dotty.tools.dotc.typer.Typer.op$1(Typer.scala:2518)
[error]         at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2527)
[error]         at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2530)
[error]         at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:2641)
[error]         at dotty.tools.dotc.typer.Typer.typedDefDef(Typer.scala:1916)
[error]         at dotty.tools.dotc.transform.Erasure$Typer.typedDefDef(Erasure.scala:860)
[error]         at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2369)
[error]         at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2451)
[error]         at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:124)
[error]         at dotty.tools.dotc.typer.Typer.op$1(Typer.scala:2518)
[error]         at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2527)
[error]         at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2530)
[error]         at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:2552)
[error]         at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:2597)
[error]         at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:947)
[error]         at dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:2050)
[error]         at dotty.tools.dotc.typer.Typer.typedTypeOrClassDef$2(Typer.scala:2380)
[error]         at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2384)
[error]         at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2451)
[error]         at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:124)
[error]         at dotty.tools.dotc.typer.Typer.op$1(Typer.scala:2518)
[error]         at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2527)
[error]         at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2530)
[error]         at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:2552)
[error]         at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:2597)
[error]         at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:947)
[error]         at dotty.tools.dotc.typer.Typer.typedPackageDef(Typer.scala:2176)
[error]         at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2424)
[error]         at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2452)
[error]         at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:124)
[error]         at dotty.tools.dotc.typer.Typer.op$1(Typer.scala:2518)
[error]         at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2527)
[error]         at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2530)
[error]         at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:2641)
[error]         at dotty.tools.dotc.transform.Erasure.run(Erasure.scala:121)
[error]         at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:318)
[error]         at scala.collection.immutable.List.map(List.scala:246)
[error]         at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:319)
[error]         at dotty.tools.dotc.Run.runPhases$4$$anonfun$4(Run.scala:166)
[error]         at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error]         at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error]         at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1323)
[error]         at dotty.tools.dotc.Run.runPhases$5(Run.scala:176)
[error]         at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:184)
[error]         at dotty.runtime.function.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
[error]         at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:64)
[error]         at dotty.tools.dotc.Run.compileUnits(Run.scala:191)
[error]         at dotty.tools.dotc.Run.compileUnits(Run.scala:133)
[error]         at dotty.tools.repl.ReplCompiler.runCompilationUnit(ReplCompiler.scala:156)
[error]         at dotty.tools.repl.ReplCompiler.compile(ReplCompiler.scala:166)
[error]         at dotty.tools.repl.ReplDriver.compile(ReplDriver.scala:231)
[error]         at dotty.tools.repl.ReplDriver.interpret(ReplDriver.scala:195)
[error]         at dotty.tools.repl.ReplDriver.loop$1(ReplDriver.scala:128)
[error]         at dotty.tools.repl.ReplDriver.runUntilQuit$$anonfun$1(ReplDriver.scala:131)
[error]         at dotty.tools.repl.ReplDriver.withRedirectedOutput(ReplDriver.scala:150)
[error]         at dotty.tools.repl.ReplDriver.runUntilQuit(ReplDriver.scala:131)
[error]         at xsbt.ConsoleInterface.run(ConsoleInterface.java:52)
[error]         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[error]         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[error]         at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error]         at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[error]         at sbt.internal.inc.AnalyzingCompiler.call(AnalyzingCompiler.scala:248)
[error]         at sbt.internal.inc.AnalyzingCompiler.console(AnalyzingCompiler.scala:210)
[error]         at sbt.Console.console0$1(Console.scala:48)
[error]         at sbt.Console.$anonfun$apply$2(Console.scala:51)
[error]         at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
[error]         at sbt.util.InterfaceUtil$$anon$1.get(InterfaceUtil.scala:10)
[error]         at sbt.TrapExit$App.run(TrapExit.scala:257)
[error]         at java.base/java.lang.Thread.run(Thread.java:834)
[error] Nonzero exit code: 1
[error] (core / Compile / console) Nonzero exit code: 1

Example B

Very strange scope behaved in REPL

Minimized code

https://github.com/FabioPinheiro/cats-money/blob/dotty-repl-AssertionError/modules/core/src/main/scala/experiments/Ex1Definition.scala

In a file

  opaque type Rate[T] = Double
  object Rate {
    def apply[T](d: Double): Rate[T] = d
    extension Ex1SameNameToBeToImport on [T] (x: Rate[T]) { def value: Double = x }
  }

In REPL (sbt console)

import experiments.Ex1Definition._                                 //ok
Rate(1d).value                                                     //ok
Rate(1d).value //Does not compile  -> value value is not a member of experiments.Ex1Definition.Rate[Nothing]
Rate(1d).value //Does not compile  -> value value is not a member of experiments.Ex1Definition.Rate[Nothing]
...
import experiments.Ex1Definition._                                 //ok
Rate(1d).value  //Does not compile  -> value value is not a member of experiments.Ex1Definition.Rate[Nothing]
import experiments.Ex1Definition.Rate.Ex1SameNameToBeToImport._    //ok
Rate(1d).value                                                     //ok
Rate(1d).value //Does not compile  -> value value is not a member of experiments.Ex1Definition.Rate[Nothing]
import experiments.Ex1Definition.Rate.Ex1SameNameToBeToImport      //ok Note the '._' difference between the import before!
Rate(1d).value //ok
Rate(1d).value //ok
...

Output (click arrow to expand)

sbt:root> core/console [info] Compiling 1 Scala source to /home/fabio/workspace/cats-money/modules/core/target/scala-0.25/classes ...

scala> import experiments.Ex1Definition._

scala> Rate(1d).value
val res0: Double = 1.0

scala> Rate(1d).value
1 |Rate(1d).value
|^^^^^^^^^^^^^^
|value value is not a member of experiments.Ex1Definition.Rate[Nothing]

scala> import experiments.Ex1Definition.Rate.Ex1SameNameToBeToImport._

scala> Rate(1d).value
val res1: Double = 1.0

scala> Rate(1d).value
1 |Rate(1d).value
|^^^^^^^^^^^^^^
|value value is not a member of experiments.Ex1Definition.Rate[Nothing]

scala> import experiments.Ex1Definition.Rate.Ex1SameNameToBeToImport

scala> Rate(1d).value
val res2: Double = 1.0

scala> Rate(1d).value
val res3: Double = 1.0

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions