summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Namers.scala
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan@lightbend.com>2016-11-30 13:42:36 -0800
committerAdriaan Moors <adriaan@lightbend.com>2016-12-05 08:47:34 +0100
commit7a57c6eec6c37e8ca3a7f182f0cf2604d7bc80df (patch)
treee880de7e67ec2144096660faa3ab4b5dbf41d6f9 /src/compiler/scala/tools/nsc/typechecker/Namers.scala
parent0339663cbbd4d22b0758257f2ce078b5a007f316 (diff)
downloadscala-7a57c6eec6c37e8ca3a7f182f0cf2604d7bc80df.tar.gz
scala-7a57c6eec6c37e8ca3a7f182f0cf2604d7bc80df.tar.bz2
scala-7a57c6eec6c37e8ca3a7f182f0cf2604d7bc80df.zip
SI-10075 annotations go to lazy val's underlying field
This likely regressed in #5294. Review feedback from retronym: - Tie annotation triaging a bit closer together durban kindly provided initial version of test/files/run/t10075.scala And pointed out you must force `lazy val`, since `null`-valued field is serializable regardless of its type. Test test/files/run/t10075b courtesy of retronym
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Namers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala11
1 files changed, 7 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 78e8c8c073..27a586e543 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -902,9 +902,10 @@ trait Namers extends MethodSynthesis {
// Annotations on ValDefs can be targeted towards the following: field, getter, setter, beanGetter, beanSetter, param.
// The defaults are:
// - (`val`-, `var`- or plain) constructor parameter annotations end up on the parameter, not on any other entity.
- // - val/var member annotations solely end up on the underlying field, except in traits (@since 2.12),
+ // - val/var member annotations solely end up on the underlying field, except in traits and for all lazy vals (@since 2.12),
// where there is no field, and the getter thus holds annotations targeting both getter & field.
- // As soon as there is a field/getter (in subclasses mixing in the trait), we triage the annotations.
+ // As soon as there is a field/getter (in subclasses mixing in the trait, or after expanding the lazy val during the fields phase),
+ // we triage the annotations.
//
// TODO: these defaults can be surprising for annotations not meant for accessors/fields -- should we revisit?
// (In order to have `@foo val X` result in the X getter being annotated with `@foo`, foo needs to be meta-annotated with @getter)
@@ -918,15 +919,17 @@ trait Namers extends MethodSynthesis {
BeanPropertyAnnotationLimitationError(tree)
}
+ val canTriageAnnotations = isSetter || !fields.getterTreeAnnotationsTargetFieldAndGetter(owner, mods)
+
def filterAccessorAnnotations: AnnotationInfo => Boolean =
- if (isSetter || !owner.isTrait)
+ if (canTriageAnnotations)
annotationFilter(if (isSetter) SetterTargetClass else GetterTargetClass, defaultRetention = false)
else (ann =>
annotationFilter(FieldTargetClass, defaultRetention = true)(ann) ||
annotationFilter(GetterTargetClass, defaultRetention = true)(ann))
def filterBeanAccessorAnnotations: AnnotationInfo => Boolean =
- if (isSetter || !owner.isTrait)
+ if (canTriageAnnotations)
annotationFilter(if (isSetter) BeanSetterTargetClass else BeanGetterTargetClass, defaultRetention = false)
else (ann =>
annotationFilter(FieldTargetClass, defaultRetention = true)(ann) ||