Skip to content

Commit 19cec83

Browse files
committed
Update comments; add test cases for function type inference with union types.
1 parent d93ed6c commit 19cec83

File tree

2 files changed

+40
-8
lines changed

2 files changed

+40
-8
lines changed

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1921,21 +1921,21 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
19211921
NoType
19221922
}
19231923

1924-
def instantiateInUnion(tp: Type): Unit = tp match
1924+
def tryToInstantiateInUnion(tp: Type): Unit = tp match
19251925
case tp: OrType =>
1926-
instantiateInUnion(tp.tp1)
1927-
instantiateInUnion(tp.tp2)
1926+
tryToInstantiateInUnion(tp.tp1)
1927+
tryToInstantiateInUnion(tp.tp2)
19281928
case tp: FlexibleType =>
1929-
instantiateInUnion(tp.hi)
1929+
tryToInstantiateInUnion(tp.hi)
19301930
case tp: TypeVar =>
19311931
isFullyDefined(tp, ForceDegree.flipBottom)
19321932
case _ =>
19331933

19341934
if untpd.isFunctionWithUnknownParamType(tree) && !calleeType.exists then
1935-
// try to instantiate `pt` if this is possible. If it does not
1936-
// work the error will be reported later in `inferredParam`,
1937-
// when we try to infer the parameter type.
1938-
instantiateInUnion(pt)
1935+
// Try to instantiate `pt` when possible, including type variables in union types
1936+
// to help finding function types. If it does not work the error will be reported
1937+
// later in `inferredParam`, when we try to infer the parameter type.
1938+
tryToInstantiateInUnion(pt)
19391939

19401940
val (protoFormals, resultTpt) = decomposeProtoFunction(pt, params.length, tree.srcPos)
19411941

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
2+
def f[T](x: T): T = ???
3+
def f2[T](x: T | T): T = ???
4+
def f3[T](x: T | Null): T = ???
5+
def f4[T](x: Int | T): T = ???
6+
7+
trait MyOption[+T]
8+
9+
object MyOption:
10+
def apply[T](x: T | Null): MyOption[T] = ???
11+
12+
def test =
13+
val g: AnyRef => Boolean = f {
14+
x => x eq null // ok
15+
}
16+
val g2: AnyRef => Boolean = f2 {
17+
x => x eq null // ok
18+
}
19+
val g3: AnyRef => Boolean = f3 {
20+
x => x eq null // was error
21+
}
22+
val g4: AnyRef => Boolean = f4 {
23+
x => x eq null // was error
24+
}
25+
26+
val o1: MyOption[String] = MyOption(null)
27+
val o2: MyOption[String => Boolean] = MyOption {
28+
x => x.length > 0
29+
}
30+
val o3: MyOption[(String, String) => Boolean] = MyOption {
31+
(x, y) => x.length > y.length
32+
}

0 commit comments

Comments
 (0)