<div dir="ltr"><div dir="ltr">On Fri, Jun 26, 2020 at 5:16 PM Richard Smith via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">On Fri, 26 Jun 2020 at 12:53, Louis Dionne via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div><div><br></div><div>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.</div></div></div></blockquote><div><br></div><div>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:</div><div><br></div><div>template<typename T> int f() {</div><div>  [[clang::its_ok_if_this_doesnt_exist]] using T::x;</div><div>  return x;</div><div>}</div><div><br></div><div>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.</div></div></div></blockquote><div><br></div><div>IIUC, you're saying that two-phase lookup inside a C++ template requires that the compiler always be certain <i><b>what</b></i> names are introduced <i><b>where</b></i>. 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?</div><div><br></div><div>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.</div><div><br></div><div>AFAICT, `using T::x;` (with dependent T) is only ever well-formed inside a class body, which is not Louis's use-case.</div><div><a href="https://godbolt.org/z/JvdCmd">https://godbolt.org/z/JvdCmd</a><br></div><div>It would be quite reasonable for Clang to reject `__using_if_exists` in this context (but still permit it at file or namespace scope).</div><div><br></div><div>AFAICT, `using T::x;` can never be dependent at function scope, either,</div><div><a href="https://godbolt.org/z/gSvR_n">https://godbolt.org/z/gSvR_n</a><br></div><div></div><div>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.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div>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.</div></div></div></blockquote><div><br></div><div>`using`-declarations at class scope <a href="https://godbolt.org/z/bp8tgW">already behave radically differently</a> 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 <i>non-member</i> 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.")</div><div><br></div><div>–Arthur</div></div></div>