diff options
author | Adriaan Moors <adriaan@lightbend.com> | 2016-11-30 13:42:36 -0800 |
---|---|---|
committer | Adriaan Moors <adriaan@lightbend.com> | 2016-12-05 08:47:34 +0100 |
commit | 7a57c6eec6c37e8ca3a7f182f0cf2604d7bc80df (patch) | |
tree | e880de7e67ec2144096660faa3ab4b5dbf41d6f9 /src/compiler/scala/tools/nsc/typechecker/Namers.scala | |
parent | 0339663cbbd4d22b0758257f2ce078b5a007f316 (diff) | |
download | scala-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.scala | 11 |
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) || |