Closed
Description
Title: Non-type template parameter used as type-id is not diagnosed.
Description:
I encountered this when poking Cppfront to get it to emit a type-constraint.
The issue is alleviated by resolving #425,
as it would only happen with an NTTP by copy
.
Minimal reproducer (https://cpp2.godbolt.org/z/WehjhjPjY):
t: @struct <T: std::regular> type = {
v: T;
}
f: <T: std::regular> (v: T) = _ = v;
g: <T: std::regular> (forward v: T) = _ = v;
h: <T: std::regular> (move v: T) = _ = v;
main: () = {
_ = :t = (0); // Not OK (works, should error)
f(0); // error (by chance?)
g(0); // error (by chance?)
h(0); // Not OK (works, should error)
}
Commands:
cppfront main.cpp2
clang++17 -std=c++23 -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -fsanitize=undefined -Werror=unused-result -I . main.cpp
Expected result: A diagnostic when using an NTTP as a type.
Actual result and error:
Cpp2 lowered to Cpp1:
//=== Cpp2 type declarations ====================================================
#include "cpp2util.h"
template<std::regular T> class t;
//=== Cpp2 type definitions and function declarations ===========================
template<std::regular T> class t {
public: T v;
};
template<std::regular T> auto f(cpp2::in<T> v) -> void;
template<std::regular T> auto g(auto&& v) -> void
CPP2_REQUIRES (std::is_same_v<CPP2_TYPEOF(v), T>)
;
template<std::regular T> auto h(T&& v) -> void;
auto main() -> int;
//=== Cpp2 function definitions =================================================
template<std::regular T> auto f(cpp2::in<T> v) -> void { (void) v; }
template<std::regular T> auto g(auto&& v) -> void
requires (std::is_same_v<CPP2_TYPEOF(v), T>)
{ (void) CPP2_FORWARD(v); }
template<std::regular T> auto h(T&& v) -> void { (void) std::move(v); }
auto main() -> int{
(void) t{0}; // Not OK (works, should error)
f(0); // error (by chance?)
g(0); // error (by chance?)
h(0); // Not OK (works, should error)
}
Output:
main.cpp2:10:3: error: no matching function for call to 'f'
10 | f(0); // error (by chance?)
| ^
main.cpp2:4:31: note: candidate template ignored: couldn't infer template argument 'T'
4 | template<std::regular T> auto f(cpp2::in<T> v) -> void { (void) v; }
| ^
main.cpp2:11:3: error: no matching function for call to 'g'
11 | g(0); // error (by chance?)
| ^
main.cpp2:5:31: note: candidate template ignored: couldn't infer template argument 'T'
5 | template<std::regular T> auto g(auto&& v) -> void
| ^
2 errors generated.