Skip to content

Fix #9051: Fix accessibility test for implicit candidates #9129

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions compiler/src/dotty/tools/dotc/typer/Implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ object Implicits {
if (wtp.derivesFrom(SingletonClass)) defn.AnyType else wtp
}

protected def isAccessible(ref: TermRef)(using Context): Boolean

/** Return those references in `refs` that are compatible with type `pt`. */
protected def filterMatching(pt: Type)(using Context): List[Candidate] = {
record("filterMatching")
Expand Down Expand Up @@ -198,7 +200,8 @@ object Implicits {
case _ => tp

var ckind =
if (!ref.symbol.isAccessibleFrom(ref.prefix)) Candidate.None
if !isAccessible(ref) then
Candidate.None
else pt match {
case pt: ViewProto =>
viewCandidateKind(ref.widen, pt.argType, pt.resType)
Expand Down Expand Up @@ -259,6 +262,9 @@ object Implicits {
filterMatching(tp)
}

override def isAccessible(ref: TermRef)(using Context): Boolean =
ref.symbol.exists && !ref.symbol.is(Private)

override def toString: String =
i"OfTypeImplicits($tp), companions = ${companionRefs.toList}%, %; refs = $refs%, %."
}
Expand Down Expand Up @@ -326,6 +332,9 @@ object Implicits {
}
}

override def isAccessible(ref: TermRef)(using Context): Boolean =
ref.symbol.isAccessibleFrom(ref.prefix)

override def toString: String = {
val own = i"(implicits: $refs%, %)"
if (isOuterMost) own else own + "\n " + outerImplicits
Expand Down Expand Up @@ -960,7 +969,6 @@ trait Implicits { self: Typer =>
implicits.println(i"committing ${result.tstate.constraint} yielding ${ctx.typerState.constraint} in ${ctx.typerState}")
result
case result: SearchFailure if result.isAmbiguous =>
//println(i"FAIL for $pt / $argument: $result0")
val deepPt = pt.deepenProto
if (deepPt ne pt) inferImplicit(deepPt, argument, span)
else if (migrateTo3 && !ctx.mode.is(Mode.OldOverloadingResolution))
Expand All @@ -975,10 +983,8 @@ trait Implicits { self: Typer =>
}
else result
case NoMatchingImplicitsFailure =>
//println(i"FAIL for $pt / $argument: $result0")
SearchFailure(new NoMatchingImplicits(pt, argument, ctx.typerState.constraint))
case _ =>
//println(i"FAIL for $pt / $argument: $result0")
result0
}
// If we are at the outermost implicit search then emit the implicit dictionary, if any.
Expand Down Expand Up @@ -1024,7 +1030,9 @@ trait Implicits { self: Typer =>
case _ =>
tryConversion
}
if (ctx.reporter.hasErrors) {
if ctx.reporter.hasErrors
|| !cand.ref.symbol.isAccessibleFrom(cand.ref.prefix)
then
ctx.reporter.removeBufferedMessages
adapted.tpe match {
case _: SearchFailureType => SearchFailure(adapted)
Expand All @@ -1036,13 +1044,11 @@ trait Implicits { self: Typer =>
else
SearchFailure(adapted.withType(new MismatchedImplicit(ref, pt, argument)))
}
}
else {
else
val returned =
if (cand.isExtension) Applications.ExtMethodApply(adapted)
else adapted
SearchSuccess(returned, ref, cand.level)(ctx.typerState, ctx.gadt)
}
}

/** An implicit search; parameters as in `inferImplicit` */
Expand All @@ -1067,8 +1073,6 @@ trait Implicits { self: Typer =>

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

//println(i"search implicits $pt / ${eligible.map(_.ref)}")

/** Try to type-check implicit reference, after checking that this is not
* a diverging search
*/
Expand Down
11 changes: 11 additions & 0 deletions tests/neg/i9051.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package zio:

class ZRef
object ZRef:

private[zio] implicit class ZRefSyntax(private val self: ZRef):
def unsafeUpdate: Boolean = true

object Main:
val ref = new zio.ZRef
println(ref.unsafeUpdate) // error
15 changes: 15 additions & 0 deletions tests/pos/i9051.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package zio

class ZRef

object ZRef {

private[zio] implicit class ZRefSyntax(private val self: ZRef) extends AnyVal {
def unsafeUpdate: Boolean = true
}
}

object Main extends App {
val ref = new ZRef
println(ref.unsafeUpdate)
}