Skip to content

Commit ba914d3

Browse files
committed
Fix #8531: Annnotations on class value parameters go to the constructor
Mimic the behavior of Scala 2: an annotation on a class value parameters (but not on a type parameter) is moved to the constructor parameter and not to any of the derived parameters.
1 parent b64b8a9 commit ba914d3

File tree

2 files changed

+22
-18
lines changed

2 files changed

+22
-18
lines changed

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

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,10 @@ object desugar {
452452
else originalTparams
453453
}
454454
else originalTparams
455+
456+
// Annotations on class _type_ parameters are set on the derived parameters
457+
// but not on the constructor parameters. The reverse is true for
458+
// annotations on class _value_ parameters.
455459
val constrTparams = impliedTparams.map(toDefParam(_, keepAnnotations = false))
456460
val constrVparamss =
457461
if (originalVparamss.isEmpty) { // ensure parameter list is non-empty
@@ -463,7 +467,18 @@ object desugar {
463467
ctx.error(CaseClassMissingNonImplicitParamList(cdef), namePos)
464468
ListOfNil
465469
}
466-
else originalVparamss.nestedMap(toDefParam(_, keepAnnotations = false))
470+
else originalVparamss.nestedMap(toDefParam(_, keepAnnotations = true))
471+
val derivedTparams = {
472+
val impliedTparamsIt = impliedTparams.iterator
473+
constrTparams.map(tparam => derivedTypeParam(tparam)
474+
.withAnnotations(impliedTparamsIt.next().mods.annotations))
475+
}
476+
val derivedVparamss = {
477+
val constrVparamsIt = constrVparamss.iterator.flatten
478+
constrVparamss.nestedMap(vparam => derivedTermParam(vparam)
479+
.withAnnotations(Nil))
480+
}
481+
467482
val constr = cpy.DefDef(constr1)(tparams = constrTparams, vparamss = constrVparamss)
468483

469484
val (normalizedBody, enumCases, enumCompanionRef) = {
@@ -499,19 +514,6 @@ object desugar {
499514

500515
def anyRef = ref(defn.AnyRefAlias.typeRef)
501516

502-
// Annotations are dropped from the constructor parameters but should be
503-
// preserved in all derived parameters.
504-
val derivedTparams = {
505-
val impliedTparamsIt = impliedTparams.iterator
506-
constrTparams.map(tparam => derivedTypeParam(tparam)
507-
.withAnnotations(impliedTparamsIt.next().mods.annotations))
508-
}
509-
val derivedVparamss = {
510-
val constrVparamsIt = constrVparamss.iterator.flatten
511-
constrVparamss.nestedMap(vparam => derivedTermParam(vparam)
512-
.withAnnotations(constrVparamsIt.next().mods.annotations))
513-
}
514-
515517
val arity = constrVparamss.head.length
516518

517519
val classTycon: Tree = TypeRefTree() // watching is set at end of method
@@ -800,8 +802,10 @@ object desugar {
800802
val originalVparamsIt = originalVparamss.iterator.flatten
801803
derivedVparamss match {
802804
case first :: rest =>
803-
first.map(_.withMods(originalVparamsIt.next().mods | caseAccessor)) ++
804-
rest.flatten.map(_.withMods(originalVparamsIt.next().mods))
805+
// Annotations on the class _value_ parameters are not set on the parameter accessors
806+
def mods(vdef: ValDef) = vdef.mods.withAnnotations(Nil)
807+
first.map(_.withMods(mods(originalVparamsIt.next()) | caseAccessor)) ++
808+
rest.flatten.map(_.withMods(mods(originalVparamsIt.next())))
805809
case _ =>
806810
Nil
807811
}

compiler/src/dotty/tools/dotc/transform/Constructors.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,12 +228,12 @@ class Constructors extends MiniPhase with IdentityDenotTransformer { thisPhase =
228228
Nil
229229
}
230230
else {
231-
if (acc.hasAnnotation(defn.TransientParamAnnot))
231+
val param = acc.subst(accessors, paramSyms)
232+
if (param.hasAnnotation(defn.TransientParamAnnot))
232233
ctx.error(em"transient parameter $acc is retained as field in class ${acc.owner}", acc.sourcePos)
233234
val target = if (acc.is(Method)) acc.field else acc
234235
if (!target.exists) Nil // this case arises when the parameter accessor is an alias
235236
else {
236-
val param = acc.subst(accessors, paramSyms)
237237
val assigns = Assign(ref(target), ref(param)).withSpan(tree.span) :: Nil
238238
if (acc.name != nme.OUTER) assigns
239239
else {

0 commit comments

Comments
 (0)