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] Lookup of emitted definition differs from what's apparent in source code #704
This is relevant to type-scope object alias
emitted during Phase 2 "Cpp2 type definitions and function declarations"
(all of them if #700 isn't fixed).
Lookup for the variable's type doesn't include the declaring class
because t:: hasn't been parsed.
Worse, there is a mismatch if lookup finds something else.
Of course, a: t::u == u(); would work,
but you wouldn't guess it just looking at Cpp2.
This is the same issue (or sufficiently similar) as pointed out by commit ca42e2c.
Note: It's a known limitation that these won't yet work right on templated types. I will likely add that sometime in the future, and will require doing the dance Cpp1 requires to emit friend template specializations, and to handle dependent types more fully in cpp2::in<> for cases like cpp2::in<mytype<T>>.
There seems to be a simpler solution accepted by the supported compilers.
From the generated code of the reproducer,
replacing inline CPP2_CONSTEXPR u t::a = u();
with inline CPP2_CONSTEXPR decltype(t::a) t::a = u(); works: https://compiler-explorer.com/z/a14P79Yar.
Anyways, the same issue pops up again when you use a name in myclass before the lowered myclass:: qualifier (https://cpp2.godbolt.org/z/z3WM6ovsb):
// u: @struct type = { }
v: @struct <T> type = { }
t: @struct type = {
u: @struct type = { }
a: <_: v<u>> int == 0;
}
main: () = { }
//=== Cpp2 type definitions and function declarations ===========================public:template<v<u> _> staticconstint a;
//=== Cpp2 function definitions =================================================template<v<u> _> inlineCPP2_CONSTEXPRint t::a = 0;
main.cpp2:5:14: error: use of undeclared identifier 'u'
5 | template<v<u> _> inline CPP2_CONSTEXPR int t::a = 0;
| ^
main.cpp2:5:17: error: template non-type parameter has a different type 'int' in template redeclaration
5 | template<v<u> _> inline CPP2_CONSTEXPR int t::a = 0;
| ^
main.cpp2:5:25: note: previous non-type template parameter with type 'v<u>' is here
5 | public: template<v<u> _> static const int a;
| ^
2 errors generated.
// u: @struct type = { }
v: @struct <T> type = { }
t: @struct type = {
u: @struct type = { }
f: <_: v<u>> () = { }
}
main: () = { }
main.cpp2:5:14: error: use of undeclared identifier 'u'
5 | template<v<u> _> auto t::f() -> void{}
| ^
main.cpp2:5:28: error: out-of-line definition of 'f' does not match any declaration in 't'
5 | template<v<u> _> auto t::f() -> void{}
| ^
2 errors generated.
changed the title [-][BUG] Type-scope object alias of nested type needs explicit qualification[/-][+][BUG] Lookup of emitted definition differs from what's apparent in source code[/+]on Jan 9, 2024
Now we have a local name lookup algorithm.
We can identify when we're lowering a name local to a type
during Phase 2 "Cpp2 type definitions and function declarations"
and before the my_class:: in the declaration's name
to appropriately qualify the name.
Taking the example above,
when lowering template<v<u> _> auto t::f() -> void{},
when lowering the v and u, we're still before t::,
so those are looked up in t.
Only u has a match, so that gets t:: prepended.
Activity
JohelEGP commentedon Sep 27, 2023
This is the same issue (or sufficiently similar) as pointed out by commit ca42e2c.
Well, that wasn't it.
I don't know the "dance".
Previously.
IIUC, it's so that both of these parameters are emitted equally (https://cpp2.godbolt.org/z/enPGfjx7a):
It currently emits:
But should be
Because
tis the injected-class-name.JohelEGP commentedon Sep 27, 2023
It's like templated
@enums not working (https://cpp2.godbolt.org/z/vPGj1sKvn):JohelEGP commentedon Sep 29, 2023
There seems to be a simpler solution accepted by the supported compilers.
From the generated code of the reproducer,
replacing
inline CPP2_CONSTEXPR u t::a = u();with
inline CPP2_CONSTEXPR decltype(t::a) t::a = u();works:https://compiler-explorer.com/z/a14P79Yar.
JohelEGP commentedon Sep 29, 2023
Anyways, the same issue pops up again when you use a name in
myclassbefore the loweredmyclass::qualifier (https://cpp2.godbolt.org/z/z3WM6ovsb):JohelEGP commentedon Jan 9, 2024
Using a function (https://cpp2.godbolt.org/z/3hbPMT5ar):
[-][BUG] Type-scope object alias of nested type needs explicit qualification[/-][+][BUG] Lookup of emitted definition differs from what's apparent in source code[/+]JohelEGP commentedon Sep 30, 2024
Now we have a local name lookup algorithm.
We can identify when we're lowering a name local to a type
during Phase 2 "Cpp2 type definitions and function declarations"
and before the
my_class::in the declaration's nameto appropriately qualify the name.
Taking the example above,
when lowering
template<v<u> _> auto t::f() -> void{},when lowering the
vandu, we're still beforet::,so those are looked up in
t.Only
uhas a match, so that getst::prepended.