Skip to content

Conversation

nico
Copy link
Contributor

@nico nico commented Jun 7, 2024

For using std::literals, we now output:

error: using declaration cannot refer to a namespace
    4 |   using std::literals;
      |         ~~~~~^
note: did you mean 'using namespace'?
    4 |   using std::literals;
      |         ^
      |         namespace

Previously, we didn't have the note.

This only fires for qualified namespaces. Just using std; doesn't trigger this, since using declarations without cxx scope specifier are rejected earlier. Making that work is an exercise for future selves :)

For `using std::literals`, we now output:

    error: using declaration cannot refer to a namespace
        4 |   using std::literals;
          |         ~~~~~^
    note: did you mean 'using namespace'?
        4 |   using std::literals;
          |         ^
          |         namespace

Previously, we didn't have the note.

This only fires for qualified namespaces. Just `using std;` doesn't
trigger this, since using declarations without cxx scope specifier are
rejected earlier. Making that work is an exercise for future selves :)
@nico nico requested a review from Endilll as a code owner June 7, 2024 15:21
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jun 7, 2024
@llvmbot
Copy link
Member

llvmbot commented Jun 7, 2024

@llvm/pr-subscribers-clang

Author: Nico Weber (nico)

Changes

For using std::literals, we now output:

error: using declaration cannot refer to a namespace
    4 |   using std::literals;
      |         ~~~~~^
note: did you mean 'using namespace'?
    4 |   using std::literals;
      |         ^
      |         namespace

Previously, we didn't have the note.

This only fires for qualified namespaces. Just using std; doesn't trigger this, since using declarations without cxx scope specifier are rejected earlier. Making that work is an exercise for future selves :)


Full diff: https://github.com/llvm/llvm-project/pull/94762.diff

4 Files Affected:

  • (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+2)
  • (modified) clang/lib/Sema/SemaDeclCXX.cpp (+3)
  • (modified) clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx11.cpp (+3)
  • (modified) clang/test/CXX/drs/cwg4xx.cpp (+2)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9f0b6f5a36389..13a73b39135b4 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -607,6 +607,8 @@ def note_using_decl_class_member_workaround : Note<
   "a const variable|a constexpr variable}0 instead">;
 def err_using_decl_can_not_refer_to_namespace : Error<
   "using declaration cannot refer to a namespace">;
+def note_namespace_using_decl : Note<
+  "did you mean 'using namespace'?">;
 def warn_cxx17_compat_using_decl_scoped_enumerator: Warning<
   "using declaration naming a scoped enumerator is incompatible with "
   "C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 3c28da1b077cd..b5ffa75f04ffa 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -13080,6 +13080,9 @@ NamedDecl *Sema::BuildUsingDeclaration(
   if (R.getAsSingle<NamespaceDecl>()) {
     Diag(IdentLoc, diag::err_using_decl_can_not_refer_to_namespace)
       << SS.getRange();
+    // Suggest using 'using namespace ...' instead.
+    Diag(SS.getBeginLoc(), diag::note_namespace_using_decl)
+      << FixItHint::CreateInsertion(SS.getBeginLoc(), "namespace ");
     return BuildInvalid();
   }
 
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx11.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx11.cpp
index 97b2953b90312..473290dd1c191 100644
--- a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx11.cpp
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx11.cpp
@@ -1,7 +1,10 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
 
 namespace A {
   namespace B { }
 }
 
+// CHECK: fix-it:"{{.*}}":{[[@LINE+1]]:7-[[@LINE+1]]:7}:"namespace "
 using A::B; // expected-error{{using declaration cannot refer to a namespace}}
+            // expected-note@-1 {{did you mean 'using namespace'?}}
diff --git a/clang/test/CXX/drs/cwg4xx.cpp b/clang/test/CXX/drs/cwg4xx.cpp
index 07162cc28f6b6..40ad5fb9b7900 100644
--- a/clang/test/CXX/drs/cwg4xx.cpp
+++ b/clang/test/CXX/drs/cwg4xx.cpp
@@ -941,8 +941,10 @@ namespace cwg460 { // cwg460: yes
     // expected-error@-1 {{using declaration requires a qualified name}}
     using cwg460::X;
     // expected-error@-1 {{using declaration cannot refer to a namespace}}
+    // expected-note@-2 {{did you mean 'using namespace'?}}
     using X::Q;
     // expected-error@-1 {{using declaration cannot refer to a namespace}}
+    // expected-note@-2 {{did you mean 'using namespace'?}}
   }
 }
 

Copy link

github-actions bot commented Jun 7, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Collaborator

@zmodem zmodem left a comment

Choose a reason for hiding this comment

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

lgtm

@@ -13080,6 +13080,9 @@ NamedDecl *Sema::BuildUsingDeclaration(
if (R.getAsSingle<NamespaceDecl>()) {
Diag(IdentLoc, diag::err_using_decl_can_not_refer_to_namespace)
<< SS.getRange();
// Suggest using 'using namespace ...' instead.
Diag(SS.getBeginLoc(), diag::note_namespace_using_decl)
<< FixItHint::CreateInsertion(SS.getBeginLoc(), "namespace ");
return BuildInvalid();
Copy link
Collaborator

Choose a reason for hiding this comment

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

I suppose another exercise for our future selves could be to recover as if the user typed "using namespace"

@nico nico merged commit 2c047e6 into llvm:main Jun 7, 2024
@nico nico deleted the namespace-fixit branch June 7, 2024 18:08
@HerrCai0907 HerrCai0907 mentioned this pull request Jun 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants