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

Reply via email to