Skip to content

Commit bf64e9d

Browse files
committed
Fix scala#9751: Fix Inline puurity checks
1 parent ce48f5a commit bf64e9d

File tree

7 files changed

+44
-5
lines changed

7 files changed

+44
-5
lines changed

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,12 +454,14 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
454454
def refPurity(tree: Tree)(using Context): PurityLevel = {
455455
val sym = tree.symbol
456456
if (!tree.hasType) Impure
457-
else if (!tree.tpe.widen.isParameterless || sym.isEffectivelyErased) PurePath
457+
else if !tree.tpe.widen.isParameterless then PurePath
458+
else if sym.is(Erased) then PurePath
458459
else if tree.tpe.isInstanceOf[ConstantType] then PurePath
459460
else if (!sym.isStableMember) Impure
460461
else if (sym.is(Module))
461462
if (sym.moduleClass.isNoInitsClass) PurePath else IdempotentPath
462463
else if (sym.is(Lazy)) IdempotentPath
464+
else if sym.isAllOf(Inline | Param) then Impure
463465
else PurePath
464466
}
465467

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
521521
| Literal(_) =>
522522
true
523523
case Ident(_) =>
524-
isPureRef(tree)
524+
isPureRef(tree) || tree.symbol.isAllOf(Inline | Param)
525525
case Select(qual, _) =>
526526
if (tree.symbol.is(Erased)) true
527527
else isPureRef(tree) && apply(qual)

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3629,8 +3629,12 @@ class Typer extends Namer
36293629
}
36303630

36313631
private def checkStatementPurity(tree: tpd.Tree)(original: untpd.Tree, exprOwner: Symbol)(using Context): Unit =
3632-
if (!tree.tpe.isErroneous && !ctx.isAfterTyper && isPureExpr(tree) &&
3633-
!tree.tpe.isRef(defn.UnitClass) && !isSelfOrSuperConstrCall(tree))
3632+
if !tree.tpe.isErroneous
3633+
&& !ctx.isAfterTyper
3634+
&& !tree.isInstanceOf[Inlined]
3635+
&& isPureExpr(tree)
3636+
&& !isSelfOrSuperConstrCall(tree)
3637+
then
36343638
report.warning(PureExpressionInStatementPosition(original, exprOwner), original.srcPos)
36353639

36363640
/** Types the body Scala 2 macro declaration `def f = macro <body>` */

library/src/dotty/DottyPredef.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package dotty
33
object DottyPredef {
44
import compiletime.summonFrom
55

6-
inline final def assert(inline assertion: Boolean, inline message: => Any): Unit = {
6+
inline final def assert(inline assertion: Boolean, inline message: Any): Unit = {
77
if (!assertion)
88
assertFail(message)
99
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
def f(): Unit = {
2+
() // error
3+
()
4+
}
5+
6+
inline def g(): Unit = {
7+
() // error
8+
()
9+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
object Test {
2+
extension (x: Int)
3+
inline def times(inline op: Unit): Unit = {
4+
var count = 0
5+
while count < x do
6+
op
7+
count += 1
8+
}
9+
10+
10.times { println("hello") }
11+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
object Test {
2+
inline def f(inline x: Boolean): Unit =
3+
inline if x then println()
4+
5+
f(true)
6+
f(false)
7+
8+
inline def g(inline x: => Boolean): Unit =
9+
inline if x then println()
10+
11+
g(true)
12+
g(false)
13+
}

0 commit comments

Comments
 (0)