Skip to content

CWG3033 [basic.scope.namespace] Scope fragment of inline namespaces in redeclarations after the declarator-id but before determination of correspondence #698

@hubert-reinterpretcast

Description

@hubert-reinterpretcast

Full name of submitter (unless configured in github; will be published with the issue): Hubert Tong

Reference (section label): [basic.scope.namespace]

Link to reflector thread (if any): N/A

Issue description:
Consider the following:

namespace N {
inline namespace A {
constexpr int f(int *);
}
inline namespace B {
constexpr int f(long *);
}
} // namespace N

template <typename T> struct Q { using type = long; };

constexpr int N::f(Q<struct X *>::type *) { return 42; }

namespace N {
inline namespace B {
struct X {};
}
} // namespace N
template <> struct Q<N::B::X *>;  // explicit specialization after implicit instantiation
static_assert(N::B::f(0) == 42);

https://eel.is/c++draft/basic.scope.namespace#1.sentence-2 tells us that:

For each non-friend redeclaration or specialization whose target scope is or is contained by the scope, the portion after the declarator-id, class-head-name, or enum-head-name is also included in the scope.

The target scope of the declaration whose declarator-id is N::f is N::B according to https://eel.is/c++draft/dcl.meaning.general#3.4.

It is unclear how, for the purposes of https://eel.is/c++draft/dcl.type.elab#3, a compiler is supposed to know that the nearest enclosing namespace (and, thus, the target scope for struct X) is N::B at the point the specialization of Q is required.

Indeed, no implementation uses N::B as the target scope for the elaborated type specifier.
Clang reasonably uses N and the other implementations questionably use the global namespace: https://godbolt.org/z/drfo4rz9E

Suggested resolution:
Perhaps the scope that starts after the declarator-id should be the one named by the nested-name-specifier until after the declarator.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions