https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101140
--- Comment #5 from Nathaniel Shead <nshead at gcc dot gnu.org> --- (In reply to Patrick Palka from comment #4) > FWIW I was thinking we might want to perform two-phase name lookup for > new-expressions like we do for other operator expressions, wherein > unqualified lookup is performed at template definition time, saved inside > the expression (via DEPENDENT_OPERATOR_TYPE) and then reused at > instantiation time. I actually wonder if this is even correct. [basic.argdep.lookup] p4 says: > If the lookup is for a dependent name ([temp.dep], [temp.dep.candidate]), the > above lookup is also performed from each point in the instantiation context > ([module.context]) of the lookup, additionally ignoring any declaration that > appears in another translation unit, is attached to the global module, and is > either discarded ([module.global.frag]) or has internal linkage. And the instantiation context is defined to include ([module.context] p3): > ...if the template is defined in a module interface unit of a module M and > the point of instantiation is not in a module interface unit of M, the point > at the end of the declaration-seq of the primary module interface unit of M > (prior to the private-module-fragment, if any). Which implies to me that the following sample should work: export module M; export template <typename T> void f(T t) { g(t); } namespace ns { export struct X {}; void g(X); } // import M; int main() { f(ns::X{}); // should compile? } but we currently error. Whether this is a sensible thing to support is another question...