On Mon, Mar 02, 2026 at 06:42:32PM -0500, Jason Merrill wrote:
> On 2/28/26 6:54 PM, Nathaniel Shead wrote:
> > Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?
> >
> > I'm slightly concerned about ordering based on DECL_UID for imported
> > namespace-scope names as that will depend on when lazy loading occurs
> > for the entity in question, which will not generally be predictable at
> > all. Maybe we should check for DECL_MODULE_ENTITY_P, and always order
> > them at the end based on their index in entity_ary or something? Not
> > sure if that is actually much better though.
> >
> > But it should still be at least deterministic as far as I'm aware, so I
> > think this could be improved upon incrementally.
> >
> > One question I had is how we should determine the visibility of names
> > for members_of; does this get affected by instantiation context, e.g.
> > for
> > export module M;
> > import std;
> > constexpr auto ctx = std::meta::access_context::unchecked();
> >
> > export template <std::meta::info scope>
> > consteval std::size_t num_members() {
> > constexpr auto result = num_members(scope, ctx).size(); // #1
(Assuming this was meant to be members_of.)
> > return result;
> > }
> >
> > namespace ns {
> > void foo() {}
> > export void bar() {}
> > }
> >
> > does doing 'num_members<^^ns>()' from an unrelated importing module
> > return '1' or '2' (that is, does it include 'foo')? This patch
> > implements so that it always returns 1, evaluation is done from the
> > lookup context of the current module, but I wonder if evaluation here
> > should be done from the context of the constant expression at #1.
>
> https://eel.is/c++draft/meta#reflection.member.queries-4.1 says we want to
> include things that 'precede' the evaluation context, which I initially
> assumed was something accumulative like instantiation context.
>
> But since https://github.com/cplusplus/CWG/issues/848 the evaluation context
> is limited to specifically where the core constant expression appears.
>
> I think this must assume that "core constant expression" refers to the
> outermost evaluation, and not an sub-evaluation. But even then the
> outermost evaluation here is the full initializer of 'result', suggesting
> that the evaluation context is #1.
>
> But surely this needs to take the instantiation context into account, or
> templates like this would become useless since they couldn't reflect on user
> code defined later.
>
> Marek, has this been discussed at all?
Interesting, thanks. Dan pointed me to
https://cplusplus.github.io/LWG/issue4496
so we should be saying "reachable" rather than "precedes" which is about
name lookup.
The evaluation context is supposed to be the innermost core constant
evaluation. ns::foo is reachable from the importing module so we should
find ns::foo and return 2.
If it were
namespace ns {
static void foo() {}
export void bar() {}
}
then the result should be 1 because ns::foo is TU-local.
Marek