Skip to content

[basic.scope.scope] Fix a note about declarations that do not bind names #7238

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 30, 2024

Conversation

Endilll
Copy link
Contributor

@Endilll Endilll commented Aug 23, 2024

The note is saying that declarations of qualified names do not bind names, but this is not supported by normative wording in [dcl.meaning]. @opensdh suggested that this is a leftover from P1787R4 (R6 is what was voted in).

This was discussed in Mattermost (https://chat.isocpp.org/general/pl/1rjh7gn95ifg9kx11kgibcg1fw) and on the Core reflector (https://lists.isocpp.org/core/2024/08/16249.php).

CC @jensmaurer

The note is saying that declarations of qualified names do not bind names, but this is not supported by normative wording in [dcl.meaning]
Copy link
Member

@jensmaurer jensmaurer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks ok to me.

@opensdh , could you have a look, please?

@opensdh
Copy link
Contributor

opensdh commented Aug 30, 2024

There is still implementation divergence here, but I agree that the change in the note reflects the current normative wording.

@tkoeppe tkoeppe merged commit e010cf6 into cplusplus:main Aug 30, 2024
2 checks passed
@Endilll Endilll deleted the qualified-id-name-binding branch August 30, 2024 20:04
Endilll added a commit to llvm/llvm-project that referenced this pull request Sep 2, 2024
…106117)

