Skip to content

Commit

Permalink
Avoid cyclic references due to experimental check when inlining
Browse files Browse the repository at this point in the history
  • Loading branch information
odersky authored and little-inferno committed Jan 25, 2023
1 parent 003ce03 commit 36508ab
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 2 deletions.
5 changes: 4 additions & 1 deletion compiler/src/dotty/tools/dotc/inlines/Inlines.scala
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,10 @@ object Inlines:
if (tree.symbol == defn.CompiletimeTesting_typeChecks) return Intrinsics.typeChecks(tree)
if (tree.symbol == defn.CompiletimeTesting_typeCheckErrors) return Intrinsics.typeCheckErrors(tree)

CrossVersionChecks.checkExperimentalRef(tree.symbol, tree.srcPos)
if ctx.isAfterTyper then
// During typer we wait with cross version checks until PostTyper, in order
// not to provoke cyclic references. See i16116 for a test case.
CrossVersionChecks.checkExperimentalRef(tree.symbol, tree.srcPos)

if tree.symbol.isConstructor then return tree // error already reported for the inline constructor definition

Expand Down
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/transform/PostTyper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
}
case Inlined(call, bindings, expansion) if !call.isEmpty =>
val pos = call.sourcePos
CrossVersionChecks.checkExperimentalRef(call.symbol, pos)
val callTrace = Inlines.inlineCallTrace(call.symbol, pos)(using ctx.withSource(pos.source))
cpy.Inlined(tree)(callTrace, transformSub(bindings), transform(expansion)(using inlineContext(call)))
case templ: Template =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ import scala.annotation.experimental
inline def g() = ()

def test: Unit =
g() // errors
g() // error
()
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import scala.annotation.experimental

@experimental
transparent inline def g() = ()

def test: Unit =
g() // error
()
39 changes: 39 additions & 0 deletions tests/pos-custom-args/captures/i16116.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package x

import scala.annotation.*
import scala.concurrent.*

trait CpsMonad[F[_]] {
type Context
}

object CpsMonad {
type Aux[F[_],C] = CpsMonad[F] { type Context = C }
given CpsMonad[Future] with {}
}

@experimental
object Test {

@capability
class CpsTransform[F[_]] {
def await[T](ft: F[T]): { this } T = ???
}

transparent inline def cpsAsync[F[_]](using m:CpsMonad[F]) =
new Test.InfernAsyncArg

class InfernAsyncArg[F[_],C](using am:CpsMonad.Aux[F,C]) {
def apply[A](expr: (CpsTransform[F], C) ?=> A): F[A] = ???
}

def asyncPlus[F[_]](a:Int, b:F[Int])(using cps: CpsTransform[F]): { cps } Int =
a + (cps.await(b).asInstanceOf[Int])

def testExample1Future(): Unit =
val fr = cpsAsync[Future] {
val y = asyncPlus(1,Future successful 2).asInstanceOf[Int]
y+1
}

}

0 comments on commit 36508ab

Please sign in to comment.