Skip to content

Commit 46cba9e

Browse files
committed
Only allow sound inline parameters in overrides
Inline overrides can only use inline parameters if the overriden parameter is inline.
1 parent d010ef7 commit 46cba9e

File tree

4 files changed

+51
-3
lines changed

4 files changed

+51
-3
lines changed

compiler/src/dotty/tools/dotc/config/Printers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ object Printers {
77
}
88

99
object noPrinter extends Printer {
10-
inline override def println(inline msg: => String): Unit = ()
10+
inline override def println(msg: => String): Unit = ()
1111
}
1212

1313
val default = new Printer

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,8 @@ object Checking {
451451
|| sym.is(TermParam) && !sym.owner.isInlineMethod
452452
))
453453
fail(ParamsNoInline(sym.owner))
454-
454+
if sym.isInlineMethod && !sym.is(Deferred) && sym.allOverriddenSymbols.nonEmpty then
455+
checkInlineOverrideParameters(sym)
455456
if (sym.isOneOf(GivenOrImplicit)) {
456457
if (sym.owner.is(Package))
457458
fail(TopLevelCantBeImplicit(sym))
@@ -646,6 +647,18 @@ object Checking {
646647
val enumCls = enumCase.owner.linkedClass
647648
if !cls.info.parents.exists(_.typeSymbol == enumCls) then
648649
ctx.error(i"enum case does not extend its enum $enumCls", enumCase.sourcePos)
650+
651+
/** Check the inline override methods only use inline parameteres if they override an inline parameter. */
652+
def checkInlineOverrideParameters(sym: Symbol)(using Context): Unit =
653+
val params = sym.paramSymss.flatten
654+
if params.exists(_.is(Inline)) then
655+
for
656+
sym2 <- sym.allOverriddenSymbols
657+
(p1, p2) <- params.lazyZip(sym2.paramSymss.flatten)
658+
if p1.is(Inline) && !p2.is(Inline)
659+
do
660+
ctx.error("Cannot override non-inline parameter with and inline parameter", p1.sourcePos)
661+
649662
}
650663

651664
trait Checking {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
2+
3+
abstract class Logger {
4+
def log1(msg: String): Unit
5+
inline def log2(msg: String): Unit
6+
inline def log3(inline msg: String): Unit
7+
}
8+
9+
class Logger1 extends Logger {
10+
inline def log1(msg: String): Unit = ()
11+
inline def log2(msg: String): Unit = ()
12+
inline def log3(msg: String): Unit = ()
13+
}
14+
15+
class Logger2 extends Logger {
16+
inline def log1(inline msg: String): Unit = () // error: Cannot override non-inline parameter with and inline parameter
17+
inline def log2(inline msg: String): Unit = () // error: Cannot override non-inline parameter with and inline parameter
18+
inline def log3(inline msg: String): Unit = ()
19+
}
20+
21+
trait A {
22+
inline def f(inline a: Int): Int
23+
}
24+
25+
trait B {
26+
def f(a: Int): Int
27+
}
28+
29+
class C extends A, B {
30+
inline def f(inline a: Int): Int = 3 // error: Cannot override non-inline parameter with and inline parameter
31+
}
32+
33+
class D extends B, A {
34+
inline def f(inline a: Int): Int = 3 // error: Cannot override non-inline parameter with and inline parameter
35+
}

tests/run/inline-override-num.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ trait Num[T] {
44

55
object Num {
66
class IntNum extends Num[Int] {
7-
inline def plus(inline x: Int, inline y: Int): Int = x + y
7+
inline def plus(x: Int, y: Int): Int = x + y
88
}
99
given IntNum
1010

0 commit comments

Comments
 (0)