Skip to content

Commit b9fdb78

Browse files
committed
Fix #2712: Check lazy keyword
1 parent 6409a78 commit b9fdb78

File tree

4 files changed

+30
-7
lines changed

4 files changed

+30
-7
lines changed

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

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -550,17 +550,25 @@ trait Checking {
550550
tp
551551
}
552552

553-
/** Check that inline is only used on valid trees */
554-
def checkInlineKeyword(tree: tpd.Tree)(implicit ctx: Context) = {
553+
/** Check that keywords are only used on valid trees */
554+
def checkKeywords(tree: tpd.Tree)(implicit ctx: Context): Unit = {
555555
val sym = tree.symbol
556-
def error() = ctx.error("inlined keyword cannot be used on " + ctx.kindString(sym), tree.pos)
557556
if (sym is Inline) {
557+
def error() = ctx.error("inlined keyword cannot be used on " + ctx.kindString(sym), tree.pos)
558558
tree match {
559559
case _: TypeDef => error()
560560
case _: ValDef if sym.is(Module) || sym.is(Mutable) || sym.is(Lazy) => error()
561561
case _ =>
562562
}
563563
}
564+
if (sym is Lazy) {
565+
def error(kind: String) = ctx.error("lazy keyword cannot be used on " + kind, tree.pos)
566+
tree match {
567+
case _: DefDef => error("def")
568+
case _: ValDef if sym.is(Mutable) => error("var")
569+
case _ =>
570+
}
571+
}
564572
}
565573

566574
/** Check that `tree` is a pure expression of constant type */

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,7 +1204,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
12041204
case rhs => typedExpr(rhs, tpt1.tpe)
12051205
}
12061206
val vdef1 = assignType(cpy.ValDef(vdef)(name, tpt1, rhs1), sym)
1207-
checkInlineKeyword(vdef1)
1207+
checkKeywords(vdef1)
12081208
if (sym.is(Inline, butNot = DeferredOrParamAccessor))
12091209
checkInlineConformant(rhs1, em"right-hand side of inline $sym")
12101210
patchIfLazy(vdef1)
@@ -1272,7 +1272,11 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
12721272
tpt1 = tpt1.withType(avoid(tpt1.tpe, vparamss1.flatMap(_.map(_.symbol))))
12731273
}
12741274

1275-
assignType(cpy.DefDef(ddef)(name, tparams1, vparamss1, tpt1, rhs1), sym)
1275+
val ddef1 = assignType(cpy.DefDef(ddef)(name, tparams1, vparamss1, tpt1, rhs1), sym)
1276+
1277+
checkKeywords(ddef1)
1278+
1279+
ddef1
12761280
//todo: make sure dependent method types do not depend on implicits or by-name params
12771281
}
12781282

@@ -1288,7 +1292,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
12881292
typedType(rhs)
12891293
}
12901294
val tdef1 = assignType(cpy.TypeDef(tdef)(name, rhs1), sym)
1291-
checkInlineKeyword(tdef1)
1295+
checkKeywords(tdef1)
12921296
tdef1
12931297
}
12941298

@@ -1391,7 +1395,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
13911395
// check value class constraints
13921396
checkDerivedValueClass(cls, body1)
13931397

1394-
checkInlineKeyword(cdef1)
1398+
checkKeywords(cdef1)
13951399

13961400
if (ctx.settings.YretainTrees.value) {
13971401
cls.myTree = cdef1

tests/neg/i2712.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
object Foo {
2+
lazy var x: Int = 42 // error
3+
lazy def y: Int = 42 // error
4+
}

tests/neg/i2712b.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
lazy class Bar // error: modifier(s) `lazy' incompatible with type definition
2+
lazy abstract class Baz // error: modifier(s) `lazy abstract' incompatible with type definition
3+
lazy trait Qux // error: modifier(s) `lazy' not allowed for trait
4+
5+
object Quux {
6+
lazy type T // error: modifier(s) `lazy' incompatible with type definition
7+
}

0 commit comments

Comments
 (0)