File tree Expand file tree Collapse file tree 4 files changed +27
-1
lines changed
crates/ty_python_semantic Expand file tree Collapse file tree 4 files changed +27
-1
lines changed Original file line number Diff line number Diff line change 1- # Bidirectional Type Inference
1+ # Bidirectional type inference
22
33ty partially supports bidirectional type inference. This is a mechanism for inferring the type of an
44expression "from the outside in". Normally, type inference proceeds "from the inside out". That is,
@@ -46,6 +46,13 @@ def _(l: list[int] | None = None):
4646 l2: list[int ] = l or list ()
4747 # TODO : should be `list[int]`
4848 reveal_type(l2) # revealed: (list[int] & ~AlwaysFalsy) | list[Unknown]
49+
50+ def f[T](x: T, cond: bool ) -> T | list[T]:
51+ return x if cond else [x]
52+
53+ # TODO : no error
54+ # error: [invalid-assignment] "Object of type `Literal[1] | list[Literal[1]]` is not assignable to `int | list[int]`"
55+ l5: int | list[int ] = f(1 , True )
4956```
5057
5158``` py
@@ -123,4 +130,10 @@ reveal_type(f("a")) # revealed: list[str]
123130
124131async def g () -> list[int ]:
125132 return list1(1 )
133+
134+ def h[T](x: T, cond: bool ) -> T | list[T]:
135+ return i(x, cond)
136+
137+ def i[T](x: T, cond: bool ) -> T | list[T]:
138+ return x if cond else [x]
126139```
Original file line number Diff line number Diff line change @@ -323,6 +323,10 @@ def union_param(x: T | None) -> T:
323323reveal_type(union_param(" a" )) # revealed: Literal["a"]
324324reveal_type(union_param(1 )) # revealed: Literal[1]
325325reveal_type(union_param(None )) # revealed: Unknown
326+
327+ def _ (x : int | None ):
328+ # TODO : should be `int`
329+ reveal_type(union_param(x)) # revealed: Unknown
326330```
327331
328332``` py
Original file line number Diff line number Diff line change @@ -286,6 +286,10 @@ def union_param[T](x: T | None) -> T:
286286reveal_type(union_param(" a" )) # revealed: Literal["a"]
287287reveal_type(union_param(1 )) # revealed: Literal[1]
288288reveal_type(union_param(None )) # revealed: Unknown
289+
290+ def _ (x : int | None ):
291+ # TODO : should be `int`
292+ reveal_type(union_param(x)) # revealed: Unknown
289293```
290294
291295``` py
Original file line number Diff line number Diff line change @@ -1088,6 +1088,11 @@ impl<'db> SpecializationBuilder<'db> {
10881088 }
10891089
10901090 match ( formal, actual) {
1091+ ( Type :: Union ( _) , Type :: Union ( _) ) => {
1092+ // TODO: We need to infer specializations appropriately.
1093+ // e.g.
1094+ // `formal: list[T] | T | U, actual: V | int | list[V]` => `T = V, U = int`
1095+ }
10911096 ( Type :: Union ( formal) , _) => {
10921097 // TODO: We haven't implemented a full unification solver yet. If typevars appear
10931098 // in multiple union elements, we ideally want to express that _only one_ of them
You can’t perform that action at this time.
0 commit comments