Skip to content

Commit 008b21a

Browse files
committed
Fix OfType Implicits Search in UnsafeNulls
1 parent 1b0602c commit 008b21a

File tree

4 files changed

+27
-5
lines changed

4 files changed

+27
-5
lines changed

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

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -280,11 +280,18 @@ object Implicits:
280280
buf.toList
281281
}
282282

283+
@threadUnsafe lazy val eligibleCache: List[Candidate] = filterMatching(tp)
284+
285+
@threadUnsafe lazy val eligibleCacheUnsafeNulls: List[Candidate] =
286+
inContext(ctx.addMode(Mode.UnsafeNullConversion)) {
287+
filterMatching(tp)
288+
}
289+
283290
/** The candidates that are eligible for expected type `tp` */
284-
@threadUnsafe lazy val eligible: List[Candidate] =
291+
def eligible(enableUnsafeNulls: Boolean): List[Candidate] =
285292
trace(i"eligible($tp), companions = ${companionRefs.showAsList}%, %", implicitsDetailed, show = true) {
286293
if (refs.nonEmpty && monitored) record(s"check eligible refs in tpe", refs.length)
287-
filterMatching(tp)
294+
if enableUnsafeNulls then eligibleCacheUnsafeNulls else eligibleCache
288295
}
289296

290297
override def isAccessible(ref: TermRef)(using Context): Boolean =
@@ -1287,7 +1294,7 @@ trait Implicits:
12871294
private def searchImplicit(contextual: Boolean): SearchResult =
12881295
val eligible =
12891296
if contextual then ctx.implicits.eligible(wildProto, ctx.mode.is(Mode.UnsafeNullConversion))
1290-
else implicitScope(wildProto).eligible
1297+
else implicitScope(wildProto).eligible(ctx.mode.is(Mode.UnsafeNullConversion))
12911298
searchImplicit(eligible, contextual) match
12921299
case result: SearchSuccess =>
12931300
result
@@ -1330,7 +1337,8 @@ trait Implicits:
13301337
def allImplicits: Set[TermRef] = {
13311338
val contextuals = ctx.implicits.eligible(wildProto, ctx.mode.is(Mode.UnsafeNullConversion))
13321339
.map(tryImplicit(_, contextual = true))
1333-
val inscope = implicitScope(wildProto).eligible.map(tryImplicit(_, contextual = false))
1340+
val inscope = implicitScope(wildProto).eligible(ctx.mode.is(Mode.UnsafeNullConversion))
1341+
.map(tryImplicit(_, contextual = false))
13341342
(contextuals.toSet ++ inscope).collect {
13351343
case success: SearchSuccess => success.ref
13361344
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ trait ImportSuggestions:
159159
val wildProto = wildApprox(pt)
160160
val contextualCandidates = ctx.implicits.eligible(wildProto, ctx.mode.is(Mode.UnsafeNullConversion))
161161
val implicitScopeCandidates = ctx.run.implicitScope(wildProto).eligible
162-
val allCandidates = contextualCandidates ++ implicitScopeCandidates
162+
val allCandidates = contextualCandidates ++ implicitScopeCandidates(ctx.mode.is(Mode.UnsafeNullConversion))
163163
allCandidates.map(_.implicitRef.underlyingRef.symbol).toSet
164164
}
165165

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Ensure we don't have cyclic complete
2+
3+
import scala.collection.immutable.BitSet
4+
5+
val e = BitSet.empty

tests/explicit-nulls/unsafe-common/unsafe-implicit.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,13 @@ class S {
4747
f1 // error
4848
f2
4949
}
50+
51+
locally {
52+
// OfType Implicits
53+
54+
import java.nio.charset.StandardCharsets
55+
import scala.io.Codec
56+
57+
val c: Codec = StandardCharsets.UTF_8 // error
58+
}
5059
}

0 commit comments

Comments
 (0)