@@ -811,6 +811,9 @@ namespace {
811
811
// / The expressions that are direct arguments of call expressions.
812
812
llvm::SmallPtrSet<Expr *, 4 > CallArgs;
813
813
814
+ // / Keep track of acceptable DiscardAssignmentExpr's.
815
+ llvm::SmallPtrSet<DiscardAssignmentExpr*, 2 > CorrectDiscardAssignmentExprs;
816
+
814
817
// / Simplify expressions which are type sugar productions that got parsed
815
818
// / as expressions due to the parser not knowing which identifiers are
816
819
// / type names.
@@ -935,6 +938,27 @@ namespace {
935
938
StrangeInterpolationRewriter (getASTContext ()));
936
939
}
937
940
941
+ // / Scout out the specified destination of an AssignExpr to recursively
942
+ // / identify DiscardAssignmentExpr in legal places. We can only allow them
943
+ // / in simple pattern-like expressions, so we reject anything complex here.
944
+ void markAcceptableDiscardExprs (Expr *E) {
945
+ if (!E) return ;
946
+
947
+ if (auto *PE = dyn_cast<ParenExpr>(E))
948
+ return markAcceptableDiscardExprs (PE->getSubExpr ());
949
+ if (auto *TE = dyn_cast<TupleExpr>(E)) {
950
+ for (auto &elt : TE->getElements ())
951
+ markAcceptableDiscardExprs (elt);
952
+ return ;
953
+ }
954
+ if (auto *BOE = dyn_cast<BindOptionalExpr>(E))
955
+ return markAcceptableDiscardExprs (BOE->getSubExpr ());
956
+ if (auto *DAE = dyn_cast<DiscardAssignmentExpr>(E))
957
+ CorrectDiscardAssignmentExprs.insert (DAE);
958
+
959
+ // Otherwise, we can't support this.
960
+ }
961
+
938
962
public:
939
963
PreCheckExpression (DeclContext *dc, Expr *parent,
940
964
bool replaceInvalidRefsWithErrors)
@@ -1118,6 +1142,9 @@ namespace {
1118
1142
if (auto *ISLE = dyn_cast<InterpolatedStringLiteralExpr>(expr))
1119
1143
correctInterpolationIfStrange (ISLE);
1120
1144
1145
+ if (auto *assignment = dyn_cast<AssignExpr>(expr))
1146
+ markAcceptableDiscardExprs (assignment->getDest ());
1147
+
1121
1148
return finish (true , expr);
1122
1149
}
1123
1150
@@ -1244,7 +1271,8 @@ namespace {
1244
1271
// generating any of the unnecessary constraints.
1245
1272
if (auto BOE = dyn_cast<BindOptionalExpr>(expr)) {
1246
1273
if (auto DAE = dyn_cast<DiscardAssignmentExpr>(BOE->getSubExpr ()))
1247
- return DAE;
1274
+ if (CorrectDiscardAssignmentExprs.count (DAE))
1275
+ return DAE;
1248
1276
}
1249
1277
1250
1278
// If this is a sugared type that needs to be folded into a single
@@ -1425,6 +1453,13 @@ TypeExpr *PreCheckExpression::simplifyTypeExpr(Expr *E) {
1425
1453
return simplifyNestedTypeExpr (UDE);
1426
1454
}
1427
1455
1456
+ // Fold '_' into a placeholder type.
1457
+ if (auto *DAE = dyn_cast<DiscardAssignmentExpr>(E)) {
1458
+ auto *placeholderRepr =
1459
+ new (getASTContext ()) PlaceholderTypeRepr (DAE->getLoc ());
1460
+ return new (getASTContext ()) TypeExpr (placeholderRepr);
1461
+ }
1462
+
1428
1463
// Fold T? into an optional type when T is a TypeExpr.
1429
1464
if (isa<OptionalEvaluationExpr>(E) || isa<BindOptionalExpr>(E)) {
1430
1465
TypeExpr *TyExpr;
@@ -1630,6 +1665,8 @@ TypeExpr *PreCheckExpression::simplifyTypeExpr(Expr *E) {
1630
1665
return nullptr ;
1631
1666
if (auto *TyE = dyn_cast<TypeExpr>(E))
1632
1667
return TyE->getTypeRepr ();
1668
+ if (auto *DAE = dyn_cast<DiscardAssignmentExpr>(E))
1669
+ return new (getASTContext ()) PlaceholderTypeRepr (DAE->getLoc ());
1633
1670
if (auto *TE = dyn_cast<TupleExpr>(E))
1634
1671
if (TE->getNumElements () == 0 )
1635
1672
return TupleTypeRepr::createEmpty (ctx, TE->getSourceRange ());
0 commit comments