Skip to content

Commit 0ff280a

Browse files
committed
fix(to_cpp1): define type-scope object alias with wildcard type inline
1 parent 210b2a0 commit 0ff280a

5 files changed

+110
-15
lines changed

regression-tests/pure2-bugfix-for-ufcs-name-lookup.cpp2

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ ns: namespace = {
1212
f: (_) -> int == 1;
1313
} // namespace ns
1414

15-
// v: @struct type = {
16-
// f :== :(_) 0; // Pending on #706.
17-
// g: (i) i.f();
18-
// }
15+
v: @struct type = {
16+
f :== :(_) 0;
17+
g: (i) i.f();
18+
}
1919

2020
main: () = {
2121
{

regression-tests/pure2-type-and-namespace-aliases.cpp2

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,25 @@ main: () = {
3333
myfunc2 :== myfunc;
3434
myfunc2();
3535
}
36+
37+
myclass5: type == myclass4;
38+
39+
myclass3: @struct type = {
40+
// Defined inline.
41+
i0 :== :std::array = (0);
42+
i1 :== i0;
43+
i3: _ == i0;
44+
i7 :== :() 0;
45+
46+
// Defined out of line.
47+
o2: myclass3 == myclass3();
48+
o4: myclass3 == o2;
49+
o5: myclass4 == myclass4();
50+
o6: myclass5 == myclass5();
51+
}
52+
53+
myclass4: @struct type = { }
54+
55+
myclass6: @struct <T: type> type = {
56+
v: <U> _ requires true == 0;
57+
}

regression-tests/test-results/pure2-bugfix-for-ufcs-name-lookup.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ namespace ns {
2222

2323
}
2424

25+
class v;
26+
2527

2628
//=== Cpp2 type definitions and function declarations ===========================
2729

@@ -41,10 +43,10 @@ namespace ns {
4143
[[nodiscard]] constexpr auto f([[maybe_unused]] auto const& unnamed_param_1) -> int;
4244
} // namespace ns
4345

44-
// v: @struct type = {
45-
// f :== :(_) 0; // Pending on #706.
46-
// g: (i) i.f();
47-
// }
46+
class v {
47+
public: static constexpr auto f = []([[maybe_unused]] auto const& unnamed_param_1) mutable -> auto { return 0; };
48+
public: [[nodiscard]] static auto g(auto const& i) -> auto;
49+
};
4850

4951
auto main() -> int;
5052

@@ -63,6 +65,9 @@ namespace ns {
6365
[[nodiscard]] constexpr auto f([[maybe_unused]] auto const& unnamed_param_1) -> int { return 1; }
6466
}
6567

68+
#line 17 "pure2-bugfix-for-ufcs-name-lookup.cpp2"
69+
[[nodiscard]] auto v::g(auto const& i) -> auto { return CPP2_UFCS(f)(i); }
70+
6671
#line 20 "pure2-bugfix-for-ufcs-name-lookup.cpp2"
6772
auto main() -> int{
6873
{

regression-tests/test-results/pure2-type-and-namespace-aliases.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ class myclass;
2121
template<typename T> class myclass2;
2222

2323

24+
#line 39 "pure2-type-and-namespace-aliases.cpp2"
25+
class myclass3;
26+
27+
28+
#line 53 "pure2-type-and-namespace-aliases.cpp2"
29+
class myclass4;
30+
31+
template<typename T> class myclass6;
32+
33+
2434
//=== Cpp2 type definitions and function declarations ===========================
2535

2636
#line 1 "pure2-type-and-namespace-aliases.cpp2"
@@ -60,6 +70,31 @@ template<typename T> class myclass2 {
6070

6171
auto main() -> int;
6272

73+
#line 37 "pure2-type-and-namespace-aliases.cpp2"
74+
using myclass5 = myclass4;
75+
76+
class myclass3 {
77+
// Defined inline.
78+
public: static constexpr auto i0 = std::array{0};
79+
public: static constexpr auto i1 = i0;
80+
public: static constexpr auto i3 = i0;
81+
public: static constexpr auto i7 = []() mutable -> auto { return 0; };
82+
83+
// Defined out of line.
84+
public: static const myclass3 o2;
85+
public: static const myclass3 o4;
86+
public: static const myclass4 o5;
87+
public: static const myclass5 o6;
88+
};
89+
90+
class myclass4 {};
91+
92+
template<typename T> class myclass6 {
93+
#line 56 "pure2-type-and-namespace-aliases.cpp2"
94+
public: template<typename U>
95+
CPP2_REQUIRES_ (true) static constexpr auto v = 0;
96+
};
97+
6398
//=== Cpp2 function definitions =================================================
6499

65100
#line 1 "pure2-type-and-namespace-aliases.cpp2"
@@ -94,3 +129,9 @@ auto main() -> int{
94129
myfunc2();
95130
}
96131

132+
#line 47 "pure2-type-and-namespace-aliases.cpp2"
133+
inline CPP2_CONSTEXPR myclass3 myclass3::o2 = myclass3();
134+
inline CPP2_CONSTEXPR myclass3 myclass3::o4 = o2;
135+
inline CPP2_CONSTEXPR myclass4 myclass3::o5 = myclass4();
136+
inline CPP2_CONSTEXPR myclass5 myclass3::o6 = myclass5();
137+

source/to_cpp1.h

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4639,7 +4639,7 @@ class cppfront
46394639
);
46404640
}
46414641
else {
4642-
emit(*n.parameters, false, false, generating_postfix_inc_dec);
4642+
emit(*n.parameters, false, false, generating_postfix_inc_dec);
46434643
}
46444644

46454645
// For an anonymous function, the emitted lambda is 'constexpr' or 'mutable'
@@ -5378,8 +5378,18 @@ class cppfront
53785378
auto& a = std::get<declaration_node::an_alias>(n.type);
53795379
assert(a);
53805380

5381+
// Helper for aliases that emit as a defining declaration.
5382+
auto const type_scope_object_alias_emits_in_phase_1_only = [&]() {
5383+
assert(
5384+
n.parent_is_type()
5385+
&& n.is_object_alias()
5386+
);
5387+
return !a->type_id
5388+
|| a->type_id->is_wildcard();
5389+
};
5390+
53815391
// Namespace-scope aliases are emitted in phase 1,
5382-
// type-scope object aliases in both phases 1 and 2, and
5392+
// type-scope object aliases is emitted in phase 1 and maybe 2, and
53835393
// function-scope aliases in phase 2
53845394
if (
53855395
(
@@ -5391,6 +5401,7 @@ class cppfront
53915401
n.parent_is_type()
53925402
&& n.is_object_alias()
53935403
&& printer.get_phase() == printer.phase2_func_defs
5404+
&& !type_scope_object_alias_emits_in_phase_1_only()
53945405
)
53955406
||
53965407
(
@@ -5465,21 +5476,34 @@ class cppfront
54655476
// Handle object aliases:
54665477
// - at function scope, it's const&
54675478
// - at namespace scope, it's inline constexpr
5468-
// - at type scope, it's also inline constexpr but see note (*) below
5479+
// - at type scope, it's also static constexpr but see note (*) below
54695480
else if (a->is_object_alias())
54705481
{
54715482
auto type = std::string{"auto"};
54725483
if (a->type_id) {
54735484
type = print_to_string(*a->type_id);
54745485
}
54755486

5476-
// (*) If this is at type scope, Cpp1 requires an out-of-line declaration dance
5477-
// for some cases to work - see https://stackoverflow.com/questions/11928089/
54785487
if (n.parent_is_type())
54795488
{
54805489
assert (n.parent_declaration->name());
54815490

5482-
if (printer.get_phase() == printer.phase1_type_defs_func_decls) {
5491+
if (type_scope_object_alias_emits_in_phase_1_only()) {
5492+
if (printer.get_phase() == printer.phase1_type_defs_func_decls) {
5493+
printer.print_cpp2(
5494+
"static constexpr "
5495+
+ type + " "
5496+
+ print_to_string(*n.identifier)
5497+
+ " = "
5498+
+ print_to_string( *std::get<alias_node::an_object>(a->initializer) )
5499+
+ ";\n",
5500+
n.position()
5501+
);
5502+
}
5503+
}
5504+
// At type scope, Cpp1 requires an out-of-line declaration dance
5505+
// for some cases to work - see https://stackoverflow.com/questions/11928089/
5506+
else if (printer.get_phase() == printer.phase1_type_defs_func_decls) {
54835507
printer.print_cpp2(
54845508
"static const "
54855509
+ type + " "
@@ -5663,7 +5687,10 @@ class cppfront
56635687

56645688
// In class definitions, emit the explicit access specifier if there
56655689
// is one, or default to private for data and public for functions
5666-
if (printer.get_phase() == printer.phase1_type_defs_func_decls)
5690+
if (
5691+
printer.get_phase() == printer.phase1_type_defs_func_decls
5692+
&& n.identifier
5693+
)
56675694
{
56685695
if (!n.is_default_access()) {
56695696
assert (is_in_type);

0 commit comments

Comments
 (0)