[cfe-dev] RFC: A mechanism for importing a declaration only when it exists

Arthur O'Dwyer via cfe-dev cfe-dev at lists.llvm.org
Fri Jun 26 14:58:07 PDT 2020


On Fri, Jun 26, 2020 at 5:16 PM Richard Smith via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> On Fri, 26 Jun 2020 at 12:53, Louis Dionne via cfe-dev <
> cfe-dev at lists.llvm.org> wrote:
>
>>
>> I think the better semantics would be to have no effect if no names are
>> found, since that's what's closest in effect to having an #ifdef in front
>> that removes it.
>>
>
> That semantic model may be a better fit for your use case, but it's not
> really a great fit for C++ more broadly. Consider a case such as:
>
> template<typename T> int f() {
>   [[clang::its_ok_if_this_doesnt_exist]] using T::x;
>   return x;
> }
>
> During the phase 1 name lookup for 'x' in the return-statement, we find
> the local (but dependent) using-declaration and bind to that. During
> template instantiation, it would be challenging to pretend that that 'x'
> doesn't exist and fall back on an enclosing name 'x'. The semantic model
> that fits better for this case would be to say that name lookup stops at
> the using-declaration (and doesn't consider enclosing scopes), but then the
> result is an error because the name 'x' didn't resolve to anything.
>

IIUC, you're saying that two-phase lookup inside a C++ template requires
that the compiler always be certain *what* names are introduced *where*.
Therefore, a declaration that (dependently) "might or might not" introduce
a name is incompatible with the first phase of two-phase lookup. Did I get
that roughly correct?

If so, I still think it would be simpler to patch `__using_if_exists N::x;`
so that it would simply fail to compile at all if the name `N::x` was
dependent.

AFAICT, `using T::x;` (with dependent T) is only ever well-formed inside a
class body, which is not Louis's use-case.
https://godbolt.org/z/JvdCmd
It would be quite reasonable for Clang to reject `__using_if_exists` in
this context (but still permit it at file or namespace scope).

AFAICT, `using T::x;` can never be dependent at function scope, either,
https://godbolt.org/z/gSvR_n
so you could permit it even at function scope... although I see no reason
to. Louis wants it only at namespace scope, where AFAICT this whole
two-phase-lookup thing poses no problem at all.

If we're going to add an extension for this, I'd prefer that it's something
> that can be applied soundly in general, rather than introducing another
> situation like the one for `__if_exists` where we support it only partially
> and only in certain contexts.
>

`using`-declarations at class scope already behave radically differently
<https://godbolt.org/z/bp8tgW> from `using`-declarations in any other kind
of scope.  So I don't see anything inconsistent or unsound about saying
"This __using_if_exists thing is able to stand in only for a *non-member*
using-declaration."  (I don't know what the Standardese for that is, but
there must be some, given how radically "member using-declarations" differ
semantically from "non-member using-declarations.")

–Arthur
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20200626/0d5b9b58/attachment.html>


More information about the cfe-dev mailing list