Let's say I have the following Jakt code:
/// Expect:
/// - output: ""
struct SecretHolder<T> {
private secret: T
function create(secret: T) -> SecretHolder<T> => SecretHolder(secret)
}
function main() {
let holder = SecretHolder::create(42i32)
}
It will typecheck and generate:
#include <lib.h>
namespace Jakt {
template <typename T>struct SecretHolder;
template <typename T>struct SecretHolder {
public:
T secret;static SecretHolder<T> create(const T secret) {
{
return (SecretHolder());
}
}
SecretHolder(T a_secret) :secret(a_secret){}
ErrorOr<String> debug_description() const { auto builder = MUST(StringBuilder::create());TRY(builder.append("SecretHolder("));JaktInternal::_pretty_print_level++;
TRY(JaktInternal::_output_pretty_indent(builder));TRY(builder.append("secret: "));TRY(builder.appendff("{}", secret));
JaktInternal::_pretty_print_level--;
TRY(builder.append(")"));return builder.to_string(); }};ErrorOr<int> main(Array<String>) {
{
const SecretHolder<i32> holder = SecretHolder::create(static_cast<i32>(42));
}
return 0;
}
template<typename T>struct Formatter<SecretHolder<T>
> : Formatter<StringView>{
ErrorOr<void> format(FormatBuilder& builder, SecretHolder<T>
const& value)
{ if (m_alternative_form) { JaktInternal::_pretty_print_enabled = true; }return Formatter<StringView>::format(builder, MUST(value.debug_description())); }};
} // namespace Jakt
Here, the typechecking is correct. It inferred correctly that I have created a SecretHolder<i32>
, and that SecretHolder::create
does not throw. The problem is that codegen did not add the template arguments in SecretHolder<T>::create
, and this confuses clang++:
❯ clang++ -w -I. -I<path/to/runtime> test.cpp -std=c++20
test.cpp:18:34: error: 'SecretHolder' is not a class, namespace, or enumeration
const SecretHolder<i32> holder = SecretHolder::create(static_cast<i32>(42));
^
test.cpp:4:29: note: 'SecretHolder' declared here
template <typename T>struct SecretHolder {
^
1 error generated.
Clang fails at recognizing SecretHolder
as a struct, since it's really a template.
The correct behavior should use SecretHolder<i32>::create(static_cast<i32>)
, i.e instantiating the template explicitly.
EDIT: simplified sample snippet to contain just Jakt code.
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too