Skip to content

Commit 809f12c

Browse files
committed
check for illegal uses of @unroll
1 parent 44a3048 commit 809f12c

File tree

3 files changed

+91
-1
lines changed

3 files changed

+91
-1
lines changed

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

+26-1
Original file line numberDiff line numberDiff line change
@@ -81,18 +81,37 @@ class CrossVersionChecks extends MiniPhase:
8181
report.deprecationWarning(em"inheritance from $psym is deprecated$since$msg", parent.srcPos, origin=psym.showFullName)
8282
}
8383

84+
private def unrollError(pos: SrcPos)(using Context): Unit =
85+
report.error("@unroll is only allowed on a method parameter", pos)
86+
87+
private def checkUnrollAnnot(annotSym: Symbol, pos: SrcPos)(using Context): Unit =
88+
if annotSym == defn.UnrollAnnot then
89+
unrollError(pos)
90+
91+
private def checkUnrollMemberDef(memberDef: MemberDef)(using Context): Unit =
92+
val sym = memberDef.symbol
93+
if
94+
sym.hasAnnotation(defn.UnrollAnnot)
95+
&& !(sym.isTerm && sym.is(Param))
96+
then
97+
val normSym = if sym.is(ModuleVal) then sym.moduleClass else sym
98+
unrollError(normSym.srcPos)
99+
84100
override def transformValDef(tree: ValDef)(using Context): ValDef =
101+
checkUnrollMemberDef(tree)
85102
checkDeprecatedOvers(tree)
86103
checkExperimentalAnnots(tree.symbol)
87104
tree
88105

89106
override def transformDefDef(tree: DefDef)(using Context): DefDef =
107+
checkUnrollMemberDef(tree)
90108
checkDeprecatedOvers(tree)
91109
checkExperimentalAnnots(tree.symbol)
92110
tree
93111

94112
override def transformTypeDef(tree: TypeDef)(using Context): TypeDef =
95113
// TODO do we need to check checkDeprecatedOvers(tree)?
114+
checkUnrollMemberDef(tree)
96115
checkExperimentalAnnots(tree.symbol)
97116
tree
98117

@@ -126,6 +145,8 @@ class CrossVersionChecks extends MiniPhase:
126145
if tree.span.isSourceDerived then
127146
checkDeprecatedRef(sym, tree.srcPos)
128147
checkExperimentalRef(sym, tree.srcPos)
148+
case AnnotatedType(_, annot) =>
149+
checkUnrollAnnot(annot.symbol, tree.srcPos)
129150
case _ =>
130151
}
131152
tree
@@ -140,7 +161,11 @@ class CrossVersionChecks extends MiniPhase:
140161
case tree: TypeTree => transformTypeTree(tree)
141162
case _ =>
142163
}
143-
tree
164+
tree match
165+
case Annotated(_, annot) =>
166+
checkUnrollAnnot(annot.tpe.typeSymbol, tree.srcPos)
167+
tree
168+
case tree => tree
144169

145170
end CrossVersionChecks
146171

tests/neg/unroll-illegal.check

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
-- Error: tests/neg/unroll-illegal.scala:6:6 ---------------------------------------------------------------------------
2+
6 |class UnrollClass // error
3+
| ^
4+
| @unroll is only allowed on a method parameter
5+
-- Error: tests/neg/unroll-illegal.scala:9:6 ---------------------------------------------------------------------------
6+
9 |trait UnrollTrait // error
7+
| ^
8+
| @unroll is only allowed on a method parameter
9+
-- Error: tests/neg/unroll-illegal.scala:12:7 --------------------------------------------------------------------------
10+
12 |object UnrollObject // error
11+
| ^
12+
| @unroll is only allowed on a method parameter
13+
-- Error: tests/neg/unroll-illegal.scala:18:5 --------------------------------------------------------------------------
14+
18 |enum UnrollEnum { case X } // error
15+
| ^
16+
| @unroll is only allowed on a method parameter
17+
-- Error: tests/neg/unroll-illegal.scala:21:25 -------------------------------------------------------------------------
18+
21 | val annotExpr: Int = 23: @unroll // error
19+
| ^
20+
| @unroll is only allowed on a method parameter
21+
-- Error: tests/neg/unroll-illegal.scala:22:19 -------------------------------------------------------------------------
22+
22 | type annotType = Int @unroll // error
23+
| ^^^^^^^^^^^
24+
| @unroll is only allowed on a method parameter
25+
-- Error: tests/neg/unroll-illegal.scala:25:6 --------------------------------------------------------------------------
26+
25 | val unrollVal: Int = 23 // error
27+
| ^
28+
| @unroll is only allowed on a method parameter
29+
-- Error: tests/neg/unroll-illegal.scala:28:6 --------------------------------------------------------------------------
30+
28 | def unrollDef: Int = 23 // error
31+
| ^
32+
| @unroll is only allowed on a method parameter
33+
-- Error: tests/neg/unroll-illegal.scala:15:5 --------------------------------------------------------------------------
34+
15 |type UnrollType = Int // error
35+
| ^
36+
| @unroll is only allowed on a method parameter

tests/neg/unroll-illegal.scala

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//> using options -experimental
2+
3+
import scala.annotation.unroll
4+
5+
@unroll
6+
class UnrollClass // error
7+
8+
@unroll
9+
trait UnrollTrait // error
10+
11+
@unroll
12+
object UnrollObject // error
13+
14+
@unroll
15+
type UnrollType = Int // error
16+
17+
@unroll
18+
enum UnrollEnum { case X } // error
19+
20+
object wrap {
21+
val annotExpr: Int = 23: @unroll // error
22+
type annotType = Int @unroll // error
23+
24+
@unroll
25+
val unrollVal: Int = 23 // error
26+
27+
@unroll
28+
def unrollDef: Int = 23 // error
29+
}

0 commit comments

Comments
 (0)