Skip to content

Use transparent inline in the library #8756

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3278,6 +3278,7 @@ object Parsers {
leadingVparamss ::: rparamss
var tpt = fromWithinReturnType {
if in.token == SUBTYPE && mods.is(Inline) && AllowOldWhiteboxSyntax then
deprecationWarning("`<:` return type will no longer be supported. Use transparent modifier instead.")
in.nextToken()
mods1 = addMod(mods1, Mod.Transparent())
toplevelTyp()
Expand Down Expand Up @@ -3547,6 +3548,7 @@ object Parsers {
mods1 |= Final
DefDef(name, tparams, vparamss, tpt, subExpr())
if in.token == USCORE && AllowOldWhiteboxSyntax then
deprecationWarning("`<:` return type will no longer be supported. Use transparent modifier instead.")
if !mods.is(Inline) then
syntaxError("`_ <:` is only allowed for given with `inline` modifier")
in.nextToken()
Expand Down
2 changes: 1 addition & 1 deletion library/src/dotty/DottyPredef.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ object DottyPredef {
assertFail(message)
}

inline final def assert(inline assertion: Boolean) <: Unit = {
transparent inline final def assert(inline assertion: Boolean): Unit = {
if (!assertion)
assertFail()
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I miss something here, what is the purpose of making this white box, as the result type is Unit?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you write assert(false) the inclined expression becomes of type Nothing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is like a ??? With a message

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this should be supported thought

Expand Down
4 changes: 2 additions & 2 deletions library/src/scala/compiletime/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ package object compiletime {
*
* the returned value would be `2`.
*/
inline def summonFrom[T](f: Nothing => T) <: T = ???
transparent inline def summonFrom[T](f: Nothing => T): T = ???


/** Summon a given value of type `T`. Usually, the argument is not passed explicitly.
Expand All @@ -61,7 +61,7 @@ package object compiletime {
* @tparam T the type of the value to be summoned
* @return the given value typed as the provided type parameter
*/
inline def summonInline[T] <: T = summonFrom {
transparent inline def summonInline[T]: T = summonFrom {
case t: T => t
}

Expand Down
4 changes: 2 additions & 2 deletions tests/invalid/run/typelevel-patmat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ object Test extends App {
inline val i2 = toInt(y2)
val j2: 2 = i2

inline def concat(xs: HList, ys: HList) <: HList = inline xs match {
transparent inline def concat(xs: HList, ys: HList): HList = inline xs match {
case HNil => ys
case HCons(x, xs1) => HCons(x, concat(xs1, ys))
}
Expand All @@ -68,7 +68,7 @@ object Test extends App {
val r6 = concat(HCons(1, HCons("a", HNil)), HCons(true, HCons(1.0, HNil)))
val c6: HCons[Int, HCons[String, HCons[Boolean, HCons[Double, HNil]]]] = r6

inline def nth(xs: HList, n: Int) <: Any = inline xs match {
transparent inline def nth(xs: HList, n: Int): Any = inline xs match {
case HCons(x, _) if n == 0 => x
case HCons(_, xs1) if n > 0 => nth(xs1, n - 1)
}
Expand Down
8 changes: 4 additions & 4 deletions tests/invalid/run/typelevel1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ trait HList {
def head: Any
def tail: HList

inline def isEmpty <: Boolean = length == 0
transparent inline def isEmpty: Boolean = length == 0
}

case object HNil extends HList {
inline override def length <: Int = 0
transparent inline override def length: Int = 0
def head: Nothing = ???
def tail: Nothing = ???
}

case class :: [H, T <: HList] (hd: H, tl: T) extends HList {
inline override def length <: Int = 1 + tl.length
transparent inline override def length: Int = 1 + tl.length
inline def head: H = this.hd
inline def tail: T = this.tl
}
Expand All @@ -32,7 +32,7 @@ object Test extends App {

// Does not work since it infers `Any` as a type argument for `::`
// and we cannot undo that without a typing from untyped.
inline def concat[T1, T2](xs: HList, ys: HList) <: HList =
transparent inline def concat[T1, T2](xs: HList, ys: HList): HList =
inline if xs.isEmpty then ys
else new ::(xs.head, concat(xs.tail, ys))

Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/quote-whitebox/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import scala.quoted._

object Macros {
inline def defaultOf(inline str: String) <: Any = ${ defaultOfImpl('str) }
transparent inline def defaultOf(inline str: String): Any = ${ defaultOfImpl('str) }
def defaultOfImpl(str: Expr[String]) (using QuoteContext): Expr[Any] = str.unliftOrError match {
case "int" => '{1}
case "string" => '{"a"}
Expand Down
2 changes: 1 addition & 1 deletion tests/neg/specializing-inline.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ object Test {
val z = h(true)
val zc: Int = z // error

inline def g <: Any = 1
transparent inline def g: Any = 1
val y = g
val yc: Int = y // OK

Expand Down
6 changes: 3 additions & 3 deletions tests/pending/pos/summonFrom.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ object summonFroms {
object invariant {
case class Box[T](value: T)
implicit val box: Box[Int] = Box(0)
inline def unbox <: Any = summonInline[Box[t]].value
transparent inline def unbox: Any = summonInline[Box[t]].value
val i: Int = unbox
val i2 = unbox
val i3: Int = i2
Expand All @@ -13,7 +13,7 @@ object summonFroms {
object covariant {
case class Box[+T](value: T)
implicit val box: Box[Int] = Box(0)
inline def unbox <: Any = summonInline[Box[t]].value
transparent inline def unbox: Any = summonInline[Box[t]].value
val i: Int = unbox
val i2 = unbox
val i3: Int = i2
Expand All @@ -22,7 +22,7 @@ object summonFroms {
object contravariant {
case class TrashCan[-T](trash: T => Unit)
implicit val trashCan: TrashCan[Int] = TrashCan { i => ; }
inline def trash <: Nothing => Unit = summonInline[TrashCan[t]].trash
transparent inline def trash: Nothing => Unit = summonInline[TrashCan[t]].trash
val t1: Int => Unit = trash
val t2 = trash
val t3: Int => Unit = t2
Expand Down
2 changes: 1 addition & 1 deletion tests/pos-macros/quote-whitebox-2/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import scala.quoted._

object Macro {

inline def charOrString(inline str: String) <: Any = ${ impl('str) }
transparent inline def charOrString(inline str: String): Any = ${ impl('str) }

def impl(strExpr: Expr[String]) (using QuoteContext)=
val str = strExpr.unliftOrError
Expand Down
2 changes: 1 addition & 1 deletion tests/pos/given-pattern.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
class Test {
import scala.collection.immutable.{TreeSet, HashSet}

inline def trySummon[S, T](f: PartialFunction[S, T]) <: T = ???
transparent inline def trySummon[S, T](f: PartialFunction[S, T]): T = ???

inline def setFor[T]: Set[T] = trySummon {
case given ord: Ordering[T] => new TreeSet[T]
Expand Down
2 changes: 1 addition & 1 deletion tests/pos/i4006.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class Foo {
inline def foo <: Int = try { 1 } finally println("Hello")
transparent inline def foo: Int = try { 1 } finally println("Hello")
foo
}
2 changes: 1 addition & 1 deletion tests/pos/i5574.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import scala.compiletime._
object i5574 {
class Box[F[_]]

inline def foo[T] <: Any =
transparent inline def foo[T]: Any =
inline erasedValue[T] match {
case _: Box[f] =>
type t = f
Expand Down
2 changes: 1 addition & 1 deletion tests/pos/i6213.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
object Test {
class C { type T }
inline def foo[U] <: Any = (??? : C { type T = U })
transparent inline def foo[U]: Any = (??? : C { type T = U })

foo[Int]
}
2 changes: 1 addition & 1 deletion tests/pos/i7078.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
trait A
class B extends A

inline given tc as _ <: A = B()
transparent inline given tc as A = B()

val x: B = summon[A]

2 changes: 1 addition & 1 deletion tests/pos/i7358.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package test
import scala.quoted._
import scala.compiletime._

inline def summonT[Tp <: Tuple](using QuoteContext) <: Tuple = inline erasedValue[Tp] match {
transparent inline def summonT[Tp <: Tuple](using QuoteContext): Tuple = inline erasedValue[Tp] match {
case _ : Unit => ()
case _ : (hd *: tl) => {
type H = hd
Expand Down
2 changes: 1 addition & 1 deletion tests/pos/inline-caseclass.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ case class S[N <: Nat](n: N) extends Nat
object Test {
type Z = Z.type

inline def add(x: Nat, y: Int) <: Int = inline x match {
transparent inline def add(x: Nat, y: Int): Int = inline x match {
case Z => y
case S(x1) => add(x1, y) + 1
}
Expand Down
4 changes: 2 additions & 2 deletions tests/pos/inline-constfold.scala
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
object Test {
inline def not(x: Boolean) <: Boolean = {
transparent inline def not(x: Boolean): Boolean = {
!x
}

final val a = not(true)
val b: false = a

inline def add(x: Int, y: Int) <: Int = {
transparent inline def add(x: Int, y: Int): Int = {
x + y
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
object Utils {
class Box[T]
inline def foo[T](t: T) <: Any = inline t match {
transparent inline def foo[T](t: T): Any = inline t match {
case _: Box[a] => scala.compiletime.constValue[a]
}
}
6 changes: 3 additions & 3 deletions tests/pos/reference/compile-time.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class Test:
case object Zero extends Nat
case class Succ[N <: Nat](n: N) extends Nat

inline def toIntC[N] <: Int =
transparent inline def toIntC[N]: Int =
inline constValue[N] match
case 0 => 0
case _: S[n1] => 1 + toIntC[n1]
Expand All @@ -31,10 +31,10 @@ class Test:
val dBoolean: Some[Boolean] = defaultValue[Boolean]
val dAny: None.type = defaultValue[Any]

inline def toIntT[N <: Nat] <: Int = inline scala.compiletime.erasedValue[N] match
transparent inline def toIntT[N <: Nat]: Int = inline scala.compiletime.erasedValue[N] match
case _: Zero.type => 0
case _: Succ[n] => toIntT[n] + 1

inline def summonFrom(f: Nothing => Any) <: Any = ???
transparent inline def summonFrom(f: Nothing => Any): Any = ???

final val two = toIntT[Succ[Succ[Zero.type]]]
4 changes: 2 additions & 2 deletions tests/pos/reference/inline-match.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package inlinematch

class Test {

inline def g(x: Any) <: Any = inline x match {
transparent inline def g(x: Any): Any = inline x match {
case x: String => (x, x) // Tuple2[String, String](x, x)
case x: Double => x
}
Expand All @@ -14,7 +14,7 @@ class Test {
case object Zero extends Nat
case class Succ[N <: Nat](n: N) extends Nat

inline def toInt(n: Nat) <: Int = inline n match {
transparent inline def toInt(n: Nat): Int = inline n match {
case Zero => 0
case Succ(n1) => toInt(n1) + 1
}
Expand Down
2 changes: 1 addition & 1 deletion tests/pos/reference/inline-specializing.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ object Test{
def meth() = true
}

inline def choose(b: Boolean) <: A = {
transparent inline def choose(b: Boolean): A = {
if (b) new A()
else new B()
}
Expand Down
6 changes: 3 additions & 3 deletions tests/pos/typelevel0.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ trait HList {
def head: Any
def tail: HList

inline def isEmpty <: Boolean = length == 0
transparent inline def isEmpty: Boolean = length == 0
}

case object HNil extends HList {
inline override def length <: Int = 0
transparent inline override def length: Int = 0
def head: Nothing = ???
def tail: Nothing = ???
}

case class :: [+H, +T <: HList] (hd: H, tl: T) extends HList {
inline override def length <: Int = 1 + tl.length
transparent inline override def length: Int = 1 + tl.length
def head: H = this.hd
def tail: T = this.tl
}
Expand Down
2 changes: 1 addition & 1 deletion tests/run-custom-args/companion-loading.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ implicit object FooAssoc extends Assoc[Foo] {

import compiletime.summonFrom

inline def link[T] <: Any =
transparent inline def link[T]: Any =
summonFrom {
case _: Link[T, s] =>
summonFrom {
Expand Down
2 changes: 1 addition & 1 deletion tests/run-macros/i7898/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ object Main {
}
}

inline def myMacro(body: => Any) <: Any = ${
transparent inline def myMacro(body: => Any): Any = ${
myMacroImpl('body)
}
}
2 changes: 1 addition & 1 deletion tests/run-macros/quote-whitebox/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import scala.quoted._

object Macros {
inline def defaultOf(inline str: String) <: Any = ${ defaultOfImpl('str) }
transparent inline def defaultOf(inline str: String): Any = ${ defaultOfImpl('str) }
def defaultOfImpl(str: Expr[String]) (using QuoteContext): Expr[Any] = str.unliftOrError match {
case "int" => '{1}
case "string" => '{"a"}
Expand Down
4 changes: 2 additions & 2 deletions tests/run-macros/refined-selectable-macro/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import scala.quoted._
object Macro {

trait SelectableRecord extends Selectable {
inline def toTuple <: Tuple = ${ toTupleImpl('this)}
transparent inline def toTuple: Tuple = ${ toTupleImpl('this)}
}

trait SelectableRecordCompanion[T] {
protected def fromUntypedTuple(elems: (String, Any)*): T
inline def fromTuple[T <: Tuple](inline s: T) <: Any = ${ fromTupleImpl('s, '{ (x: Array[(String, Any)]) => fromUntypedTuple(x: _*) } ) }
transparent inline def fromTuple[T <: Tuple](inline s: T): Any = ${ fromTupleImpl('s, '{ (x: Array[(String, Any)]) => fromUntypedTuple(x: _*) } ) }
}

private def toTupleImpl(s: Expr[Selectable])(using qctx:QuoteContext) : Expr[Tuple] = {
Expand Down
2 changes: 1 addition & 1 deletion tests/run-staging/i3876-d.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ object Test {
println(withQuoteContext(Expr.betaReduce(f4)(x).show))
}

inline def inlineLambda <: Int => Int = x => x + x
transparent inline def inlineLambda: Int => Int = x => x + x
}
2 changes: 1 addition & 1 deletion tests/run-staging/i3876-e.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ object Test {
println(withQuoteContext(Expr.betaReduce(f4)(x).show))
}

inline def inlineLambda <: Int => Int = x => x + x
transparent inline def inlineLambda: Int => Int = x => x + x
}