Skip to content

Commit 862e9b3

Browse files
committed
Fix #2712: Check lazy keyword
1 parent 79705ca commit 862e9b3

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
@@ -1228,7 +1228,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
12281228
case rhs => typedExpr(rhs, tpt1.tpe)
12291229
}
12301230
val vdef1 = assignType(cpy.ValDef(vdef)(name, tpt1, rhs1), sym)
1231-
checkInlineKeyword(vdef1)
1231+
checkKeywords(vdef1)
12321232
if (sym.is(Inline, butNot = DeferredOrParamAccessor))
12331233
checkInlineConformant(rhs1, em"right-hand side of inline $sym")
12341234
patchIfLazy(vdef1)
@@ -1296,7 +1296,11 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
12961296
tpt1 = tpt1.withType(avoid(tpt1.tpe, vparamss1.flatMap(_.map(_.symbol))))
12971297
}
12981298

1299-
assignType(cpy.DefDef(ddef)(name, tparams1, vparamss1, tpt1, rhs1), sym)
1299+
val ddef1 = assignType(cpy.DefDef(ddef)(name, tparams1, vparamss1, tpt1, rhs1), sym)
1300+
1301+
checkKeywords(ddef1)
1302+
1303+
ddef1
13001304
//todo: make sure dependent method types do not depend on implicits or by-name params
13011305
}
13021306

@@ -1312,7 +1316,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
13121316
typedType(rhs)
13131317
}
13141318
val tdef1 = assignType(cpy.TypeDef(tdef)(name, rhs1), sym)
1315-
checkInlineKeyword(tdef1)
1319+
checkKeywords(tdef1)
13161320
tdef1
13171321
}
13181322

@@ -1415,7 +1419,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
14151419
// check value class constraints
14161420
checkDerivedValueClass(cls, body1)
14171421

1418-
checkInlineKeyword(cdef1)
1422+
checkKeywords(cdef1)
14191423

14201424
if (ctx.settings.YretainTrees.value) {
14211425
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)