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

Fix stability check for inline parameters #15511

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: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,7 @@ object SymDenotations {
* So the first call to a stable member might fail and/or produce side effects.
*/
final def isStableMember(using Context): Boolean = {
def isUnstableValue = isOneOf(UnstableValueFlags) || info.isInstanceOf[ExprType]
def isUnstableValue = isOneOf(UnstableValueFlags) || info.isInstanceOf[ExprType] || isAllOf(InlineParam)
isType || is(StableRealizable) || exists && !isUnstableValue
}

Expand Down
2 changes: 1 addition & 1 deletion library/src/scala/quoted/Quotes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import scala.reflect.TypeTest
* }
* ```
*/
transparent inline def quotes(using inline q: Quotes): q.type = q
transparent inline def quotes(using q: Quotes): q.type = q

/** Quotation context provided by a macro expansion or in the scope of `scala.quoted.staging.run`.
* Used to perform all operations on quoted `Expr` or `Type`.
Expand Down
2 changes: 1 addition & 1 deletion library/src/scala/runtime/stdLibPatches/Predef.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ object Predef:
* @tparam T the type of the value to be summoned
* @return the given value typed: the provided type parameter
*/
transparent inline def summon[T](using inline x: T): x.type = x
transparent inline def summon[T](using x: T): x.type = x

// Extension methods for working with explicit nulls

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
object B {

inline def inlinedAny(x: String): x.type = x
inline def inlinedAny(x: String): String = x

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
object B {

inline def inlinedAny(inline x: String): x.type = x
inline def inlinedAny(inline x: String): String = x

}
2 changes: 1 addition & 1 deletion scaladoc/src/dotty/tools/scaladoc/tasty/reflect.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ package tasty
import scala.quoted._

/** Shorthand for `quotes.reflect` */
transparent inline def reflect(using inline q: Quotes): q.reflect.type = q.reflect
transparent inline def reflect(using q: Quotes): q.reflect.type = q.reflect
6 changes: 6 additions & 0 deletions tests/neg/inline-param-unstable-path.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
inline val a = 3
inline def f(inline x: Int, y: Int, z: => Int): Unit =
val x2: x.type = x // error: (x : Int) is not a valid singleton type, since it is not an immutable path
nicolasstucki marked this conversation as resolved.
Show resolved Hide resolved
val y2: y.type = y
val z2: z.type = z // error: (z : Int) is not a valid singleton type, since it is not an immutable path
val a2: a.type = a
8 changes: 8 additions & 0 deletions tests/neg/inline-val-in-inline-method.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
inline def f(inline x: Int): Unit =
inline val b = x
val c: b.type = b

def test =
f(1)
def a = 1
f(a) // error: inline value must have a literal constant type
4 changes: 2 additions & 2 deletions tests/pos/i11163.scala
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
inline def summonA[T](using x: T): x.type = x
inline def summonB[T](using inline x: T): x.type = x
// inline def summonB[T](using inline x: T): x.type = x // inline parameters are unstable
inline def summonC[T](using inline x: T): T = x

trait Foo:
def f: Int = 9

def test(using Foo) =
summonA[Foo].f
summonB[Foo].f
// summonB[Foo].f
summonC[Foo].f
()
4 changes: 2 additions & 2 deletions tests/pos/i12379a.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
inline def convFail[Of, From](inline from : From) : Unit =
inline def convFail[Of, From](from : From) : Unit = // removed inline from parameter to avoid unsound path selection
val c = compiletime.summonInline[Conversion[from.type, Of]]

inline def convOK[Of, From](inline from : From)(using c : Conversion[from.type, Of]) : Unit = {}
inline def convOK[Of, From](from : From)(using c : Conversion[from.type, Of]) : Unit = {} // removed inline from parameter to avoid unsound path selection

class Bar[T](value : T)
given [T <: Int] : Conversion[T, Bar[T]] = Bar(_)
Expand Down
2 changes: 1 addition & 1 deletion tests/run/deriving-constructor-order.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import scala.compiletime.erasedValue
import scala.deriving.Mirror

object Test extends App {
inline def checkElems[A, T](using inline A: Mirror.SumOf[A]): Unit =
inline def checkElems[A, T](using A: Mirror.SumOf[A]): Unit = // removed inline from parameter to avoid unsound path selection
inline erasedValue[A.MirroredElemTypes] match {
case _: T => ()
}
Expand Down