Here's an example of the template visibility problem that John raised in CWG discussion:
module A;
export template<typename X, typename Y, typename Z> void f(X x, Y y, Z z) {
g(x);
g(y);
g(z);
}
module B;
import A;
export struct X {};
export void g(X);
export template<typename Y, typename Z> void f(Y y, Z z) {
f(X(), y, z);
}
module C;
import A;
export struct Y {};
export void g(Y);
export template<typename Z> void f(Z z) {
f(Y(), z);
}
// ----
import C;
struct Z {};
int main() {
f(Z());
}
I think it's clear that this should work. However, the proposed "you do phase 2 lookup in the context of the instantiation" rule would reject it, because module B is not visible there (and also not visible in the context of the template), so ADL would be unable to find "g(X)".
As mentioned in CWG, the way that Clang deals with this is to track a sequence of points of instantiation for each template specialization (if you consider 14.6.4.1 [temp.point]'s "point of instantiation" recursive computation, we effectively track all the points that are visited on the path to the point of instantiation) -- in this case, that includes all three 'f' templates -- and make visible all declarations that are visible at the end of the module unit containing each such point of instantiation.
Note that Clang does not require a declaration to be re-exported in order to be found in this way. That is necessary to permit a case like this:
module X;
import std.utility;
import C;
template<typename T> void f() {
std::pair<T, Y> p;
}
// ----
import X;
void g() { f<int>(); }
Note that Y is not exported by X, but its definition must be visible in the instantiation of the pair default constructor in order for this code to work.
However, the precise rule to use here will presumably require some discussion -- should module linkage entities be visible? (I think yes) Should internal linkage entities be visible? (... I don't know. But if we permit their use from exported templates defined within the module interface unit at all, I think the answer there must also be yes, or people will be very confused.)