Skip to content

Commit ed4454b

Browse files
committed
Clean code
1 parent de903f4 commit ed4454b

File tree

6 files changed

+40
-36
lines changed

6 files changed

+40
-36
lines changed

compiler/src/dotty/tools/dotc/core/JavaNullInterop.scala

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
package dotty.tools.dotc.core
1+
package dotty.tools.dotc
2+
package core
23

3-
import dotty.tools.dotc.core.Contexts._
4-
import dotty.tools.dotc.core.Flags.JavaDefined
5-
import dotty.tools.dotc.core.StdNames.{jnme, nme}
6-
import dotty.tools.dotc.core.Symbols._
7-
import dotty.tools.dotc.core.Types._
4+
import config.Feature._
5+
import Contexts._
6+
import Flags.JavaDefined
87
import NullOpsDecorator._
8+
import StdNames.nme
9+
import Symbols._
10+
import Types._
911

1012
/** This module defines methods to interpret types of Java symbols, which are implicitly nullable in Java,
1113
* as Scala types, which are explicitly nullable.
@@ -35,6 +37,12 @@ import NullOpsDecorator._
3537
*/
3638
object JavaNullInterop {
3739

40+
/** Should we try to convert values ignoring Null type at this moment? */
41+
def convertUnsafeNulls(using Context): Boolean =
42+
ctx.explicitNulls && (
43+
config.Feature.enabled(nme.unsafeNulls) ||
44+
ctx.mode.is(Mode.UnsafeNullConversion))
45+
3846
/** Transforms the type `tp` of Java member `sym` to be explicitly nullable.
3947
* `tp` is needed because the type inside `sym` might not be set when this method is called.
4048
*

compiler/src/dotty/tools/dotc/core/Mode.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,5 +113,6 @@ object Mode {
113113
/** Are we in a quote in a pattern? */
114114
val QuotedPattern: Mode = newMode(25, "QuotedPattern")
115115

116+
/** Should we try to convert values ignoring Null type? */
116117
val UnsafeNullConversion: Mode = newMode(26, "UnsafeNullConversion")
117118
}

