From 98378321cf9ac357e686125847800169b9da29c6 Mon Sep 17 00:00:00 2001 From: Neil Henderson Date: Fri, 1 Nov 2024 14:15:26 +1000 Subject: [PATCH 1/4] Add `is` and `as` support for `std::expected` --- include/cpp2util.h | 87 +++++++++++++ regression-tests/pure2-expected-is-as.cpp2 | 90 ++++++++++++++ .../pure2-expected-is-as.cpp.output | 67 ++++++++++ .../pure2-expected-is-as.cpp.execution | 15 +++ .../pure2-expected-is-as.cpp.output | 1 + .../test-results/pure2-expected-is-as.cpp | 117 ++++++++++++++++++ .../pure2-expected-is-as.cpp2.output | 2 + 7 files changed, 379 insertions(+) create mode 100644 regression-tests/pure2-expected-is-as.cpp2 create mode 100644 regression-tests/test-results/msvc-2022-c++20/pure2-expected-is-as.cpp.output create mode 100644 regression-tests/test-results/msvc-2022-c++latest/pure2-expected-is-as.cpp.execution create mode 100644 regression-tests/test-results/msvc-2022-c++latest/pure2-expected-is-as.cpp.output create mode 100644 regression-tests/test-results/pure2-expected-is-as.cpp create mode 100644 regression-tests/test-results/pure2-expected-is-as.cpp2.output diff --git a/include/cpp2util.h b/include/cpp2util.h index dee5bd2a9..4aead2ae1 100644 --- a/include/cpp2util.h +++ b/include/cpp2util.h @@ -2078,6 +2078,93 @@ constexpr auto as( X&& x ) -> decltype(auto) { } + +//------------------------------------------------------------------------------------------------------------- +// std::expected is and as +// +#ifdef __cpp_lib_expected + +// is Type +// +template + requires std::is_same_v> +constexpr auto is(X const& x) -> bool +{ + return x.has_value(); +} + +template + requires std::is_same_v +constexpr auto is(std::expected const& x) -> bool +{ + return !x.has_value(); +} + +// is std::unexpected Type +// +template + requires ( + std::is_same_v> + && std::is_same_v> + ) +constexpr auto is(X const& x) -> bool +{ + return !x.has_value(); +} + + +// is Value +// +template +constexpr auto is(std::expected const& x, auto&& value) -> bool +{ + // Predicate case + if constexpr (requires{ bool{ value(x) }; }) { + return value(x); + } + else if constexpr (std::is_function_v || requires{ &value.operator(); }) { + return false; + } + + // Value case + else if constexpr (requires{ bool{ x.value() == value }; }) { + return x.has_value() && x.value() == value; + } + else { + return false; + } +} + + +// as +// +template + requires std::is_same_v> +constexpr auto as(X const& x) -> decltype(auto) +{ + return x.value(); +} + +// as std::unexpected +// +template + requires ( + std::is_same_v> + && std::is_same_v> + ) +constexpr auto as(X const& x) -> decltype(auto) +{ + // It's UB to call `error` if `has_value` is true. + if (x.has_value()) { + Throw( + std::runtime_error("Cannot cast 'expected' to 'unexpected' because it has a value"), + "Cannot cast 'expected' to 'unexpected' because it has a value"); + } + + return std::unexpected(x.error()); +} +#endif + } // impl diff --git a/regression-tests/pure2-expected-is-as.cpp2 b/regression-tests/pure2-expected-is-as.cpp2 new file mode 100644 index 000000000..d144b2770 --- /dev/null +++ b/regression-tests/pure2-expected-is-as.cpp2 @@ -0,0 +1,90 @@ +// `std::expected` requires C++23 so a dedicated test file is needed +// since only MSVC supports it at time of writing, and there's no #ifdef +// or `static if` support in Cpp2 (yet?). + +main: () -> int = { + + ex1: std::expected = (123); + ex2: std::expected = std::unexpected(-1); + ex3: std::expected = ("Expect the unexpected"); + + if ex1 is int { + std::cout << "ex1 is int\n"; + } + + if ex1 is bool { + std::cout << "BUG - ex1 is not a bool\n"; + return -1; + } + + if ex1 is void { + std::cout << "BUG - ex1 is not 'empty'\n"; + return -1; + } + + if ex1 is std::unexpected { + std::cout << "BUG - ex1 is not unexpected\n"; + return -1; + } + + if ex1 is 123 { + std::cout << "ex1 is 123\n"; + } + + if ex1 is 100 { + std::cout << "BUG - ex1's value is not 100\n"; + return -1; + } + + val1:= ex1 as int; + std::cout << "ex1 as int = " << val1 << "\n"; + + if ex2 is int { + std::cout << "BUG - ex2 is not an int\n"; + return -1; + } + + if ex2 is bool { + std::cout << "BUG - ex2 is not a bool\n"; + return -1; + } + + if ex2 is 123 { + std::cout << "BUG - ex2 does not have a value\n"; + return -1; + } + + if ex2 is std::unexpected { + std::cout << "ex2 is unexpected and error is: " << ex2.error() << "\n"; + } + + if ex2 is void { + std::cout << "ex2 is 'empty' aka unexpected and error is: " << ex2.error() << "\n"; + } + + ex2_err:= ex2 as std::unexpected; + std::cout << "ex2 as std::unexpected and error = " << ex2_err.error() << "\n"; + + test_inspect(ex1, "expected with value"); + test_inspect(ex2, "expected with unexpected"); + test_inspect(ex3, "expected with value"); + + return 0; +} + +test_inspect: ( x: _, msg: _ ) = { + + unwrap:= :(unexp: std::unexpected) -> _ = { + return unexp.error(); + }; + + std::cout + << "\n" << msg << "\n ..." + << inspect x -> std::string { + is int = "integer " + std::to_string(x as int); + is std::unexpected = "unexpected " + std::to_string(unwrap(x as std::unexpected)); + is std::string = "string " + x as std::string; + is _ = " no match"; + } + << "\n"; +} \ No newline at end of file diff --git a/regression-tests/test-results/msvc-2022-c++20/pure2-expected-is-as.cpp.output b/regression-tests/test-results/msvc-2022-c++20/pure2-expected-is-as.cpp.output new file mode 100644 index 000000000..287904b4d --- /dev/null +++ b/regression-tests/test-results/msvc-2022-c++20/pure2-expected-is-as.cpp.output @@ -0,0 +1,67 @@ +pure2-expected-is-as.cpp +pure2-expected-is-as.cpp2(7): error C2039: 'expected': is not a member of 'std' +predefined C++ types (compiler internal)(346): note: see declaration of 'std' +pure2-expected-is-as.cpp2(7): error C2062: type 'int' unexpected +pure2-expected-is-as.cpp2(7): error C2143: syntax error: missing ';' before '{' +pure2-expected-is-as.cpp2(7): error C2143: syntax error: missing ';' before '}' +pure2-expected-is-as.cpp2(8): error C2039: 'expected': is not a member of 'std' +predefined C++ types (compiler internal)(346): note: see declaration of 'std' +pure2-expected-is-as.cpp2(8): error C2062: type 'int' unexpected +pure2-expected-is-as.cpp2(8): error C2143: syntax error: missing ';' before '{' +pure2-expected-is-as.cpp2(8): error C2039: 'unexpected': is not a member of 'std' +predefined C++ types (compiler internal)(346): note: see declaration of 'std' +pure2-expected-is-as.cpp2(8): error C2660: 'unexpected': function does not take 1 arguments +C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.41.34120\include\eh.h(33): note: see declaration of 'unexpected' +pure2-expected-is-as.cpp2(8): note: while trying to match the argument list '(int)' +pure2-expected-is-as.cpp2(8): error C2143: syntax error: missing ';' before '}' +pure2-expected-is-as.cpp2(9): error C2039: 'expected': is not a member of 'std' +predefined C++ types (compiler internal)(346): note: see declaration of 'std' +pure2-expected-is-as.cpp2(9): error C2275: 'std::string': expected an expression instead of a type +pure2-expected-is-as.cpp2(9): error C2065: 'ex3': undeclared identifier +pure2-expected-is-as.cpp2(9): error C2275: 'size_t': expected an expression instead of a type +pure2-expected-is-as.cpp2(11): error C2065: 'ex1': undeclared identifier +pure2-expected-is-as.cpp2(15): error C2065: 'ex1': undeclared identifier +pure2-expected-is-as.cpp2(20): error C2065: 'ex1': undeclared identifier +pure2-expected-is-as.cpp2(25): error C2039: 'unexpected': is not a member of 'std' +predefined C++ types (compiler internal)(346): note: see declaration of 'std' +pure2-expected-is-as.cpp2(25): error C2062: type 'int' unexpected +pure2-expected-is-as.cpp2(25): error C2059: syntax error: '>' +pure2-expected-is-as.cpp2(25): error C2143: syntax error: missing ';' before '{' +pure2-expected-is-as.cpp2(30): error C2065: 'ex1': undeclared identifier +pure2-expected-is-as.cpp2(34): error C2065: 'ex1': undeclared identifier +pure2-expected-is-as.cpp2(39): error C2065: 'ex1': undeclared identifier +pure2-expected-is-as.cpp2(39): error C2119: 'val1': the type for 'auto' cannot be deduced from an empty initializer +pure2-expected-is-as.cpp2(42): error C2065: 'ex2': undeclared identifier +pure2-expected-is-as.cpp2(47): error C2065: 'ex2': undeclared identifier +pure2-expected-is-as.cpp2(52): error C2065: 'ex2': undeclared identifier +pure2-expected-is-as.cpp2(57): error C2039: 'unexpected': is not a member of 'std' +predefined C++ types (compiler internal)(346): note: see declaration of 'std' +pure2-expected-is-as.cpp2(57): error C2062: type 'int' unexpected +pure2-expected-is-as.cpp2(57): error C2059: syntax error: '>' +pure2-expected-is-as.cpp2(57): error C2143: syntax error: missing ';' before '{' +pure2-expected-is-as.cpp2(58): error C2065: 'ex2': undeclared identifier +pure2-expected-is-as.cpp2(61): error C2065: 'ex2': undeclared identifier +pure2-expected-is-as.cpp2(62): error C2065: 'ex2': undeclared identifier +pure2-expected-is-as.cpp2(65): error C2039: 'unexpected': is not a member of 'std' +predefined C++ types (compiler internal)(346): note: see declaration of 'std' +pure2-expected-is-as.cpp2(65): error C2062: type 'int' unexpected +pure2-expected-is-as.cpp2(65): error C2062: type 'unknown-type' unexpected +pure2-expected-is-as.cpp2(65): error C2143: syntax error: missing ';' before '}' +pure2-expected-is-as.cpp2(66): error C2143: syntax error: missing ';' before '<<' +pure2-expected-is-as.cpp2(66): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int +pure2-expected-is-as.cpp2(66): error C2371: 'std::cout': redefinition; different basic types +C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.41.34120\include\iostream(39): note: see declaration of 'std::cout' +pure2-expected-is-as.cpp2(66): error C2059: syntax error: '<<' +pure2-expected-is-as.cpp2(66): error C2143: syntax error: missing ';' before '{' +pure2-expected-is-as.cpp2(66): error C2447: '{': missing function header (old-style formal list?) +pure2-expected-is-as.cpp2(66): error C2059: syntax error: '||' +pure2-expected-is-as.cpp2(66): error C2065: 'Obj': undeclared identifier +pure2-expected-is-as.cpp2(66): error C2065: 'Params': undeclared identifier +pure2-expected-is-as.cpp2(66): error C2059: syntax error: '}' +pure2-expected-is-as.cpp2(66): error C2143: syntax error: missing ')' before ';' +pure2-expected-is-as.cpp2(66): error C2059: syntax error: 'requires' +pure2-expected-is-as.cpp2(66): error C2059: syntax error: ')' +pure2-expected-is-as.cpp2(66): error C2065: 'obj': undeclared identifier +pure2-expected-is-as.cpp2(66): error C3553: decltype expects an expression not a type +pure2-expected-is-as.cpp2(66): error C2065: 'params': undeclared identifier +pure2-expected-is-as.cpp2(66): fatal error C1003: error count exceeds 100; stopping compilation diff --git a/regression-tests/test-results/msvc-2022-c++latest/pure2-expected-is-as.cpp.execution b/regression-tests/test-results/msvc-2022-c++latest/pure2-expected-is-as.cpp.execution new file mode 100644 index 000000000..5483d6cd7 --- /dev/null +++ b/regression-tests/test-results/msvc-2022-c++latest/pure2-expected-is-as.cpp.execution @@ -0,0 +1,15 @@ +ex1 is int +ex1 is 123 +ex1 as int = 123 +ex2 is unexpected and error is: -1 +ex2 is 'empty' aka unexpected and error is: -1 +ex2 as std::unexpected and error = -1 + +expected with value + ...integer 123 + +expected with unexpected + ...unexpected -1 + +expected with value + ...string Expect the unexpected diff --git a/regression-tests/test-results/msvc-2022-c++latest/pure2-expected-is-as.cpp.output b/regression-tests/test-results/msvc-2022-c++latest/pure2-expected-is-as.cpp.output new file mode 100644 index 000000000..6e7839bd6 --- /dev/null +++ b/regression-tests/test-results/msvc-2022-c++latest/pure2-expected-is-as.cpp.output @@ -0,0 +1 @@ +pure2-expected-is-as.cpp diff --git a/regression-tests/test-results/pure2-expected-is-as.cpp b/regression-tests/test-results/pure2-expected-is-as.cpp new file mode 100644 index 000000000..956d9547e --- /dev/null +++ b/regression-tests/test-results/pure2-expected-is-as.cpp @@ -0,0 +1,117 @@ + +#define CPP2_IMPORT_STD Yes + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + +#line 1 "pure2-expected-is-as.cpp2" + + +//=== Cpp2 type definitions and function declarations =========================== + +#line 1 "pure2-expected-is-as.cpp2" +// `std::expected` requires C++23 so a dedicated test file is needed +// since only MSVC supports it at time of writing, and there's no #ifdef +// or `static if` support in Cpp2 (yet?). + +#line 5 "pure2-expected-is-as.cpp2" +[[nodiscard]] auto main() -> int; + +#line 75 "pure2-expected-is-as.cpp2" +auto test_inspect(auto const& x, auto const& msg) -> void; + +//=== Cpp2 function definitions ================================================= + +#line 1 "pure2-expected-is-as.cpp2" + +#line 5 "pure2-expected-is-as.cpp2" +[[nodiscard]] auto main() -> int{ + + std::expected ex1 {123}; + std::expected ex2 {std::unexpected(-1)}; + std::expected ex3 {"Expect the unexpected"}; + + if (cpp2::impl::is(ex1)) { + std::cout << "ex1 is int\n"; + } + + if (cpp2::impl::is(ex1)) { + std::cout << "BUG - ex1 is not a bool\n"; + return -1; + } + + if (cpp2::impl::is(ex1)) { + std::cout << "BUG - ex1 is not 'empty'\n"; + return -1; + } + + if (cpp2::impl::is>(ex1)) { + std::cout << "BUG - ex1 is not unexpected\n"; + return -1; + } + + if (cpp2::impl::is(ex1, 123)) { + std::cout << "ex1 is 123\n"; + } + + if (cpp2::impl::is(ex1, 100)) { + std::cout << "BUG - ex1's value is not 100\n"; + return -1; + } + + auto val1 {cpp2::impl::as_(ex1)}; + std::cout << "ex1 as int = " << cpp2::move(val1) << "\n"; + + if (cpp2::impl::is(ex2)) { + std::cout << "BUG - ex2 is not an int\n"; + return -1; + } + + if (cpp2::impl::is(ex2)) { + std::cout << "BUG - ex2 is not a bool\n"; + return -1; + } + + if (cpp2::impl::is(ex2, 123)) { + std::cout << "BUG - ex2 does not have a value\n"; + return -1; + } + + if (cpp2::impl::is>(ex2)) { + std::cout << "ex2 is unexpected and error is: " << CPP2_UFCS(error)(ex2) << "\n"; + } + + if (cpp2::impl::is(ex2)) { + std::cout << "ex2 is 'empty' aka unexpected and error is: " << CPP2_UFCS(error)(ex2) << "\n"; + } + + auto ex2_err {cpp2::impl::as_>(ex2)}; + std::cout << "ex2 as std::unexpected and error = " << CPP2_UFCS(error)(cpp2::move(ex2_err)) << "\n"; + + test_inspect(cpp2::move(ex1), "expected with value"); + test_inspect(cpp2::move(ex2), "expected with unexpected"); + test_inspect(cpp2::move(ex3), "expected with value"); + + return 0; +} + +#line 75 "pure2-expected-is-as.cpp2" +auto test_inspect(auto const& x, auto const& msg) -> void{ + + auto unwrap {[](cpp2::impl::in> unexp) -> auto{ + return CPP2_UFCS(error)(unexp); + }}; + + std::cout + << "\n" << msg << "\n ..." + << [&] () -> std::string { auto&& _expr = x; + if (cpp2::impl::is(_expr)) { if constexpr( requires{"integer " + std::to_string(cpp2::impl::as(x));} ) if constexpr( std::is_convertible_v(x)))),std::string> ) return "integer " + std::to_string(cpp2::impl::as(x)); else return std::string{}; else return std::string{}; } + else if (cpp2::impl::is>(_expr)) { if constexpr( requires{"unexpected " + std::to_string(cpp2::move(unwrap)(cpp2::impl::as>(x)));} ) if constexpr( std::is_convertible_v " + std::to_string(cpp2::move(unwrap)(cpp2::impl::as>(x))))),std::string> ) return "unexpected " + std::to_string(cpp2::move(unwrap)(cpp2::impl::as>(x))); else return std::string{}; else return std::string{}; } + else if (cpp2::impl::is(_expr)) { if constexpr( requires{"string " + cpp2::impl::as(x);} ) if constexpr( std::is_convertible_v(x))),std::string> ) return "string " + cpp2::impl::as(x); else return std::string{}; else return std::string{}; } + else return " no match"; } + () + << "\n"; +} + diff --git a/regression-tests/test-results/pure2-expected-is-as.cpp2.output b/regression-tests/test-results/pure2-expected-is-as.cpp2.output new file mode 100644 index 000000000..a63d2c2a1 --- /dev/null +++ b/regression-tests/test-results/pure2-expected-is-as.cpp2.output @@ -0,0 +1,2 @@ +pure2-expected-is-as.cpp2... ok (all Cpp2, passes safety checks) + From 0320148237f5df27a36b7291ed2983352e3c4496 Mon Sep 17 00:00:00 2001 From: Neil Henderson Date: Fri, 1 Nov 2024 15:51:13 +1000 Subject: [PATCH 2/4] Add test-results for `pure2-expected-is-as` test case --- .../pure2-expected-is-as.cpp.output | 63 +++++ .../pure2-expected-is-as.cpp.execution | 15 ++ .../pure2-expected-is-as.cpp.output | 169 ++++++++++++ .../pure2-expected-is-as.cpp.output | 63 +++++ .../pure2-expected-is-as.cpp.output | 245 ++++++++++++++++++ .../pure2-expected-is-as.cpp.output | 245 ++++++++++++++++++ .../pure2-expected-is-as.cpp.execution | 15 ++ .../pure2-expected-is-as.cpp.output | 39 +++ .../pure2-expected-is-as.cpp.execution | 15 ++ .../pure2-expected-is-as.cpp.execution | 15 ++ .../pure2-expected-is-as.cpp.output | 18 +- 11 files changed, 893 insertions(+), 9 deletions(-) create mode 100644 regression-tests/test-results/apple-clang-14-c++2b/pure2-expected-is-as.cpp.output create mode 100644 regression-tests/test-results/apple-clang-15-c++2b/pure2-expected-is-as.cpp.execution create mode 100644 regression-tests/test-results/clang-12-c++20/pure2-expected-is-as.cpp.output create mode 100644 regression-tests/test-results/clang-15-c++20-libcpp/pure2-expected-is-as.cpp.output create mode 100644 regression-tests/test-results/clang-15-c++20/pure2-expected-is-as.cpp.output create mode 100644 regression-tests/test-results/clang-18-c++20/pure2-expected-is-as.cpp.output create mode 100644 regression-tests/test-results/clang-18-c++23-libcpp/pure2-expected-is-as.cpp.execution create mode 100644 regression-tests/test-results/gcc-10-c++20/pure2-expected-is-as.cpp.output create mode 100644 regression-tests/test-results/gcc-13-c++2b/pure2-expected-is-as.cpp.execution create mode 100644 regression-tests/test-results/gcc-14-c++2b/pure2-expected-is-as.cpp.execution diff --git a/regression-tests/test-results/apple-clang-14-c++2b/pure2-expected-is-as.cpp.output b/regression-tests/test-results/apple-clang-14-c++2b/pure2-expected-is-as.cpp.output new file mode 100644 index 000000000..56906de2a --- /dev/null +++ b/regression-tests/test-results/apple-clang-14-c++2b/pure2-expected-is-as.cpp.output @@ -0,0 +1,63 @@ +pure2-expected-is-as.cpp2:7:10: error: no member named 'expected' in namespace 'std' + std::expected ex1 {123}; + ~~~~~^ +pure2-expected-is-as.cpp2:7:22: error: expected '(' for function-style cast or type construction + std::expected ex1 {123}; + ~~~^ +pure2-expected-is-as.cpp2:8:10: error: no member named 'expected' in namespace 'std' + std::expected ex2 {std::unexpected(-1)}; + ~~~~~^ +pure2-expected-is-as.cpp2:8:22: error: expected '(' for function-style cast or type construction + std::expected ex2 {std::unexpected(-1)}; + ~~~^ +pure2-expected-is-as.cpp2:9:10: error: no member named 'expected' in namespace 'std' + std::expected ex3 {"Expect the unexpected"}; + ~~~~~^ +pure2-expected-is-as.cpp2:9:30: error: expected '(' for function-style cast or type construction + std::expected ex3 {"Expect the unexpected"}; + ~~~~~~~~~~~^ +pure2-expected-is-as.cpp2:11:29: error: use of undeclared identifier 'ex1' + if (cpp2::impl::is(ex1)) { + ^ +pure2-expected-is-as.cpp2:15:30: error: use of undeclared identifier 'ex1' + if (cpp2::impl::is(ex1)) { + ^ +pure2-expected-is-as.cpp2:20:30: error: use of undeclared identifier 'ex1' + if (cpp2::impl::is(ex1)) { + ^ +pure2-expected-is-as.cpp2:25:29: error: no member named 'unexpected' in namespace 'std' + if (cpp2::impl::is>(ex1)) { + ~~~~~^ +pure2-expected-is-as.cpp2:25:43: error: expected '(' for function-style cast or type construction + if (cpp2::impl::is>(ex1)) { + ~~~^ +pure2-expected-is-as.cpp2:25:46: error: use of undeclared identifier 'ex1'; did you mean 'exp'? + if (cpp2::impl::is>(ex1)) { + ^~~ + exp +/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/usr/include/c++/v1/math.h:895:1: note: 'exp' declared here +exp(_A1 __lcpp_x) _NOEXCEPT {return ::exp((double)__lcpp_x);} +^ +pure2-expected-is-as.cpp2:30:24: error: use of undeclared identifier 'ex1' + if (cpp2::impl::is(ex1, 123)) { + ^ +pure2-expected-is-as.cpp2:34:24: error: use of undeclared identifier 'ex1' + if (cpp2::impl::is(ex1, 100)) { + ^ +pure2-expected-is-as.cpp2:39:37: error: use of undeclared identifier 'ex1' + auto val1 {cpp2::impl::as_(ex1)}; + ^ +pure2-expected-is-as.cpp2:42:29: error: use of undeclared identifier 'ex2' + if (cpp2::impl::is(ex2)) { + ^ +pure2-expected-is-as.cpp2:47:30: error: use of undeclared identifier 'ex2' + if (cpp2::impl::is(ex2)) { + ^ +pure2-expected-is-as.cpp2:52:24: error: use of undeclared identifier 'ex2' + if (cpp2::impl::is(ex2, 123)) { + ^ +pure2-expected-is-as.cpp2:57:29: error: no member named 'unexpected' in namespace 'std' + if (cpp2::impl::is>(ex2)) { + ~~~~~^ +fatal error: too many errors emitted, stopping now [-ferror-limit=] +20 errors generated. diff --git a/regression-tests/test-results/apple-clang-15-c++2b/pure2-expected-is-as.cpp.execution b/regression-tests/test-results/apple-clang-15-c++2b/pure2-expected-is-as.cpp.execution new file mode 100644 index 000000000..5483d6cd7 --- /dev/null +++ b/regression-tests/test-results/apple-clang-15-c++2b/pure2-expected-is-as.cpp.execution @@ -0,0 +1,15 @@ +ex1 is int +ex1 is 123 +ex1 as int = 123 +ex2 is unexpected and error is: -1 +ex2 is 'empty' aka unexpected and error is: -1 +ex2 as std::unexpected and error = -1 + +expected with value + ...integer 123 + +expected with unexpected + ...unexpected -1 + +expected with value + ...string Expect the unexpected diff --git a/regression-tests/test-results/clang-12-c++20/pure2-expected-is-as.cpp.output b/regression-tests/test-results/clang-12-c++20/pure2-expected-is-as.cpp.output new file mode 100644 index 000000000..78c70e989 --- /dev/null +++ b/regression-tests/test-results/clang-12-c++20/pure2-expected-is-as.cpp.output @@ -0,0 +1,169 @@ +pure2-expected-is-as.cpp2:7:22: error: expected '(' for function-style cast or type construction + std::expected ex1 {123}; + ~~~^ +pure2-expected-is-as.cpp2:7:10: error: no member named 'expected' in namespace 'std'; did you mean 'unexpected'? + std::expected ex1 {123}; + ~~~~~^~~~~~~~ + unexpected +/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/exception:92:8: note: 'unexpected' declared here + void unexpected() __attribute__ ((__noreturn__)); + ^ +pure2-expected-is-as.cpp2:8:22: error: expected '(' for function-style cast or type construction + std::expected ex2 {std::unexpected(-1)}; + ~~~^ +pure2-expected-is-as.cpp2:8:10: error: no member named 'expected' in namespace 'std'; did you mean 'unexpected'? + std::expected ex2 {std::unexpected(-1)}; + ~~~~~^~~~~~~~ + unexpected +/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/exception:92:8: note: 'unexpected' declared here + void unexpected() __attribute__ ((__noreturn__)); + ^ +pure2-expected-is-as.cpp2:9:30: error: expected '(' for function-style cast or type construction + std::expected ex3 {"Expect the unexpected"}; + ~~~~~~~~~~~^ +pure2-expected-is-as.cpp2:9:10: error: no member named 'expected' in namespace 'std'; did you mean 'unexpected'? + std::expected ex3 {"Expect the unexpected"}; + ~~~~~^~~~~~~~ + unexpected +/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/exception:92:8: note: 'unexpected' declared here + void unexpected() __attribute__ ((__noreturn__)); + ^ +pure2-expected-is-as.cpp2:11:29: error: use of undeclared identifier 'ex1'; did you mean 'exp'? + if (cpp2::impl::is(ex1)) { + ^~~ + exp +/usr/include/x86_64-linux-gnu/bits/mathcalls.h:95:17: note: 'exp' declared here +__MATHCALL_VEC (exp,, (_Mdouble_ __x)); + ^ +pure2-expected-is-as.cpp2:15:30: error: use of undeclared identifier 'ex1'; did you mean 'exp'? + if (cpp2::impl::is(ex1)) { + ^~~ + exp +/usr/include/x86_64-linux-gnu/bits/mathcalls.h:95:17: note: 'exp' declared here +__MATHCALL_VEC (exp,, (_Mdouble_ __x)); + ^ +pure2-expected-is-as.cpp2:20:30: error: use of undeclared identifier 'ex1'; did you mean 'exp'? + if (cpp2::impl::is(ex1)) { + ^~~ + exp +/usr/include/x86_64-linux-gnu/bits/mathcalls.h:95:17: note: 'exp' declared here +__MATHCALL_VEC (exp,, (_Mdouble_ __x)); + ^ +pure2-expected-is-as.cpp2:25:29: error: 'unexpected' does not name a template but is followed by template arguments + if (cpp2::impl::is>(ex1)) { + ^ ~~~~~ +/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/exception:92:8: note: non-template declaration found by name lookup + void unexpected() __attribute__ ((__noreturn__)); + ^ +pure2-expected-is-as.cpp2:25:46: error: use of undeclared identifier 'ex1'; did you mean 'exp'? + if (cpp2::impl::is>(ex1)) { + ^~~ + exp +/usr/include/x86_64-linux-gnu/bits/mathcalls.h:95:17: note: 'exp' declared here +__MATHCALL_VEC (exp,, (_Mdouble_ __x)); + ^ +pure2-expected-is-as.cpp2:30:24: error: use of undeclared identifier 'ex1'; did you mean 'exp'? + if (cpp2::impl::is(ex1, 123)) { + ^~~ + exp +/usr/include/x86_64-linux-gnu/bits/mathcalls.h:95:17: note: 'exp' declared here +__MATHCALL_VEC (exp,, (_Mdouble_ __x)); + ^ +pure2-expected-is-as.cpp2:34:24: error: use of undeclared identifier 'ex1'; did you mean 'exp'? + if (cpp2::impl::is(ex1, 100)) { + ^~~ + exp +/usr/include/x86_64-linux-gnu/bits/mathcalls.h:95:17: note: 'exp' declared here +__MATHCALL_VEC (exp,, (_Mdouble_ __x)); + ^ +In file included from pure2-expected-is-as.cpp:7: +../../../include/cpp2util.h:1770:72: error: invalid application of 'sizeof' to a function type + (std::is_floating_point_v && std::is_floating_point_v && sizeof(From) > sizeof(To)) || // NOLINT(misc-redundant-expression) + ^~~~~~~~~~~~ +../../../include/cpp2util.h:2891:19: note: in instantiation of variable template specialization 'cpp2::impl::is_narrowing_v' requested here + if constexpr (is_narrowing_v) { + ^ +pure2-expected-is-as.cpp2:39:28: note: in instantiation of function template specialization 'cpp2::impl::as_' requested here + auto val1 {cpp2::impl::as_(ex1)}; + ^ +In file included from pure2-expected-is-as.cpp:7: +../../../include/cpp2util.h:2911:12: error: no matching function for call to 'as' + return as(CPP2_FORWARD(x)); + ^~~~~ +pure2-expected-is-as.cpp2:39:28: note: in instantiation of function template specialization 'cpp2::impl::as_' requested here + auto val1 {cpp2::impl::as_(ex1)}; + ^ +../../../include/cpp2util.h:1838:16: note: candidate template ignored: constraints not satisfied [with C = int, x:auto = double (&)(double) noexcept] +constexpr auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto) + ^ +../../../include/cpp2util.h:1844:18: note: because 'std::is_scalar_v >' evaluated to false + (std::is_scalar_v && !std::is_enum_v) + ^ +../../../include/cpp2util.h:1845:17: note: and 'std::is_floating_point_v >' evaluated to false + || std::is_floating_point_v + ^ +../../../include/cpp2util.h:1846:17: note: and 'std::is_base_of_v >' evaluated to false + || std::is_base_of_v + ^ +../../../include/cpp2util.h:1847:17: note: and 'std::is_base_of_v, int>' evaluated to false + || std::is_base_of_v + ^ +../../../include/cpp2util.h:1848:30: note: and 'C({std::forward(x)})' would be invalid: cannot initialize a value of type 'int' with an lvalue of type 'double (double) noexcept' + || requires { C{CPP2_FORWARD(x)}; } + ^ +../../../include/cpp2util.h:325:37: note: expanded from macro 'CPP2_FORWARD' +#define CPP2_FORWARD(x) std::forward(x) + ^ +../../../include/cpp2util.h:1977:6: note: candidate template ignored: constraints not satisfied [with C = int, X = double (&)(double) noexcept] +auto as(X&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto) + ^ +../../../include/cpp2util.h:1976:23: note: because 'specialization_of_template' evaluated to false +template< typename C, specialization_of_template X > + ^ +../../../include/cpp2util.h:724:7: note: because 'specialization_of_template_helper(std::forward(x))' would be invalid: no matching function for call to 'specialization_of_template_helper' + { specialization_of_template_helper(std::forward(x)) } -> std::same_as; + ^ +../../../include/cpp2util.h:2024:16: note: candidate template ignored: constraints not satisfied [with T = int, X = double (&)(double) noexcept] +constexpr auto as( X && x ) -> decltype(auto) { + ^ +../../../include/cpp2util.h:2023:22: note: because 'same_type_as' evaluated to false +template X> + ^ +../../../include/cpp2util.h:754:29: note: because 'std::same_as, std::remove_cvref_t >' evaluated to false +concept same_type_as = std::same_as, std::remove_cvref_t>; + ^ +/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/concepts:63:19: note: because '__detail::__same_as' evaluated to false + = __detail::__same_as<_Tp, _Up> && __detail::__same_as<_Up, _Tp>; + ^ +/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/concepts:57:27: note: because 'std::is_same_v' evaluated to false + concept __same_as = std::is_same_v<_Tp, _Up>; + ^ +../../../include/cpp2util.h:2069:16: note: candidate template ignored: constraints not satisfied [with T = int, X = double (&)(double) noexcept] +constexpr auto as( X&& x ) -> decltype(auto) { + ^ +../../../include/cpp2util.h:2068:22: note: because 'specialization_of_template' evaluated to false +template X> + ^ +../../../include/cpp2util.h:724:7: note: because 'specialization_of_template_helper(std::forward(x))' would be invalid: no matching function for call to 'specialization_of_template_helper' + { specialization_of_template_helper(std::forward(x)) } -> std::same_as; + ^ +../../../include/cpp2util.h:1813:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided +constexpr auto as() -> auto + ^ +../../../include/cpp2util.h:1824:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided +constexpr auto as() -> auto + ^ +pure2-expected-is-as.cpp2:39:37: error: use of undeclared identifier 'ex1' + auto val1 {cpp2::impl::as_(ex1)}; + ^ +pure2-expected-is-as.cpp2:42:29: error: use of undeclared identifier 'ex2' + if (cpp2::impl::is(ex2)) { + ^ +pure2-expected-is-as.cpp2:47:30: error: use of undeclared identifier 'ex2' + if (cpp2::impl::is(ex2)) { + ^ +pure2-expected-is-as.cpp2:52:24: error: use of undeclared identifier 'ex2' + if (cpp2::impl::is(ex2, 123)) { + ^ +fatal error: too many errors emitted, stopping now [-ferror-limit=] +20 errors generated. diff --git a/regression-tests/test-results/clang-15-c++20-libcpp/pure2-expected-is-as.cpp.output b/regression-tests/test-results/clang-15-c++20-libcpp/pure2-expected-is-as.cpp.output new file mode 100644 index 000000000..657d2b8ed --- /dev/null +++ b/regression-tests/test-results/clang-15-c++20-libcpp/pure2-expected-is-as.cpp.output @@ -0,0 +1,63 @@ +pure2-expected-is-as.cpp2:7:10: error: no member named 'expected' in namespace 'std' + std::expected ex1 {123}; + ~~~~~^ +pure2-expected-is-as.cpp2:7:22: error: expected '(' for function-style cast or type construction + std::expected ex1 {123}; + ~~~^ +pure2-expected-is-as.cpp2:8:10: error: no member named 'expected' in namespace 'std' + std::expected ex2 {std::unexpected(-1)}; + ~~~~~^ +pure2-expected-is-as.cpp2:8:22: error: expected '(' for function-style cast or type construction + std::expected ex2 {std::unexpected(-1)}; + ~~~^ +pure2-expected-is-as.cpp2:9:10: error: no member named 'expected' in namespace 'std' + std::expected ex3 {"Expect the unexpected"}; + ~~~~~^ +pure2-expected-is-as.cpp2:9:30: error: expected '(' for function-style cast or type construction + std::expected ex3 {"Expect the unexpected"}; + ~~~~~~~~~~~^ +pure2-expected-is-as.cpp2:11:29: error: use of undeclared identifier 'ex1' + if (cpp2::impl::is(ex1)) { + ^ +pure2-expected-is-as.cpp2:15:30: error: use of undeclared identifier 'ex1' + if (cpp2::impl::is(ex1)) { + ^ +pure2-expected-is-as.cpp2:20:30: error: use of undeclared identifier 'ex1' + if (cpp2::impl::is(ex1)) { + ^ +pure2-expected-is-as.cpp2:25:29: error: no member named 'unexpected' in namespace 'std' + if (cpp2::impl::is>(ex1)) { + ~~~~~^ +pure2-expected-is-as.cpp2:25:43: error: expected '(' for function-style cast or type construction + if (cpp2::impl::is>(ex1)) { + ~~~^ +pure2-expected-is-as.cpp2:25:46: error: use of undeclared identifier 'ex1'; did you mean 'exp'? + if (cpp2::impl::is>(ex1)) { + ^~~ + exp +/usr/lib/llvm-15/bin/../include/c++/v1/math.h:895:1: note: 'exp' declared here +exp(_A1 __lcpp_x) _NOEXCEPT {return ::exp((double)__lcpp_x);} +^ +pure2-expected-is-as.cpp2:30:24: error: use of undeclared identifier 'ex1' + if (cpp2::impl::is(ex1, 123)) { + ^ +pure2-expected-is-as.cpp2:34:24: error: use of undeclared identifier 'ex1' + if (cpp2::impl::is(ex1, 100)) { + ^ +pure2-expected-is-as.cpp2:39:37: error: use of undeclared identifier 'ex1' + auto val1 {cpp2::impl::as_(ex1)}; + ^ +pure2-expected-is-as.cpp2:42:29: error: use of undeclared identifier 'ex2' + if (cpp2::impl::is(ex2)) { + ^ +pure2-expected-is-as.cpp2:47:30: error: use of undeclared identifier 'ex2' + if (cpp2::impl::is(ex2)) { + ^ +pure2-expected-is-as.cpp2:52:24: error: use of undeclared identifier 'ex2' + if (cpp2::impl::is(ex2, 123)) { + ^ +pure2-expected-is-as.cpp2:57:29: error: no member named 'unexpected' in namespace 'std' + if (cpp2::impl::is>(ex2)) { + ~~~~~^ +fatal error: too many errors emitted, stopping now [-ferror-limit=] +20 errors generated. diff --git a/regression-tests/test-results/clang-15-c++20/pure2-expected-is-as.cpp.output b/regression-tests/test-results/clang-15-c++20/pure2-expected-is-as.cpp.output new file mode 100644 index 000000000..613220d97 --- /dev/null +++ b/regression-tests/test-results/clang-15-c++20/pure2-expected-is-as.cpp.output @@ -0,0 +1,245 @@ +pure2-expected-is-as.cpp2:7:22: error: expected '(' for function-style cast or type construction + std::expected ex1 {123}; + ~~~^ +pure2-expected-is-as.cpp2:7:10: error: no member named 'expected' in namespace 'std'; did you mean 'unexpected'? + std::expected ex1 {123}; + ~~~~~^~~~~~~~ + unexpected +/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/exception:109:8: note: 'unexpected' declared here + void unexpected() __attribute__ ((__noreturn__)); + ^ +pure2-expected-is-as.cpp2:8:22: error: expected '(' for function-style cast or type construction + std::expected ex2 {std::unexpected(-1)}; + ~~~^ +pure2-expected-is-as.cpp2:8:10: error: no member named 'expected' in namespace 'std'; did you mean 'unexpected'? + std::expected ex2 {std::unexpected(-1)}; + ~~~~~^~~~~~~~ + unexpected +/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/exception:109:8: note: 'unexpected' declared here + void unexpected() __attribute__ ((__noreturn__)); + ^ +pure2-expected-is-as.cpp2:9:30: error: expected '(' for function-style cast or type construction + std::expected ex3 {"Expect the unexpected"}; + ~~~~~~~~~~~^ +pure2-expected-is-as.cpp2:9:10: error: no member named 'expected' in namespace 'std'; did you mean 'unexpected'? + std::expected ex3 {"Expect the unexpected"}; + ~~~~~^~~~~~~~ + unexpected +/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/exception:109:8: note: 'unexpected' declared here + void unexpected() __attribute__ ((__noreturn__)); + ^ +pure2-expected-is-as.cpp2:11:29: error: use of undeclared identifier 'ex1'; did you mean 'exp'? + if (cpp2::impl::is(ex1)) { + ^~~ + exp +/usr/include/x86_64-linux-gnu/bits/mathcalls.h:95:17: note: 'exp' declared here +__MATHCALL_VEC (exp,, (_Mdouble_ __x)); + ^ +pure2-expected-is-as.cpp2:15:30: error: use of undeclared identifier 'ex1'; did you mean 'exp'? + if (cpp2::impl::is(ex1)) { + ^~~ + exp +/usr/include/x86_64-linux-gnu/bits/mathcalls.h:95:17: note: 'exp' declared here +__MATHCALL_VEC (exp,, (_Mdouble_ __x)); + ^ +pure2-expected-is-as.cpp2:20:30: error: use of undeclared identifier 'ex1'; did you mean 'exp'? + if (cpp2::impl::is(ex1)) { + ^~~ + exp +/usr/include/x86_64-linux-gnu/bits/mathcalls.h:95:17: note: 'exp' declared here +__MATHCALL_VEC (exp,, (_Mdouble_ __x)); + ^ +pure2-expected-is-as.cpp2:25:29: warning: 'unexpected' is deprecated [-Wdeprecated-declarations] + if (cpp2::impl::is>(ex1)) { + ^ +/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/exception:108:3: note: 'unexpected' has been explicitly marked deprecated here + _GLIBCXX11_DEPRECATED + ^ +/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/x86_64-linux-gnu/c++/12/bits/c++config.h:103:32: note: expanded from macro '_GLIBCXX11_DEPRECATED' +# define _GLIBCXX11_DEPRECATED _GLIBCXX_DEPRECATED + ^ +/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/x86_64-linux-gnu/c++/12/bits/c++config.h:94:46: note: expanded from macro '_GLIBCXX_DEPRECATED' +# define _GLIBCXX_DEPRECATED __attribute__ ((__deprecated__)) + ^ +pure2-expected-is-as.cpp2:25:29: error: 'unexpected' does not name a template but is followed by template arguments + if (cpp2::impl::is>(ex1)) { + ^ ~~~~~ +/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/exception:109:8: note: non-template declaration found by name lookup + void unexpected() __attribute__ ((__noreturn__)); + ^ +pure2-expected-is-as.cpp2:25:46: error: use of undeclared identifier 'ex1'; did you mean 'exp'? + if (cpp2::impl::is>(ex1)) { + ^~~ + exp +/usr/include/x86_64-linux-gnu/bits/mathcalls.h:95:17: note: 'exp' declared here +__MATHCALL_VEC (exp,, (_Mdouble_ __x)); + ^ +pure2-expected-is-as.cpp2:30:24: error: use of undeclared identifier 'ex1'; did you mean 'exp'? + if (cpp2::impl::is(ex1, 123)) { + ^~~ + exp +/usr/include/x86_64-linux-gnu/bits/mathcalls.h:95:17: note: 'exp' declared here +__MATHCALL_VEC (exp,, (_Mdouble_ __x)); + ^ +pure2-expected-is-as.cpp2:34:24: error: use of undeclared identifier 'ex1'; did you mean 'exp'? + if (cpp2::impl::is(ex1, 100)) { + ^~~ + exp +/usr/include/x86_64-linux-gnu/bits/mathcalls.h:95:17: note: 'exp' declared here +__MATHCALL_VEC (exp,, (_Mdouble_ __x)); + ^ +In file included from pure2-expected-is-as.cpp:7: +../../../include/cpp2util.h:1770:72: error: invalid application of 'sizeof' to a function type + (std::is_floating_point_v && std::is_floating_point_v && sizeof(From) > sizeof(To)) || // NOLINT(misc-redundant-expression) + ^~~~~~~~~~~~ +../../../include/cpp2util.h:2891:19: note: in instantiation of variable template specialization 'cpp2::impl::is_narrowing_v' requested here + if constexpr (is_narrowing_v) { + ^ +pure2-expected-is-as.cpp2:39:28: note: in instantiation of function template specialization 'cpp2::impl::as_' requested here + auto val1 {cpp2::impl::as_(ex1)}; + ^ +In file included from pure2-expected-is-as.cpp:7: +../../../include/cpp2util.h:2892:9: error: static assertion failed due to requirement 'program_violates_type_safety_guarantee': 'as' does not allow unsafe possibly-lossy narrowing conversions - if you're sure you want this, use 'unchecked_narrow' to explicitly force the conversion and possibly lose information + static_assert( + ^ +pure2-expected-is-as.cpp2:39:28: note: in instantiation of function template specialization 'cpp2::impl::as_' requested here + auto val1 {cpp2::impl::as_(ex1)}; + ^ +In file included from pure2-expected-is-as.cpp:7: +../../../include/cpp2util.h:2904:52: error: no matching function for call to 'as' + else if constexpr( std::is_same_v< CPP2_TYPEOF(as(CPP2_FORWARD(x))), nonesuch_ > ) { + ^~~~~ +../../../include/cpp2util.h:315:66: note: expanded from macro 'CPP2_TYPEOF' +#define CPP2_TYPEOF(x) std::remove_cvref_t + ^ +../../../include/cpp2util.h:1838:16: note: candidate template ignored: constraints not satisfied [with C = int, x:auto = double (&)(double) noexcept] +constexpr auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto) + ^ +../../../include/cpp2util.h:1844:18: note: because 'std::is_scalar_v >' evaluated to false + (std::is_scalar_v && !std::is_enum_v) + ^ +../../../include/cpp2util.h:1845:17: note: and 'std::is_floating_point_v >' evaluated to false + || std::is_floating_point_v + ^ +../../../include/cpp2util.h:1846:17: note: and 'std::is_base_of_v >' evaluated to false + || std::is_base_of_v + ^ +../../../include/cpp2util.h:1847:17: note: and 'std::is_base_of_v, int>' evaluated to false + || std::is_base_of_v + ^ +../../../include/cpp2util.h:1848:30: note: and 'C{std::forward(x)}' would be invalid: cannot initialize a value of type 'int' with an lvalue of type 'double (double) noexcept' + || requires { C{CPP2_FORWARD(x)}; } + ^ +../../../include/cpp2util.h:325:37: note: expanded from macro 'CPP2_FORWARD' +#define CPP2_FORWARD(x) std::forward(x) + ^ +../../../include/cpp2util.h:1977:6: note: candidate template ignored: constraints not satisfied [with C = int, X = double (&)(double) noexcept] +auto as(X&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto) + ^ +../../../include/cpp2util.h:1976:23: note: because 'specialization_of_template' evaluated to false +template< typename C, specialization_of_template X > + ^ +../../../include/cpp2util.h:724:7: note: because 'specialization_of_template_helper(std::forward(x))' would be invalid: no matching function for call to 'specialization_of_template_helper' + { specialization_of_template_helper(std::forward(x)) } -> std::same_as; + ^ +../../../include/cpp2util.h:2024:16: note: candidate template ignored: constraints not satisfied [with T = int, X = double (&)(double) noexcept] +constexpr auto as( X && x ) -> decltype(auto) { + ^ +../../../include/cpp2util.h:2023:22: note: because 'same_type_as' evaluated to false +template X> + ^ +../../../include/cpp2util.h:754:24: note: because 'std::same_as, std::remove_cvref_t >' evaluated to false +concept same_type_as = std::same_as, std::remove_cvref_t>; + ^ +/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/concepts:63:9: note: because '__detail::__same_as' evaluated to false + = __detail::__same_as<_Tp, _Up> && __detail::__same_as<_Up, _Tp>; + ^ +/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/concepts:57:27: note: because 'std::is_same_v' evaluated to false + concept __same_as = std::is_same_v<_Tp, _Up>; + ^ +../../../include/cpp2util.h:2069:16: note: candidate template ignored: constraints not satisfied [with T = int, X = double (&)(double) noexcept] +constexpr auto as( X&& x ) -> decltype(auto) { + ^ +../../../include/cpp2util.h:2068:22: note: because 'specialization_of_template' evaluated to false +template X> + ^ +../../../include/cpp2util.h:724:7: note: because 'specialization_of_template_helper(std::forward(x))' would be invalid: no matching function for call to 'specialization_of_template_helper' + { specialization_of_template_helper(std::forward(x)) } -> std::same_as; + ^ +../../../include/cpp2util.h:1813:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided +constexpr auto as() -> auto + ^ +../../../include/cpp2util.h:1824:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided +constexpr auto as() -> auto + ^ +../../../include/cpp2util.h:2905:9: error: static assertion failed due to requirement 'program_violates_type_safety_guarantee': No safe 'as' cast available - please check your cast + static_assert( + ^ +../../../include/cpp2util.h:2911:12: error: no matching function for call to 'as' + return as(CPP2_FORWARD(x)); + ^~~~~ +../../../include/cpp2util.h:1838:16: note: candidate template ignored: constraints not satisfied [with C = int, x:auto = double (&)(double) noexcept] +constexpr auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto) + ^ +../../../include/cpp2util.h:1844:18: note: because 'std::is_scalar_v >' evaluated to false + (std::is_scalar_v && !std::is_enum_v) + ^ +../../../include/cpp2util.h:1845:17: note: and 'std::is_floating_point_v >' evaluated to false + || std::is_floating_point_v + ^ +../../../include/cpp2util.h:1846:17: note: and 'std::is_base_of_v >' evaluated to false + || std::is_base_of_v + ^ +../../../include/cpp2util.h:1847:17: note: and 'std::is_base_of_v, int>' evaluated to false + || std::is_base_of_v + ^ +../../../include/cpp2util.h:1848:30: note: and 'C{std::forward(x)}' would be invalid: cannot initialize a value of type 'int' with an lvalue of type 'double (double) noexcept' + || requires { C{CPP2_FORWARD(x)}; } + ^ +../../../include/cpp2util.h:325:37: note: expanded from macro 'CPP2_FORWARD' +#define CPP2_FORWARD(x) std::forward(x) + ^ +../../../include/cpp2util.h:1977:6: note: candidate template ignored: constraints not satisfied [with C = int, X = double (&)(double) noexcept] +auto as(X&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto) + ^ +../../../include/cpp2util.h:1976:23: note: because 'specialization_of_template' evaluated to false +template< typename C, specialization_of_template X > + ^ +../../../include/cpp2util.h:724:7: note: because 'specialization_of_template_helper(std::forward(x))' would be invalid: no matching function for call to 'specialization_of_template_helper' + { specialization_of_template_helper(std::forward(x)) } -> std::same_as; + ^ +../../../include/cpp2util.h:2024:16: note: candidate template ignored: constraints not satisfied [with T = int, X = double (&)(double) noexcept] +constexpr auto as( X && x ) -> decltype(auto) { + ^ +../../../include/cpp2util.h:2023:22: note: because 'same_type_as' evaluated to false +template X> + ^ +../../../include/cpp2util.h:754:24: note: because 'std::same_as, std::remove_cvref_t >' evaluated to false +concept same_type_as = std::same_as, std::remove_cvref_t>; + ^ +/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/concepts:63:9: note: because '__detail::__same_as' evaluated to false + = __detail::__same_as<_Tp, _Up> && __detail::__same_as<_Up, _Tp>; + ^ +/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/concepts:57:27: note: because 'std::is_same_v' evaluated to false + concept __same_as = std::is_same_v<_Tp, _Up>; + ^ +../../../include/cpp2util.h:2069:16: note: candidate template ignored: constraints not satisfied [with T = int, X = double (&)(double) noexcept] +constexpr auto as( X&& x ) -> decltype(auto) { + ^ +../../../include/cpp2util.h:2068:22: note: because 'specialization_of_template' evaluated to false +template X> + ^ +../../../include/cpp2util.h:724:7: note: because 'specialization_of_template_helper(std::forward(x))' would be invalid: no matching function for call to 'specialization_of_template_helper' + { specialization_of_template_helper(std::forward(x)) } -> std::same_as; + ^ +../../../include/cpp2util.h:1813:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided +constexpr auto as() -> auto + ^ +../../../include/cpp2util.h:1824:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided +constexpr auto as() -> auto + ^ +pure2-expected-is-as.cpp2:39:37: error: use of undeclared identifier 'ex1' + auto val1 {cpp2::impl::as_(ex1)}; + ^ +fatal error: too many errors emitted, stopping now [-ferror-limit=] +1 warning and 20 errors generated. diff --git a/regression-tests/test-results/clang-18-c++20/pure2-expected-is-as.cpp.output b/regression-tests/test-results/clang-18-c++20/pure2-expected-is-as.cpp.output new file mode 100644 index 000000000..5c06a61b0 --- /dev/null +++ b/regression-tests/test-results/clang-18-c++20/pure2-expected-is-as.cpp.output @@ -0,0 +1,245 @@ +pure2-expected-is-as.cpp2:7:22: error: expected '(' for function-style cast or type construction + 7 | std::expected ex1 {123}; + | ~~~^ +pure2-expected-is-as.cpp2:7:10: error: no member named 'expected' in namespace 'std'; did you mean 'unexpected'? + 7 | std::expected ex1 {123}; + | ~~~~~^~~~~~~~ + | unexpected +/usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/exception:110:8: note: 'unexpected' declared here + 110 | void unexpected() __attribute__ ((__noreturn__,__cold__)); + | ^ +pure2-expected-is-as.cpp2:8:22: error: expected '(' for function-style cast or type construction + 8 | std::expected ex2 {std::unexpected(-1)}; + | ~~~^ +pure2-expected-is-as.cpp2:8:10: error: no member named 'expected' in namespace 'std'; did you mean 'unexpected'? + 8 | std::expected ex2 {std::unexpected(-1)}; + | ~~~~~^~~~~~~~ + | unexpected +/usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/exception:110:8: note: 'unexpected' declared here + 110 | void unexpected() __attribute__ ((__noreturn__,__cold__)); + | ^ +pure2-expected-is-as.cpp2:9:30: error: expected '(' for function-style cast or type construction + 9 | std::expected ex3 {"Expect the unexpected"}; + | ~~~~~~~~~~~^ +pure2-expected-is-as.cpp2:9:10: error: no member named 'expected' in namespace 'std'; did you mean 'unexpected'? + 9 | std::expected ex3 {"Expect the unexpected"}; + | ~~~~~^~~~~~~~ + | unexpected +/usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/exception:110:8: note: 'unexpected' declared here + 110 | void unexpected() __attribute__ ((__noreturn__,__cold__)); + | ^ +pure2-expected-is-as.cpp2:11:29: error: use of undeclared identifier 'ex1'; did you mean 'exp'? + 11 | if (cpp2::impl::is(ex1)) { + | ^~~ + | exp +/usr/include/x86_64-linux-gnu/bits/mathcalls.h:95:17: note: 'exp' declared here + 95 | __MATHCALL_VEC (exp,, (_Mdouble_ __x)); + | ^ +pure2-expected-is-as.cpp2:15:30: error: use of undeclared identifier 'ex1'; did you mean 'exp'? + 15 | if (cpp2::impl::is(ex1)) { + | ^~~ + | exp +/usr/include/x86_64-linux-gnu/bits/mathcalls.h:95:17: note: 'exp' declared here + 95 | __MATHCALL_VEC (exp,, (_Mdouble_ __x)); + | ^ +pure2-expected-is-as.cpp2:20:30: error: use of undeclared identifier 'ex1'; did you mean 'exp'? + 20 | if (cpp2::impl::is(ex1)) { + | ^~~ + | exp +/usr/include/x86_64-linux-gnu/bits/mathcalls.h:95:17: note: 'exp' declared here + 95 | __MATHCALL_VEC (exp,, (_Mdouble_ __x)); + | ^ +pure2-expected-is-as.cpp2:25:29: warning: 'unexpected' is deprecated [-Wdeprecated-declarations] + 25 | if (cpp2::impl::is>(ex1)) { + | ^ +/usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/exception:109:3: note: 'unexpected' has been explicitly marked deprecated here + 109 | _GLIBCXX11_DEPRECATED + | ^ +/usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14/bits/c++config.h:107:32: note: expanded from macro '_GLIBCXX11_DEPRECATED' + 107 | # define _GLIBCXX11_DEPRECATED _GLIBCXX_DEPRECATED + | ^ +/usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14/bits/c++config.h:98:46: note: expanded from macro '_GLIBCXX_DEPRECATED' + 98 | # define _GLIBCXX_DEPRECATED __attribute__ ((__deprecated__)) + | ^ +pure2-expected-is-as.cpp2:25:29: error: 'unexpected' does not name a template but is followed by template arguments + 25 | if (cpp2::impl::is>(ex1)) { + | ^ ~~~~~ +/usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/exception:110:8: note: non-template declaration found by name lookup + 110 | void unexpected() __attribute__ ((__noreturn__,__cold__)); + | ^ +pure2-expected-is-as.cpp2:25:46: error: use of undeclared identifier 'ex1'; did you mean 'exp'? + 25 | if (cpp2::impl::is>(ex1)) { + | ^~~ + | exp +/usr/include/x86_64-linux-gnu/bits/mathcalls.h:95:17: note: 'exp' declared here + 95 | __MATHCALL_VEC (exp,, (_Mdouble_ __x)); + | ^ +pure2-expected-is-as.cpp2:30:24: error: use of undeclared identifier 'ex1'; did you mean 'exp'? + 30 | if (cpp2::impl::is(ex1, 123)) { + | ^~~ + | exp +/usr/include/x86_64-linux-gnu/bits/mathcalls.h:95:17: note: 'exp' declared here + 95 | __MATHCALL_VEC (exp,, (_Mdouble_ __x)); + | ^ +pure2-expected-is-as.cpp2:34:24: error: use of undeclared identifier 'ex1'; did you mean 'exp'? + 34 | if (cpp2::impl::is(ex1, 100)) { + | ^~~ + | exp +/usr/include/x86_64-linux-gnu/bits/mathcalls.h:95:17: note: 'exp' declared here + 95 | __MATHCALL_VEC (exp,, (_Mdouble_ __x)); + | ^ +In file included from pure2-expected-is-as.cpp:7: +../../../include/cpp2util.h:1770:72: error: invalid application of 'sizeof' to a function type + 1770 | (std::is_floating_point_v && std::is_floating_point_v && sizeof(From) > sizeof(To)) || // NOLINT(misc-redundant-expression) + | ^~~~~~~~~~~~ +../../../include/cpp2util.h:2891:19: note: in instantiation of variable template specialization 'cpp2::impl::is_narrowing_v' requested here + 2891 | if constexpr (is_narrowing_v) { + | ^ +pure2-expected-is-as.cpp2:39:28: note: in instantiation of function template specialization 'cpp2::impl::as_' requested here + 39 | auto val1 {cpp2::impl::as_(ex1)}; + | ^ +In file included from pure2-expected-is-as.cpp:7: +../../../include/cpp2util.h:2893:13: error: static assertion failed due to requirement 'program_violates_type_safety_guarantee': 'as' does not allow unsafe possibly-lossy narrowing conversions - if you're sure you want this, use 'unchecked_narrow' to explicitly force the conversion and possibly lose information + 2893 | program_violates_type_safety_guarantee, + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +pure2-expected-is-as.cpp2:39:28: note: in instantiation of function template specialization 'cpp2::impl::as_' requested here + 39 | auto val1 {cpp2::impl::as_(ex1)}; + | ^ +In file included from pure2-expected-is-as.cpp:7: +../../../include/cpp2util.h:2904:52: error: no matching function for call to 'as' + 2904 | else if constexpr( std::is_same_v< CPP2_TYPEOF(as(CPP2_FORWARD(x))), nonesuch_ > ) { + | ^~~~~ +../../../include/cpp2util.h:315:66: note: expanded from macro 'CPP2_TYPEOF' + 315 | #define CPP2_TYPEOF(x) std::remove_cvref_t + | ^ +../../../include/cpp2util.h:1838:16: note: candidate template ignored: constraints not satisfied [with C = int, x:auto = double (&)(double) noexcept] + 1838 | constexpr auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto) + | ^ +../../../include/cpp2util.h:1844:18: note: because 'std::is_scalar_v >' evaluated to false + 1844 | (std::is_scalar_v && !std::is_enum_v) + | ^ +../../../include/cpp2util.h:1845:17: note: and 'std::is_floating_point_v >' evaluated to false + 1845 | || std::is_floating_point_v + | ^ +../../../include/cpp2util.h:1846:17: note: and 'std::is_base_of_v >' evaluated to false + 1846 | || std::is_base_of_v + | ^ +../../../include/cpp2util.h:1847:17: note: and 'std::is_base_of_v, int>' evaluated to false + 1847 | || std::is_base_of_v + | ^ +../../../include/cpp2util.h:1848:30: note: and 'C{std::forward(x)}' would be invalid: cannot initialize a value of type 'int' with an lvalue of type 'double (double) noexcept' + 1848 | || requires { C{CPP2_FORWARD(x)}; } + | ^ +../../../include/cpp2util.h:325:37: note: expanded from macro 'CPP2_FORWARD' + 325 | #define CPP2_FORWARD(x) std::forward(x) + | ^ +../../../include/cpp2util.h:1977:6: note: candidate template ignored: constraints not satisfied [with C = int, X = double (&)(double) noexcept] + 1977 | auto as(X&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto) + | ^ +../../../include/cpp2util.h:1976:23: note: because 'specialization_of_template' evaluated to false + 1976 | template< typename C, specialization_of_template X > + | ^ +../../../include/cpp2util.h:724:7: note: because 'specialization_of_template_helper(std::forward(x))' would be invalid: no matching function for call to 'specialization_of_template_helper' + 724 | { specialization_of_template_helper(std::forward(x)) } -> std::same_as; + | ^ +../../../include/cpp2util.h:2024:16: note: candidate template ignored: constraints not satisfied [with T = int, X = double (&)(double) noexcept] + 2024 | constexpr auto as( X && x ) -> decltype(auto) { + | ^ +../../../include/cpp2util.h:2023:22: note: because 'same_type_as' evaluated to false + 2023 | template X> + | ^ +../../../include/cpp2util.h:754:24: note: because 'std::same_as, std::remove_cvref_t >' evaluated to false + 754 | concept same_type_as = std::same_as, std::remove_cvref_t>; + | ^ +/usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/concepts:63:9: note: because '__detail::__same_as' evaluated to false + 63 | = __detail::__same_as<_Tp, _Up> && __detail::__same_as<_Up, _Tp>; + | ^ +/usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/concepts:57:27: note: because 'std::is_same_v' evaluated to false + 57 | concept __same_as = std::is_same_v<_Tp, _Up>; + | ^ +../../../include/cpp2util.h:2069:16: note: candidate template ignored: constraints not satisfied [with T = int, X = double (&)(double) noexcept] + 2069 | constexpr auto as( X&& x ) -> decltype(auto) { + | ^ +../../../include/cpp2util.h:2068:22: note: because 'specialization_of_template' evaluated to false + 2068 | template X> + | ^ +../../../include/cpp2util.h:724:7: note: because 'specialization_of_template_helper(std::forward(x))' would be invalid: no matching function for call to 'specialization_of_template_helper' + 724 | { specialization_of_template_helper(std::forward(x)) } -> std::same_as; + | ^ +../../../include/cpp2util.h:1813:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided + 1813 | constexpr auto as() -> auto + | ^ +../../../include/cpp2util.h:1824:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided + 1824 | constexpr auto as() -> auto + | ^ +../../../include/cpp2util.h:2906:13: error: static assertion failed due to requirement 'program_violates_type_safety_guarantee': No safe 'as' cast available - please check your cast + 2906 | program_violates_type_safety_guarantee, + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +../../../include/cpp2util.h:2911:12: error: no matching function for call to 'as' + 2911 | return as(CPP2_FORWARD(x)); + | ^~~~~ +../../../include/cpp2util.h:1838:16: note: candidate template ignored: constraints not satisfied [with C = int, x:auto = double (&)(double) noexcept] + 1838 | constexpr auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto) + | ^ +../../../include/cpp2util.h:1844:18: note: because 'std::is_scalar_v >' evaluated to false + 1844 | (std::is_scalar_v && !std::is_enum_v) + | ^ +../../../include/cpp2util.h:1845:17: note: and 'std::is_floating_point_v >' evaluated to false + 1845 | || std::is_floating_point_v + | ^ +../../../include/cpp2util.h:1846:17: note: and 'std::is_base_of_v >' evaluated to false + 1846 | || std::is_base_of_v + | ^ +../../../include/cpp2util.h:1847:17: note: and 'std::is_base_of_v, int>' evaluated to false + 1847 | || std::is_base_of_v + | ^ +../../../include/cpp2util.h:1848:30: note: and 'C{std::forward(x)}' would be invalid: cannot initialize a value of type 'int' with an lvalue of type 'double (double) noexcept' + 1848 | || requires { C{CPP2_FORWARD(x)}; } + | ^ +../../../include/cpp2util.h:325:37: note: expanded from macro 'CPP2_FORWARD' + 325 | #define CPP2_FORWARD(x) std::forward(x) + | ^ +../../../include/cpp2util.h:1977:6: note: candidate template ignored: constraints not satisfied [with C = int, X = double (&)(double) noexcept] + 1977 | auto as(X&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto) + | ^ +../../../include/cpp2util.h:1976:23: note: because 'specialization_of_template' evaluated to false + 1976 | template< typename C, specialization_of_template X > + | ^ +../../../include/cpp2util.h:724:7: note: because 'specialization_of_template_helper(std::forward(x))' would be invalid: no matching function for call to 'specialization_of_template_helper' + 724 | { specialization_of_template_helper(std::forward(x)) } -> std::same_as; + | ^ +../../../include/cpp2util.h:2024:16: note: candidate template ignored: constraints not satisfied [with T = int, X = double (&)(double) noexcept] + 2024 | constexpr auto as( X && x ) -> decltype(auto) { + | ^ +../../../include/cpp2util.h:2023:22: note: because 'same_type_as' evaluated to false + 2023 | template X> + | ^ +../../../include/cpp2util.h:754:24: note: because 'std::same_as, std::remove_cvref_t >' evaluated to false + 754 | concept same_type_as = std::same_as, std::remove_cvref_t>; + | ^ +/usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/concepts:63:9: note: because '__detail::__same_as' evaluated to false + 63 | = __detail::__same_as<_Tp, _Up> && __detail::__same_as<_Up, _Tp>; + | ^ +/usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/concepts:57:27: note: because 'std::is_same_v' evaluated to false + 57 | concept __same_as = std::is_same_v<_Tp, _Up>; + | ^ +../../../include/cpp2util.h:2069:16: note: candidate template ignored: constraints not satisfied [with T = int, X = double (&)(double) noexcept] + 2069 | constexpr auto as( X&& x ) -> decltype(auto) { + | ^ +../../../include/cpp2util.h:2068:22: note: because 'specialization_of_template' evaluated to false + 2068 | template X> + | ^ +../../../include/cpp2util.h:724:7: note: because 'specialization_of_template_helper(std::forward(x))' would be invalid: no matching function for call to 'specialization_of_template_helper' + 724 | { specialization_of_template_helper(std::forward(x)) } -> std::same_as; + | ^ +../../../include/cpp2util.h:1813:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided + 1813 | constexpr auto as() -> auto + | ^ +../../../include/cpp2util.h:1824:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided + 1824 | constexpr auto as() -> auto + | ^ +pure2-expected-is-as.cpp2:39:37: error: use of undeclared identifier 'ex1' + 39 | auto val1 {cpp2::impl::as_(ex1)}; + | ^ +fatal error: too many errors emitted, stopping now [-ferror-limit=] +1 warning and 20 errors generated. diff --git a/regression-tests/test-results/clang-18-c++23-libcpp/pure2-expected-is-as.cpp.execution b/regression-tests/test-results/clang-18-c++23-libcpp/pure2-expected-is-as.cpp.execution new file mode 100644 index 000000000..5483d6cd7 --- /dev/null +++ b/regression-tests/test-results/clang-18-c++23-libcpp/pure2-expected-is-as.cpp.execution @@ -0,0 +1,15 @@ +ex1 is int +ex1 is 123 +ex1 as int = 123 +ex2 is unexpected and error is: -1 +ex2 is 'empty' aka unexpected and error is: -1 +ex2 as std::unexpected and error = -1 + +expected with value + ...integer 123 + +expected with unexpected + ...unexpected -1 + +expected with value + ...string Expect the unexpected diff --git a/regression-tests/test-results/gcc-10-c++20/pure2-expected-is-as.cpp.output b/regression-tests/test-results/gcc-10-c++20/pure2-expected-is-as.cpp.output new file mode 100644 index 000000000..bce72f964 --- /dev/null +++ b/regression-tests/test-results/gcc-10-c++20/pure2-expected-is-as.cpp.output @@ -0,0 +1,39 @@ +pure2-expected-is-as.cpp2: In function ‘int main()’: +pure2-expected-is-as.cpp2:7:10: error: ‘expected’ is not a member of ‘std’; did you mean ‘unexpected’? +pure2-expected-is-as.cpp2:7:19: error: expected primary-expression before ‘int’ +pure2-expected-is-as.cpp2:8:10: error: ‘expected’ is not a member of ‘std’; did you mean ‘unexpected’? +pure2-expected-is-as.cpp2:8:19: error: expected primary-expression before ‘int’ +pure2-expected-is-as.cpp2:9:10: error: ‘expected’ is not a member of ‘std’; did you mean ‘unexpected’? +pure2-expected-is-as.cpp2:9:30: error: expected primary-expression before ‘,’ token +pure2-expected-is-as.cpp2:9:37: error: expected primary-expression before ‘>’ token +pure2-expected-is-as.cpp2:9:39: error: ‘ex3’ was not declared in this scope; did you mean ‘exp’? +pure2-expected-is-as.cpp2:11:29: error: ‘ex1’ was not declared in this scope; did you mean ‘exp’? +pure2-expected-is-as.cpp2:15:30: error: ‘ex1’ was not declared in this scope; did you mean ‘exp’? +pure2-expected-is-as.cpp2:20:30: error: ‘ex1’ was not declared in this scope; did you mean ‘exp’? +pure2-expected-is-as.cpp2:25:21: error: parse error in template argument list +pure2-expected-is-as.cpp2:25:46: error: ‘ex1’ was not declared in this scope; did you mean ‘exp’? +pure2-expected-is-as.cpp2:30:24: error: ‘ex1’ was not declared in this scope; did you mean ‘exp’? +pure2-expected-is-as.cpp2:34:24: error: ‘ex1’ was not declared in this scope; did you mean ‘exp’? +pure2-expected-is-as.cpp2:39:37: error: ‘ex1’ was not declared in this scope; did you mean ‘exp’? +pure2-expected-is-as.cpp2:42:29: error: ‘ex2’ was not declared in this scope; did you mean ‘exp2’? +pure2-expected-is-as.cpp2:47:30: error: ‘ex2’ was not declared in this scope; did you mean ‘exp2’? +pure2-expected-is-as.cpp2:52:24: error: ‘ex2’ was not declared in this scope; did you mean ‘exp2’? +pure2-expected-is-as.cpp2:57:21: error: parse error in template argument list +pure2-expected-is-as.cpp2:57:46: error: ‘ex2’ was not declared in this scope; did you mean ‘exp2’? +pure2-expected-is-as.cpp2:61:30: error: ‘ex2’ was not declared in this scope; did you mean ‘exp2’? +pure2-expected-is-as.cpp2:65:31: error: parse error in template argument list +pure2-expected-is-as.cpp2:65:57: error: ‘ex2’ was not declared in this scope; did you mean ‘exp2’? +pure2-expected-is-as.cpp2: In function ‘void test_inspect(const auto:110&, const auto:111&)’: +pure2-expected-is-as.cpp2:77:55: error: template argument 1 is invalid +pure2-expected-is-as.cpp2:77:21: error: ‘cpp2::impl::unexp’ has not been declared +pure2-expected-is-as.cpp2: In lambda function: +pure2-expected-is-as.cpp2:78:33: error: ‘unexp’ was not declared in this scope +pure2-expected-is-as.cpp2: In lambda function: +pure2-expected-is-as.cpp2:85:34: error: parse error in template argument list +pure2-expected-is-as.cpp2:85:159: error: parse error in template argument list +In file included from pure2-expected-is-as.cpp:7: +pure2-expected-is-as.cpp2:85:309: error: parse error in template argument list +../../../include/cpp2util.h:315:66: note: in definition of macro ‘CPP2_TYPEOF’ + 315 | #define CPP2_TYPEOF(x) std::remove_cvref_t + | ^ +pure2-expected-is-as.cpp2:85:430: error: parse error in template argument list diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-expected-is-as.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-expected-is-as.cpp.execution new file mode 100644 index 000000000..5483d6cd7 --- /dev/null +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-expected-is-as.cpp.execution @@ -0,0 +1,15 @@ +ex1 is int +ex1 is 123 +ex1 as int = 123 +ex2 is unexpected and error is: -1 +ex2 is 'empty' aka unexpected and error is: -1 +ex2 as std::unexpected and error = -1 + +expected with value + ...integer 123 + +expected with unexpected + ...unexpected -1 + +expected with value + ...string Expect the unexpected diff --git a/regression-tests/test-results/gcc-14-c++2b/pure2-expected-is-as.cpp.execution b/regression-tests/test-results/gcc-14-c++2b/pure2-expected-is-as.cpp.execution new file mode 100644 index 000000000..5483d6cd7 --- /dev/null +++ b/regression-tests/test-results/gcc-14-c++2b/pure2-expected-is-as.cpp.execution @@ -0,0 +1,15 @@ +ex1 is int +ex1 is 123 +ex1 as int = 123 +ex2 is unexpected and error is: -1 +ex2 is 'empty' aka unexpected and error is: -1 +ex2 as std::unexpected and error = -1 + +expected with value + ...integer 123 + +expected with unexpected + ...unexpected -1 + +expected with value + ...string Expect the unexpected diff --git a/regression-tests/test-results/msvc-2022-c++20/pure2-expected-is-as.cpp.output b/regression-tests/test-results/msvc-2022-c++20/pure2-expected-is-as.cpp.output index 287904b4d..9b87b96a3 100644 --- a/regression-tests/test-results/msvc-2022-c++20/pure2-expected-is-as.cpp.output +++ b/regression-tests/test-results/msvc-2022-c++20/pure2-expected-is-as.cpp.output @@ -1,21 +1,21 @@ pure2-expected-is-as.cpp pure2-expected-is-as.cpp2(7): error C2039: 'expected': is not a member of 'std' -predefined C++ types (compiler internal)(346): note: see declaration of 'std' +predefined C++ types (compiler internal)(347): note: see declaration of 'std' pure2-expected-is-as.cpp2(7): error C2062: type 'int' unexpected pure2-expected-is-as.cpp2(7): error C2143: syntax error: missing ';' before '{' pure2-expected-is-as.cpp2(7): error C2143: syntax error: missing ';' before '}' pure2-expected-is-as.cpp2(8): error C2039: 'expected': is not a member of 'std' -predefined C++ types (compiler internal)(346): note: see declaration of 'std' +predefined C++ types (compiler internal)(347): note: see declaration of 'std' pure2-expected-is-as.cpp2(8): error C2062: type 'int' unexpected pure2-expected-is-as.cpp2(8): error C2143: syntax error: missing ';' before '{' pure2-expected-is-as.cpp2(8): error C2039: 'unexpected': is not a member of 'std' -predefined C++ types (compiler internal)(346): note: see declaration of 'std' +predefined C++ types (compiler internal)(347): note: see declaration of 'std' pure2-expected-is-as.cpp2(8): error C2660: 'unexpected': function does not take 1 arguments -C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.41.34120\include\eh.h(33): note: see declaration of 'unexpected' +C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.41.34120\include\eh.h(33): note: see declaration of 'unexpected' pure2-expected-is-as.cpp2(8): note: while trying to match the argument list '(int)' pure2-expected-is-as.cpp2(8): error C2143: syntax error: missing ';' before '}' pure2-expected-is-as.cpp2(9): error C2039: 'expected': is not a member of 'std' -predefined C++ types (compiler internal)(346): note: see declaration of 'std' +predefined C++ types (compiler internal)(347): note: see declaration of 'std' pure2-expected-is-as.cpp2(9): error C2275: 'std::string': expected an expression instead of a type pure2-expected-is-as.cpp2(9): error C2065: 'ex3': undeclared identifier pure2-expected-is-as.cpp2(9): error C2275: 'size_t': expected an expression instead of a type @@ -23,7 +23,7 @@ pure2-expected-is-as.cpp2(11): error C2065: 'ex1': undeclared identifier pure2-expected-is-as.cpp2(15): error C2065: 'ex1': undeclared identifier pure2-expected-is-as.cpp2(20): error C2065: 'ex1': undeclared identifier pure2-expected-is-as.cpp2(25): error C2039: 'unexpected': is not a member of 'std' -predefined C++ types (compiler internal)(346): note: see declaration of 'std' +predefined C++ types (compiler internal)(347): note: see declaration of 'std' pure2-expected-is-as.cpp2(25): error C2062: type 'int' unexpected pure2-expected-is-as.cpp2(25): error C2059: syntax error: '>' pure2-expected-is-as.cpp2(25): error C2143: syntax error: missing ';' before '{' @@ -35,7 +35,7 @@ pure2-expected-is-as.cpp2(42): error C2065: 'ex2': undeclared identifier pure2-expected-is-as.cpp2(47): error C2065: 'ex2': undeclared identifier pure2-expected-is-as.cpp2(52): error C2065: 'ex2': undeclared identifier pure2-expected-is-as.cpp2(57): error C2039: 'unexpected': is not a member of 'std' -predefined C++ types (compiler internal)(346): note: see declaration of 'std' +predefined C++ types (compiler internal)(347): note: see declaration of 'std' pure2-expected-is-as.cpp2(57): error C2062: type 'int' unexpected pure2-expected-is-as.cpp2(57): error C2059: syntax error: '>' pure2-expected-is-as.cpp2(57): error C2143: syntax error: missing ';' before '{' @@ -43,14 +43,14 @@ pure2-expected-is-as.cpp2(58): error C2065: 'ex2': undeclared identifier pure2-expected-is-as.cpp2(61): error C2065: 'ex2': undeclared identifier pure2-expected-is-as.cpp2(62): error C2065: 'ex2': undeclared identifier pure2-expected-is-as.cpp2(65): error C2039: 'unexpected': is not a member of 'std' -predefined C++ types (compiler internal)(346): note: see declaration of 'std' +predefined C++ types (compiler internal)(347): note: see declaration of 'std' pure2-expected-is-as.cpp2(65): error C2062: type 'int' unexpected pure2-expected-is-as.cpp2(65): error C2062: type 'unknown-type' unexpected pure2-expected-is-as.cpp2(65): error C2143: syntax error: missing ';' before '}' pure2-expected-is-as.cpp2(66): error C2143: syntax error: missing ';' before '<<' pure2-expected-is-as.cpp2(66): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int pure2-expected-is-as.cpp2(66): error C2371: 'std::cout': redefinition; different basic types -C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.41.34120\include\iostream(39): note: see declaration of 'std::cout' +C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.41.34120\include\iostream(39): note: see declaration of 'std::cout' pure2-expected-is-as.cpp2(66): error C2059: syntax error: '<<' pure2-expected-is-as.cpp2(66): error C2143: syntax error: missing ';' before '{' pure2-expected-is-as.cpp2(66): error C2447: '{': missing function header (old-style formal list?) From 825850ba9d41c94e003b9fc40346b2b4e972bbe3 Mon Sep 17 00:00:00 2001 From: Neil Henderson Date: Fri, 1 Nov 2024 16:01:03 +1000 Subject: [PATCH 3/4] Update test-results --- .../apple-clang-14-c++2b/pure2-expected-is-as.cpp.output | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression-tests/test-results/apple-clang-14-c++2b/pure2-expected-is-as.cpp.output b/regression-tests/test-results/apple-clang-14-c++2b/pure2-expected-is-as.cpp.output index 56906de2a..7280779fa 100644 --- a/regression-tests/test-results/apple-clang-14-c++2b/pure2-expected-is-as.cpp.output +++ b/regression-tests/test-results/apple-clang-14-c++2b/pure2-expected-is-as.cpp.output @@ -35,7 +35,7 @@ pure2-expected-is-as.cpp2:25:46: error: use of undeclared identifier 'ex1'; did if (cpp2::impl::is>(ex1)) { ^~~ exp -/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/usr/include/c++/v1/math.h:895:1: note: 'exp' declared here +/Applications/Xcode_14.3.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/v1/math.h:895:1: note: 'exp' declared here exp(_A1 __lcpp_x) _NOEXCEPT {return ::exp((double)__lcpp_x);} ^ pure2-expected-is-as.cpp2:30:24: error: use of undeclared identifier 'ex1' From 64e112161d4a4ccacbc968a4ecb73f19cd82be66 Mon Sep 17 00:00:00 2001 From: Neil Henderson Date: Sat, 2 Nov 2024 10:36:09 +1000 Subject: [PATCH 4/4] [CI] run-tests.sh now allows each compiler config to exclude test files that it doesn't want to run There are 2 macOS test configs which share the same expected results directory (to avoid duplication). This works great except for the new `pure2-expected-is-as` test. This new test code fails to compile (as expected) on both compilers, but produces a slightly different error diagnostic because the path is different. E.g. /Applications/Xcode_14.3.1.app/...etc.../math.h and /Library/Developer/CommandLineTools/...etc.../math.h One option would be to stop sharing the expected results for both of these compilers, but that seems wasteful since it's just one test which fails to compile. So instead the `run-tests` script has a new way to exclude a test from running. --- regression-tests/run-tests.sh | 53 ++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/regression-tests/run-tests.sh b/regression-tests/run-tests.sh index b4cfc8787..6e3ac81b7 100644 --- a/regression-tests/run-tests.sh +++ b/regression-tests/run-tests.sh @@ -135,28 +135,11 @@ if [ -z "$label" ]; then usage fi -tests=$(ls | grep ".cpp2$") -if [[ -n "$chosen_tests" ]]; then - for test in $chosen_tests; do - if ! [[ -f "$test" ]]; then - echo "Requested test ($test) not found" - exit 1 - fi - done - echo "Performing tests:" - for test in $chosen_tests; do - echo " $test" - done - echo - tests="$chosen_tests" -else - printf "Performing all regression tests\n\n" -fi - -expected_results_dir="test-results" - ################ # Get the directory with the exec outputs and compilation command +# We also allow each compiler configuration to specify any test files(s) to exclude from running. +expected_results_dir="test-results" +exclude_test_filter="" if [[ "$cxx_compiler" == *"cl.exe"* ]]; then compiler_cmd="cl.exe -nologo -std:${cxx_std} -MD -EHsc -I ..\..\..\include -Fe:" exec_out_dir="$expected_results_dir/msvc-2022-${cxx_std}" @@ -174,6 +157,12 @@ else if [[ "$compiler_version" == *"Apple clang version 14.0"* || "$compiler_version" == *"Homebrew clang version 15.0"* ]]; then exec_out_dir="$expected_results_dir/apple-clang-14" + # We share the expected results dir for these two compilers, but there is one + # test which (as expected) fails to compile on both compilers, but has a slightly + # different error diagnostic because the clang path differs. So we exclude it from + # running. The alternative would be to duplicate the expected results files, which + # seems wasteful for just one test (that doesn't even compile). + exclude_test_filter="pure2-expected-is-as.cpp2" elif [[ "$compiler_version" == *"Apple clang version 15.0"* ]]; then exec_out_dir="$expected_results_dir/apple-clang-15" elif [[ "$compiler_version" == *"clang version 12.0"* ]]; then @@ -236,6 +225,30 @@ else exit 2 fi +################ +# Get the list of .cpp2 test files +if [[ -n "$exclude_test_filter" ]]; then + tests=$(ls | grep ".cpp2$" | grep -v $exclude_test_filter) +else + tests=$(ls | grep ".cpp2$") +fi +if [[ -n "$chosen_tests" ]]; then + for test in $chosen_tests; do + if ! [[ -f "$test" ]]; then + echo "Requested test ($test) not found" + exit 1 + fi + done + echo "Performing tests:" + for test in $chosen_tests; do + echo " $test" + done + echo + tests="$chosen_tests" +else + printf "Performing all regression tests\n\n" +fi + ################ cppfront_cmd="cppfront.exe" echo "Building cppfront"