Skip to content

Commit 9b79bb9

Browse files
committed
Fix unary function call
1 parent 2f488aa commit 9b79bb9

File tree

4 files changed

+41
-31
lines changed

4 files changed

+41
-31
lines changed

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

Lines changed: 32 additions & 5 deletions
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

Lines changed: 1 addition & 13 deletions
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

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -645,18 +645,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
645645

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

661651
def javaSelectOnType(qual: Tree)(using Context) =
662652
// semantic name conversion for `O$` in java code
@@ -3689,7 +3679,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
36893679
}
36903680
simplify(typed(etaExpand(tree, wtp, arity), pt), pt, locked)
36913681
else if (wtp.paramInfos.isEmpty && isAutoApplied(tree.symbol))
3692-
readaptSimplified(tpd.Apply(tree, Nil))
3682+
val app = tpd.Apply(tree, Nil).tryToCastToCanEqualNull
3683+
readaptSimplified(app)
36933684
else if (wtp.isImplicitMethod)
36943685
err.typeMismatch(tree, pt)
36953686
else
Lines changed: 4 additions & 0 deletions
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)