compiler/src/dotty/tools/dotc/core/NullOpsDecorator.scala

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,21 +59,19 @@ object NullOpsDecorator {
5959

6060
/** Can the type have null value after erasure?
6161
*/
62-
def hasNullAfterErasure(using Context): Boolean = {
63-
self match {
64-
case tp: ClassInfo => tp.cls.isNullableClassAfterErasure
65-
case tp: TypeProxy => tp.underlying.hasNullAfterErasure
66-
case OrType(lhs, rhs) =>
67-
lhs.hasNullAfterErasure || rhs.hasNullAfterErasure
68-
case _ =>
69-
self <:< defn.ObjectType
70-
}
62+
def isNullableAfterErasure(using Context): Boolean = self match {
63+
case tp: ClassInfo => tp.cls.isNullableClassAfterErasure
64+
case tp: TypeProxy => tp.underlying.isNullableAfterErasure
65+
case OrType(lhs, rhs) =>
66+
lhs.isNullableAfterErasure || rhs.isNullableAfterErasure
67+
case _ =>
68+
self.isNullType || self <:< defn.ObjectType
7169
}
7270

7371
/** Can we convert a tree with type `self` to type `pt` unsafely.
7472
*/
7573
def isUnsafeConvertable(pt: Type)(using Context): Boolean =
76-
(self.isNullType && pt.hasNullAfterErasure) ||
74+
(self.isNullType && pt.isNullableAfterErasure) ||
7775
(self.stripAllNulls <:< pt.stripAllNulls)
7876
}
7977
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,7 @@ trait Checking {
768768
* - it is defined in Predef
769769
* - it is the scala.reflect.Selectable.reflectiveSelectable conversion
770770
*/
771-
def checkImplicitConversionUseOK(sym: Symbol, tpe: Type, posd: SrcPos)(using Context): Unit =
771+
def checkImplicitConversionUseOK(sym: Symbol, tpe: Type, pos: SrcPos)(using Context): Unit =
772772
if (sym.exists) {
773773
val conv =
774774
if (sym.isOneOf(GivenOrImplicit) || sym.info.isErroneous) sym
@@ -784,7 +784,7 @@ trait Checking {
784784
conv.name == nme.reflectiveSelectable && conv.maybeOwner.maybeOwner.maybeOwner == defn.ScalaPackageClass
785785
if (!conversionOK)
786786
checkFeature(nme.implicitConversions,
787-
i"Use of implicit conversion ${conv.showLocated}", NoSymbol, posd)
787+
i"Use of implicit conversion ${conv.showLocated}", NoSymbol, pos)
788788
}
789789

790790
private def infixOKSinceFollowedBy(tree: untpd.Tree): Boolean = tree match {
@@ -1246,7 +1246,7 @@ trait NoChecking extends ReChecking {
12461246
override def checkStable(tp: Type, pos: SrcPos, kind: String)(using Context): Unit = ()
12471247
override def checkClassType(tp: Type, pos: SrcPos, traitReq: Boolean, stablePrefixReq: Boolean)(using Context): Type = tp
12481248
override def checkImplicitConversionDefOK(sym: Symbol)(using Context): Unit = ()
1249-
override def checkImplicitConversionUseOK(sym: Symbol, tpe: Type, posd: SrcPos)(using Context): Unit = ()
1249+
override def checkImplicitConversionUseOK(sym: Symbol, tpe: Type, pos: SrcPos)(using Context): Unit = ()
12501250
override def checkFeasibleParent(tp: Type, pos: SrcPos, where: => String = "")(using Context): Type = tp
12511251
override def checkInlineConformant(tpt: Tree, tree: Tree, sym: Symbol)(using Context): Unit = ()
12521252
override def checkNoAlphaConflict(stats: List[Tree])(using Context): Unit = ()

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ object ProtoTypes {
141141

142142
// equals comes from case class; no need to redefine
143143
end IgnoredProto
144-
144+
145145
final class CachedIgnoredProto(ignored: Type) extends IgnoredProto(ignored)
146146

147147
object IgnoredProto:
@@ -364,7 +364,7 @@ object ProtoTypes {
364364
/** Type single argument and remember the unadapted result in `myTypedArg`.
365365
* used to avoid repeated typings of trees when backtracking.
366366
*/
367-
def typedArg(arg: untpd.Tree, formal: Type)(using Context): Tree = {
367+
def typedArg(arg: untpd.Tree, formal: Type)(using Context): Tree = {
368368
val wideFormal = formal.widenExpr
369369
val argCtx =
370370
if wideFormal eq formal then ctx

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

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3443,23 +3443,17 @@ class Typer extends Namer
34433443
return tpd.Block(tree1 :: Nil, Literal(Constant(())))
34443444
}
34453445

3446-
val adaptWithUnsafeNullConver =
3447-
ctx.explicitNulls && (
3448-
config.Feature.enabled(nme.unsafeNulls) ||
3449-
ctx.mode.is(Mode.UnsafeNullConversion))
3450-
34513446
// convert function literal to SAM closure
34523447
tree match {
34533448
case closure(Nil, id @ Ident(nme.ANON_FUN), _)
34543449
if defn.isFunctionType(wtp) && !defn.isFunctionType(pt) =>
3455-
val pt1 =
3456-
if ctx.explicitNulls then
3457-
pt.stripNull
3458-
else pt
3450+
// Strip the Null type from the pt before check SAM type
3451+
val pt1 = if ctx.explicitNulls then pt.stripNull else pt
34593452
pt1 match {
34603453
case SAMType(sam)
34613454
if wtp <:< sam.toFunctionType() ||
3462-
(adaptWithUnsafeNullConver && wtp.isUnsafeConvertable(sam.toFunctionType())) =>
3455+
(JavaNullInterop.convertUnsafeNulls &&
3456+
wtp.isUnsafeConvertable(sam.toFunctionType())) =>
34633457
// was ... && isFullyDefined(pt, ForceDegree.flipBottom)
34643458
// but this prevents case blocks from implementing polymorphic partial functions,
34653459
// since we do not know the result parameter a priori. Have to wait until the
@@ -3554,13 +3548,16 @@ class Typer extends Namer
35543548
if ctx.mode.is(Mode.ImplicitsEnabled) && tree.typeOpt.isValueType then
35553549
if pt.isRef(defn.AnyValClass) || pt.isRef(defn.ObjectClass) then
35563550
report.error(em"the result of an implicit conversion must be more specific than $pt", tree.srcPos)
3551+
def normalSearch =
3552+
searchTree(tree)(failure => tryUnsafeNullConver(cannotFind(failure)))
35573553
tree.tpe match {
3558-
case OrNull(tpe1) if ctx.explicitNulls && config.Feature.enabled(nme.unsafeNulls) =>
3559-
searchTree(tree.cast(tpe1)) { _ =>
3560-
searchTree(tree)(failure => tryUnsafeNullConver(cannotFind(failure)))
3561-
}
3554+
case OrNull(tpe1) if ctx.mode.is(Mode.UnsafeNullConversion) =>
3555+
// If the type of the tree is nullable, and unsafeNullConversion is enabled,
3556+
// then we search the tree without the `Null` type first.
3557+
// If this fails, we search the original tree.
3558+
searchTree(tree.cast(tpe1)) { _ => normalSearch }
35623559
case _ =>
3563-
searchTree(tree)(failure => tryUnsafeNullConver(cannotFind(failure)))
3560+
normalSearch
35643561
}
35653562
else tryUnsafeNullConver(recover(NoMatchingImplicits))
35663563
}

0 commit comments

Comments
 (0)