Skip to content

Commit b037a49

Browse files
committed
Fix unary function call
1 parent 8b2524b commit b037a49

File tree

4 files changed

+41
-31
lines changed

4 files changed

+41
-31
lines changed

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

+32-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package core
33

44
import Annotations._
55
import Contexts._
6+
import Flags._
67
import Symbols._
78
import Types._
89

@@ -71,10 +72,36 @@ object NullOpsDecorator:
7172

7273
import ast.tpd._
7374

74-
extension (self: Tree)
75+
extension (tree: Tree)
76+
7577
// cast the type of the tree to a non-nullable type
76-
def castToNonNullable(using Context): Tree = self.typeOpt match {
77-
case OrNull(tp) => self.cast(tp)
78-
case _ => self
79-
}
78+
def castToNonNullable(using Context): Tree = tree.typeOpt match
79+
case OrNull(tp) => tree.cast(tp)
80+
case _ => tree
81+
82+
def tryToCastToCanEqualNull(using Context): Tree =
83+
val sym = tree.symbol
84+
val tp = tree.tpe
85+
86+
if !ctx.mode.is(Mode.UnsafeJavaReturn)
87+
|| !sym.is(JavaDefined)
88+
|| sym.is(Package)
89+
|| !sym.isTerm
90+
|| tp.isError then
91+
return tree
92+
93+
tree match
94+
case _: Apply if sym.is(Method) && !sym.isConstructor =>
95+
val tp2 = tp.replaceOrNull
96+
if tp ne tp2 then
97+
tree.cast(tp2)
98+
else tree
99+
case _: Select if !sym.is(Method) =>
100+
val tpw = tp.widen
101+
val tp2 = tpw.replaceOrNull
102+
if tpw ne tp2 then
103+
tree.cast(tp2)
104+
else tree
105+
case _ => tree
106+
80107
end NullOpsDecorator

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

+1-13
Original file line numberDiff line numberDiff line change
@@ -909,19 +909,7 @@ trait Applications extends Compatibility {
909909
def simpleApply(fun1: Tree, proto: FunProto)(using Context): Tree =
910910
methPart(fun1).tpe match {
911911
case funRef: TermRef =>
912-
var app = ApplyTo(tree, fun1, funRef, proto, pt)
913-
if ctx.mode.is(Mode.UnsafeJavaReturn) then
914-
// When UnsafeJavaReturn is enabled and the applied function is Java defined,
915-
// we replece `| Null` with `@CanEqualNull` in the return type.
916-
val funSym = fun1.symbol
917-
if funSym.is(JavaDefined)
918-
&& funSym.isTerm
919-
&& funSym.is(Method)
920-
&& !funSym.isConstructor then
921-
val rtp1 = app.tpe
922-
val rtp2 = rtp1.replaceOrNull
923-
if rtp1 ne rtp2 then
924-
app = app.cast(rtp2)
912+
val app = ApplyTo(tree, fun1, funRef, proto, pt).tryToCastToCanEqualNull
925913
convertNewGenericArray(
926914
widenEnumCase(
927915
postProcessByNameArgs(funRef, app).computeNullable(),

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

+4-13
Original file line numberDiff line numberDiff line change
@@ -643,18 +643,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
643643

644644
def typeSelectOnTerm(using Context): Tree =
645645
val qual = typedExpr(tree.qualifier, shallowSelectionProto(tree.name, pt, this))
646-
var sel = typedSelect(tree, pt, qual).withSpan(tree.span).computeNullable()
647-
if ctx.mode.is(Mode.UnsafeJavaReturn) && pt != AssignProto then
648-
// When UnsafeJavaReturn is enabled and the selected member is Java defined,
649-
// we replece `| Null` with `@CanEqualNull` in its type
650-
// if it is not at left hand side of assignments.
651-
val sym = sel.symbol
652-
if sym.is(JavaDefined) && sym.isTerm && !sym.is(Method) then
653-
val stp1 = sel.tpe.widen
654-
val stp2 = stp1.replaceOrNull
655-
if stp1 ne stp2 then
656-
sel = sel.cast(stp2)
657-
sel
646+
val sel = typedSelect(tree, pt, qual).withSpan(tree.span).computeNullable()
647+
if pt != AssignProto then sel.tryToCastToCanEqualNull else sel
658648

659649
def javaSelectOnType(qual: Tree)(using Context) =
660650
// semantic name conversion for `O$` in java code
@@ -3666,7 +3656,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
36663656
}
36673657
simplify(typed(etaExpand(tree, wtp, arity), pt), pt, locked)
36683658
else if (wtp.paramInfos.isEmpty && isAutoApplied(tree.symbol))
3669-
readaptSimplified(tpd.Apply(tree, Nil))
3659+
val app = tpd.Apply(tree, Nil).tryToCastToCanEqualNull
3660+
readaptSimplified(app)
36703661
else if (wtp.isImplicitMethod)
36713662
err.typeMismatch(tree, pt)
36723663
else
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import scala.language.unsafeJavaReturn
2+
3+
val s = "foo"
4+
val methods: Array[java.lang.reflect.Method] = s.getClass.getMethods

0 commit comments

Comments
 (0)