diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index fcf9d984bcf4..3694c218f716 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -854,9 +854,14 @@ object Types { // is made to save execution time in the common case. See i9844.scala for test cases. def qualifies(sd: SingleDenotation) = !sd.symbol.is(Private) || sd.symbol.owner == tp.cls - d match + d.match case d: SingleDenotation => if qualifies(d) then d else NoDenotation case d => d.filterWithPredicate(qualifies) + .orElse: + // Only inaccessible private symbols were found. But there could still be + // shadowed non-private symbols, so as a fallback search for those. + // Test case is i18361.scala. + findMember(name, pre, required, excluded | Private) else d else // There is a special case to handle: diff --git a/tests/pos/i18361.scala b/tests/pos/i18361.scala new file mode 100644 index 000000000000..a84d5f0a09db --- /dev/null +++ b/tests/pos/i18361.scala @@ -0,0 +1,15 @@ +package test1: + class Service(val name: String) + class CrudService(name: String) extends Service(name) + + trait Foo { self: CrudService => + val x = self.name + } + +package test2: + abstract class Service[F[_]](val name: String) + abstract class CrudService[F[_]](name: String) extends Service[F](name) + + trait Foo[F[_]] { self: CrudService[?] => + val x = self.name + }