As reported in PR46111, implicit instantiation of a deduction guide
causes us to have an elaborated type as the parameter, rather than the
dependent type.
After review and feedback from @rsmith, this patch solves this problem
by wrapping the value in an uninstantiated typedef/type-alias that is
instantiated when required later.
Removing the qualifier seems like it might work out OK in practice, given that we've already resolved the name to a specific declaration, but removing the elaborated type keyword (eg, struct X -> X) seems wrong to me.
If the problem is that expanding the typedef is breaking the invariants of NestedNameSpecifier, I'd be concerned that there are other cases where we're breaking those invariants in addition to this one. For example, do we have the same problem with DependentNameType?
Perhaps we should be special-casing transform of nested name specifiers instead. In your example below, it would seem more correct to transform typename STy::Child -> typename PR46111::template S<T>::Child. But that doesn't work in general; consider typedef struct PR46111::S<T> STy; for example.
One possible option would be to change TransformTypedefType to wrap its resulting type in a TypeofType type. That would give us a consistent transformation pattern: typename STy::Child -> typename __typeof(<substituted typedef>)::Child. But it's a bit hacky. It would be cleaner in some sense for TransformTypedefType to actually produce a new TypedefDecl (as if by instantiating the member typedef), and to produce a new TypedefType referring to the transformed typedef declaration.
Out of the available options, transforming the typedef declaration is, I think, my favored choice so far. (In the absence of a better DeclContext for it, I think we could set its DeclContext to be the CXXDeductionGuideDecl. That would at least have the right template parameters etc. in scope. We'll need to delay parenting it until after we create the deduction guide, perhaps by initially creating it as a child of the TUDecl then reparenting it, like we do for function parameters.)