diff options
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Implicits.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Implicits.scala | 14 |
1 files changed, 10 insertions, 4 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 || |