diff --git a/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala b/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala index 2eacd1b010e1..2cb17d216f68 100644 --- a/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala +++ b/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala @@ -9,6 +9,7 @@ import dotty.tools.dotc.core.Names.TermName import dotty.tools.dotc.core.StdNames._ import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.core.Types._ +import dotty.tools.dotc.core.NameKinds._ import dotty.tools.dotc.transform.MegaPhase.MiniPhase object InterceptedMethods { @@ -22,6 +23,7 @@ object InterceptedMethods { * - `x.##` for ## in Any becomes calls to ScalaRunTime.hash, * using the most precise overload available * - `x.getClass` for getClass in primitives becomes `x.getClass` with getClass in class Object. + * - `!{...;true}` becomes val tmp = {...;true};!tmp (similar to other primitives/unary ops) */ class InterceptedMethods extends MiniPhase { import tpd._ @@ -45,6 +47,16 @@ class InterceptedMethods extends MiniPhase { ctx.log(s"$phaseName rewrote $tree to $rewritten") rewritten } + // if the qualifier is constant folded then its type doesn't have a symbol + // in case a unary operator is applied to a block (potentially containing impure expressions) + // we create a synthetic variable and then apply the operator + else if (!tree.qualifier.symbol.exists && tree.name.startsWith(nme.UNARY_PREFIX.toString)) { + val tempDef = SyntheticValDef(UniqueName.fresh().toTermName, tree.qualifier) + val rewritten = Block(tempDef :: Nil, ref(tempDef.symbol).select(tree.name)) + ctx.log(s"$phaseName rewrote $tree to $rewritten") + + rewritten + } else tree } diff --git a/tests/pos/i5386.scala b/tests/pos/i5386.scala new file mode 100644 index 000000000000..56c509d1309d --- /dev/null +++ b/tests/pos/i5386.scala @@ -0,0 +1,23 @@ +object Test { + ~{ + println("!") + 1 + } + + +{ + println("!") + 1 + } + + -{ + println("!") + 1 + } + + !{ + println("!") + true + } + + !(try true finally{()}) +} \ No newline at end of file