Skip to content

Commit a5de7f4

Browse files
committed
Update implicit search
1 parent 67a46ef commit a5de7f4

File tree

6 files changed

+67
-4
lines changed

6 files changed

+67
-4
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import config.Printers.{implicits, implicitsDetailed}
3535
import collection.mutable
3636
import reporting._
3737
import annotation.tailrec
38+
import NullOpsDecorator._
3839

3940
import scala.annotation.internal.sharable
4041
import scala.annotation.threadUnsafe
@@ -130,7 +131,9 @@ object Implicits:
130131
else if (mt.paramInfos.lengthCompare(1) == 0 && {
131132
var formal = widenSingleton(mt.paramInfos.head)
132133
if (approx) formal = wildApprox(formal)
133-
explore(argType relaxed_<:< formal.widenExpr)
134+
explore((argType relaxed_<:< formal.widenExpr) ||
135+
Nullables.convertUnsafeNulls &&
136+
argType.isUnsafelyConvertable(formal.widenExpr))
134137
})
135138
Candidate.Conversion
136139
else

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
3232
case defn.ArrayOf(elemTp) =>
3333
val etag = typer.inferImplicitArg(defn.ClassTagClass.typeRef.appliedTo(elemTp), span)
3434
if etag.tpe.isError then EmptyTree else etag.select(nme.wrap)
35-
case tp if hasStableErasure(tp) && !defn.isBottomClass(tp.typeSymbol) =>
35+
case tp if hasStableErasure(tp) && !defn.isBottomClassAfterErasure(tp.typeSymbol) =>
3636
val sym = tp.typeSymbol
3737
val classTag = ref(defn.ClassTagModule)
3838
val tag =

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3549,6 +3549,7 @@ class Typer extends Namer
35493549
report.error(em"the result of an implicit conversion must be more specific than $pt", tree.srcPos)
35503550
tree.cast(pt)
35513551
else
3552+
// TODO: we don't need to second time search, need to modify Implicits more
35523553
def normalSearch =
35533554
searchTree(tree)(failure => tryUnsafeNullConver(cannotFind(failure)))
35543555
treeTpe match {
@@ -3559,7 +3560,7 @@ class Typer extends Namer
35593560
searchTree(tree.cast(tpe1)) { _ => normalSearch }
35603561
case _ =>
35613562
normalSearch
3562-
}
3563+
}
35633564
else tryUnsafeNullConver(recover(NoMatchingImplicits))
35643565
}
35653566
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
def f = {
2+
val a: Array[Null] = Array(null) // error: No ClassTag available for Null
3+
}
4+
5+
def g = {
6+
import scala.language.unsafeNulls
7+
val a: Array[Null] = Array(null) // error: No ClassTag available for Null
8+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class S {
5757
n1(Array("a", "b"))
5858
n2(Array("a", "b"))
5959

60-
n0(Array(null)) // error
60+
n0(Array[String](null)) // error
6161
n1(Array(null))
6262
n2(Array(null))
6363

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

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,41 @@ class S {
5252
val z8: Array[String | Null] | Null = y2 // error
5353
}
5454

55+
locally {
56+
implicit def g(x: Array[String]): String = ???
57+
58+
val y1: Array[String] = ???
59+
val y2: Array[String] | Null = ???
60+
val y3: Array[String | Null] | Null = ???
61+
62+
y1: String
63+
y2: String // error
64+
y3: String // error
65+
66+
y1: String | Null
67+
y2: String | Null // error
68+
y3: String | Null // error
69+
}
70+
71+
locally {
72+
implicit def g(x: Array[String | Null]): String | Null = ???
73+
74+
val y1: Array[String] = ???
75+
val y2: Array[String] | Null = ???
76+
val y3: Array[String | Null] = ???
77+
val y4: Array[String | Null] | Null = ???
78+
79+
y1: String // error
80+
y2: String // error
81+
y3: String // error
82+
y4: String // error
83+
84+
y1: String | Null // error
85+
y2: String | Null // error
86+
y3: String | Null
87+
y4: String | Null // error
88+
}
89+
5590
locally {
5691
given Conversion[String, Array[String]] = _ => ???
5792

@@ -69,6 +104,22 @@ class S {
69104
val z8: Array[String | Null] | Null = y2 // error
70105
}
71106

107+
locally {
108+
given Conversion[Array[String], String] = _ => ???
109+
110+
val y1: Array[String] = ???
111+
val y2: Array[String] | Null = ???
112+
val y3: Array[String | Null] | Null = ???
113+
114+
y1: String
115+
y2: String // error
116+
y3: String // error
117+
118+
y1: String | Null
119+
y2: String | Null // error
120+
y3: String | Null // error
121+
}
122+
72123
abstract class MyConversion[T] extends Conversion[T, Array[T]]
73124

74125
locally {

0 commit comments

Comments
 (0)