Skip to content

[dcl.meaning.general] Improve clarity of presentation #4611

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 22 additions & 15 deletions source/declarations.tex
Original file line number Diff line number Diff line change
Expand Up @@ -2460,6 +2460,8 @@
\indextext{declaration!type}%
A declarator contains exactly one \grammarterm{declarator-id};
it names the entity that is declared.
The terminal name of the \grammarterm{declarator-id} is not looked up
except as specified below.
If the \grammarterm{unqualified-id} occurring in a \grammarterm{declarator-id}
is a \grammarterm{template-id},
the declarator shall appear in the \grammarterm{declaration} of a
Expand All @@ -2484,8 +2486,9 @@
a \grammarterm{qualified-id} or a \grammarterm{template-id}:
\begin{itemize}
\item
The terminal name of the \grammarterm{declarator-id} is looked up.
If the friend declaration is not a template declaration,
then in the lookup for the terminal name of $E$:
then in this name lookup:
\begin{itemize}
\item
if the \grammarterm{unqualified-id} in $E$ is a \grammarterm{template-id},
Expand All @@ -2507,15 +2510,15 @@
the target scope of the \grammarterm{declarator} is that scope.
\end{itemize}
\item
Otherwise, the terminal name of $E$ is not looked up.
The declaration's target scope is the innermost enclosing namespace scope;
if the declaration is contained by a block scope,
Otherwise,
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 declaration
that inhabits the innermost block scope.
\end{itemize}

\pnum
Otherwise:
If the declaration is not a friend declaration:
Copy link
Contributor

Choose a reason for hiding this comment

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

As this is exhaustive together with the previous paragraph, I'd prefer to use one of our formulations that indicates that: perhaps

Otherwise, the declaration is not a friend declaration:

or

Otherwise (for a non-friend declaration):

\begin{itemize}
\item
If the \grammarterm{id-expression} in
Expand All @@ -2526,15 +2529,19 @@
\item
Otherwise, let $S$ be the entity associated with the scope inhabited by
the \grammarterm{declarator}.
\end{itemize}
Then:
\begin{itemize}
\item
If the \grammarterm{declarator} declares
an explicit instantiation or a partial or explicit specialization,
the \grammarterm{declarator} does not bind a name.
Comment on lines 2536 to 2538
Copy link
Contributor

Choose a reason for hiding this comment

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

This is actually redundant: such declarations do not introduce names ([temp.explicit]/5, [temp.expl.spec]/4, and [temp.spec.partial.general]/7), so [basic.scope.scope]/2.5 ignores them already. This is relevant because it is an opportunity to merge into the next sentence (once we're sure exactly what we mean it to mean).

If it declares a class member,
the terminal name of the \grammarterm{declarator-id} is not looked up;
otherwise, only those lookup results that are nominable in $S$
If such a \grammarterm{declarator} does not declare a class member,
Copy link
Member Author

Choose a reason for hiding this comment

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

@opensdh I tried to figure out why we're treating class members differently from non-class-members here and didn't succeed. Perhaps an example would help? I'm also not sure how we're supposed to handle an explicit specialization of a class member template without performing name lookup. Was the intent here instead that if the specialization or instantiation is for a non-template member of a class template specialization, no lookup is performed?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think that you're right: we do have to do the lookup for the same reason that we have to do it when encountering template<> my_namespace::my_class< since it might continue int>::sub_template<int> { or just int> {. You're probably right about the intent too, but I'm less clear on that at the moment. (My plan is to, tomorrow, look at your wording here and see if I see any problems with it of a similar sort; if not, it stands to reason that it reflects the intent better.)

the terminal name of the \grammarterm{declarator-id} is looked up,
and only those lookup results that are nominable in $S$
are considered when identifying
any function template specialization being declared\iref{temp.deduct.decl}.
any function or variable template specialization
Copy link
Member Author

Choose a reason for hiding this comment

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

@opensdh Was the different treatment of function and variable template specializations intended?

Copy link
Contributor

Choose a reason for hiding this comment

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

It was (although that doesn't guarantee that it's good to do so!). The idea is that we do ordinary lookup for the name before the < (and for an explicit specialization/instantiation without an explicit template argument list, for consistency): if we find a variable template, it must be the unique lookup result, so there isn't any reason to disqualify that one result because of nominability. I think we did talk about this in the review, but I can't find the minutes for it.

being declared\iref{temp.deduct.decl}.
\begin{example}
\begin{codeblock}
namespace N {
Expand All @@ -2554,8 +2561,7 @@
\end{example}
\item
Otherwise,
the terminal name of the \grammarterm{declarator-id} is not looked up.
If it is a qualified name,
if the terminal name of the \grammarterm{declarator-id} is a qualified name,
the \grammarterm{declarator} shall correspond to
one or more declarations nominable in $S$;
all the declarations shall have the same target scope and
Expand All @@ -2578,11 +2584,13 @@
}
\end{codeblock}
\end{example}
\item
\end{itemize}

\pnum
If the declaration inhabits a block scope $S$ and
declares a function\iref{dcl.fct} or uses the \keyword{extern} specifier,
the declaration shall not be attached to a named module\iref{module.unit};
its target scope is the innermost enclosing namespace scope,
the declaration shall not be attached to a named module\iref{module.unit}.
Its target scope is the innermost enclosing namespace scope,
but the name is bound in $S$.
\begin{example}
\begin{codeblock}
Expand All @@ -2604,7 +2612,6 @@
void X::r() { @\commentellip@ } // error: \tcode{r} cannot be declared by \grammarterm{qualified-id}
\end{codeblock}
\end{example}
\end{itemize}

\pnum
A
Expand Down