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

    <tr>
        <th>Summary</th>
        <td>
            Internal module partitions export content
        </td>
    </tr>

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

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

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

<pre>
    I have this example code:

```cpp
module math:numbers.detail;

import std;
import math.ops;
import math.symbols;

import :numbers.naturals;
import :numbers.integers;
import :numbers.rationals;

#if defined(__clang__)
export namespace zero::math {
#elif defined(_MSC_VER)
using namespace zero::math;
#endif

template <typename L, typename R>
concept EitherRational =
    std::is_same_v<L, Rational> || std::is_same_v<R, Rational>;

// Helper to extract the inner value of a Number type or avoid the method
// call if it's a primitive (std::is_arithmetic_v).
template <typename T> constexpr auto normalize(const T &value) noexcept {
  if constexpr (std::is_arithmetic_v<T> || std::is_same_v<T, Rational>)
    return value; // Return primitive arithmetic types and Rationals as-is
  else
 return value.number();
}

// Generalized arithmetic operation helper using lambdas
template <typename L, typename R, typename Op>
constexpr auto arithmetic_op(const L &lhs, const R &rhs, Op op) noexcept {
  if constexpr (EitherRational<L, R>)
    return op(lhs, rhs);
  else
 return op(normalize(lhs), normalize(rhs));
}

// Specialized addition and subtraction for Rational types
template <typename L, typename R>
constexpr auto rational_add_or_subtract(const L &lhs, const R &rhs, int sign) noexcept {
  if constexpr (std::is_same_v<L, Rational> && std::is_same_v<R, Rational>) {
    return sum_or_subtract(lhs, rhs, sign);
  } else if constexpr (std::is_same_v<L, Rational>) {
    return sum_or_subtract(lhs, Rational(rhs), sign);
  } else if constexpr (std::is_same_v<R, Rational>) {
    return sum_or_subtract(Rational(lhs), rhs, sign);
  }
}

template <typename L, typename R>
constexpr auto rational_mult(const L &lhs, const R &rhs) noexcept {
    if constexpr (std::is_same_v<std::decay_t<decltype(lhs)>, Rational> &&
 std::is_same_v<std::decay_t<decltype(rhs)>, Rational>) {
      return Rational(lhs.numerator() * rhs.numerator(),
 lhs.denominator() * rhs.denominator());
    } else if constexpr (std::is_same_v<std::decay_t<decltype(lhs)>, Rational>) {
      return Rational(lhs.numerator() * normalize(rhs), lhs.denominator());
    } else if constexpr (std::is_same_v<std::decay_t<decltype(rhs)>, Rational>) {
 return Rational(normalize(lhs) * rhs.numerator(), rhs.denominator());
 } 
}

// Helper function to sum or subtract two Rationals
[[nodiscard]] constexpr Rational
sum_or_subtract(const Rational &lhs, const Rational &rhs, int sign) noexcept {
  const int lhs_numerator = lhs.numerator().number();
  const int rhs_numerator = sign * rhs.numerator().number();
  const int lhs_denominator = lhs.denominator().number();
  const int rhs_denominator = rhs.denominator().number();

  if (lhs_denominator == rhs_denominator) { // Like fractions
    return {lhs_numerator + rhs_numerator, lhs_denominator};
  } else { // Unlike fractions
    // Get their LCD by finding their LCM
    const auto lcd = zero::math::lcm(lhs_denominator, rhs_denominator);

    // Scale numerators to have the common denominator (LCM)
    const int numerator = (lhs_numerator * (lcd / lhs_denominator)) +
                          (rhs_numerator * (lcd / rhs_denominator));

    return {numerator, lcd};
  }
}

#if defined(__clang__)
}
#endif
```

- `Clang` is letting export content from an **internal module partition**. `MSVC` is *not*
- Also, for having visibility of those declared templates at call site, I need to have the `export namespace...`, or it won't be visible.
In `MSVC`, they don't have such trouble (as shown in the code).

Am I doing anything wrong off the `standard` or is this an issue of the frontend?

