@@ -1755,6 +1755,45 @@ void CompletionLookup::addNominalTypeRef(const NominalTypeDecl *NTD,
1755
1755
Builder.setTypeContext (expectedTypeContext, CurrDeclContext);
1756
1756
}
1757
1757
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
+
1758
1797
void CompletionLookup::addTypeAliasRef (const TypeAliasDecl *TAD,
1759
1798
DeclVisibilityKind Reason,
1760
1799
DynamicLookupInfo dynamicLookupInfo) {
@@ -1764,18 +1803,7 @@ void CompletionLookup::addTypeAliasRef(const TypeAliasDecl *TAD,
1764
1803
Builder.setAssociatedDecl (TAD);
1765
1804
addLeadingDot (Builder);
1766
1805
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));
1779
1807
}
1780
1808
1781
1809
void CompletionLookup::addGenericTypeParamRef (
0 commit comments