<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/102349>102349</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [C++20] [Modules] Errors in exporting forward declared structs
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          davidstone
      </td>
    </tr>
</table>

<pre>
    Given the following translation units:

```c++
export module a;

export template<typename>
struct a;

template<typename>
struct a {
};

export template<typename T>
constexpr auto aa = a<T>();
```

```c++
export module b;

import a;

static void b() {
        static_cast<void>(a<void>());
}
```

```c++
export module c;

import a;

static void c() {
        static_cast<void>(aa<void>);
}
```

```c++
import a;
import b;
import c;

static void d() {
        static_cast<void>(a<void>());
}
```

clang erroneously rejects with

```console
In file included from /app/d.cpp:1:
a.cpp:7:8: error: declaration 'a<void>' attached to named module 'a' can't be attached to other modules
    7 | struct a {
 |        ^
a.cpp:7:8: note: also found
a.cpp:7:8: error: declaration 'a' attached to named module 'a' can't be attached to other modules
    7 | struct a {
      |        ^
a.cpp:7:8: note: also found
a.cpp:7:8: error: declaration 'a' attached to named module 'a' can't be attached to other modules
    7 | struct a {
      |        ^
a.cpp:7:8: note: also found
a.cpp:7:8: error: declaration 'a' attached to named module 'a' can't be attached to other modules
    7 | struct a {
      | ^
a.cpp:7:8: note: also found
a.cpp:7:8: error: declaration '~a' attached to named module 'a' can't be attached to other modules
    7 | struct a {
      |        ^
a.cpp:7:8: note: also found
5 errors generated.
```

See it live: https://godbolt.org/z/EM9dh38WP

As a workaround, users must type `export` on both the forward declaration and the definition:

```c++
export module a;

export template<typename>
struct a;

export template<typename>
struct a {
};

export template<typename T>
constexpr auto aa = a<T>();
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsVkuv2zYT_TXjzSCGTFmWtdDC177-8C0CFGiBLguKHFlsKVIgR3ZuF_3thR43sX3bIkbQBAFqCH7Mi-eQM-aRMZqTIyohe4LssJA9Nz6UWp6NjuwdLSqvX8r_mTM55Iaw9tb6i3En5CBdtJKNd9g7wxHSHSQHSF7fN8n0KBBPwzNa6UPnA2PrdW8JJaRP1zmzl6ntrGSCdM8vHTnZEqTPU0jk0Ct-k_k5KQj5a05--OyV8aePhZR3kelDF1D27FFKhPQwQNmPMWILovhU95X_o5tS3UEz7ei9ZxxZslF49kZjNa19RTApJv8vSkaGdD-ETRjlza8B8TXo_PCF6NXj6NUj6G_gfxnwN9BmQ3VvuOd0DV5_na1XVroTUgjeke-jfcFAv5LiiBfDzV9z9S56S5P1_w5rYwmNU7bXpLEOvkUQR9l1II56qboO0t3q4xDL2ZJDuttCuhvXDsMXTcrKMA0-iPyGVI6SWaqGNLLHYXz0a2OMoSJHJR2InLGim1jPDYU5Nk4QEBFzhHyPbyd4NM8vyJ7_BrPzwyjvUNrosfa90w-T-4qUJjL_8frueP2LhP74zk4qm5hEPJGjIJn08h_-1X4kQsNozXks1jB3o4wQRxDHk9eVt7z04QTi-DuI4_P7Qjfp9ucfrmvsIkq8-PCbDCMMscc-UojY9pFxuMURNsl0ScEmQe-w8tzMaiZcZNA3my6dHn2aauPMYPqmwuaBzG-kbxa6THWRFnJB5SoXaZJl23yzaEqVZDpRSqZrWhekslpsVtUqX6tNUdeqSBamFIlYJ9skX23TPNsst4WQxUanWVHVW5VXsE6olcYurT23QyMsTIw9latEpOtiYWVFNo7aVQhHFxy9IMQgZUM5JL2r-lOEdWJN5PipDBu2o-jdT2coEsgOCNnT-3lWsgM-T41sHE6bN4je24YhPQ9RXPTBlnfta7jpq6XyLYjjsPD88a4Lfri5QRxHuBHEceZzLsWfAQAA__-7rFiX">