This is tested with `Clang 18.1.8` via `Msys2` on `Windows` and with `Clang 19.0.0` on `Linux`.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy0WNFy4joS_Rrx0jUuRx4MPPBAzGQ3VZm9VZns3UdKWE2sXVlySTIJ9-u3JBvbgMkwmd2pKQJy63T3Oa2WZGateFWISzK9J9P1hNWu0Gb5UuBzbZ3YHdBMtpoflo9QsD2CK4QFfGdlJRFyzZEkKxKvSXz8TOPmf15VzUipeS0RSuYKkqxUXW7R2IijY0KS5H44WZSVNg6s492DdsjPjnRlR8ftodxqacfBBj4Vc7Vh8gJkYCKUw1c0H5kY5oRW7MIfoYnYAcedUMgJnW82uWTqdbMhdNFY4HvAUqxEW7Ec4S802vOXrHweQGb3HRTKU7DvP7LNn9-eO6zaCvV6FaoPjSaouNgNA3VYVpI5BJJk7lChB4EnQjPofj2T5FtjnGuVY-Xgm3AFmuc2dyDJunkOAI1e3rWwG8tK3OxJkgXAoz1JvgGZZWSWjRs_nxlfUPtA6AP8HWWFBpwGfHeG5Q5cgSCUQgN7JmsEvQMG_whChWRAG2B7LXiwLNEVmp9A5kxKEDsQjtCZBQaVEaVwYo9A6HwYKzPCFSU6kW_2hC6iD7h88enmWlmH75UBVjsNSpuSSfEXEjoPj-AFCE1D2IQuQGl8D0R3RQA-rh7lo3CS7OVnDL-cM3wsJC-gQVcb1XBIkntoyXluhntKeqeBXQtM8Q7UArNfhD2iorTYfh_CR80yInTuI-hknq1H9P4bKjSBND50rSts1iAUTUE0a0GycsuZ_YUaH_76oxqW_FC5AdO66tR78urJwnqQZuTZj5hm5I8KvO1tsp4urW7pXBEpxNA6Dt56FsdID-bD4pPNHJqdlGSL9FNJflSYi6MknIsgg68CW2_DkvS_d9p0VdEUyucaz1CFY9fdMM432myO_m4URCgHfqP7zFL7oKXRlND0xpZGF0OHnZ62Ls_yGYqbHaMeiExm6yD054L-5Ti6uX2V_H5Un2dnEE5fyh9xNVrO_5NSLGt5W_2N19yNVdcNcszZYeNIknHMpY-z58AzOFabra9PAJsrwBdKdVqdKuMbve_Tuu31QOjK63Q-TmjWYvlJHJUuhRqZdvHkVOhfLcDPsfpbyY_122w86_9nbrcJe5nW5SbygaQ3SOZz-miraU97u1o1u4rTvhv4E92xG4B70_3xo53srzH3SnNhc2Y4ma7JdD3grEsoWF-2l3bpdufc8zU9eHDj1tJM9FaysJuOKn-EhpFSGT8gDWHMBYx3f02Mn-P5sAZSdYFdyHdbaOdQo5Vw5RjY78ZNkZ2DtXibE7xQtscz65P4D8KuPYnYi_2EzO7PVKD3p4S2a_LExWw9ttENvP5TySt-u6NsuKwIA0_ZGrYH2AnF_an1OPi9n9LQGbYamfPA4fntzn-TeXlJUrv0zgi6ILiL60fOJEKXvPWrrL3n--t9WWoFJxrQuY91eC7t1T8tyja4IdWrMOhzog8XJIf24PUYdtexf00Puw48kv8oBX1JnIqf8wvBr_Spn134-wmn1_DjO5Ih2hcgaZx5AJLGICxIdM5XSPvWINfKoXKwM7oEFpY7oSuhHBrfj9q3LBUzLhzKm8eRB_3-48-sxSR0pbTzz1qfK2m1T9of2Qu29_72woqtkMId_HXaFdoi-O2DGeRwPDdZYK65PFvh0CM8gkJvMKgfksbnrzyiKPJ508z3ceHgzUc6c7DFxq_E9mL9qAahh3NZgQfgrXlwYeu8AGd0vZXhts4s2EK_KRCqLV-O_U29-VyV8Ahc-zyZOrjCf3kzWr2C3u2OQVvHFPebRxqHMG3z1ospENY2bxm85c4ESThJHoYuXrytn4PWIYc34YpOWribR3fR3APvBQsZ2oOlwVFI-F9Ccf1m_YC_VZ1NXkRxFPfGT0LV7ySNowlfJnyRLNgEl3czOk2TeZIkk2LJZzmmPE1yHifzJE5xmufb-WJKF8n07ut0NxFLGtOv8SJO76bT-TSJ5os0xhjveDy_my14Qr7GWDIhIyn3ZaTN6yRwsLyLZ2lMJ5JtUdrw8pBShW8NQ4RSMl1PzNJP-rKtXy35Gkthne1hnHASl4_X6tee1f2kNnJZOFdZ3_1C83oVrqi3Ua5LQh88bvvnS2X0v9Hv5g8hGkvoQxvufkn_GwAA__-SZH-G">