@@ -1826,10 +1826,37 @@ VarDecl *PreCheckExpression::getImplicitSelfDeclForSuperContext(SourceLoc Loc) {
18261826 return methodSelf;
18271827}
18281828
1829+ // / Check whether this expression refers to the ~ operator.
1830+ static bool isTildeOperator (Expr *expr) {
1831+ auto nameMatches = [&](DeclName name) {
1832+ return name.isOperator () && name.getBaseName ().getIdentifier ().is (" ~" );
1833+ };
1834+
1835+ if (auto overload = dyn_cast<OverloadedDeclRefExpr>(expr)) {
1836+ return llvm::any_of (overload->getDecls (), [=](auto *decl) -> bool {
1837+ return nameMatches (decl->getName ());
1838+ });
1839+ }
1840+
1841+ if (auto unresolved = dyn_cast<UnresolvedDeclRefExpr>(expr)) {
1842+ return nameMatches (unresolved->getName ().getFullName ());
1843+ }
1844+
1845+ if (auto declRef = dyn_cast<DeclRefExpr>(expr)) {
1846+ return nameMatches (declRef->getDecl ()->getName ());
1847+ }
1848+
1849+ return false ;
1850+ }
1851+
18291852// / Simplify expressions which are type sugar productions that got parsed
18301853// / as expressions due to the parser not knowing which identifiers are
18311854// / type names.
18321855TypeExpr *PreCheckExpression::simplifyTypeExpr (Expr *E) {
1856+ // If it's already a type expression, return it.
1857+ if (auto typeExpr = dyn_cast<TypeExpr>(E))
1858+ return typeExpr;
1859+
18331860 // Fold member types.
18341861 if (auto *UDE = dyn_cast<UnresolvedDotExpr>(E)) {
18351862 return simplifyNestedTypeExpr (UDE);
@@ -2081,6 +2108,17 @@ TypeExpr *PreCheckExpression::simplifyTypeExpr(Expr *E) {
20812108 return new (Ctx) TypeExpr (NewTypeRepr);
20822109 }
20832110
2111+ // Fold '~P' into a composition type.
2112+ if (auto *unaryExpr = dyn_cast<PrefixUnaryExpr>(E)) {
2113+ if (isTildeOperator (unaryExpr->getFn ())) {
2114+ if (auto operand = simplifyTypeExpr (unaryExpr->getOperand ())) {
2115+ auto inverseTypeRepr = new (Ctx) InverseTypeRepr (
2116+ unaryExpr->getLoc (), operand->getTypeRepr ());
2117+ return new (Ctx) TypeExpr (inverseTypeRepr);
2118+ }
2119+ }
2120+ }
2121+
20842122 // Fold 'P & Q' into a composition type
20852123 if (auto *binaryExpr = getCompositionExpr (E)) {
20862124 // The protocols we are composing
0 commit comments