Skip to content

Commit e9cd045

Browse files
committed
Make sure that inline val can be inlined
Inline vals are inlined based on their literal type. We only checked that the RHS had a literal type that could be inlined, but we did not check if the type of the val was also a literal. When it is not, the value will not be inlined.
1 parent 63ee630 commit e9cd045

File tree

4 files changed

+16
-14
lines changed

4 files changed

+16
-14
lines changed

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

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -862,15 +862,14 @@ trait Checking {
862862
}
863863

864864
/** Check that `tree` can be right hand-side or argument to `inline` value or parameter. */
865-
def checkInlineConformant(tree: Tree, isFinal: Boolean, what: => String)(using Context): Unit = {
866-
// final vals can be marked inline even if they're not pure, see Typer#patchFinalVals
867-
val purityLevel = if (isFinal) Idempotent else Pure
868-
tree.tpe.widenTermRefExpr match {
869-
case tp: ConstantType if exprPurity(tree) >= purityLevel => // ok
870-
case _ =>
871-
if (!ctx.erasedTypes && !ctx.inInlineMethod)
872-
ctx.error(em"$what must be a known value", tree.sourcePos)
873-
}
865+
def checkInlineConformant(tpt: Tree, tree: Tree, sym: Symbol)(using Context): Unit = {
866+
if sym.is(Inline, butNot = DeferredOrTermParamOrAccessor) && !ctx.erasedTypes && !ctx.inInlineMethod then
867+
// final vals can be marked inline even if they're not pure, see Typer#patchFinalVals
868+
val purityLevel = if (sym.is(Final)) Idempotent else Pure
869+
tpt.tpe.widenTermRefExpr match
870+
case tp: ConstantType if exprPurity(tree) >= purityLevel => // ok
871+
case _ =>
872+
ctx.error(em"type of inline must be a known value", tree.sourcePos)
874873
}
875874

876875
/** A hook to exclude selected symbols from double declaration check */
@@ -1199,7 +1198,7 @@ trait NoChecking extends ReChecking {
11991198
override def checkImplicitConversionDefOK(sym: Symbol)(using Context): Unit = ()
12001199
override def checkImplicitConversionUseOK(sym: Symbol, posd: Positioned)(using Context): Unit = ()
12011200
override def checkFeasibleParent(tp: Type, pos: SourcePosition, where: => String = "")(using Context): Type = tp
1202-
override def checkInlineConformant(tree: Tree, isFinal: Boolean, what: => String)(using Context): Unit = ()
1201+
override def checkInlineConformant(tpt: Tree, tree: Tree, sym: Symbol)(using Context): Unit = ()
12031202
override def checkNoAlphaConflict(stats: List[Tree])(using Context): Unit = ()
12041203
override def checkParentCall(call: Tree, caller: ClassSymbol)(using Context): Unit = ()
12051204
override def checkSimpleKinded(tpt: Tree)(using Context): Tree = tpt

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1803,8 +1803,7 @@ class Typer extends Namer
18031803
}
18041804
val vdef1 = assignType(cpy.ValDef(vdef)(name, tpt1, rhs1), sym)
18051805
checkSignatureRepeatedParam(sym)
1806-
if (sym.is(Inline, butNot = DeferredOrTermParamOrAccessor))
1807-
checkInlineConformant(rhs1, isFinal = sym.is(Final), em"right-hand side of inline $sym")
1806+
checkInlineConformant(tpt1, rhs1, sym)
18081807
patchFinalVals(vdef1)
18091808
vdef1.setDefTree
18101809
}

tests/neg/i2421.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ inline trait Qux // error: modifier(s) `inline' incompatible with type definitio
55

66
object Quux {
77
inline type T // error: modifier(s) `inline' incompatible with type definition
8-
inline var x: Int = 42 // error: modifier(s) `inline' incompatible with var definition
9-
inline lazy val y: Int = 43 // error: modifier(s) `inline' incompatible with lazy val definition
8+
inline var x: 42 = 42 // error: modifier(s) `inline' incompatible with var definition
9+
inline lazy val y: 43 = 43 // error: modifier(s) `inline' incompatible with lazy val definition
1010
}

tests/neg/inline-val.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
inline val a = 1 : Int // error
3+
inline val b: Int = 1 // error
4+
inline val c = b // error

0 commit comments

Comments
 (0)