diff --git a/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala b/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala index 8837f7319117..bf6b6d431509 100644 --- a/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala +++ b/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala @@ -93,11 +93,7 @@ class CommunityBuildTestC: @Test def sconfig = projects.sconfig.run() @Test def shapeless = projects.shapeless.run() @Test def sourcecode = projects.sourcecode.run() - - // Disabled. Currently fails in FutureMatchers.scala. The call to - // `checkResultFailure` goes to a protected method which is not accessible. - // I tried to fix it, but get test failures. - // @Test def specs2 = projects.specs2.run() + @Test def specs2 = projects.specs2.run() @Test def stdLib213 = projects.stdLib213.run() @Test def ujson = projects.ujson.run() diff --git a/compiler/src/dotty/tools/dotc/core/Flags.scala b/compiler/src/dotty/tools/dotc/core/Flags.scala index 8100bea374eb..62cb5726c6af 100644 --- a/compiler/src/dotty/tools/dotc/core/Flags.scala +++ b/compiler/src/dotty/tools/dotc/core/Flags.scala @@ -600,6 +600,7 @@ object Flags { val TermParamOrAccessor: FlagSet = Param | ParamAccessor val PrivateParamAccessor: FlagSet = ParamAccessor | Private val PrivateOrArtifact: FlagSet = Private | Artifact + val PrivateOrProtected: FlagSet = Private | Protected val ClassTypeParam: FlagSet = Private | TypeParam val Scala2Trait: FlagSet = Scala2x | Trait val SyntheticArtifact: FlagSet = Synthetic | Artifact diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index 44787dcfeedc..9c67d1a11f73 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -223,11 +223,10 @@ class Namer { typer: Typer => var flags1 = flags var privateWithin = privateWithinClass(tree.mods) val effectiveOwner = owner.skipWeakOwner - if (flags.is(Private) && effectiveOwner.is(Package)) { - // If effective owner is a package p, widen private to private[p] - flags1 = flags1 &~ PrivateLocal + if (flags.isOneOf(PrivateOrProtected) && !privateWithin.exists) && effectiveOwner.is(Package) then + // If effective owner is a package p, widen private to private[p] and protected to protected[p] + flags1 = flags1 &~ PrivateLocal // drop private but keep protected privateWithin = effectiveOwner - } val sym = if (prev.exists) { diff --git a/tests/pos/i18124/definition.scala b/tests/pos/i18124/definition.scala new file mode 100644 index 000000000000..1377c94fe7cd --- /dev/null +++ b/tests/pos/i18124/definition.scala @@ -0,0 +1,15 @@ +// definition.scala +package oolong.bson: + + trait BsonValue + protected def merge( + base: BsonValue, + patch: BsonValue, + arraySubvalues: Boolean = false + ): BsonValue = ??? + + private def foo: Int = 1 + + package inner: + protected[bson] def bar = 2 + diff --git a/tests/pos/i18124/usage.scala b/tests/pos/i18124/usage.scala new file mode 100644 index 000000000000..0bc0417c01ad --- /dev/null +++ b/tests/pos/i18124/usage.scala @@ -0,0 +1,8 @@ +// usage.scala +package oolong.bson + +extension (bv: BsonValue) + def :+(other: BsonValue): BsonValue = merge(other, bv, false) + +val x = foo +val y = inner.bar