diff --git a/regression-tests/mixed-overview-of-is-inspections.cpp2 b/regression-tests/mixed-overview-of-is-inspections.cpp2
new file mode 100644
index 000000000..643a6733f
--- /dev/null
+++ b/regression-tests/mixed-overview-of-is-inspections.cpp2
@@ -0,0 +1,327 @@
+int* raw_null = nullptr;
+
+auto expect_throws(auto l) -> bool {
+ try {
+ l();
+ } catch (...) {
+ return true;
+ }
+ return false;
+}
+
+struct ThrowingConstruction {
+ constexpr ThrowingConstruction() = default;
+ ThrowingConstruction(int) { throw 1; }
+};
+
+
+main: () = {
+
+ print_header("type is type");
+ {
+ print(" is A", cpp2::is(), true);
+ print(" is B", cpp2::is(), false);
+ print(" is C", cpp2::is(), false);
+ print(" is A", cpp2::is(), false);
+ print(" is B", cpp2::is(), true);
+ print(" is C", cpp2::is(), false);
+ print(" is A", cpp2::is(), true);
+ print(" is B", cpp2::is(), false);
+ print(" is C", cpp2::is(), true);
+ }
+
+ print_header("type is template");
+ {
+ print("> is std::vector", cpp2::is,std::vector>(), true);
+ print("> is std::array", cpp2::is,std::array>(), false);
+ print("> is std::optional", cpp2::is,std::optional>(), false);
+ print("> is ", cpp2::is,std::vector>(), false);
+ print("> is ", cpp2::is,std::array>(), true);
+ print("> is ", cpp2::is,std::optional>(), false);
+ print("> is ", cpp2::is,std::vector>(), false);
+ print("> is ", cpp2::is,std::array>(), false);
+ print("> is ", cpp2::is,std::optional>(), true);
+ }
+
+ print_header("type is type_trait");
+ {
+ v : std::vector = ();
+ print("> is std::is_const", cpp2::is,std::is_const>(), true);
+ print("> is std::is_const", cpp2::is,std::is_const>(), false);
+ print("&> is std::is_reference", cpp2::is(), true);
+ }
+
+ print_header("type is concept");
+ {
+ // requires: clang-13+, gcc-12.1+, msvc-v19.34+
+ print(" is std::integral", cpp2::is()={}>(), true);
+ print(" is std::integral", cpp2::is()={}>(), false);
+ }
+
+ print_header("variable is template");
+ {
+ v : std::vector = (1, 2, 3);
+ print("v is vector", v is std::vector, true);
+ print("v is array", v is std::array, false);
+ print("v is optional", v is std::optional, false);
+ a : std::array = (4,3,2,1);
+ print("a is array", a is std::array, true);
+ print("a is vector", a is std::vector, false);
+ print("a is optional", a is std::optional, false);
+ o : std::optional = 42;
+ print("o is array", o is std::array, false);
+ print("o is vector", o is std::vector, false);
+ print("o is optional", o is std::optional, true);
+
+ }
+
+ print_header("variable is type");
+ {
+ a: A = ();
+ b: B = ();
+ c: C = ();
+ print("a is A", a is A, true);
+ print("b is A", b is A, false);
+ print("c is A", c is A, true);
+ }
+ {
+ vc: VC = ();
+ ptr_va0: *VA<0> = vc&;
+ ptr_va1: *VA<1> = vc&;
+ cptr_va0: * const VA<0> = vc&;
+
+ print("vc is VA<0>", vc is VA<0>, true);
+ print("vc is VA<1>", vc is VA<1>, true);
+ print("vc& is *VA<0>", vc& is *VA<0>, true);
+ print("vc& is *VA<1>", vc& is *VA<1>, true);
+
+ print("ptr_va0 is *VC", ptr_va0 is *VC, true);
+ print("ptr_va1 is *VC", ptr_va1 is *VC, true);
+ print("ptr_va0 is *VA<1>", ptr_va0 is *VA<1>, true);
+ print("ptr_va1 is *VA<0>", ptr_va1 is *VA<0>, true);
+ print("cptr_va0 is *VC", cptr_va0 is *VC, false);
+ print("cptr_va0 is * const VC", cptr_va0 is * const VC, true);
+
+ print("ptr_va0* is VC", ptr_va0* is VC, true);
+ print("ptr_va1* is VC", ptr_va1* is VC, true);
+ print("ptr_va0* is VA<1>", ptr_va0* is VA<1>, true);
+ print("ptr_va1* is VA<0>", ptr_va1* is VA<0>, true);
+ print("cptr_va0* is VC", cptr_va0* is VC, false);
+ print("cptr_va0* is const VC", cptr_va0* is const VC, true);
+ }
+
+ print_header("pointer-like variable is empty");
+ {
+ print("raw_null is empty", raw_null is cpp2::empty, true);
+ print("nullptr is empty", nullptr is cpp2::empty, true);
+ print("shared_ptr() is empty", std::shared_ptr() is cpp2::empty, true);
+ print("unique_ptr() is empty", std::unique_ptr() is cpp2::empty, true);
+
+ i := 42;
+ print("i& is empty", i& is cpp2::empty, false);
+ print("std::make_shared(42) is empty", std::make_shared(42) is cpp2::empty, false);
+ print("std::make_unique(44) is empty", std::make_unique(44) is cpp2::empty, false);
+ }
+
+ print_header("variable is value");
+ {
+ i := 42;
+ print("i{42} is empty", i is cpp2::empty, false);
+ print("i{42} is 24", i is 24, false);
+ print("i{42} is 42", i is 42, true);
+ print("i{42} is 42u", i is 42u, true);
+ print("i{42} is 42L", i is 42L, true);
+ print("i{42} is 42.0", i is 42.0, true);
+ print("i{42} is 42.0f", i is 42.0f, true);
+ print("3.14f is 3.14", 3.14f is 3.14, false);
+ close_to := :(v) -> _ = :(x) -> bool = {
+ return std::abs(v$ - x) < std::max,std::decay_t>>(std::numeric_limits>::epsilon(), std::numeric_limits>::epsilon());
+ };
+ print("3.14f is (close_to(3.14 ))", 3.14f is (close_to(3.14 )), true);
+ print("3.14 is (close_to(3.14f))", 3.14 is (close_to(3.14f)), true);
+ }
+
+ print_header("variable is type_trait");
+ {
+ i : int = 42;
+ ci : const int = 24;
+
+ print("i{int} is std::is_const", i is std::is_const, false);
+ print("ci{const int} is std::is_const", ci is std::is_const, true);
+ print("ci{const int} is std::is_integral", ci is std::is_integral, true);
+ print("ci{const int} is std::is_floating_point", ci is std::is_floating_point, false);
+ }
+
+ print_header("variable is predicate");
+ {
+ d := 3.14;
+
+ print("d{3.14} is (:(x) -> bool = x>0;)", d is (:(x) -> bool = x>0;), true);
+ print("d{3.14} is (:(x:int) -> bool = x>0;)", d is (:(x:int) -> bool = x>0;), false);
+ print("d{3.14} is (:(x:std::string) -> bool = x.ssize()>5;)", d is (:(x:std::string) -> bool = x.ssize()>5;), false);
+ print("std::string(\"abcdefg\") is (:(x:std::string) -> bool = x.ssize()>5;)", std::string("abcdefg") is (:(x:std::string) -> bool = x.ssize()>5;), true);
+
+ print("d{3.14} is (pred_i)", d is (pred_i), false);
+ print("d{3.14} is (pred_d)", d is (pred_d), true);
+ print("d{3.14} is (pred_)", true, true);
+
+ print("d{3.14} is (: () -> _ = true;)", d is (: () -> _ = true;), true);
+ print("d{3.14} is (: () = {})", d is (: () = {}), true);
+ print("d{3.14} is (: () = {})", d is (: () = {}), false);
+ }
+
+ print_header("variant variable is value");
+ {
+ v : std::variant> = (42);
+
+ print("v{42} is 42", v is 42, true);
+ print("v{42} is int", v is int, true);
+ print("v{42} is int", v is double, false);
+ print("v{42} is 42.0", v is 42.0, true);
+ print("v{42} is 24", v is 24, false);
+ print("v{42} is (std::string(\"hello\"))", v is (std::string("hello")), false);
+ print("v{42} is std::integral", v is (: () = {}), true);
+ print("v{42} is std::floating_point", v is (: () = {}), false);
+
+ v = std::string("hello");
+ print("v{hello} is (std::string(\"hello\"))", v is (std::string("hello")), true);
+ print("v{hello} is 42", v is 42, false);
+ print("v{hello} is empty", v is cpp2::empty, false);
+ print("v{hello} is int", v is int, false);
+ print("v{hello} is std::string", v is std::string, true);
+
+ v = :std::vector = (1,2,3,4);
+ print("v{std::vector{1,2,3,4}} is std::vector", v is std::vector, true );
+ print("v{std::vector{1,2,3,4}} is std::vector", v is std::vector, true );
+ print("v{std::vector{1,2,3,4}} is std::map", v is std::map, false);
+ print("v{std::vector{1,2,3,4}} is std::variant", v is std::variant, true );
+ }
+
+ print_header("variant variable is empty");
+ {
+ v : std::variant = ();
+ print("v{int} is empty", v is cpp2::empty, false, "v contains default value of first type");
+
+ v = std::monostate();
+ print("v{monostate} is empty", v is cpp2::empty, true);
+
+ expect_throws(:() = v&$*.emplace<1>(42););
+ print("v{valueless_by_exception} is empty", v is cpp2::empty, true, "is valueless: " + cpp2::to_string(v.valueless_by_exception()));
+
+ }
+
+ print_header("any variable is type");
+ {
+ a : std::any = 42;
+
+ print("a{42} is int", a is int, true);
+ print("a{42} is double", a is double, false);
+ print("a{42} is empty", a is cpp2::empty, false);
+
+ print("std::any() is empty", std::any() is cpp2::empty, true);
+ }
+
+ print_header("any variable is value");
+ {
+ a : std::any = 42;
+
+ print("a{42} is 42", a is 42, true);
+ print("a{42} is 24", a is 24, false);
+ print("a{42} is 42L", a is 42L, false);
+ print("std::any(3.14) is 3", std::any(3.14) is 3, false);
+
+ print("a{42} is :(v)->bool = v.has_value();", a is :(v)->bool = v.has_value();, true);
+ print("a{42} is :(v:std::any)->bool = v.has_value();", a is :(v:std::any)->bool = v.has_value();, true);
+ print("a{42} is :(v:int)->bool = v>0;", a is :(v:int)->bool = v>0;, true);
+ }
+
+ print_header("optional variable is type");
+ {
+ o : std::optional = 42;
+
+ print("o{42} is int", o is int, true);
+ print("o{42} is empty", o is cpp2::empty, false);
+ print("std::optional() is empty", std::optional() is cpp2::empty, true);
+ }
+
+ print_header("optional variable is value");
+ {
+ o : std::optional = 42;
+
+ print("o{42} is 42", o is 42, true);
+ print("o{42} is 24", o is 24, false);
+ print("o{42} is 42.0", o is 42.0, true);
+
+ print("o{42} is :(v) -> bool = v > 0;", o is :(v) -> bool = v > 0;, true);
+ print("o{42} is :(v:std::optional) -> bool = v > 0;", o is :(v:std::optional) -> bool = v > 0;, true);
+ print("o{42} is :(v:std::optional) -> bool = v > 0;", o is :(v:std::optional) -> bool = v > 0;, true);
+ print("std::optional(3.14) is :(v:std::optional) -> bool = v == 3;", std::optional(3.14) is :(v:std::optional) -> bool = v* == 3;, false);
+ }
+
+}
+
+A: type = {}
+B: type = {}
+C: type = {
+ this: A = ();
+}
+
+VA: @polymorphic_base type = {}
+
+VC: type = {
+ this: VA<0>;
+ this: VA<1>;
+}
+
+
+pred_i: (x : int ) -> bool = {
+ return x > 0;
+}
+
+pred_d: (x : double ) -> bool = {
+ return x > 0;
+}
+
+pred_: (x) -> bool = {
+ return x > 0;
+}
+
+col : std::array = (70, 8, 8, 8, 40);
+
+print: (what, value, expected, comment) = {
+ l := :(value) -> std::string = {
+ if value {
+ return "true";
+ } else {
+ return "false";
+ }
+ };
+ print(what, l(value), l(expected), inspect (value == expected) -> std::string { is (true) = "OK"; is _ = "FAILED!";}, comment );
+}
+
+print: (what, value, expected) = {
+ print(what, value, expected, std::string());
+}
+
+print: (what, value, expected, result, comment) = {
+ std::cout << "|" << std::setw(col[0]) << std::right << what;
+ std::cout << "|" << std::setw(col[1]) << std::internal << value;
+ std::cout << "|" << std::setw(col[2]) << std::internal << expected;
+ std::cout << "|" << std::setw(col[3]) << std::internal << result;
+ std::cout << "|" << std::setw(col[4]) << std::left << std::setprecision(20) << comment;
+ std::cout << "|" << std::endl;
+}
+
+print_header: (title) = {
+ std::cout << "\n# (title)$\n\n";
+ print("Test", "Actual", "Expected", "Result", "Comment");
+ print( std::string(col[0]-1,'-')+":"
+ , ":"+std::string(col[1]-2,'-')+":"
+ , ":"+std::string(col[2]-2,'-')+":"
+ , ":"+std::string(col[3]-2,'-')+":"
+ , ":"+std::string(col[4]-1,'-')
+ );
+}
+
+#include
+#include