From a7cf5cb22ae4c439c9cbf65c76f8abcd7be504e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 18 Oct 2023 14:22:35 +0200 Subject: [PATCH 1/4] Tests covering the uses of polymorphic functions and types --- ...onomorphic_function_call_type_mismatch.sol | 16 ++ .../inference/polymorphic_function_call.sol | 53 ++++++ ...morphic_function_call_let_polymorphism.sol | 19 ++ ...olymorphic_function_call_type_mismatch.sol | 16 ++ .../inference/polymorphic_type.sol | 47 +++++ .../polymorphic_type_abs_and_rep.sol | 69 +++++++ ...rphic_type_instantiation_and_operators.sol | 168 ++++++++++++++++++ 7 files changed, 388 insertions(+) create mode 100644 test/libsolidity/syntaxTests/experimental/inference/monomorphic_function_call_type_mismatch.sol create mode 100644 test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol create mode 100644 test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call_let_polymorphism.sol create mode 100644 test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call_type_mismatch.sol create mode 100644 test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol create mode 100644 test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_abs_and_rep.sol create mode 100644 test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol diff --git a/test/libsolidity/syntaxTests/experimental/inference/monomorphic_function_call_type_mismatch.sol b/test/libsolidity/syntaxTests/experimental/inference/monomorphic_function_call_type_mismatch.sol new file mode 100644 index 000000000000..e7af573aeed6 --- /dev/null +++ b/test/libsolidity/syntaxTests/experimental/inference/monomorphic_function_call_type_mismatch.sol @@ -0,0 +1,16 @@ +pragma experimental solidity; + +type T; +type U; + +function f(x: T, y: U) {} + +function run(a: U, b: T) { + f(a, b); +} +// ==== +// EVMVersion: >=constantinople +// ---- +// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. +// TypeError 8456: (106-113): Cannot unify T and U. +// TypeError 8456: (106-113): Cannot unify U and T. diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol new file mode 100644 index 000000000000..6fe19f07d00e --- /dev/null +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol @@ -0,0 +1,53 @@ +pragma experimental solidity; + +type T; +type U(A); + +function f(x, y: X, z: U(Y)) {} + +function run(a: T, b: U(T), c: U(U(T))) { + f(a, a, b); + f(b, b, c); +} +// ==== +// EVMVersion: >=constantinople +// compileViaYul: true +// ---- +// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. +// Info 4164: (31-38): Inferred type: T +// Info 4164: (39-49): Inferred type: tfun('u:type, U('u:type)) +// Info 4164: (45-48): Inferred type: 't:type +// Info 4164: (46-47): Inferred type: 't:type +// Info 4164: (51-82): Inferred type: ('x:type, 'y:type, U('bb:type)) -> () +// Info 4164: (61-79): Inferred type: ('x:type, 'y:type, U('bb:type)) +// Info 4164: (62-63): Inferred type: 'x:type +// Info 4164: (65-69): Inferred type: 'y:type +// Info 4164: (68-69): Inferred type: 'y:type +// Info 4164: (71-78): Inferred type: U('bb:type) +// Info 4164: (74-78): Inferred type: U('bb:type) +// Info 4164: (74-75): Inferred type: tfun('bb:type, U('bb:type)) +// Info 4164: (76-77): Inferred type: 'bb:type +// Info 4164: (84-159): Inferred type: (T, U(T), U(U(T))) -> () +// Info 4164: (96-123): Inferred type: (T, U(T), U(U(T))) +// Info 4164: (97-101): Inferred type: T +// Info 4164: (100-101): Inferred type: T +// Info 4164: (103-110): Inferred type: U(T) +// Info 4164: (106-110): Inferred type: U(T) +// Info 4164: (106-107): Inferred type: tfun(T, U(T)) +// Info 4164: (108-109): Inferred type: T +// Info 4164: (112-122): Inferred type: U(U(T)) +// Info 4164: (115-122): Inferred type: U(U(T)) +// Info 4164: (115-116): Inferred type: tfun(U(T), U(U(T))) +// Info 4164: (117-121): Inferred type: U(T) +// Info 4164: (117-118): Inferred type: tfun(T, U(T)) +// Info 4164: (119-120): Inferred type: T +// Info 4164: (130-140): Inferred type: () +// Info 4164: (130-131): Inferred type: (T, T, U(T)) -> () +// Info 4164: (132-133): Inferred type: T +// Info 4164: (135-136): Inferred type: T +// Info 4164: (138-139): Inferred type: U(T) +// Info 4164: (146-156): Inferred type: () +// Info 4164: (146-147): Inferred type: (U(T), U(T), U(U(T))) -> () +// Info 4164: (148-149): Inferred type: U(T) +// Info 4164: (151-152): Inferred type: U(T) +// Info 4164: (154-155): Inferred type: U(U(T)) diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call_let_polymorphism.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call_let_polymorphism.sol new file mode 100644 index 000000000000..1a43d0807ac2 --- /dev/null +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call_let_polymorphism.sol @@ -0,0 +1,19 @@ +pragma experimental solidity; + +type T; +type U; + +function f(x) {} + +function run(a: T, b: U) { + // NOTE: The type of f is polymorphic but the inferred type of g is not - this would be + // let-polymorphism, which we decided not to support. + let g = f; + g(a); + g(b); +} +// ==== +// EVMVersion: >=constantinople +// ---- +// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. +// TypeError 8456: (272-276): Cannot unify T and U. diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call_type_mismatch.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call_type_mismatch.sol new file mode 100644 index 000000000000..74f102a88183 --- /dev/null +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call_type_mismatch.sol @@ -0,0 +1,16 @@ +pragma experimental solidity; + +type T(A); +type U; +type V; + +function f(x: T(U)) {} + +function run(a: T(V)) { + f(a); +} +// ==== +// EVMVersion: >=constantinople +// ---- +// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. +// TypeError 8456: (111-115): Cannot unify U and V. diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol new file mode 100644 index 000000000000..eae572a0db28 --- /dev/null +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol @@ -0,0 +1,47 @@ +pragma experimental solidity; + +type T(P, Q, R); +type U; +type V; + +class Self: C {} +class Self: D {} + +function run() { + let x: T(U, X, Z: C); + let y: T(V, Y, Z: D); +} +// ==== +// EVMVersion: >=constantinople +// compileViaYul: true +// ---- +// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. +// Info 4164: (31-47): Inferred type: tfun(('ba:type, 'bb:type, 'bc:type), T('ba:type, 'bb:type, 'bc:type)) +// Info 4164: (37-46): Inferred type: ('x:type, 'y:type, 'z:type) +// Info 4164: (38-39): Inferred type: 'x:type +// Info 4164: (41-42): Inferred type: 'y:type +// Info 4164: (44-45): Inferred type: 'z:type +// Info 4164: (48-55): Inferred type: U +// Info 4164: (56-63): Inferred type: V +// Info 4164: (65-81): Inferred type: C +// Info 4164: (71-75): Inferred type: 'be:(type, C) +// Info 4164: (82-98): Inferred type: D +// Info 4164: (88-92): Inferred type: 'bg:(type, D) +// Info 4164: (100-170): Inferred type: () -> () +// Info 4164: (112-114): Inferred type: () +// Info 4164: (125-141): Inferred type: T(U, 'bo:type, 'bq:(type, C)) +// Info 4164: (128-141): Inferred type: T(U, 'bo:type, 'bq:(type, C)) +// Info 4164: (128-129): Inferred type: tfun((U, 'bo:type, 'bq:(type, C)), T(U, 'bo:type, 'bq:(type, C))) +// Info 4164: (130-131): Inferred type: U +// Info 4164: (133-134): Inferred type: 'bo:type +// Info 4164: (136-140): Inferred type: 'bq:(type, C) +// Info 4164: (136-137): Inferred type: 'bq:(type, C) +// Info 4164: (139-140): Inferred type: 'bq:(type, C) +// Info 4164: (151-167): Inferred type: T(V, 'bx:type, 'bz:(type, D)) +// Info 4164: (154-167): Inferred type: T(V, 'bx:type, 'bz:(type, D)) +// Info 4164: (154-155): Inferred type: tfun((V, 'bx:type, 'bz:(type, D)), T(V, 'bx:type, 'bz:(type, D))) +// Info 4164: (156-157): Inferred type: V +// Info 4164: (159-160): Inferred type: 'bx:type +// Info 4164: (162-166): Inferred type: 'bz:(type, D) +// Info 4164: (162-163): Inferred type: 'bz:(type, D) +// Info 4164: (165-166): Inferred type: 'bz:(type, D) diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_abs_and_rep.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_abs_and_rep.sol new file mode 100644 index 000000000000..3c4adb71717c --- /dev/null +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_abs_and_rep.sol @@ -0,0 +1,69 @@ +pragma experimental solidity; + +type uint; +type string; + +type T(A); +type U(B) = T(B); + +function fun() { + let w: U(uint); + let v: T(uint); + U.rep(w); + U.abs(v); + + let s: U(string); + let t: T(string); + U.rep(s); + U.abs(t); +} +// ==== +// EVMVersion: >=constantinople +// compileViaYul: true +// ---- +// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. +// Info 4164: (31-41): Inferred type: uint +// Info 4164: (42-54): Inferred type: string +// Info 4164: (56-66): Inferred type: tfun('v:type, T('v:type)) +// Info 4164: (62-65): Inferred type: 'u:type +// Info 4164: (63-64): Inferred type: 'u:type +// Info 4164: (67-84): Inferred type: tfun('x:type, U('x:type)) +// Info 4164: (73-76): Inferred type: 'w:type +// Info 4164: (74-75): Inferred type: 'w:type +// Info 4164: (79-83): Inferred type: T('w:type) +// Info 4164: (79-80): Inferred type: tfun('w:type, T('w:type)) +// Info 4164: (81-82): Inferred type: 'w:type +// Info 4164: (86-245): Inferred type: () -> () +// Info 4164: (98-100): Inferred type: () +// Info 4164: (111-121): Inferred type: U(uint) +// Info 4164: (114-121): Inferred type: U(uint) +// Info 4164: (114-115): Inferred type: tfun(uint, U(uint)) +// Info 4164: (116-120): Inferred type: uint +// Info 4164: (131-141): Inferred type: T(uint) +// Info 4164: (134-141): Inferred type: T(uint) +// Info 4164: (134-135): Inferred type: tfun(uint, T(uint)) +// Info 4164: (136-140): Inferred type: uint +// Info 4164: (147-155): Inferred type: T('bp:type) +// Info 4164: (147-152): Inferred type: U(uint) -> T('bp:type) +// Info 4164: (147-148): Inferred type: U('bm:type) +// Info 4164: (153-154): Inferred type: U(uint) +// Info 4164: (161-169): Inferred type: U('bv:type) +// Info 4164: (161-166): Inferred type: T(uint) -> U('bv:type) +// Info 4164: (161-162): Inferred type: U('bs:type) +// Info 4164: (167-168): Inferred type: T(uint) +// Info 4164: (180-192): Inferred type: U(string) +// Info 4164: (183-192): Inferred type: U(string) +// Info 4164: (183-184): Inferred type: tfun(string, U(string)) +// Info 4164: (185-191): Inferred type: string +// Info 4164: (202-214): Inferred type: T(string) +// Info 4164: (205-214): Inferred type: T(string) +// Info 4164: (205-206): Inferred type: tfun(string, T(string)) +// Info 4164: (207-213): Inferred type: string +// Info 4164: (220-228): Inferred type: T('cj:type) +// Info 4164: (220-225): Inferred type: U(string) -> T('cj:type) +// Info 4164: (220-221): Inferred type: U('cg:type) +// Info 4164: (226-227): Inferred type: U(string) +// Info 4164: (234-242): Inferred type: U('cp:type) +// Info 4164: (234-239): Inferred type: T(string) -> U('cp:type) +// Info 4164: (234-235): Inferred type: U('cm:type) +// Info 4164: (240-241): Inferred type: T(string) diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol new file mode 100644 index 000000000000..b1cda1b3ed22 --- /dev/null +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol @@ -0,0 +1,168 @@ +pragma experimental solidity; + +type bool = __builtin("bool"); + +type T(A); +type int; +type str; + +class Self: C { + function foo(a: Self, b: Self) -> Self; +} + +class Self: P1 {} +class Self: P2 {} +class Self: P3 {} +class Self: P4 {} + +instantiation int: P1 {} +instantiation int: P2 {} +instantiation int: P3 {} + +instantiation str: P1 {} +instantiation str: P2 {} +instantiation str: P4 {} + +instantiation T(A: P1): + { + function add(x: T(A), y: T(A)) -> T(A) {} +} + +instantiation T(A: P2): == { + function eq(x: T(A), y: T(A)) -> bool {} +} + +instantiation T(A: (P1, P2)): C { + function foo(x: T(A), y: T(A)) -> T(A) {} +} + +function fun(a: T(int: P3), b: T(str: P4)) { + a + a; + b + b; + + a == a; + b == b; + + C.foo(a, a); + C.foo(b, b); +} +// ==== +// EVMVersion: >=constantinople +// compileViaYul: true +// ---- +// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. +// Info 4164: (31-61): Inferred type: bool +// Info 4164: (63-73): Inferred type: tfun('z:type, T('z:type)) +// Info 4164: (69-72): Inferred type: 'y:type +// Info 4164: (70-71): Inferred type: 'y:type +// Info 4164: (74-83): Inferred type: int +// Info 4164: (84-93): Inferred type: str +// Info 4164: (95-156): Inferred type: C +// Info 4164: (101-105): Inferred type: 'bf:(type, C) +// Info 4164: (115-154): Inferred type: ('bf:(type, C), 'bf:(type, C)) -> 'bf:(type, C) +// Info 4164: (127-145): Inferred type: ('bf:(type, C), 'bf:(type, C)) +// Info 4164: (128-135): Inferred type: 'bf:(type, C) +// Info 4164: (131-135): Inferred type: 'bf:(type, C) +// Info 4164: (137-144): Inferred type: 'bf:(type, C) +// Info 4164: (140-144): Inferred type: 'bf:(type, C) +// Info 4164: (149-153): Inferred type: 'bf:(type, C) +// Info 4164: (158-175): Inferred type: P1 +// Info 4164: (164-168): Inferred type: 'bi:(type, P1) +// Info 4164: (176-193): Inferred type: P2 +// Info 4164: (182-186): Inferred type: 'bl:(type, P2) +// Info 4164: (194-211): Inferred type: P3 +// Info 4164: (200-204): Inferred type: 'cb:(type, P3) +// Info 4164: (212-229): Inferred type: P4 +// Info 4164: (218-222): Inferred type: 'cd:(type, P4) +// Info 4164: (231-255): Inferred type: void +// Info 4164: (256-280): Inferred type: void +// Info 4164: (281-305): Inferred type: void +// Info 4164: (307-331): Inferred type: void +// Info 4164: (332-356): Inferred type: void +// Info 4164: (357-381): Inferred type: void +// Info 4164: (383-458): Inferred type: void +// Info 4164: (398-405): Inferred type: 'cf:(type, P1) +// Info 4164: (399-404): Inferred type: 'cf:(type, P1) +// Info 4164: (402-404): Inferred type: 'cf:(type, P1) +// Info 4164: (415-456): Inferred type: (T('cf:(type, P1)), T('cf:(type, P1))) -> T('cf:(type, P1)) +// Info 4164: (427-445): Inferred type: (T('cf:(type, P1)), T('cf:(type, P1))) +// Info 4164: (428-435): Inferred type: T('cf:(type, P1)) +// Info 4164: (431-435): Inferred type: T('cf:(type, P1)) +// Info 4164: (431-432): Inferred type: tfun('cf:(type, P1), T('cf:(type, P1))) +// Info 4164: (433-434): Inferred type: 'cf:(type, P1) +// Info 4164: (437-444): Inferred type: T('cf:(type, P1)) +// Info 4164: (440-444): Inferred type: T('cf:(type, P1)) +// Info 4164: (440-441): Inferred type: tfun('cf:(type, P1), T('cf:(type, P1))) +// Info 4164: (442-443): Inferred type: 'cf:(type, P1) +// Info 4164: (449-453): Inferred type: T('cf:(type, P1)) +// Info 4164: (449-450): Inferred type: tfun('cf:(type, P1), T('cf:(type, P1))) +// Info 4164: (451-452): Inferred type: 'cf:(type, P1) +// Info 4164: (460-535): Inferred type: void +// Info 4164: (475-482): Inferred type: 'cs:(type, P2) +// Info 4164: (476-481): Inferred type: 'cs:(type, P2) +// Info 4164: (479-481): Inferred type: 'cs:(type, P2) +// Info 4164: (493-533): Inferred type: (T('cs:(type, P2)), T('cs:(type, P2))) -> bool +// Info 4164: (504-522): Inferred type: (T('cs:(type, P2)), T('cs:(type, P2))) +// Info 4164: (505-512): Inferred type: T('cs:(type, P2)) +// Info 4164: (508-512): Inferred type: T('cs:(type, P2)) +// Info 4164: (508-509): Inferred type: tfun('cs:(type, P2), T('cs:(type, P2))) +// Info 4164: (510-511): Inferred type: 'cs:(type, P2) +// Info 4164: (514-521): Inferred type: T('cs:(type, P2)) +// Info 4164: (517-521): Inferred type: T('cs:(type, P2)) +// Info 4164: (517-518): Inferred type: tfun('cs:(type, P2), T('cs:(type, P2))) +// Info 4164: (519-520): Inferred type: 'cs:(type, P2) +// Info 4164: (526-530): Inferred type: bool +// Info 4164: (537-618): Inferred type: void +// Info 4164: (552-565): Inferred type: 'bo:(type, P1, P2) +// Info 4164: (553-564): Inferred type: 'bo:(type, P1, P2) +// Info 4164: (556-564): Inferred type: 'bo:(type, P1, P2) +// Info 4164: (557-559): Inferred type: 'bo:(type, P1, P2) +// Info 4164: (561-563): Inferred type: 'bo:(type, P1, P2) +// Info 4164: (575-616): Inferred type: (T('bo:(type, P1, P2)), T('bo:(type, P1, P2))) -> T('bo:(type, P1, P2)) +// Info 4164: (587-605): Inferred type: (T('bo:(type, P1, P2)), T('bo:(type, P1, P2))) +// Info 4164: (588-595): Inferred type: T('bo:(type, P1, P2)) +// Info 4164: (591-595): Inferred type: T('bo:(type, P1, P2)) +// Info 4164: (591-592): Inferred type: tfun('bo:(type, P1, P2), T('bo:(type, P1, P2))) +// Info 4164: (593-594): Inferred type: 'bo:(type, P1, P2) +// Info 4164: (597-604): Inferred type: T('bo:(type, P1, P2)) +// Info 4164: (600-604): Inferred type: T('bo:(type, P1, P2)) +// Info 4164: (600-601): Inferred type: tfun('bo:(type, P1, P2), T('bo:(type, P1, P2))) +// Info 4164: (602-603): Inferred type: 'bo:(type, P1, P2) +// Info 4164: (609-613): Inferred type: T('bo:(type, P1, P2)) +// Info 4164: (609-610): Inferred type: tfun('bo:(type, P1, P2), T('bo:(type, P1, P2))) +// Info 4164: (611-612): Inferred type: 'bo:(type, P1, P2) +// Info 4164: (620-748): Inferred type: (T(int), T(str)) -> () +// Info 4164: (632-662): Inferred type: (T(int), T(str)) +// Info 4164: (633-646): Inferred type: T(int) +// Info 4164: (636-646): Inferred type: T(int) +// Info 4164: (636-637): Inferred type: tfun(int, T(int)) +// Info 4164: (638-645): Inferred type: int +// Info 4164: (638-641): Inferred type: int +// Info 4164: (643-645): Inferred type: int +// Info 4164: (648-661): Inferred type: T(str) +// Info 4164: (651-661): Inferred type: T(str) +// Info 4164: (651-652): Inferred type: tfun(str, T(str)) +// Info 4164: (653-660): Inferred type: str +// Info 4164: (653-656): Inferred type: str +// Info 4164: (658-660): Inferred type: str +// Info 4164: (669-674): Inferred type: T(int) +// Info 4164: (669-670): Inferred type: T(int) +// Info 4164: (673-674): Inferred type: T(int) +// Info 4164: (680-685): Inferred type: T(str) +// Info 4164: (680-681): Inferred type: T(str) +// Info 4164: (684-685): Inferred type: T(str) +// Info 4164: (692-698): Inferred type: bool +// Info 4164: (692-693): Inferred type: T(int) +// Info 4164: (697-698): Inferred type: T(int) +// Info 4164: (704-710): Inferred type: bool +// Info 4164: (704-705): Inferred type: T(str) +// Info 4164: (709-710): Inferred type: T(str) +// Info 4164: (717-728): Inferred type: T(int) +// Info 4164: (717-722): Inferred type: (T(int), T(int)) -> T(int) +// Info 4164: (717-718): Inferred type: C +// Info 4164: (723-724): Inferred type: T(int) +// Info 4164: (726-727): Inferred type: T(int) +// Info 4164: (734-745): Inferred type: T(str) +// Info 4164: (734-739): Inferred type: (T(str), T(str)) -> T(str) +// Info 4164: (734-735): Inferred type: C +// Info 4164: (740-741): Inferred type: T(str) +// Info 4164: (743-744): Inferred type: T(str) From afb7a625a42c96ec925338bac4a40f59653fe234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 18 Oct 2023 14:39:55 +0200 Subject: [PATCH 2/4] Function types in `typeClassFunctions()` do not need `polymorphicInstance()` --- libsolidity/experimental/analysis/TypeInference.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libsolidity/experimental/analysis/TypeInference.cpp b/libsolidity/experimental/analysis/TypeInference.cpp index 590e82b4227d..3cc56bbba342 100644 --- a/libsolidity/experimental/analysis/TypeInference.cpp +++ b/libsolidity/experimental/analysis/TypeInference.cpp @@ -216,8 +216,7 @@ bool TypeInference::visit(TypeClassDefinition const& _typeClassDefinition) subNode->accept(*this); auto const* functionDefinition = dynamic_cast(subNode.get()); solAssert(functionDefinition); - // TODO: need polymorphicInstance? - auto functionType = polymorphicInstance(typeAnnotation(*functionDefinition)); + auto functionType = typeAnnotation(*functionDefinition); if (!functionTypes.emplace(functionDefinition->name(), functionType).second) m_errorReporter.fatalTypeError(3195_error, functionDefinition->location(), "Function in type class declared multiple times."); auto typeVars = TypeEnvironmentHelpers{*m_env}.typeVars(functionType); From 7a29114b4b8d3a9fab7486634b40f4750abd7cf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 18 Oct 2023 14:41:12 +0200 Subject: [PATCH 3/4] Type classes currently cannot take type parameters --- libsolidity/experimental/analysis/TypeInference.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libsolidity/experimental/analysis/TypeInference.cpp b/libsolidity/experimental/analysis/TypeInference.cpp index 3cc56bbba342..333912f02f86 100644 --- a/libsolidity/experimental/analysis/TypeInference.cpp +++ b/libsolidity/experimental/analysis/TypeInference.cpp @@ -480,7 +480,10 @@ experimental::Type TypeInference::handleIdentifierByReferencedDeclaration(langut else if (dynamic_cast(&_declaration)) return polymorphicInstance(*declarationAnnotation.type); else if (dynamic_cast(&_declaration)) - return polymorphicInstance(*declarationAnnotation.type); + { + solAssert(TypeEnvironmentHelpers{*m_env}.typeVars(*declarationAnnotation.type).empty()); + return *declarationAnnotation.type; + } else if (dynamic_cast(&_declaration)) { // TODO: can we avoid this? From f83283d4c6b8b421a325e6aa8292f3ca5312dfde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 27 Oct 2023 17:00:37 +0200 Subject: [PATCH 4/4] Remove TypeInference::unifyGeneralized() --- .../experimental/analysis/TypeInference.cpp | 13 +- .../experimental/analysis/TypeInference.h | 4 +- .../builtin/builtin_type_definition.sol | 4 +- .../inference/polymorphic_function_call.sol | 12 +- .../inference/polymorphic_type.sol | 28 ++--- .../polymorphic_type_abs_and_rep.sol | 24 ++-- ...rphic_type_instantiation_and_operators.sol | 118 +++++++++--------- 7 files changed, 97 insertions(+), 106 deletions(-) diff --git a/libsolidity/experimental/analysis/TypeInference.cpp b/libsolidity/experimental/analysis/TypeInference.cpp index 333912f02f86..3a3ebfa63a05 100644 --- a/libsolidity/experimental/analysis/TypeInference.cpp +++ b/libsolidity/experimental/analysis/TypeInference.cpp @@ -1071,18 +1071,9 @@ TypeRegistration::TypeClassInstantiations const& typeClassInstantiations(Analysi } } -void TypeInference::unifyGeneralized(Type _type, Type _scheme, std::vector _monomorphicTypes, langutil::SourceLocation _location) +experimental::Type TypeInference::polymorphicInstance(Type const& _scheme) { - solUnimplementedAssert(_monomorphicTypes.empty(), "unsupported"); - Type fresh = m_env->fresh(_scheme); - unify(_type, fresh, _location); -} - -experimental::Type TypeInference::polymorphicInstance(Type _scheme, langutil::SourceLocation _location) -{ - Type result = m_typeSystem.freshTypeVariable({}); - unifyGeneralized(result, _scheme, {}, _location); - return result; + return m_env->fresh(_scheme); } void TypeInference::unify(Type _a, Type _b, langutil::SourceLocation _location) diff --git a/libsolidity/experimental/analysis/TypeInference.h b/libsolidity/experimental/analysis/TypeInference.h index eb1b03f6974d..2f156eae02bd 100644 --- a/libsolidity/experimental/analysis/TypeInference.h +++ b/libsolidity/experimental/analysis/TypeInference.h @@ -110,8 +110,8 @@ class TypeInference: public ASTConstVisitor GlobalAnnotation& annotation(); void unify(Type _a, Type _b, langutil::SourceLocation _location = {}); - void unifyGeneralized(Type _type, Type _scheme, std::vector _monomorphicTypes, langutil::SourceLocation _location = {}); - Type polymorphicInstance(Type _scheme, langutil::SourceLocation _location = {}); + /// Creates a polymorphic instance of a global type scheme + Type polymorphicInstance(Type const& _scheme); Type memberType(Type _type, std::string _memberName, langutil::SourceLocation _location = {}); enum class ExpressionContext { Term, Type, Sort }; Type handleIdentifierByReferencedDeclaration(langutil::SourceLocation _location, Declaration const& _declaration); diff --git a/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol b/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol index d3a6ce2e5865..fc4783ceba19 100644 --- a/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol +++ b/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol @@ -84,9 +84,9 @@ contract C { // Info 4164: (525-529): Inferred type: word // Info 4164: (540-553): Inferred type: bool // Info 4164: (540-550): Inferred type: (bool, word) -> bool -// Info 4164: (540-544): Inferred type: ('cb:type, 'cc:type) +// Info 4164: (540-544): Inferred type: ('bl:type, 'bm:type) // Info 4164: (551-552): Inferred type: (bool, word) // Info 4164: (563-577): Inferred type: word // Info 4164: (563-574): Inferred type: (bool, word) -> word -// Info 4164: (563-567): Inferred type: ('ci:type, 'cj:type) +// Info 4164: (563-567): Inferred type: ('bq:type, 'br:type) // Info 4164: (575-576): Inferred type: (bool, word) diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol index 6fe19f07d00e..eacc895202f3 100644 --- a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol @@ -18,15 +18,15 @@ function run(a: T, b: U(T), c: U(U(T))) { // Info 4164: (39-49): Inferred type: tfun('u:type, U('u:type)) // Info 4164: (45-48): Inferred type: 't:type // Info 4164: (46-47): Inferred type: 't:type -// Info 4164: (51-82): Inferred type: ('x:type, 'y:type, U('bb:type)) -> () -// Info 4164: (61-79): Inferred type: ('x:type, 'y:type, U('bb:type)) +// Info 4164: (51-82): Inferred type: ('x:type, 'y:type, U('ba:type)) -> () +// Info 4164: (61-79): Inferred type: ('x:type, 'y:type, U('ba:type)) // Info 4164: (62-63): Inferred type: 'x:type // Info 4164: (65-69): Inferred type: 'y:type // Info 4164: (68-69): Inferred type: 'y:type -// Info 4164: (71-78): Inferred type: U('bb:type) -// Info 4164: (74-78): Inferred type: U('bb:type) -// Info 4164: (74-75): Inferred type: tfun('bb:type, U('bb:type)) -// Info 4164: (76-77): Inferred type: 'bb:type +// Info 4164: (71-78): Inferred type: U('ba:type) +// Info 4164: (74-78): Inferred type: U('ba:type) +// Info 4164: (74-75): Inferred type: tfun('ba:type, U('ba:type)) +// Info 4164: (76-77): Inferred type: 'ba:type // Info 4164: (84-159): Inferred type: (T, U(T), U(U(T))) -> () // Info 4164: (96-123): Inferred type: (T, U(T), U(U(T))) // Info 4164: (97-101): Inferred type: T diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol index eae572a0db28..b597a5b25295 100644 --- a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol @@ -29,19 +29,19 @@ function run() { // Info 4164: (88-92): Inferred type: 'bg:(type, D) // Info 4164: (100-170): Inferred type: () -> () // Info 4164: (112-114): Inferred type: () -// Info 4164: (125-141): Inferred type: T(U, 'bo:type, 'bq:(type, C)) -// Info 4164: (128-141): Inferred type: T(U, 'bo:type, 'bq:(type, C)) -// Info 4164: (128-129): Inferred type: tfun((U, 'bo:type, 'bq:(type, C)), T(U, 'bo:type, 'bq:(type, C))) +// Info 4164: (125-141): Inferred type: T(U, 'bm:type, 'bo:(type, C)) +// Info 4164: (128-141): Inferred type: T(U, 'bm:type, 'bo:(type, C)) +// Info 4164: (128-129): Inferred type: tfun((U, 'bm:type, 'bo:(type, C)), T(U, 'bm:type, 'bo:(type, C))) // Info 4164: (130-131): Inferred type: U -// Info 4164: (133-134): Inferred type: 'bo:type -// Info 4164: (136-140): Inferred type: 'bq:(type, C) -// Info 4164: (136-137): Inferred type: 'bq:(type, C) -// Info 4164: (139-140): Inferred type: 'bq:(type, C) -// Info 4164: (151-167): Inferred type: T(V, 'bx:type, 'bz:(type, D)) -// Info 4164: (154-167): Inferred type: T(V, 'bx:type, 'bz:(type, D)) -// Info 4164: (154-155): Inferred type: tfun((V, 'bx:type, 'bz:(type, D)), T(V, 'bx:type, 'bz:(type, D))) +// Info 4164: (133-134): Inferred type: 'bm:type +// Info 4164: (136-140): Inferred type: 'bo:(type, C) +// Info 4164: (136-137): Inferred type: 'bo:(type, C) +// Info 4164: (139-140): Inferred type: 'bo:(type, C) +// Info 4164: (151-167): Inferred type: T(V, 'bt:type, 'bv:(type, D)) +// Info 4164: (154-167): Inferred type: T(V, 'bt:type, 'bv:(type, D)) +// Info 4164: (154-155): Inferred type: tfun((V, 'bt:type, 'bv:(type, D)), T(V, 'bt:type, 'bv:(type, D))) // Info 4164: (156-157): Inferred type: V -// Info 4164: (159-160): Inferred type: 'bx:type -// Info 4164: (162-166): Inferred type: 'bz:(type, D) -// Info 4164: (162-163): Inferred type: 'bz:(type, D) -// Info 4164: (165-166): Inferred type: 'bz:(type, D) +// Info 4164: (159-160): Inferred type: 'bt:type +// Info 4164: (162-166): Inferred type: 'bv:(type, D) +// Info 4164: (162-163): Inferred type: 'bv:(type, D) +// Info 4164: (165-166): Inferred type: 'bv:(type, D) diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_abs_and_rep.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_abs_and_rep.sol index 3c4adb71717c..89f3f5f1a8b9 100644 --- a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_abs_and_rep.sol +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_abs_and_rep.sol @@ -43,13 +43,13 @@ function fun() { // Info 4164: (134-141): Inferred type: T(uint) // Info 4164: (134-135): Inferred type: tfun(uint, T(uint)) // Info 4164: (136-140): Inferred type: uint -// Info 4164: (147-155): Inferred type: T('bp:type) -// Info 4164: (147-152): Inferred type: U(uint) -> T('bp:type) -// Info 4164: (147-148): Inferred type: U('bm:type) +// Info 4164: (147-155): Inferred type: T('bi:type) +// Info 4164: (147-152): Inferred type: U(uint) -> T('bi:type) +// Info 4164: (147-148): Inferred type: U('bg:type) // Info 4164: (153-154): Inferred type: U(uint) -// Info 4164: (161-169): Inferred type: U('bv:type) -// Info 4164: (161-166): Inferred type: T(uint) -> U('bv:type) -// Info 4164: (161-162): Inferred type: U('bs:type) +// Info 4164: (161-169): Inferred type: U('bm:type) +// Info 4164: (161-166): Inferred type: T(uint) -> U('bm:type) +// Info 4164: (161-162): Inferred type: U('bk:type) // Info 4164: (167-168): Inferred type: T(uint) // Info 4164: (180-192): Inferred type: U(string) // Info 4164: (183-192): Inferred type: U(string) @@ -59,11 +59,11 @@ function fun() { // Info 4164: (205-214): Inferred type: T(string) // Info 4164: (205-206): Inferred type: tfun(string, T(string)) // Info 4164: (207-213): Inferred type: string -// Info 4164: (220-228): Inferred type: T('cj:type) -// Info 4164: (220-225): Inferred type: U(string) -> T('cj:type) -// Info 4164: (220-221): Inferred type: U('cg:type) +// Info 4164: (220-228): Inferred type: T('bu:type) +// Info 4164: (220-225): Inferred type: U(string) -> T('bu:type) +// Info 4164: (220-221): Inferred type: U('bs:type) // Info 4164: (226-227): Inferred type: U(string) -// Info 4164: (234-242): Inferred type: U('cp:type) -// Info 4164: (234-239): Inferred type: T(string) -> U('cp:type) -// Info 4164: (234-235): Inferred type: U('cm:type) +// Info 4164: (234-242): Inferred type: U('by:type) +// Info 4164: (234-239): Inferred type: T(string) -> U('by:type) +// Info 4164: (234-235): Inferred type: U('bw:type) // Info 4164: (240-241): Inferred type: T(string) diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol index b1cda1b3ed22..25ab330f3b32 100644 --- a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol @@ -57,22 +57,22 @@ function fun(a: T(int: P3), b: T(str: P4)) { // Info 4164: (74-83): Inferred type: int // Info 4164: (84-93): Inferred type: str // Info 4164: (95-156): Inferred type: C -// Info 4164: (101-105): Inferred type: 'bf:(type, C) -// Info 4164: (115-154): Inferred type: ('bf:(type, C), 'bf:(type, C)) -> 'bf:(type, C) -// Info 4164: (127-145): Inferred type: ('bf:(type, C), 'bf:(type, C)) -// Info 4164: (128-135): Inferred type: 'bf:(type, C) -// Info 4164: (131-135): Inferred type: 'bf:(type, C) -// Info 4164: (137-144): Inferred type: 'bf:(type, C) -// Info 4164: (140-144): Inferred type: 'bf:(type, C) -// Info 4164: (149-153): Inferred type: 'bf:(type, C) +// Info 4164: (101-105): Inferred type: 'bd:(type, C) +// Info 4164: (115-154): Inferred type: ('bd:(type, C), 'bd:(type, C)) -> 'bd:(type, C) +// Info 4164: (127-145): Inferred type: ('bd:(type, C), 'bd:(type, C)) +// Info 4164: (128-135): Inferred type: 'bd:(type, C) +// Info 4164: (131-135): Inferred type: 'bd:(type, C) +// Info 4164: (137-144): Inferred type: 'bd:(type, C) +// Info 4164: (140-144): Inferred type: 'bd:(type, C) +// Info 4164: (149-153): Inferred type: 'bd:(type, C) // Info 4164: (158-175): Inferred type: P1 -// Info 4164: (164-168): Inferred type: 'bi:(type, P1) +// Info 4164: (164-168): Inferred type: 'bg:(type, P1) // Info 4164: (176-193): Inferred type: P2 -// Info 4164: (182-186): Inferred type: 'bl:(type, P2) +// Info 4164: (182-186): Inferred type: 'bj:(type, P2) // Info 4164: (194-211): Inferred type: P3 -// Info 4164: (200-204): Inferred type: 'cb:(type, P3) +// Info 4164: (200-204): Inferred type: 'bw:(type, P3) // Info 4164: (212-229): Inferred type: P4 -// Info 4164: (218-222): Inferred type: 'cd:(type, P4) +// Info 4164: (218-222): Inferred type: 'by:(type, P4) // Info 4164: (231-255): Inferred type: void // Info 4164: (256-280): Inferred type: void // Info 4164: (281-305): Inferred type: void @@ -80,56 +80,56 @@ function fun(a: T(int: P3), b: T(str: P4)) { // Info 4164: (332-356): Inferred type: void // Info 4164: (357-381): Inferred type: void // Info 4164: (383-458): Inferred type: void -// Info 4164: (398-405): Inferred type: 'cf:(type, P1) -// Info 4164: (399-404): Inferred type: 'cf:(type, P1) -// Info 4164: (402-404): Inferred type: 'cf:(type, P1) -// Info 4164: (415-456): Inferred type: (T('cf:(type, P1)), T('cf:(type, P1))) -> T('cf:(type, P1)) -// Info 4164: (427-445): Inferred type: (T('cf:(type, P1)), T('cf:(type, P1))) -// Info 4164: (428-435): Inferred type: T('cf:(type, P1)) -// Info 4164: (431-435): Inferred type: T('cf:(type, P1)) -// Info 4164: (431-432): Inferred type: tfun('cf:(type, P1), T('cf:(type, P1))) -// Info 4164: (433-434): Inferred type: 'cf:(type, P1) -// Info 4164: (437-444): Inferred type: T('cf:(type, P1)) -// Info 4164: (440-444): Inferred type: T('cf:(type, P1)) -// Info 4164: (440-441): Inferred type: tfun('cf:(type, P1), T('cf:(type, P1))) -// Info 4164: (442-443): Inferred type: 'cf:(type, P1) -// Info 4164: (449-453): Inferred type: T('cf:(type, P1)) -// Info 4164: (449-450): Inferred type: tfun('cf:(type, P1), T('cf:(type, P1))) -// Info 4164: (451-452): Inferred type: 'cf:(type, P1) +// Info 4164: (398-405): Inferred type: 'ca:(type, P1) +// Info 4164: (399-404): Inferred type: 'ca:(type, P1) +// Info 4164: (402-404): Inferred type: 'ca:(type, P1) +// Info 4164: (415-456): Inferred type: (T('ca:(type, P1)), T('ca:(type, P1))) -> T('ca:(type, P1)) +// Info 4164: (427-445): Inferred type: (T('ca:(type, P1)), T('ca:(type, P1))) +// Info 4164: (428-435): Inferred type: T('ca:(type, P1)) +// Info 4164: (431-435): Inferred type: T('ca:(type, P1)) +// Info 4164: (431-432): Inferred type: tfun('ca:(type, P1), T('ca:(type, P1))) +// Info 4164: (433-434): Inferred type: 'ca:(type, P1) +// Info 4164: (437-444): Inferred type: T('ca:(type, P1)) +// Info 4164: (440-444): Inferred type: T('ca:(type, P1)) +// Info 4164: (440-441): Inferred type: tfun('ca:(type, P1), T('ca:(type, P1))) +// Info 4164: (442-443): Inferred type: 'ca:(type, P1) +// Info 4164: (449-453): Inferred type: T('ca:(type, P1)) +// Info 4164: (449-450): Inferred type: tfun('ca:(type, P1), T('ca:(type, P1))) +// Info 4164: (451-452): Inferred type: 'ca:(type, P1) // Info 4164: (460-535): Inferred type: void -// Info 4164: (475-482): Inferred type: 'cs:(type, P2) -// Info 4164: (476-481): Inferred type: 'cs:(type, P2) -// Info 4164: (479-481): Inferred type: 'cs:(type, P2) -// Info 4164: (493-533): Inferred type: (T('cs:(type, P2)), T('cs:(type, P2))) -> bool -// Info 4164: (504-522): Inferred type: (T('cs:(type, P2)), T('cs:(type, P2))) -// Info 4164: (505-512): Inferred type: T('cs:(type, P2)) -// Info 4164: (508-512): Inferred type: T('cs:(type, P2)) -// Info 4164: (508-509): Inferred type: tfun('cs:(type, P2), T('cs:(type, P2))) -// Info 4164: (510-511): Inferred type: 'cs:(type, P2) -// Info 4164: (514-521): Inferred type: T('cs:(type, P2)) -// Info 4164: (517-521): Inferred type: T('cs:(type, P2)) -// Info 4164: (517-518): Inferred type: tfun('cs:(type, P2), T('cs:(type, P2))) -// Info 4164: (519-520): Inferred type: 'cs:(type, P2) +// Info 4164: (475-482): Inferred type: 'ck:(type, P2) +// Info 4164: (476-481): Inferred type: 'ck:(type, P2) +// Info 4164: (479-481): Inferred type: 'ck:(type, P2) +// Info 4164: (493-533): Inferred type: (T('ck:(type, P2)), T('ck:(type, P2))) -> bool +// Info 4164: (504-522): Inferred type: (T('ck:(type, P2)), T('ck:(type, P2))) +// Info 4164: (505-512): Inferred type: T('ck:(type, P2)) +// Info 4164: (508-512): Inferred type: T('ck:(type, P2)) +// Info 4164: (508-509): Inferred type: tfun('ck:(type, P2), T('ck:(type, P2))) +// Info 4164: (510-511): Inferred type: 'ck:(type, P2) +// Info 4164: (514-521): Inferred type: T('ck:(type, P2)) +// Info 4164: (517-521): Inferred type: T('ck:(type, P2)) +// Info 4164: (517-518): Inferred type: tfun('ck:(type, P2), T('ck:(type, P2))) +// Info 4164: (519-520): Inferred type: 'ck:(type, P2) // Info 4164: (526-530): Inferred type: bool // Info 4164: (537-618): Inferred type: void -// Info 4164: (552-565): Inferred type: 'bo:(type, P1, P2) -// Info 4164: (553-564): Inferred type: 'bo:(type, P1, P2) -// Info 4164: (556-564): Inferred type: 'bo:(type, P1, P2) -// Info 4164: (557-559): Inferred type: 'bo:(type, P1, P2) -// Info 4164: (561-563): Inferred type: 'bo:(type, P1, P2) -// Info 4164: (575-616): Inferred type: (T('bo:(type, P1, P2)), T('bo:(type, P1, P2))) -> T('bo:(type, P1, P2)) -// Info 4164: (587-605): Inferred type: (T('bo:(type, P1, P2)), T('bo:(type, P1, P2))) -// Info 4164: (588-595): Inferred type: T('bo:(type, P1, P2)) -// Info 4164: (591-595): Inferred type: T('bo:(type, P1, P2)) -// Info 4164: (591-592): Inferred type: tfun('bo:(type, P1, P2), T('bo:(type, P1, P2))) -// Info 4164: (593-594): Inferred type: 'bo:(type, P1, P2) -// Info 4164: (597-604): Inferred type: T('bo:(type, P1, P2)) -// Info 4164: (600-604): Inferred type: T('bo:(type, P1, P2)) -// Info 4164: (600-601): Inferred type: tfun('bo:(type, P1, P2), T('bo:(type, P1, P2))) -// Info 4164: (602-603): Inferred type: 'bo:(type, P1, P2) -// Info 4164: (609-613): Inferred type: T('bo:(type, P1, P2)) -// Info 4164: (609-610): Inferred type: tfun('bo:(type, P1, P2), T('bo:(type, P1, P2))) -// Info 4164: (611-612): Inferred type: 'bo:(type, P1, P2) +// Info 4164: (552-565): Inferred type: 'bm:(type, P1, P2) +// Info 4164: (553-564): Inferred type: 'bm:(type, P1, P2) +// Info 4164: (556-564): Inferred type: 'bm:(type, P1, P2) +// Info 4164: (557-559): Inferred type: 'bm:(type, P1, P2) +// Info 4164: (561-563): Inferred type: 'bm:(type, P1, P2) +// Info 4164: (575-616): Inferred type: (T('bm:(type, P1, P2)), T('bm:(type, P1, P2))) -> T('bm:(type, P1, P2)) +// Info 4164: (587-605): Inferred type: (T('bm:(type, P1, P2)), T('bm:(type, P1, P2))) +// Info 4164: (588-595): Inferred type: T('bm:(type, P1, P2)) +// Info 4164: (591-595): Inferred type: T('bm:(type, P1, P2)) +// Info 4164: (591-592): Inferred type: tfun('bm:(type, P1, P2), T('bm:(type, P1, P2))) +// Info 4164: (593-594): Inferred type: 'bm:(type, P1, P2) +// Info 4164: (597-604): Inferred type: T('bm:(type, P1, P2)) +// Info 4164: (600-604): Inferred type: T('bm:(type, P1, P2)) +// Info 4164: (600-601): Inferred type: tfun('bm:(type, P1, P2), T('bm:(type, P1, P2))) +// Info 4164: (602-603): Inferred type: 'bm:(type, P1, P2) +// Info 4164: (609-613): Inferred type: T('bm:(type, P1, P2)) +// Info 4164: (609-610): Inferred type: tfun('bm:(type, P1, P2), T('bm:(type, P1, P2))) +// Info 4164: (611-612): Inferred type: 'bm:(type, P1, P2) // Info 4164: (620-748): Inferred type: (T(int), T(str)) -> () // Info 4164: (632-662): Inferred type: (T(int), T(str)) // Info 4164: (633-646): Inferred type: T(int)