This patch covers CWG issues regarding declaration matching when
`friend` declarations are involved:
[CWG138](https://cplusplus.github.io/CWG/issues/138.html),
[CWG386](https://cplusplus.github.io/CWG/issues/386.html),
[CWG1477](https://cplusplus.github.io/CWG/issues/1477.html), and
[CWG1900](https://cplusplus.github.io/CWG/issues/1900.html). Atypical
for our CWG tests, the ones in this patch are quite extensively
commented in-line, explaining the mechanics. PR description focuses on
high-level concerns and references.

[CWG138](https://cplusplus.github.io/CWG/issues/138.html) "Friend
declaration name lookup"
-----------

[P1787R6](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html):
> [CWG138](https://cplusplus.github.io/CWG/issues/138.html) is resolved
according to [N1229](http://wg21.link/n1229), except that
using-directives that nominate nested namespaces are considered.

I find it hard to pin down the scope of this issue, so I'm relying on
three examples from the filing to define it. Because of that, it's also
hard to pinpoint exact wording changes that resolve it. Relevant
references are:
[[dcl.meaning.general]/2](http://eel.is/c++draft/dcl.meaning#general-2),
[[namespace.udecl]/10](https://eel.is/c++draft/namespace.udecl#10),
[[dcl.type.elab]/3](https://eel.is/c++draft/dcl.type.elab#3),
[[basic.lookup.elab]/1](https://eel.is/c++draft/basic.lookup.elab#1).

[CWG386](https://cplusplus.github.io/CWG/issues/386.html) "Friend
declaration of name brought in by _using-declaration_"
-----------

[P1787R6](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html):
> [CWG386](https://cplusplus.github.io/CWG/issues/386.html),
[CWG1839](https://cplusplus.github.io/CWG/issues/1839.html),
[CWG1818](https://cplusplus.github.io/CWG/issues/1818.html),
[CWG2058](https://cplusplus.github.io/CWG/issues/2058.html),
[CWG1900](https://cplusplus.github.io/CWG/issues/1900.html), and
Richard’s observation in [“are non-type names ignored in a
class-head-name or
enum-head-name?”](http://lists.isocpp.org/core/2017/01/1604.php) are
resolved by describing the limited lookup that occurs for a
declarator-id, including the changes in Richard’s [proposed resolution
for
CWG1839](http://wiki.edg.com/pub/Wg21cologne2019/CoreWorkingGroup/cwg1839.html)
(which also resolves CWG1818 and what of CWG2058 was not resolved along
with CWG2059) and rejecting the example from
[CWG1477](https://cplusplus.github.io/CWG/issues/1477.html).

Wording
([[dcl.meaning.general]/2](http://eel.is/c++draft/dcl.meaning#general-2)):
> — If the
[id-expression](http://eel.is/c++draft/expr.prim.id.general#nt:id-expression)
E in the
[declarator-id](http://eel.is/c++draft/dcl.decl.general#nt:declarator-id)
of the
[declarator](http://eel.is/c++draft/dcl.decl.general#nt:declarator) is a
[qualified-id](http://eel.is/c++draft/expr.prim.id.qual#nt:qualified-id)
or a [template-id](http://eel.is/c++draft/temp.names#nt:template-id):
>      — [...]
>      — The
[declarator](http://eel.is/c++draft/dcl.decl.general#nt:declarator)
shall correspond to one or more declarations found by the lookup; they
shall all have the same target scope, and the target scope of the
[declarator](http://eel.is/c++draft/dcl.decl.general#nt:declarator) is
that
scope[.](http://eel.is/c++draft/dcl.meaning#general-2.2.2.sentence-1)

This issue focuses on interaction of `friend` declarations with
template-id and qualified-id with using-declarations. The short answer
is that terminal name in such declarations undergo lookup, and
using-declarations do what they usually do helping that lookup. Target
scope of such friend declaration is the target scope of lookup result,
so no conflicts arise with the using-declarations.

[CWG1477](https://cplusplus.github.io/CWG/issues/1477.html) "Definition
of a `friend` outside its namespace"
-----------

[P1787R6](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html):
> [...] and rejecting the example from
[CWG1477](https://cplusplus.github.io/CWG/issues/1477.html).

Wording
([[dcl.meaning.general]/3.4](http://eel.is/c++draft/dcl.meaning#general-3.4)):
> Otherwise, the terminal name of the
[declarator-id](http://eel.is/c++draft/dcl.decl.general#nt:declarator-id)
is not looked
up[.](http://eel.is/c++draft/dcl.meaning#general-3.4.sentence-1)
If it is a qualified name, the
[declarator](http://eel.is/c++draft/dcl.decl.general#nt:declarator)
shall correspond to one or more declarations nominable in S; all the
declarations shall have the same target scope and the target scope of
the [declarator](http://eel.is/c++draft/dcl.decl.general#nt:declarator)
is that
scope[.](http://eel.is/c++draft/dcl.meaning#general-3.4.sentence-2)

This issue focuses on befriending a function in one scope, then defining
it from other scope using qualified-id. Contrary to what P1787R6 says in
prose, this example is accepted by the wording in that paper. In the
wording quote above, note the absence of a statement like "terminal name
of the declarator-id is not bound", contrary to similar statements made
before that in [dcl.meaning.general] about friend declarations and
template-ids.

There's also a note in [basic.scope.scope] that supports the rejection,
but it's considered incorrect and expected to be removed in the future.
This is tracked in cplusplus/draft#7238.

[CWG1900](https://cplusplus.github.io/CWG/issues/1900.html) "Do `friend`
declarations count as “previous declarations”?"
------------------


[P1787R6](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html):
> [CWG386](https://cplusplus.github.io/CWG/issues/386.html),
[CWG1839](https://cplusplus.github.io/CWG/issues/1839.html),
[CWG1818](https://cplusplus.github.io/CWG/issues/1818.html),
[CWG2058](https://cplusplus.github.io/CWG/issues/2058.html),
[CWG1900](https://cplusplus.github.io/CWG/issues/1900.html), and
Richard’s observation in [“are non-type names ignored in a
class-head-name or
enum-head-name?”](http://lists.isocpp.org/core/2017/01/1604.php) are
resolved by describing the limited lookup that occurs for a
declarator-id, including the changes in Richard’s [proposed resolution
for
CWG1839](http://wiki.edg.com/pub/Wg21cologne2019/CoreWorkingGroup/cwg1839.html)
(which also resolves CWG1818 and what of CWG2058 was not resolved along
with CWG2059) and rejecting the example from
[CWG1477](https://cplusplus.github.io/CWG/issues/1477.html).

Wording
([[dcl.meaning.general]/2.3](http://eel.is/c++draft/dcl.meaning#general-2.3)):
> The declaration's target scope is the innermost enclosing namespace
scope; if the declaration is contained by a block scope, the declaration
shall correspond to a reachable
([[module.reach]](http://eel.is/c++draft/module.reach)) declaration that
inhabits the innermost block
scope[.](http://eel.is/c++draft/dcl.meaning#general-2.3.sentence-2)

Wording
([[basic.scope.scope]/7](http://eel.is/c++draft/basic.scope#scope-7)):
> A declaration is
[nominable](http://eel.is/c++draft/basic.scope#def:nominable) in a
class, class template, or namespace E at a point P if it precedes P, it
does not inhabit a block scope, and its target scope is the scope
associated with E or, if E is a namespace, any element of the inline
namespace set of E
([[namespace.def]](http://eel.is/c++draft/namespace.def))[.](http://eel.is/c++draft/basic.scope#scope-7.sentence-1)

Wording
([[dcl.meaning.general]/3.4](http://eel.is/c++draft/dcl.meaning#general-3.4)):
> If it is a qualified name, the
[declarator](http://eel.is/c++draft/dcl.decl.general#nt:declarator)
shall correspond to one or more declarations nominable in S; [...]

In the new wording it's clear that while `friend` declarations of
functions do not bind names, declaration is still introduced, and is
nominable, making it eligible for a later definition by qualified-id.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants