aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-03-09 09:46:12 +0100
committerMartin Odersky <odersky@gmail.com>2016-03-12 16:08:39 +0100
commit13e3d59937ddcb9819904593cb7c6417af8eedd2 (patch)
treea676e3455112c20681b853812da7f94dfe5a4a47 /src/dotty/tools/dotc
parent13a376c80c21ddb28789530091bb54f7fa58e785 (diff)
downloaddotty-13e3d59937ddcb9819904593cb7c6417af8eedd2.tar.gz
dotty-13e3d59937ddcb9819904593cb7c6417af8eedd2.tar.bz2
dotty-13e3d59937ddcb9819904593cb7c6417af8eedd2.zip
Fix two rewrite patches.
1. trailing `_`: `x _` is rewritten to `(() => x)` not to `x` 2. lazy vals: Rewrites are done in Typer, not LazyVals. Later on we are too much at risk to hit synthetically generated lazy vals.
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r--src/dotty/tools/dotc/transform/LazyVals.scala18
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala19
2 files changed, 23 insertions, 14 deletions
diff --git a/src/dotty/tools/dotc/transform/LazyVals.scala b/src/dotty/tools/dotc/transform/LazyVals.scala
index ed5c23f8c..50db7b3fb 100644
--- a/src/dotty/tools/dotc/transform/LazyVals.scala
+++ b/src/dotty/tools/dotc/transform/LazyVals.scala
@@ -15,7 +15,6 @@ import StdNames.nme
import rewrite.Rewrites.patch
import util.Positions.Position
import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, TreeTransformer, MiniPhaseTransform}
-import dotty.tools.dotc.ast.NavigateAST._
import dotty.tools.dotc.ast.Trees._
import dotty.tools.dotc.ast.{untpd, tpd}
import dotty.tools.dotc.core.Constants.Constant
@@ -71,19 +70,14 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer with Nee
val isField = sym.owner.isClass
if (isField) {
if (sym.isVolatile ||
- ctx.scala2Mode && {
- if (ctx.settings.rewrite.value.isDefined)
- patch(ctx.compilationUnit.source, Position(toUntyped(tree).envelope.start), "@volatile ")
- false // cannot assume volatile because of problems with compilestdlib. See #1149
- } ||
- (sym.is(Flags.Module) && !sym.is(Flags.Synthetic)))
- // module class is user-defined.
- // Should be threadsafe, to mimic safety guaranteed by global object
+ (sym.is(Flags.Module)/* || ctx.scala2Mode*/) && !sym.is(Flags.Synthetic)) // TODO assume @voliat
+ // module class is user-defined.
+ // Should be threadsafe, to mimic safety guaranteed by global object
transformMemberDefVolatile(tree)
- else if (sym.is(Flags.Module)) { // synthetic module
+ else if (sym.is(Flags.Module)) // synthetic module
transformSyntheticModule(tree)
- }
- else transformMemberDefNonVolatile(tree)
+ else
+ transformMemberDefNonVolatile(tree)
}
else transformLocalDef(tree)
}
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index b9940e367..1a0525c6d 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -34,6 +34,8 @@ import Implicits._
import util.Stats.{track, record}
import config.Printers._
import rewrite.Rewrites.patch
+import NavigateAST._
+import transform.SymUtils._
import language.implicitConversions
object Typer {
@@ -985,7 +987,18 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
case rhs @ Ident(nme.WILDCARD) => rhs withType tpt1.tpe
case rhs => typedExpr(rhs, tpt1.tpe)
}
- assignType(cpy.ValDef(vdef)(name, tpt1, rhs1), sym)
+ val vdef1 = assignType(cpy.ValDef(vdef)(name, tpt1, rhs1), sym)
+ patchIfLazy(vdef1)
+ vdef1
+ }
+
+ /** Add a @volitile to lazy vals when rewriting from Scala2 */
+ private def patchIfLazy(vdef: ValDef)(implicit ctx: Context): Unit = {
+ val sym = vdef.symbol
+ if (sym.is(Lazy, butNot = Deferred | Module | Synthetic) && !sym.isVolatile &&
+ ctx.scala2Mode && ctx.settings.rewrite.value.isDefined &&
+ !ctx.isAfterTyper)
+ patch(ctx.compilationUnit.source, Position(toUntyped(vdef).envelope.start), "@volatile ")
}
def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(implicit ctx: Context) = track("typedDefDef") {
@@ -1143,8 +1156,10 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
if (pt1.eq(AnyFunctionProto) && !defn.isFunctionClass(res.tpe.classSymbol)) {
def msg = i"not a function: ${res.tpe}; cannot be followed by `_'"
if (ctx.scala2Mode) {
+ // Under -rewrite, patch `x _` to `(() => x)`
ctx.migrationWarning(msg, tree.pos)
- patch(ctx.compilationUnit.source, Position(qual.pos.end, tree.pos.end), "")
+ patch(ctx.compilationUnit.source, Position(tree.pos.start), "(() => ")
+ patch(ctx.compilationUnit.source, Position(qual.pos.end, tree.pos.end), ")")
res = typed(untpd.Function(Nil, untpd.TypedSplice(res)))
}
else ctx.error(msg, tree.pos)