You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG] Type-scope object alias can't have deduced type or use CTAD #700
//=== Cpp2 type definitions and function declarations ===========================public:staticconst std::array arr1; // error.//=== Cpp2 function definitions =================================================inlineconstexpr std::array t::arr1 = std::array{0};
//=== Cpp2 type definitions and function declarations ===========================public:staticconstauto arr1;// error.//=== Cpp2 function definitions =================================================inlineconstexprauto t::arr1 = std::array{0};
changed the title [-][BUG] Can't use CTAD for type-scope object alias[/-][+][BUG] Type-scope object alias can't have deduced type or use CTAD[/+]on Sep 24, 2023
I think that means that a templated @enum is bound to fail (on Clang and MSVC)
when you need an enumerator during constant evaluation.
I tried to actually test it, but a type-scope @enum fails: https://cpp2.godbolt.org/z/eheWhYYPz.
Right, and because Clang 3.4 is so old I just assumed that by now it would have been fixed. But it seems it's a rare enough case that it hasn't. Thank you very much for following up on this!
A definitely not-incomplete object type
to be defined in the class' body.
This is troublesome to determine.
Heuristics can only get you so far.
For example, #706 can't solve this:
t: @struct type = {
a: std::optional<t> == (); // Should be defined out of class.
b: std::optional<* t> == (); // Can be defined in class.
}
The heuristics of #706 are that those are defined in class.
It gets worse the more indirections one introduces:
f: () -> std::optional<t> == ();
g: () -> std::optional<* t> == ();
t: @struct type = {
a :== f(); // Should be defined out of class, but has a deduced type.
b :== g(); // Can be defined in class (has a deduced type, so it should?).
}
A simpler heuristic that should always works
is to define in class when the type is a placeholder.
So when you need to use CTAD,
or use the value in another member's signature,
you just need to use the placeholder type.
Activity
JohelEGP commentedon Sep 24, 2023
Title: Type-scope object alias can't have deduced type.
Description:
This is what I used before commit b589f5d.
Minimal reproducer (https://cpp2.godbolt.org/z/jhnjWPY76):
Commands:
cppfront main.cpp2 clang++17 -std=c++23 -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -Werror=unused-result -I . main.cppExpected result:
Actual result and error:
Cpp2 lowered to Cpp1:
[-][BUG] Can't use CTAD for type-scope object alias[/-][+][BUG] Type-scope object alias can't have deduced type or use CTAD[/+]JohelEGP commentedon Sep 26, 2023
One limitation of first declaring and then defining a type-scope object alias
is that implementations inconsistently accept their use as
constexpr(tested with #703).Defining in the class body always works: https://compiler-explorer.com/z/vabrK137E.
Otherwise, MSVC, Clang, and GCC give different results: https://compiler-explorer.com/z/zcdabTE4T.
For completeness, here's the previous one, but at namespace scope: https://compiler-explorer.com/z/rsabsnjGK.
(I'm polling their correctness at https://cpplang.slack.com/archives/C21PKDHSL/p1695693565690049).
JohelEGP commentedon Sep 26, 2023
I think that means that a templated
@enumis bound to fail (on Clang and MSVC)when you need an enumerator during constant evaluation.
I tried to actually test it, but a type-scope
@enumfails: https://cpp2.godbolt.org/z/eheWhYYPz.JohelEGP commentedon Sep 26, 2023
Looks like the limitation was known.
From the linked SO: https://stackoverflow.com/a/32134757.
hsutter commentedon Sep 26, 2023
Interim ack: In the meantime I'll add a diagnostic for an object alias in a nested type, which isn't currently supported. Thanks!
Add diagnostic for object alias in nested type, which isn't supported…
JohelEGP commentedon Sep 27, 2023
JohelEGP commentedon Sep 29, 2023
It actually doesn't.
But it's the same issue as #704.
Except that #706 fixes it for non-
@enumaliases by defining them in the class body.JohelEGP commentedon Oct 1, 2023
According to Brian Bi at https://cpplang.slack.com/archives/C21PKDHSL/p1696124673621459?thread_ts=1695800824.887719&cid=C21PKDHSL:
So it seems those are just compiler bugs.
hsutter commentedon Oct 1, 2023
Thanks!
Right, and because Clang 3.4 is so old I just assumed that by now it would have been fixed. But it seems it's a rare enough case that it hasn't. Thank you very much for following up on this!
JohelEGP commentedon Oct 31, 2023
This is troublesome to determine.
Heuristics can only get you so far.
For example, #706 can't solve this:
The heuristics of #706 are that those are defined in class.
It gets worse the more indirections one introduces:
JohelEGP commentedon Oct 31, 2023
This is a limitation of Cppfront.
A simpler heuristic that should always works
is to define in class when the type is a placeholder.
So when you need to use CTAD,
or use the value in another member's signature,
you just need to use the placeholder type.
Done in #706.
Add diagnostic for object alias in nested type, which isn't supported…