diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Implicits.scala | 14 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 16 |
2 files changed, 16 insertions, 14 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 9a6c4cc401..e503d721f9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -520,7 +520,7 @@ self: Analyzer => * - the symbol's type is initialized * - the symbol comes from a classfile * - the symbol comes from a different sourcefile than the current one - * - the symbol's definition comes before, and does not contain the closest enclosing definition, + * - the symbol and the accessed symbol's definitions come before, and do not contain the closest enclosing definition, // see #3373 * - the symbol's definition is a val, var, or def with an explicit result type * The aim of this method is to prevent premature cyclic reference errors * by computing the types of only those implicits for which one of these @@ -539,9 +539,15 @@ self: Analyzer => case _ => true } } - def comesBefore(sym: Symbol, owner: Symbol) = - sym.pos.pointOrElse(0) < owner.pos.pointOrElse(Integer.MAX_VALUE) && - !(owner.ownerChain contains sym) + def comesBefore(sym: Symbol, owner: Symbol) = { + val ownerPos = owner.pos.pointOrElse(Integer.MAX_VALUE) + sym.pos.pointOrElse(0) < ownerPos && ( + if(sym isGetterOrSetter) { + val symAcc = sym.accessed // #3373 + symAcc.pos.pointOrElse(0) < ownerPos && + !(owner.ownerChain exists (o => (o eq sym) || (o eq symAcc))) // probably faster to iterate only once, don't feel like duplicating hasTransOwner for this case + } else !(owner hasTransOwner sym)) // faster than owner.ownerChain contains sym + } sym.isInitialized || sym.sourceFile == null || diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index f503a797bb..92dd368ac5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1330,9 +1330,7 @@ trait Typers { self: Analyzer => val value = stat.symbol val allAnnots = value.annotations if (!isDeferred) - // keepClean: by default annotations go to the field, except if the field is - // generated for a class parameter (PARAMACCESSOR). - value.setAnnotations(memberAnnots(allAnnots, FieldTargetClass, keepClean = !mods.hasFlag(PARAMACCESSOR))) + value.setAnnotations(memberAnnots(allAnnots, FieldTargetClass)) val getter = if (isDeferred) value else value.getter(value.owner) assert(getter != NoSymbol, stat) @@ -1412,12 +1410,10 @@ trait Typers { self: Analyzer => List(stat) } - /** - * The annotations amongst `annots` that should go on a member of class - * `memberClass` (field, getter, setter, beanGetter, beanSetter, param) - * If 'keepClean' is true, annotations without any meta-annotation are kept + /** The annotations amongst `annots` that should go on a member of class + * `memberClass` (field, getter, setter, beanGetter, beanSetter, param) */ - protected def memberAnnots(annots: List[AnnotationInfo], memberClass: Symbol, keepClean: Boolean = false) = { + protected def memberAnnots(annots: List[AnnotationInfo], memberClass: Symbol) = { def hasMatching(metaAnnots: List[AnnotationInfo], orElse: => Boolean) = { // either one of the meta-annotations matches the `memberClass` @@ -1434,7 +1430,7 @@ trait Typers { self: Analyzer => // there was no meta-annotation on `ann`. Look if the class annotations of // `ann` has a `target` annotation, otherwise put `ann` only on fields. def noMetaAnnot(ann: AnnotationInfo) = { - hasMatching(ann.atp.typeSymbol.annotations, keepClean) + hasMatching(ann.atp.typeSymbol.annotations, memberClass == FieldTargetClass) } annots.filter(ann => ann.atp match { @@ -1706,7 +1702,7 @@ trait Typers { self: Analyzer => for (vparams <- ddef.vparamss; vd <- vparams) { if (vd hasFlag PARAMACCESSOR) { val sym = vd.symbol - sym.setAnnotations(memberAnnots(sym.annotations, ParamTargetClass, keepClean = true)) + sym.setAnnotations(memberAnnots(sym.annotations, ParamTargetClass)) } } } |