Skip to content

Commit cfc1c69

Browse files
Merge pull request #9319 from dotty-staging/fix-#9308
Fix #9306: Don't allow inline functions with errors in bodies
2 parents 33e34b7 + 931acfd commit cfc1c69

File tree

7 files changed

+44
-17
lines changed

7 files changed

+44
-17
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1492,7 +1492,8 @@ class Namer { typer: Typer =>
14921492
rhsCtx.setFreshGADTBounds
14931493
rhsCtx.gadt.addToConstraint(typeParams)
14941494
}
1495-
def rhsType = typedAheadExpr(mdef.rhs, (inherited orElse rhsProto).widenExpr)(using rhsCtx).tpe
1495+
def rhsType = PrepareInlineable.dropInlineIfError(sym,
1496+
typedAheadExpr(mdef.rhs, (inherited orElse rhsProto).widenExpr)(using rhsCtx)).tpe
14961497

14971498
// Approximate a type `tp` with a type that does not contain skolem types.
14981499
val deskolemize = new ApproximatingTypeMap {

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

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,17 @@ object PrepareInlineable {
209209
if original.mods.hasMod(classOf[untpd.Mod.Transparent]) then rhs
210210
else Typed(rhs, tpt)
211211

212+
/** Return result of evaluating `op`, but drop `Inline` flag and `Body` annotation
213+
* of `sym` in case that leads to errors.
214+
*/
215+
def dropInlineIfError(sym: Symbol, op: => Tree)(using Context): Tree =
216+
val initialErrorCount = ctx.reporter.errorCount
217+
try op
218+
finally
219+
if ctx.reporter.errorCount != initialErrorCount then
220+
sym.resetFlag(Inline)
221+
sym.removeAnnotation(defn.BodyAnnot)
222+
212223
/** Register inline info for given inlineable method `sym`.
213224
*
214225
* @param sym The symbol denotation of the inlineable method for which info is registered
@@ -227,21 +238,18 @@ object PrepareInlineable {
227238
val inlineCtx = ctx
228239
inlined.updateAnnotation(LazyBodyAnnotation {
229240
given ctx as Context = inlineCtx
230-
val initialErrorCount = ctx.reporter.errorCount
231-
var inlinedBody = treeExpr
232-
if (ctx.reporter.errorCount == initialErrorCount) {
233-
inlinedBody = ctx.compilationUnit.inlineAccessors.makeInlineable(inlinedBody)
234-
checkInlineMethod(inlined, inlinedBody)
235-
if (ctx.reporter.errorCount != initialErrorCount)
236-
inlinedBody = EmptyTree
237-
}
241+
var inlinedBody = dropInlineIfError(inlined, treeExpr)
242+
if inlined.isInlineMethod then
243+
inlinedBody = dropInlineIfError(inlined,
244+
checkInlineMethod(inlined,
245+
ctx.compilationUnit.inlineAccessors.makeInlineable(inlinedBody)))
238246
inlining.println(i"Body to inline for $inlined: $inlinedBody")
239247
inlinedBody
240248
})
241249
}
242250
}
243251

244-
def checkInlineMethod(inlined: Symbol, body: Tree)(using Context): Unit = {
252+
def checkInlineMethod(inlined: Symbol, body: Tree)(using Context): body.type = {
245253
if (inlined.owner.isClass && inlined.owner.seesOpaques)
246254
ctx.error(em"Implementation restriction: No inline methods allowed where opaque type aliases are in scope", inlined.sourcePos)
247255
if Inliner.inInlineMethod(using ctx.outer) then
@@ -278,5 +286,6 @@ object PrepareInlineable {
278286
}
279287
checkMacro(body)
280288
}
289+
body
281290
}
282291
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1936,11 +1936,11 @@ class Typer extends Namer
19361936
}
19371937

19381938
if (sym.isInlineMethod) rhsCtx.addMode(Mode.InlineableBody)
1939-
val rhs1 =
1939+
val rhs1 = PrepareInlineable.dropInlineIfError(sym,
19401940
if sym.isScala2Macro then typedScala2MacroBody(ddef.rhs)(using rhsCtx)
1941-
else typedExpr(ddef.rhs, tpt1.tpe.widenExpr)(using rhsCtx)
1941+
else typedExpr(ddef.rhs, tpt1.tpe.widenExpr)(using rhsCtx))
19421942

1943-
if (sym.isInlineMethod)
1943+
if sym.isInlineMethod then
19441944
val rhsToInline = PrepareInlineable.wrapRHS(ddef, tpt1, rhs1)
19451945
PrepareInlineable.registerInlineInfo(sym, rhsToInline)
19461946

tests/neg-macros/i6530.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
object Macros {
22
inline def q : Int = ${ '[ Int ] } // error
3-
val x : Int = 1 + q // error
4-
}
3+
val x : Int = 1 + q
4+
}

tests/neg/i7294-a.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ inline given f[T <: Foo] as T = ??? match {
66
case x: T => x.g(10) // error
77
}
88

9-
@main def Test = f // error // error
9+
@main def Test = f

tests/neg/i7294-b.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ inline given f[T <: Foo] as T = ??? match {
66
case x: T => x.g(10) // error
77
}
88

9-
@main def Test = f // error // error
9+
@main def Test = f

tests/neg/i9308.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
object Baz {
3+
class Foo {
4+
private var v = 0
5+
inline def run1 = {
6+
v += { v = 1 } // error
7+
v
8+
}
9+
inline def run2: Int = {
10+
v += { v = 1 } // error
11+
v
12+
}
13+
}
14+
val foo = new Foo
15+
foo.run1
16+
foo.run2
17+
}

0 commit comments

Comments
 (0)