Skip to content

[FIX] add additional parens for CPP2_TYPEOF macro used in inspect #148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

filipsajdak
Copy link
Contributor

The current implementation of cppfront is using constexpr ifs with requires expressions and the CPP2_TYPEOF macro to eliminate the compilation of alternatives that did not match in inspect expression. It suffers from issues with using macros and commas.

The below code:

template <int i, int j>
auto calc() {
    return i + j;
}

fun: (v : _) -> int = {
    return inspect v -> int {
        is int  = calc<1,2>();
        is _ = 0;
    };
}

main: () -> int = {
    return fun(42);
}

generates to (skipping boilerplate):

[[nodiscard]] auto fun(auto const& v) -> int{
    return [&] () -> int { auto&& __expr = v;
        if (cpp2::is<int>(__expr)) { if constexpr( requires{calc<1,2>();} ) if constexpr( std::is_convertible_v<CPP2_TYPEOF(calc<1,2>()),int> ) return calc<1,2>(); else return int{}; else return int{}; }
        else return 0; }
    ()
; }

[[nodiscard]] auto main() -> int{
    return fun(42); 
}

The problematic part is CPP2_TYPEOF(calc<1,2>()) that fails to compile (because of the coma) with the error:

tests/inspect_return_template.cpp2:12:132: error: too many arguments provided to function-like macro invocation
        if (cpp2::is<int>(__expr)) { if constexpr( requires{calc<1,2>();} ) if constexpr( std::is_convertible_v<CPP2_TYPEOF(calc<1,2>()),int> ) return calc<1,2>(); else return int{}; else return int{}; }
                                                                                                                                   ^
include/cpp2util.h:209:9: note: macro 'CPP2_TYPEOF' defined here
#define CPP2_TYPEOF(x)  std::remove_cvref_t<decltype(x)>
        ^
tests/inspect_return_template.cpp2:12:113: error: use of undeclared identifier 'CPP2_TYPEOF'
        if (cpp2::is<int>(__expr)) { if constexpr( requires{calc<1,2>();} ) if constexpr( std::is_convertible_v<CPP2_TYPEOF(calc<1,2>()),int> ) return calc<1,2>(); else return int{}; else return int{}; }
                                                                                                                ^
error: constexpr if condition is not a constant expression
tests/inspect_return_template.cpp2:18:12: note: in instantiation of function template specialization 'fun<int>' requested here
    return fun(42); 
           ^
3 errors generated.

This fix adds extra parens and produce:

CPP2_TYPEOF((calc<1,2>()))

Closes: #147

@hsutter
Copy link
Owner

hsutter commented Dec 3, 2022

Looks good! I'll merge this then add the new test case above to /regression-tests.

@hsutter hsutter merged commit b305745 into hsutter:main Dec 3, 2022
hsutter added a commit that referenced this pull request Dec 3, 2022
@filipsajdak filipsajdak deleted the fsajdak-fix-inspect-with-return-template-with-multiple-arguments branch December 22, 2022 10:43
Azmah-Bad pushed a commit to Azmah-Bad/cppfront that referenced this pull request Feb 24, 2023
…ith-return-template-with-multiple-arguments

[FIX] add additional parens for CPP2_TYPEOF macro used in inspect
Azmah-Bad pushed a commit to Azmah-Bad/cppfront that referenced this pull request Feb 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] using template arguments in inspect cause compiler to fail
2 participants