Skip to content

Commit 63771ac

Browse files
authored
Merge pull request #9836 from tudorv91/fix-#9772
Fix #9772: Normalize value definitions
2 parents ca67e4d + 341afb3 commit 63771ac

File tree

4 files changed

+70
-16
lines changed

4 files changed

+70
-16
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -147,24 +147,32 @@ object desugar {
147147

148148
// ----- Desugar methods -------------------------------------------------
149149

150+
/** Setter generation is needed for:
151+
* - non-private class members
152+
* - all trait members
153+
* - all package object members
154+
*/
155+
def isSetterNeeded(valDef: ValDef)(using Context): Boolean = {
156+
val mods = valDef.mods
157+
mods.is(Mutable)
158+
&& ctx.owner.isClass
159+
&& (!mods.is(Private) || ctx.owner.is(Trait) || ctx.owner.isPackageObject)
160+
}
161+
150162
/** var x: Int = expr
151163
* ==>
152164
* def x: Int = expr
153165
* def x_=($1: <TypeTree()>): Unit = ()
154166
*
155-
* Generate the setter only for
156-
* - non-private class members
157-
* - all trait members
158-
* - all package object members
167+
* Generate setter where needed
159168
*/
160169
def valDef(vdef0: ValDef)(using Context): Tree = {
161-
val vdef @ ValDef(name, tpt, rhs) = vdef0
170+
val vdef @ ValDef(_, tpt, rhs) = vdef0
162171
val mods = vdef.mods
163-
val setterNeeded =
164-
mods.is(Mutable)
165-
&& ctx.owner.isClass
166-
&& (!mods.is(Private) || ctx.owner.is(Trait) || ctx.owner.isPackageObject)
167-
if (setterNeeded) {
172+
173+
val valName = normalizeName(vdef, tpt).asTermName
174+
175+
if (isSetterNeeded(vdef)) {
168176
// TODO: copy of vdef as getter needed?
169177
// val getter = ValDef(mods, name, tpt, rhs) withPos vdef.pos?
170178
// right now vdef maps via expandedTree to a thicket which concerns itself.
@@ -173,7 +181,7 @@ object desugar {
173181
// The rhs gets filled in later, when field is generated and getter has parameters (see Memoize miniphase)
174182
val setterRhs = if (vdef.rhs.isEmpty) EmptyTree else unitLiteral
175183
val setter = cpy.DefDef(vdef)(
176-
name = name.setterName,
184+
name = valName.setterName,
177185
tparams = Nil,
178186
vparamss = (setterParam :: Nil) :: Nil,
179187
tpt = TypeTree(defn.UnitType),
@@ -887,7 +895,7 @@ object desugar {
887895
mdef.tparams.head.srcPos)
888896
defDef(
889897
cpy.DefDef(mdef)(
890-
name = mdef.name.toExtensionName,
898+
name = normalizeName(mdef, ext).toExtensionName,
891899
tparams = ext.tparams ++ mdef.tparams,
892900
vparamss = mdef.vparamss match
893901
case vparams1 :: vparamss1 if mdef.name.isRightAssocOperatorName =>
@@ -934,8 +942,13 @@ object desugar {
934942
report.error(IllegalRedefinitionOfStandardKind(kind, name), errPos)
935943
name = name.errorName
936944
}
937-
if name.isExtensionName && (!mdef.mods.is(ExtensionMethod) || name.dropExtension.isExtensionName) then
938-
report.error(em"illegal method name: $name may not start with `extension_`", errPos)
945+
mdef match {
946+
case vdef: ValDef if name.isExtension && isSetterNeeded(vdef) =>
947+
report.error(em"illegal setter name: `extension_=`", errPos)
948+
case memDef if name.isExtensionName && !mdef.mods.is(ExtensionMethod) =>
949+
report.error(em"illegal name: $name may not start with `extension_`", errPos)
950+
case _ =>
951+
}
939952
name
940953
}
941954

compiler/src/dotty/tools/dotc/core/NameOps.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,12 @@ object NameOps {
133133
else name.toTermName
134134
}
135135

136+
/** Does the name match `extension`? */
137+
def isExtension: Boolean = name match
138+
case name: SimpleName =>
139+
name.length == "extension".length && name.startsWith("extension")
140+
case _ => false
141+
136142
/** Does this name start with `extension_`? */
137143
def isExtensionName: Boolean = name match
138144
case name: SimpleName => name.startsWith("extension_")

tests/neg/illegal-extension.check

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-- Error: tests/neg/illegal-extension.scala:2:6 ------------------------------------------------------------------------
2+
2 | def extension_n: String = "illegal method" // error: illegal name: extension_n may not start with `extension_`
3+
| ^^^^^^^^^^^
4+
| illegal name: extension_n may not start with `extension_`
5+
-- Error: tests/neg/illegal-extension.scala:4:6 ------------------------------------------------------------------------
6+
4 | val extension_val = 23 // error: illegal name: extension_val may not start with `extension_`
7+
| ^^^^^^^^^^^^^
8+
| illegal name: extension_val may not start with `extension_`
9+
-- Error: tests/neg/illegal-extension.scala:5:14 -----------------------------------------------------------------------
10+
5 | private var extension = Nil // error: illegal setter name: `extension_=`
11+
| ^^^^^^^^^
12+
| illegal setter name: `extension_=`
13+
-- Error: tests/neg/illegal-extension.scala:16:23 ----------------------------------------------------------------------
14+
16 |extension (x: Any) def extension_foo: String = "foo" // error: illegal name: extension_foo may not start with `extension_`
15+
| ^^^^^^^^^^^^^
16+
| illegal name: extension_foo may not start with `extension_`
17+
-- Error: tests/neg/illegal-extension.scala:9:6 ------------------------------------------------------------------------
18+
9 | var extension = 1337 // error: illegal setter name: `extension_=`
19+
| ^^^^^^^^^
20+
| illegal setter name: `extension_=`

tests/neg/illegal-extension.scala

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
trait A {
2-
def extension_n: String = "illegal method" // error: illegal method name: extension_n may not start with `extension_`
2+
def extension_n: String = "illegal method" // error: illegal name: extension_n may not start with `extension_`
3+
type extension_type = Int // allowed because it's a type alias
4+
val extension_val = 23 // error: illegal name: extension_val may not start with `extension_`
5+
private var extension = Nil // error: illegal setter name: `extension_=`
36
}
47

5-
extension (x: Any) def extension_foo: String = "foo" // error: illegal method name: extension_foo may not start with `extension_`
8+
class B {
9+
var extension = 1337 // error: illegal setter name: `extension_=`
10+
}
11+
12+
class C {
13+
private var extension = "OK" // allowed because it does not require a setter
14+
}
15+
16+
extension (x: Any) def extension_foo: String = "foo" // error: illegal name: extension_foo may not start with `extension_`
17+
extension (some: Any) def valid_extension_name: String = {
18+
var extension = "foo" // `extension` name allowed because it doesn't require a setter
19+
s"$extension bar"
20+
}

0 commit comments

Comments
 (0)