Thanks for raising this issue, Jakub. I'm going to circle back with my coauthors regarding rationale for extending consteval-only-ness to pointers and references.
If such types weren't consteval-only, do you think that would be sufficient to solve the issue? Any concerns that come to mind with that approach (e.g., ways that it would allow meta::info to leak to anytime)? On Mon, Jan 19, 2026, 4:48 AM Jakub Jelinek <[email protected]> wrote: > On Sat, Jan 17, 2026 at 02:09:57PM +0100, Jakub Jelinek wrote: > > And another testcase I have no idea what actually should happen is > > struct Q; > > constexpr Q *q = nullptr; > > struct Q { decltype (^^int) x = ^^int; }; > > I think Q * is not a consteval-only type when parsing the q declaration, > > but when the Q class is defined, it is consteval-only and so is Q *. > > So, shall we somehow later on arrange for q not to be emitted (or error > > if say something non-consteval made it odr-used? Though, if what is > > consteval-only can change at any point, that is kind of complicated. > > Actually, that means we can't cache consteval-only on types at all. > struct A; > struct B { A *p; constexpr B (A *x) : p (x) {} }; > template <typename T> > void use (T &) {} > constexpr B c1 = nullptr; > use (c1); // Is this an error or not? c1 at its definition doesn't have > // consteval-only type, but at the end of TU it does > template <typename T, int N> > constexpr T *foo (T *x) { return x; } > constexpr B *c2 = foo <B, 42> (nullptr); > // Is foo <B, 42> immediate-only or not? > struct A { decltype (^^::) a = ^^::; }; > constexpr B c3 = nullptr; > constexpr B *c4 = foo <B, 43> (nullptr); > // foo <B, 43> should be immediate-only. > Whether a type is consteval-only can change at any time during the parsing, > but then I'm wondering whether the standard shouldn't talk about > consteval-only types at point P or something similar most of the time. > > Jakub > >
