Skip to content

Commit c33f442

Browse files
committed
Redefine semantics of inline parameters
1 parent 2ecdf91 commit c33f442

20 files changed

+227
-113
lines changed

compiler/src/dotty/tools/dotc/core/TypeErasure.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
533533
// but potentially re-introduced by ResolveSuper, when we add
534534
// forwarders to mixin methods.
535535
// See doc comment for ElimByName for speculation how we could improve this.
536-
else MethodType(Nil, Nil, eraseResult(sym.info.finalResultType))
536+
else MethodType(Nil, Nil, eraseResult(sym.info.finalResultType.underlyingIfRepeated(isJava)))
537537
case tp: PolyType =>
538538
eraseResult(tp.resultType) match {
539539
case rt: MethodType => rt

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3360,11 +3360,11 @@ object Types {
33603360
/** Produce method type from parameter symbols, with special mappings for repeated
33613361
* and inline parameters:
33623362
* - replace @repeated annotations on Seq or Array types by <repeated> types
3363-
* - add @inlineParam to inline call-by-value parameters
3363+
* - add @inlineParam to inline parameters
33643364
*/
33653365
def fromSymbols(params: List[Symbol], resultType: Type)(implicit ctx: Context): MethodType = {
33663366
def translateInline(tp: Type): Type = tp match {
3367-
case _: ExprType => tp
3367+
case ExprType(resType) => ExprType(AnnotatedType(resType, Annotation(defn.InlineParamAnnot)))
33683368
case _ => AnnotatedType(tp, Annotation(defn.InlineParamAnnot))
33693369
}
33703370
def paramInfo(param: Symbol) = {

compiler/src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -818,43 +818,8 @@ trait Checking {
818818
tree.tpe.widenTermRefExpr match {
819819
case tp: ConstantType if exprPurity(tree) >= purityLevel => // ok
820820
case _ =>
821-
tree match {
822-
case Typed(expr, _) =>
823-
checkInlineConformant(expr, isFinal, what)
824-
case Inlined(_, Nil, expr) =>
825-
checkInlineConformant(expr, isFinal, what)
826-
case SeqLiteral(elems, _) =>
827-
elems.foreach(elem => checkInlineConformant(elem, isFinal, what))
828-
case Apply(fn, List(arg)) if defn.WrapArrayMethods().contains(fn.symbol) =>
829-
checkInlineConformant(arg, isFinal, what)
830-
case _ =>
831-
def isCaseClassApply(sym: Symbol): Boolean =
832-
sym.name == nme.apply && sym.is(Synthetic) && sym.owner.is(Module) && sym.owner.companionClass.is(Case)
833-
def isCaseClassNew(sym: Symbol): Boolean =
834-
sym.isPrimaryConstructor && sym.owner.is(Case) && sym.owner.isStatic
835-
def isCaseObject(sym: Symbol): Boolean =
836-
// TODO add alias to Nil in scala package
837-
sym.is(Case) && sym.is(Module)
838-
def isStaticEnumCase(sym: Symbol): Boolean =
839-
sym.is(Enum) && sym.is(JavaStatic) && sym.is(Case)
840-
val allow =
841-
ctx.erasedTypes ||
842-
ctx.inInlineMethod ||
843-
(tree.symbol.isStatic && isCaseObject(tree.symbol) || isCaseClassApply(tree.symbol)) ||
844-
isStaticEnumCase(tree.symbol) ||
845-
isCaseClassNew(tree.symbol)
846-
847-
if (!allow) ctx.error(em"$what must be a known value", tree.sourcePos)
848-
else {
849-
def checkArgs(tree: Tree): Unit = tree match {
850-
case Apply(fn, args) =>
851-
args.foreach(arg => checkInlineConformant(arg, isFinal, what))
852-
checkArgs(fn)
853-
case _ =>
854-
}
855-
checkArgs(tree)
856-
}
857-
}
821+
if (!ctx.erasedTypes && !ctx.inInlineMethod)
822+
ctx.error(em"$what must be a known value", tree.sourcePos)
858823
}
859824
}
860825

compiler/src/dotty/tools/dotc/typer/Inliner.scala

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ object Inliner {
223223
res ++= typerErrors.map(e => ErrorKind.Typer -> e)
224224
res.toList
225225
case t =>
226-
assert(ctx.reporter.hasErrors) // at least: argument to inline parameter must be a known value
226+
ctx.error("expected argument to be a statically known String", codeArg.sourcePos)
227227
Nil
228228
}
229229

@@ -333,9 +333,10 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
333333
val argtpe = arg.tpe.dealiasKeepAnnots
334334
val isByName = paramtp.dealias.isInstanceOf[ExprType]
335335
var inlineFlags: FlagSet = InlineProxy
336-
if (paramtp.hasAnnotation(defn.InlineParamAnnot)) inlineFlags |= Inline
336+
if (paramtp.widenExpr.hasAnnotation(defn.InlineParamAnnot)) inlineFlags |= Inline
337+
if (isByName) inlineFlags |= Method
337338
val (bindingFlags, bindingType) =
338-
if (isByName) (InlineByNameProxy.toTermFlags, ExprType(argtpe.widen))
339+
if (isByName) (inlineFlags, ExprType(argtpe.widen))
339340
else (inlineFlags, argtpe.widen)
340341
val boundSym = newSym(name, bindingFlags, bindingType).asTerm
341342
val binding = {
@@ -765,10 +766,8 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
765766
def search(buf: mutable.ListBuffer[ValOrDefDef]) = buf.find(_.name == tree.name)
766767
if (paramProxies.contains(tree.typeOpt))
767768
search(bindingsBuf) match {
768-
case Some(vdef: ValDef) if vdef.symbol.is(Inline) =>
769-
Some(integrate(vdef.rhs, vdef.symbol))
770-
case Some(ddef: DefDef) =>
771-
Some(integrate(ddef.rhs, ddef.symbol))
769+
case Some(bind: ValOrDefDef) if bind.symbol.is(Inline) =>
770+
Some(integrate(bind.rhs, bind.symbol))
772771
case _ => None
773772
}
774773
else None
@@ -1198,7 +1197,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
11981197
val bindingOfSym = newMutableSymbolMap[MemberDef]
11991198

12001199
def isInlineable(binding: MemberDef) = binding match {
1201-
case DefDef(_, Nil, Nil, _, _) => true
1200+
case ddef @ DefDef(_, Nil, Nil, _, _) => isPureExpr(ddef.rhs)
12021201
case vdef @ ValDef(_, _, _) => isPureExpr(vdef.rhs)
12031202
case _ => false
12041203
}
@@ -1232,11 +1231,12 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
12321231
for (binding <- bindings) countRefs.traverse(binding)
12331232

12341233
def retain(boundSym: Symbol) = {
1235-
refCount.get(boundSym) match {
1234+
!boundSym.is(Inline) &&
1235+
(refCount.get(boundSym) match {
12361236
case Some(x) => x > 1 || x == 1 && !boundSym.is(Method)
12371237
case none => true
1238-
}
1239-
} && !(boundSym.isAllOf(InlineMethod) && boundSym.isOneOf(GivenOrImplicit))
1238+
})
1239+
} && !(boundSym.isAllOf(InlineMethod) && boundSym.isOneOf(GivenOrImplicit)) // TODO clenup unnecessary conditions?
12401240

12411241
val inlineBindings = new TreeMap {
12421242
override def transform(t: Tree)(implicit ctx: Context) = t match {

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2896,8 +2896,6 @@ class Typer extends Namer
28962896
tree
28972897
}
28982898
else if (tree.tpe.widenExpr <:< pt) {
2899-
if (pt.hasAnnotation(defn.InlineParamAnnot))
2900-
checkInlineConformant(tree, isFinal = false, "argument to inline parameter")
29012899
if (ctx.typeComparer.GADTused && pt.isValueType)
29022900
// Insert an explicit cast, so that -Ycheck in later phases succeeds.
29032901
// I suspect, but am not 100% sure that this might affect inferred types,

compiler/test/dotty/tools/backend/jvm/ArrayApplyOptTest.scala

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import scala.tools.asm.Opcodes._
88
class ArrayApplyOptTest extends DottyBytecodeTest {
99
import ASMConverters._
1010

11+
// FIXME: Re-enable IArray bytecode tests (requires updated reference compiler)
12+
// Also change: library/src/scala/IArray.scala
1113
@Test def testArrayEmptyGenericApply= {
1214
test("Array[String]()", List(Op(ICONST_0), TypeOp(ANEWARRAY, "java/lang/String"), Op(POP), Op(RETURN)))
1315
test("Array[Unit]()", List(Op(ICONST_0), TypeOp(ANEWARRAY, "scala/runtime/BoxedUnit"), Op(POP), Op(RETURN)))
@@ -22,18 +24,18 @@ class ArrayApplyOptTest extends DottyBytecodeTest {
2224
test("Array[Char]()", newArray0Opcodes(T_CHAR))
2325
test("Array[T]()", newArray0Opcodes(T_INT))
2426

25-
test("IArray[String]()", List(Op(ICONST_0), TypeOp(ANEWARRAY, "java/lang/String"), TypeOp(CHECKCAST, "[Ljava/lang/String;"), Op(POP), Op(RETURN)))
26-
test("IArray[Unit]()", List(Op(ICONST_0), TypeOp(ANEWARRAY, "scala/runtime/BoxedUnit"), TypeOp(CHECKCAST, "[Lscala/runtime/BoxedUnit;"), Op(POP), Op(RETURN)))
27-
test("IArray[Object]()", List(Op(ICONST_0), TypeOp(ANEWARRAY, "java/lang/Object"), TypeOp(CHECKCAST, "[Ljava/lang/Object;"), Op(POP), Op(RETURN)))
28-
test("IArray[Boolean]()", newArray0Opcodes(T_BOOLEAN, TypeOp(CHECKCAST, "[Z") :: Nil))
29-
test("IArray[Byte]()", newArray0Opcodes(T_BYTE, TypeOp(CHECKCAST, "[B") :: Nil))
30-
test("IArray[Short]()", newArray0Opcodes(T_SHORT, TypeOp(CHECKCAST, "[S") :: Nil))
31-
test("IArray[Int]()", newArray0Opcodes(T_INT, TypeOp(CHECKCAST, "[I") :: Nil))
32-
test("IArray[Long]()", newArray0Opcodes(T_LONG, TypeOp(CHECKCAST, "[J") :: Nil))
33-
test("IArray[Float]()", newArray0Opcodes(T_FLOAT, TypeOp(CHECKCAST, "[F") :: Nil))
34-
test("IArray[Double]()", newArray0Opcodes(T_DOUBLE, TypeOp(CHECKCAST, "[D") :: Nil))
35-
test("IArray[Char]()", newArray0Opcodes(T_CHAR, TypeOp(CHECKCAST, "[C") :: Nil))
36-
test("IArray[T]()", newArray0Opcodes(T_INT, TypeOp(CHECKCAST, "[I") :: Nil))
27+
// test("IArray[String]()", List(Op(ICONST_0), TypeOp(ANEWARRAY, "java/lang/String"), TypeOp(CHECKCAST, "[Ljava/lang/String;"), Op(POP), Op(RETURN)))
28+
// test("IArray[Unit]()", List(Op(ICONST_0), TypeOp(ANEWARRAY, "scala/runtime/BoxedUnit"), TypeOp(CHECKCAST, "[Lscala/runtime/BoxedUnit;"), Op(POP), Op(RETURN)))
29+
// test("IArray[Object]()", List(Op(ICONST_0), TypeOp(ANEWARRAY, "java/lang/Object"), TypeOp(CHECKCAST, "[Ljava/lang/Object;"), Op(POP), Op(RETURN)))
30+
// test("IArray[Boolean]()", newArray0Opcodes(T_BOOLEAN, TypeOp(CHECKCAST, "[Z") :: Nil))
31+
// test("IArray[Byte]()", newArray0Opcodes(T_BYTE, TypeOp(CHECKCAST, "[B") :: Nil))
32+
// test("IArray[Short]()", newArray0Opcodes(T_SHORT, TypeOp(CHECKCAST, "[S") :: Nil))
33+
// test("IArray[Int]()", newArray0Opcodes(T_INT, TypeOp(CHECKCAST, "[I") :: Nil))
34+
// test("IArray[Long]()", newArray0Opcodes(T_LONG, TypeOp(CHECKCAST, "[J") :: Nil))
35+
// test("IArray[Float]()", newArray0Opcodes(T_FLOAT, TypeOp(CHECKCAST, "[F") :: Nil))
36+
// test("IArray[Double]()", newArray0Opcodes(T_DOUBLE, TypeOp(CHECKCAST, "[D") :: Nil))
37+
// test("IArray[Char]()", newArray0Opcodes(T_CHAR, TypeOp(CHECKCAST, "[C") :: Nil))
38+
// test("IArray[T]()", newArray0Opcodes(T_INT, TypeOp(CHECKCAST, "[I") :: Nil))
3739
}
3840

3941
@Test def testArrayGenericApply= {
@@ -44,90 +46,90 @@ class ArrayApplyOptTest extends DottyBytecodeTest {
4446

4547
def opCodes2(tpe: String) =
4648
List(Op(ICONST_2), TypeOp(ANEWARRAY, tpe), Op(DUP), Op(ICONST_0), Ldc(LDC, "a"), Op(AASTORE), Op(DUP), Op(ICONST_1), Ldc(LDC, "b"), Op(AASTORE), TypeOp(CHECKCAST, s"[L$tpe;"), Op(POP), Op(RETURN))
47-
test("""IArray("a", "b")""", opCodes2("java/lang/String"))
48-
test("""IArray[Object]("a", "b")""", opCodes2("java/lang/Object"))
49+
// test("""IArray("a", "b")""", opCodes2("java/lang/String"))
50+
// test("""IArray[Object]("a", "b")""", opCodes2("java/lang/Object"))
4951
}
5052

5153
@Test def testArrayApplyBoolean = {
5254
val init = List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(BASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_0), Op(BASTORE))
5355
test("Array(true, false)", newArray2Opcodes(T_BOOLEAN, init))
54-
test("IArray(true, false)", newArray2Opcodes(T_BOOLEAN, init :+ TypeOp(CHECKCAST, "[Z")))
56+
// test("IArray(true, false)", newArray2Opcodes(T_BOOLEAN, init :+ TypeOp(CHECKCAST, "[Z")))
5557
}
5658

5759
@Test def testArrayApplyByte = {
5860
val init = List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(BASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(BASTORE))
5961
test("Array[Byte](1, 2)", newArray2Opcodes(T_BYTE, init))
60-
test("IArray[Byte](1, 2)", newArray2Opcodes(T_BYTE, init :+ TypeOp(CHECKCAST, "[B")))
62+
// test("IArray[Byte](1, 2)", newArray2Opcodes(T_BYTE, init :+ TypeOp(CHECKCAST, "[B")))
6163
}
6264

6365
@Test def testArrayApplyShort = {
6466
val init = List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(SASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(SASTORE))
6567
test("Array[Short](1, 2)", newArray2Opcodes(T_SHORT, init))
66-
test("IArray[Short](1, 2)", newArray2Opcodes(T_SHORT, init :+ TypeOp(CHECKCAST, "[S")))
68+
// test("IArray[Short](1, 2)", newArray2Opcodes(T_SHORT, init :+ TypeOp(CHECKCAST, "[S")))
6769
}
6870

6971
@Test def testArrayApplyInt = {
7072
val init = List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(IASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(IASTORE))
7173
test("Array(1, 2)", newArray2Opcodes(T_INT, init))
72-
test("IArray(1, 2)", newArray2Opcodes(T_INT, init :+ TypeOp(CHECKCAST, "[I")))
74+
// test("IArray(1, 2)", newArray2Opcodes(T_INT, init :+ TypeOp(CHECKCAST, "[I")))
7375

7476
val init2 = List(Op(DUP), Op(ICONST_0), Field(GETSTATIC, "Foo$", "MODULE$", "LFoo$;"), Invoke(INVOKEVIRTUAL, "Foo$", "t", "()I", false), Op(IASTORE), Op(DUP), Op(ICONST_1), Field(GETSTATIC, "Foo$", "MODULE$", "LFoo$;"), Invoke(INVOKEVIRTUAL, "Foo$", "t", "()I", false), Op(IASTORE))
7577
test("""Array[T](t, t)""", newArray2Opcodes(T_INT, init2))
76-
test("""IArray[T](t, t)""", newArray2Opcodes(T_INT, init2 :+ TypeOp(CHECKCAST, "[I")))
78+
// test("""IArray[T](t, t)""", newArray2Opcodes(T_INT, init2 :+ TypeOp(CHECKCAST, "[I")))
7779
}
7880

7981
@Test def testArrayApplyLong = {
8082
val init = List(Op(DUP), Op(ICONST_0), Ldc(LDC, 2), Op(LASTORE), Op(DUP), Op(ICONST_1), Ldc(LDC, 3), Op(LASTORE))
8183
test("Array(2L, 3L)", newArray2Opcodes(T_LONG, init))
82-
test("IArray(2L, 3L)", newArray2Opcodes(T_LONG, init :+ TypeOp(CHECKCAST, "[J")))
84+
// test("IArray(2L, 3L)", newArray2Opcodes(T_LONG, init :+ TypeOp(CHECKCAST, "[J")))
8385
}
8486

8587
@Test def testArrayApplyFloat = {
8688
val init = List(Op(DUP), Op(ICONST_0), Ldc(LDC, 2.1f), Op(FASTORE), Op(DUP), Op(ICONST_1), Ldc(LDC, 3.1f), Op(FASTORE))
8789
test("Array(2.1f, 3.1f)", newArray2Opcodes(T_FLOAT, init))
88-
test("IArray(2.1f, 3.1f)", newArray2Opcodes(T_FLOAT, init :+ TypeOp(CHECKCAST, "[F")))
90+
// test("IArray(2.1f, 3.1f)", newArray2Opcodes(T_FLOAT, init :+ TypeOp(CHECKCAST, "[F")))
8991
}
9092

9193
@Test def testArrayApplyDouble = {
9294
val init = List(Op(DUP), Op(ICONST_0), Ldc(LDC, 2.2d), Op(DASTORE), Op(DUP), Op(ICONST_1), Ldc(LDC, 3.2d), Op(DASTORE))
9395
test("Array(2.2d, 3.2d)", newArray2Opcodes(T_DOUBLE, init))
94-
test("IArray(2.2d, 3.2d)", newArray2Opcodes(T_DOUBLE, init :+ TypeOp(CHECKCAST, "[D")))
96+
// test("IArray(2.2d, 3.2d)", newArray2Opcodes(T_DOUBLE, init :+ TypeOp(CHECKCAST, "[D")))
9597
}
9698

9799
@Test def testArrayApplyChar = {
98100
val init = List(Op(DUP), Op(ICONST_0), IntOp(BIPUSH, 120), Op(CASTORE), Op(DUP), Op(ICONST_1), IntOp(BIPUSH, 121), Op(CASTORE))
99101
test("Array('x', 'y')", newArray2Opcodes(T_CHAR, init))
100-
test("IArray('x', 'y')", newArray2Opcodes(T_CHAR, init :+ TypeOp(CHECKCAST, "[C")))
102+
// test("IArray('x', 'y')", newArray2Opcodes(T_CHAR, init :+ TypeOp(CHECKCAST, "[C")))
101103
}
102104

103105
@Test def testArrayApplyUnit = {
104106
test("Array[Unit]((), ())", List(Op(ICONST_2), TypeOp(ANEWARRAY, "scala/runtime/BoxedUnit"), Op(DUP),
105107
Op(ICONST_0), Field(GETSTATIC, "scala/runtime/BoxedUnit", "UNIT", "Lscala/runtime/BoxedUnit;"), Op(AASTORE), Op(DUP),
106108
Op(ICONST_1), Field(GETSTATIC, "scala/runtime/BoxedUnit", "UNIT", "Lscala/runtime/BoxedUnit;"), Op(AASTORE), Op(POP), Op(RETURN)))
107-
test("IArray[Unit]((), ())", List(Op(ICONST_2), TypeOp(ANEWARRAY, "scala/runtime/BoxedUnit"), Op(DUP),
108-
Op(ICONST_0), Field(GETSTATIC, "scala/runtime/BoxedUnit", "UNIT", "Lscala/runtime/BoxedUnit;"), Op(AASTORE), Op(DUP),
109-
Op(ICONST_1), Field(GETSTATIC, "scala/runtime/BoxedUnit", "UNIT", "Lscala/runtime/BoxedUnit;"), Op(AASTORE), TypeOp(CHECKCAST, "[Lscala/runtime/BoxedUnit;"), Op(POP), Op(RETURN)))
109+
// test("IArray[Unit]((), ())", List(Op(ICONST_2), TypeOp(ANEWARRAY, "scala/runtime/BoxedUnit"), Op(DUP),
110+
// Op(ICONST_0), Field(GETSTATIC, "scala/runtime/BoxedUnit", "UNIT", "Lscala/runtime/BoxedUnit;"), Op(AASTORE), Op(DUP),
111+
// Op(ICONST_1), Field(GETSTATIC, "scala/runtime/BoxedUnit", "UNIT", "Lscala/runtime/BoxedUnit;"), Op(AASTORE), TypeOp(CHECKCAST, "[Lscala/runtime/BoxedUnit;"), Op(POP), Op(RETURN)))
110112
}
111113

112114
@Test def testArrayInlined = test(
113115
"""{
114-
| inline def array(xs: =>Int*): Array[Int] = Array(xs: _*)
116+
| inline def array(inline xs: Int*): Array[Int] = Array(xs: _*)
115117
| array(1, 2)
116118
|}""".stripMargin,
117119
newArray2Opcodes(T_INT, List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(IASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(IASTORE), TypeOp(CHECKCAST, "[I")))
118120
)
119121

120122
@Test def testArrayInlined2 = test(
121123
"""{
122-
| inline def array(x: =>Int, xs: =>Int*): Array[Int] = Array(x, xs: _*)
124+
| inline def array(inline x: Int, inline xs: Int*): Array[Int] = Array(x, xs: _*)
123125
| array(1, 2)
124126
|}""".stripMargin,
125127
newArray2Opcodes(T_INT, List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(IASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(IASTORE)))
126128
)
127129

128130
@Test def testArrayInlined3 = test(
129131
"""{
130-
| inline def array[T](xs: =>T*)(given ct: =>scala.reflect.ClassTag[T]): Array[T] = Array(xs: _*)
132+
| inline def array[T](inline xs: T*)(given inline ct: scala.reflect.ClassTag[T]): Array[T] = Array(xs: _*)
131133
| array(1, 2)
132134
|}""".stripMargin,
133135
newArray2Opcodes(T_INT, List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(IASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(IASTORE), TypeOp(CHECKCAST, "[I")))

compiler/test/dotty/tools/backend/jvm/InlineBytecodeTests.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class InlineBytecodeTests extends DottyBytecodeTest {
4444

4545
@Test def i4947 = {
4646
val source = """class Foo {
47-
| inline def track[T](f: => T) <: T = {
47+
| inline def track[T](inline f: T) <: T = {
4848
| foo("tracking") // line 3
4949
| f // line 4
5050
| }
@@ -103,11 +103,11 @@ class InlineBytecodeTests extends DottyBytecodeTest {
103103

104104
@Test def i4947b = {
105105
val source = """class Foo {
106-
| inline def track2[T](f: => T) <: T = {
106+
| inline def track2[T](inline f: T) <: T = {
107107
| foo("tracking2") // line 3
108108
| f // line 4
109109
| }
110-
| inline def track[T](f: => T) <: T = {
110+
| inline def track[T](inline f: T) <: T = {
111111
| foo("tracking") // line 7
112112
| track2 { // line 8
113113
| f // line 9
@@ -163,11 +163,11 @@ class InlineBytecodeTests extends DottyBytecodeTest {
163163

164164
@Test def i4947c = {
165165
val source = """class Foo {
166-
| inline def track2[T](f: => T) <: T = {
166+
| inline def track2[T](inline f: T) <: T = {
167167
| foo("tracking2") // line 3
168168
| f // line 4
169169
| }
170-
| inline def track[T](f: => T) <: T = {
170+
| inline def track[T](inline f: T) <: T = {
171171
| track2 { // line 7
172172
| foo("fgh") // line 8
173173
| f // line 9
@@ -223,11 +223,11 @@ class InlineBytecodeTests extends DottyBytecodeTest {
223223

224224
@Test def i4947d = {
225225
val source = """class Foo {
226-
| inline def track2[T](f: => T) <: T = {
226+
| inline def track2[T](inline f: T) <: T = {
227227
| foo("tracking2") // line 3
228228
| f // line 4
229229
| }
230-
| inline def track[T](f: => T) <: T = {
230+
| inline def track[T](inline f: T) <: T = {
231231
| track2 { // line 7
232232
| track2 { // line 8
233233
| f // line 9

library/src/dotty/DottyPredef.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ object DottyPredef {
88
assertFail(message)
99
}
1010

11-
inline final def assert(assertion: => Boolean) <: Unit = {
11+
inline final def assert(inline assertion: => Boolean) <: Unit = {
1212
if (!assertion)
1313
assertFail()
1414
}

0 commit comments

Comments
 (0)