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
>
>

Reply via email to