Skip to content

Commit 83e90a9

Browse files
committed
Fix #9051: Fix accessibility test for implicit candidates
If it comes from a type's implicit scope, accessibility from a context should not matter to determine the initially eligible candidates. Accessibility will be tested later when an implicit is tried.
1 parent 345c8bc commit 83e90a9

File tree

3 files changed

+43
-8
lines changed

3 files changed

+43
-8
lines changed

compiler/src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ object Implicits {
9999
if (wtp.derivesFrom(SingletonClass)) defn.AnyType else wtp
100100
}
101101

102+
protected def isAccessible(ref: TermRef)(using Context): Boolean
103+
102104
/** Return those references in `refs` that are compatible with type `pt`. */
103105
protected def filterMatching(pt: Type)(using Context): List[Candidate] = {
104106
record("filterMatching")
@@ -197,7 +199,8 @@ object Implicits {
197199
case _ => tp
198200

199201
var ckind =
200-
if (!ref.symbol.isAccessibleFrom(ref.prefix)) Candidate.None
202+
if !isAccessible(ref) then
203+
Candidate.None
201204
else pt match {
202205
case pt: ViewProto =>
203206
viewCandidateKind(ref.widen, pt.argType, pt.resType)
@@ -244,7 +247,9 @@ object Implicits {
244247
*/
245248
class OfTypeImplicits(tp: Type, val companionRefs: TermRefSet)(initctx: Context) extends ImplicitRefs(initctx) {
246249
assert(initctx.typer != null)
247-
implicits.println(i"implicits of type $tp = ${companionRefs.toList}%, %")
250+
251+
implicits.println(i"implicit scope of type $tp = ${companionRefs.toList}%, %")
252+
248253
@threadUnsafe lazy val refs: List[ImplicitRef] = {
249254
val buf = new mutable.ListBuffer[TermRef]
250255
for (companion <- companionRefs) buf ++= companion.implicitMembers
@@ -258,6 +263,9 @@ object Implicits {
258263
filterMatching(tp)
259264
}
260265

266+
override def isAccessible(ref: TermRef)(using Context): Boolean =
267+
ref.symbol.exists && !ref.symbol.is(Private)
268+
261269
override def toString: String =
262270
i"OfTypeImplicits($tp), companions = ${companionRefs.toList}%, %; refs = $refs%, %."
263271
}
@@ -325,6 +333,9 @@ object Implicits {
325333
}
326334
}
327335

336+
override def isAccessible(ref: TermRef)(using Context): Boolean =
337+
ref.symbol.isAccessibleFrom(ref.prefix)
338+
328339
override def toString: String = {
329340
val own = i"(implicits: $refs%, %)"
330341
if (isOuterMost) own else own + "\n " + outerImplicits
@@ -967,7 +978,9 @@ trait Implicits { self: Typer =>
967978
case _ =>
968979
tryConversion
969980
}
970-
if (ctx.reporter.hasErrors) {
981+
if ctx.reporter.hasErrors
982+
|| !cand.ref.symbol.isAccessibleFrom(cand.ref.prefix)
983+
then
971984
ctx.reporter.removeBufferedMessages
972985
adapted.tpe match {
973986
case _: SearchFailureType => SearchFailure(adapted)
@@ -979,13 +992,11 @@ trait Implicits { self: Typer =>
979992
else
980993
SearchFailure(adapted.withType(new MismatchedImplicit(ref, pt, argument)))
981994
}
982-
}
983-
else {
995+
else
984996
val returned =
985997
if (cand.isExtension) Applications.ExtMethodApply(adapted)
986998
else adapted
987999
SearchSuccess(returned, ref, cand.level)(ctx.typerState, ctx.gadt)
988-
}
9891000
}
9901001

9911002
/** An implicit search; parameters as in `inferImplicit` */
@@ -1010,8 +1021,6 @@ trait Implicits { self: Typer =>
10101021

10111022
val isNot: Boolean = wildProto.classSymbol == defn.NotClass
10121023

1013-
//println(i"search implicits $pt / ${eligible.map(_.ref)}")
1014-
10151024
/** Try to type-check implicit reference, after checking that this is not
10161025
* a diverging search
10171026
*/

tests/neg/i9051.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package zio:
2+
3+
class ZRef
4+
object ZRef:
5+
6+
private[zio] implicit class ZRefSyntax(private val self: ZRef):
7+
def unsafeUpdate: Boolean = true
8+
9+
object Main:
10+
val ref = new zio.ZRef
11+
println(ref.unsafeUpdate) // error

tests/pos/i9051.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package zio
2+
3+
class ZRef
4+
5+
object ZRef {
6+
7+
private[zio] implicit class ZRefSyntax(private val self: ZRef) extends AnyVal {
8+
def unsafeUpdate: Boolean = true
9+
}
10+
}
11+
12+
object Main extends App {
13+
val ref = new ZRef
14+
println(ref.unsafeUpdate)
15+
}

0 commit comments

Comments
 (0)