title: Forward declaration to break cyclic dependency in C++20 modules doesn't work
body: <p>I've been banging my head on this problem for days, I read a lot of documentation and posts about new C++20 modules among which <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1103r3.pdf" rel="noreferrer">this official one</a>, <a href="https://vector-of-bool.github.io/2019/03/10/modules-1.html" rel="noreferrer">this one</a> and <a href="https://stackoverflow.com/questions/51362591/forward-declarations-in-c-modules-msvc">this other one on Stackoverflow</a>, but I really cannot solve this problem.</p>
  <p>I'm using MSVC compiler delivered with <em>Visual Studio Preview 16.6.0 2.0</em>. I know it is not a stable release yet, but I'd like to mess around with new features to start learning them.</p>
  <p>Basically I wrote a module (<code>myModule</code>) and 2 partitions of this module (<code>mySubmodule1</code> and <code>mySubmodule2</code>) and I implemented them in two module implementation files (<code>mySubmodule1Impl.cpp</code> and <code>mySubmodule2Impl.cpp</code>).</p>
  <p><code>mySubmodule1</code> have a dependency on <code>mySubmodule2</code>, and vice-versa. Here is the source:</p>
  <p><strong>mySubmodule1.ixx</strong></p>
  <pre><code>export module myModule:mySubmodule1;
  
  export namespace myNamespace{
  
  class MyClass2;
  
  class MyClass1{
      public:
      int foo(MyClass2&amp; c);
      int x = 9;
  };
  }
  </code></pre>
  <p><strong>mySubmodule2.ixx</strong></p>
  <pre><code>export module myModule:mySubmodule2;
  import :mySubmodule1;
  
  export namespace myNamespace{
  
  class MyClass2 {
      public:
      MyClass2(MyClass1 x);
      int x = 14;
      MyClass1 c;
  };
  }
  </code></pre>
  <p><strong>mySubmodule1Impl.cpp</strong></p>
  <pre><code>module myModule:mySubmodule1;
  import :mySubmodule2;
  
  int myNamespace::MyClass1::foo(myNamespace::MyClass2&amp; c) {
      this-&gt;x = c.x-14;
      return x;
  }
  </code></pre>
  <p><strong>mySubmodule2Impl.cpp</strong></p>
  <pre><code>module myModule:mySubmodule2;
  import :mySubmodule1;
  
  myNamespace::MyClass2::MyClass2(myNamespace::MyClass1 c) {
      this-&gt;x = c.x + 419;
  }
  </code></pre>
  <p><strong>myModule.ixx</strong></p>
  <pre><code>export module myModule;
  
  export import :mySubmodule1;
  export import :mySubmodule2;
  </code></pre>
  <p>As you can see I can forward declare <code>MyClass2</code> in <code>mySubmodule1</code>, but I cannot forward declare <code>MyClass1</code> in <code>mySubmodule2</code>, because in <code>MyClass2</code> I use a concrete object of type <code>MyClass1</code>.</p>
  <p>I compile with this line: <code>cl /EHsc /experimental:module /std:c++latest mySubmodule1.ixx mySubmodule2.ixx myModule.ixx mySubmodule1Impl.cpp mySubmodule2Impl.cpp Source.cpp</code> where <code>Source.cpp</code> is just the main.</p>
  <p>I get the infamous <strong>error C2027: use of undefined type 'myNamespace::MyClass2'</strong> in <code>mySubmodule1Impl.cpp</code> and <code>mySubmodule2Impl.cpp</code> at the lines where I use <code>MyClass2</code>. Moreover the compiler tells me to look at the declaration of <code>MyClass2</code> in <code>mySubmodule1.ixx</code> where there is the forward declaration.</p>
  <p>Now, I really do not understand where is my mistake. I checked over and over but the logic of the program seems perfect to me. The order of compilation of the files should define <code>MyClass2</code> before it is even used in the implementation!</p>
  <p>I tried to compile this exact program using the &quot;old&quot; .h and .cpp files instead of modules, and it compiles and run fine. So I guess I'm missing something regarding these new modules.</p>
  <p>I checked on the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1103r0.pdf" rel="noreferrer">first official proposal of modules (paragraph 10.7.5)</a>, and in the first one there was a construct named <em>proclaimed ownership declaration</em> which seemed to be perfect in such cases. Basically it allows you to import an entity owned by another module in the current module, but without importing the module itself. But in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1103r1.pdf" rel="noreferrer">later revisions of the proposal</a> there is no sign of it. Abslolutely nothing. And in the &quot;changelog&quot; section of the new proposal it isn't even cited.</p>
  <p>Please don't tell me cyclic dependencies are bad. I know often they are bad, but not always. And even if you think they are always bad I'm not asking for a rule of the thumb. I'm asking why my code compiles with &quot;old&quot; .h + .cpp but not with new modules. Why the linker doesn't see the definition of <code>MyClass2</code>.</p>
  <hr />
  <h1>EDIT 1</h1>
  <p>Here is the new design suggested in the answer, but it still doesn't work. I get the exact same errors:</p>
  <p><strong>mySubmodule1Impl.cpp</strong></p>
  <pre><code>module myModule;
  
  int myNamespace::MyClass1::foo(myNamespace::MyClass2&amp; c) {
      this-&gt;x = c.x-14;
      return x;
  }
  </code></pre>
  <p><strong>mySubmodule2Impl.cpp</strong></p>
  <pre><code>module myModule;
  
  myNamespace::MyClass2::MyClass2(myNamespace::MyClass1 c) {
      this-&gt;x = c.x + 419;
  }
  </code></pre>
  <p>All of the other files are unchanged.</p>