@@ -1755,6 +1755,45 @@ void CompletionLookup::addNominalTypeRef(const NominalTypeDecl *NTD,
17551755 Builder.setTypeContext (expectedTypeContext, CurrDeclContext);
17561756}
17571757
1758+ Type CompletionLookup::getTypeAliasType (const TypeAliasDecl *TAD,
1759+ DynamicLookupInfo dynamicLookupInfo) {
1760+ // Substitute the base type for a nested typealias if needed.
1761+ auto ty = getTypeOfMember (TAD, dynamicLookupInfo);
1762+ auto *typeAliasTy = dyn_cast<TypeAliasType>(ty.getPointer ());
1763+ if (!typeAliasTy)
1764+ return ty;
1765+
1766+ // If the underlying type has an error, prefer to print the full typealias,
1767+ // otherwise get the underlying type. We only want the direct underlying type,
1768+ // not the full desugared type, since that more faithfully reflects what's
1769+ // written in source.
1770+ Type underlyingTy = typeAliasTy->getSinglyDesugaredType ();
1771+ if (underlyingTy->hasError ())
1772+ return ty;
1773+
1774+ // The underlying type might be unbound for e.g:
1775+ //
1776+ // struct S<T> {}
1777+ // typealias X = S
1778+ //
1779+ // Introduce type parameters such that we print the underlying type as
1780+ // 'S<T>'. We only expect unbound generics at the top-level of a type-alias,
1781+ // they are rejected by type resolution in any other position.
1782+ //
1783+ // FIXME: This is a hack – using the declared interface type isn't correct
1784+ // since the generic parameters ought to be introduced at a higher depth,
1785+ // i.e we should be treating it as `typealias X<T> = S<T>`. Ideally this would
1786+ // be fixed by desugaring the unbound typealias during type resolution. For
1787+ // now this is fine though since we only use the resulting type for printing
1788+ // the type annotation; the type relation logic currently skips type
1789+ // parameters.
1790+ if (auto *UGT = underlyingTy->getAs <UnboundGenericType>())
1791+ underlyingTy = UGT->getDecl ()->getDeclaredInterfaceType ();
1792+
1793+ ASSERT (!underlyingTy->hasUnboundGenericType ());
1794+ return underlyingTy;
1795+ }
1796+
17581797void CompletionLookup::addTypeAliasRef (const TypeAliasDecl *TAD,
17591798 DeclVisibilityKind Reason,
17601799 DynamicLookupInfo dynamicLookupInfo) {
@@ -1764,18 +1803,7 @@ void CompletionLookup::addTypeAliasRef(const TypeAliasDecl *TAD,
17641803 Builder.setAssociatedDecl (TAD);
17651804 addLeadingDot (Builder);
17661805 addValueBaseName (Builder, TAD->getBaseName ());
1767-
1768- // Substitute the base type for a nested typealias if needed.
1769- auto ty = getTypeOfMember (TAD, dynamicLookupInfo);
1770-
1771- // If the underlying type has an error, prefer to print the full typealias,
1772- // otherwise get the underlying type.
1773- if (auto *TA = dyn_cast<TypeAliasType>(ty.getPointer ())) {
1774- auto underlyingTy = TA->getSinglyDesugaredType ();
1775- if (!underlyingTy->hasError ())
1776- ty = underlyingTy;
1777- }
1778- addTypeAnnotation (Builder, ty);
1806+ addTypeAnnotation (Builder, getTypeAliasType (TAD, dynamicLookupInfo));
17791807}
17801808
17811809void CompletionLookup::addGenericTypeParamRef (
0 commit comments