Description
Inside inspect
, I have lambda where I forgot to pass argument. Like
:(x) -> _ = {return "int"} ();
instead of
:(x) -> _ = {return "int"} (x);
It was accepted by compilers and emitted code, which runs and silently returns ""
To Reproduce
https://cpp2.godbolt.org/z/aerezGKqq
Reproduction code
gettype: (x: _) -> std::string = {
return (inspect x -> std::string {
is int = :(x) -> _ = { std::cout<<x<<":"; return "int";} (); //forgot to pass argument to lambda
//is int = :(x) -> _ = { std::cout<<x<<":"; return "int";} (x); //ok, this would output "13:int, other"
is _ = "other";
});
}
main: () = {
std::cout << gettype(13) << ", " << gettype(false) << std::endl;
//outputs ", other" instead of diagnostic
// :(x) -> _ = { std::cout<<x<<":"; return "int";} (); //correct cpp1 error diagnostic
}
Command line
cppfront/cppfront $1.cpp2 -p
clang++-15 -Icppfront/include $1.cpp -std=c++20 -o $1
Expected result
Diagnostic like cpp1 for line 13:
error: no matching function for call to object of type '(lambda at lambdaparam.cpp2:13:6)'
note: candidate function template not viable: requires single argument 'x', but no arguments were provided
Actual result/error
Code silently compiles at cpp2 and cpp1 and silently runs without calling lambda and returning default value for inspect case, in this case an empty string.
Additional context
I understand this may be alpha version limitation of inspect
Emitted cpp1 code is roughly
if (cpp2::is(__expr)) { if constexpr( requires{V} ) if constexpr( std::is_convertible_v<V,T>) return V; else return T{}; else return T{}; }
Edit: after some investigation, it appears that cpp1
if constexpr( requires{[](auto const& x) -> auto{ ... }();} )
returns false.