@@ -8574,6 +8574,9 @@ namespace {
8574
8574
return Action::SkipChildren ();
8575
8575
}
8576
8576
8577
+ NullablePtr<Pattern>
8578
+ rewritePattern (Pattern *pattern, DeclContext *DC);
8579
+
8577
8580
// / Rewrite the target, producing a new target.
8578
8581
Optional<SyntacticElementTarget>
8579
8582
rewriteTarget (SyntacticElementTarget target);
@@ -8820,12 +8823,70 @@ static Expr *wrapAsyncLetInitializer(
8820
8823
return resultInit;
8821
8824
}
8822
8825
8826
+ static Pattern *rewriteExprPattern (SyntacticElementTarget matchTarget,
8827
+ Type patternTy,
8828
+ RewriteTargetFn rewriteTarget) {
8829
+ auto *EP = matchTarget.getExprPattern ();
8830
+
8831
+ // See if we can simplify to another kind of pattern.
8832
+ if (auto simplified = TypeChecker::trySimplifyExprPattern (EP, patternTy))
8833
+ return simplified.get ();
8834
+
8835
+ auto resultTarget = rewriteTarget (matchTarget);
8836
+ if (!resultTarget)
8837
+ return nullptr ;
8838
+
8839
+ matchTarget = *resultTarget;
8840
+
8841
+ EP->setMatchExpr (matchTarget.getAsExpr ());
8842
+ EP->getMatchVar ()->setInterfaceType (patternTy->mapTypeOutOfContext ());
8843
+ EP->setType (patternTy);
8844
+ return EP;
8845
+ }
8846
+
8847
+ // / Attempt to rewrite either an ExprPattern, or a pattern that was solved as
8848
+ // / an ExprPattern, e.g an EnumElementPattern that could not refer to an enum
8849
+ // / case.
8850
+ static Optional<Pattern *>
8851
+ tryRewriteExprPattern (Pattern *P, Solution &solution, Type patternTy,
8852
+ RewriteTargetFn rewriteTarget) {
8853
+ // See if we have a match expression target.
8854
+ auto matchTarget = solution.getTargetFor (P);
8855
+ if (!matchTarget)
8856
+ return None;
8857
+
8858
+ return rewriteExprPattern (*matchTarget, patternTy, rewriteTarget);
8859
+ }
8860
+
8861
+ NullablePtr<Pattern> ExprWalker::rewritePattern (Pattern *pattern,
8862
+ DeclContext *DC) {
8863
+ auto &solution = Rewriter.solution ;
8864
+
8865
+ // Figure out the pattern type.
8866
+ auto patternTy = solution.getResolvedType (pattern);
8867
+ patternTy = patternTy->reconstituteSugar (/* recursive=*/ false );
8868
+
8869
+ // Coerce the pattern to its appropriate type.
8870
+ TypeResolutionOptions patternOptions (TypeResolverContext::InExpression);
8871
+ patternOptions |= TypeResolutionFlags::OverrideType;
8872
+
8873
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
8874
+ return ::tryRewriteExprPattern (
8875
+ EP, solution, ty, [&](auto target) { return rewriteTarget (target); });
8876
+ };
8877
+
8878
+ auto contextualPattern = ContextualPattern::forRawPattern (pattern, DC);
8879
+ return TypeChecker::coercePatternToType (contextualPattern, patternTy,
8880
+ patternOptions, tryRewritePattern);
8881
+ }
8882
+
8823
8883
// / Apply the given solution to the initialization target.
8824
8884
// /
8825
8885
// / \returns the resulting initialization expression.
8826
8886
static Optional<SyntacticElementTarget>
8827
8887
applySolutionToInitialization (Solution &solution, SyntacticElementTarget target,
8828
- Expr *initializer) {
8888
+ Expr *initializer,
8889
+ RewriteTargetFn rewriteTarget) {
8829
8890
auto wrappedVar = target.getInitializationWrappedVar ();
8830
8891
Type initType;
8831
8892
if (wrappedVar) {
@@ -8890,10 +8951,14 @@ applySolutionToInitialization(Solution &solution, SyntacticElementTarget target,
8890
8951
8891
8952
finalPatternType = finalPatternType->reconstituteSugar (/* recursive =*/ false );
8892
8953
8954
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
8955
+ return ::tryRewriteExprPattern (EP, solution, ty, rewriteTarget);
8956
+ };
8957
+
8893
8958
// Apply the solution to the pattern as well.
8894
8959
auto contextualPattern = target.getContextualPattern ();
8895
8960
if (auto coercedPattern = TypeChecker::coercePatternToType (
8896
- contextualPattern, finalPatternType, options)) {
8961
+ contextualPattern, finalPatternType, options, tryRewritePattern )) {
8897
8962
resultTarget.setPattern (coercedPattern);
8898
8963
} else {
8899
8964
return None;
@@ -9040,10 +9105,15 @@ static Optional<SyntacticElementTarget> applySolutionToForEachStmt(
9040
9105
TypeResolutionOptions options (TypeResolverContext::ForEachStmt);
9041
9106
options |= TypeResolutionFlags::OverrideType;
9042
9107
9108
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9109
+ return ::tryRewriteExprPattern (EP, solution, ty, rewriteTarget);
9110
+ };
9111
+
9043
9112
// Apply the solution to the pattern as well.
9044
9113
auto contextualPattern = target.getContextualPattern ();
9045
9114
auto coercedPattern = TypeChecker::coercePatternToType (
9046
- contextualPattern, forEachStmtInfo.initType , options);
9115
+ contextualPattern, forEachStmtInfo.initType , options,
9116
+ tryRewritePattern);
9047
9117
if (!coercedPattern)
9048
9118
return None;
9049
9119
@@ -9131,7 +9201,8 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
9131
9201
switch (target.getExprContextualTypePurpose ()) {
9132
9202
case CTP_Initialization: {
9133
9203
auto initResultTarget = applySolutionToInitialization (
9134
- solution, target, rewrittenExpr);
9204
+ solution, target, rewrittenExpr,
9205
+ [&](auto target) { return rewriteTarget (target); });
9135
9206
if (!initResultTarget)
9136
9207
return None;
9137
9208
@@ -9222,47 +9293,11 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
9222
9293
ConstraintSystem &cs = solution.getConstraintSystem ();
9223
9294
auto info = *cs.getCaseLabelItemInfo (*caseLabelItem);
9224
9295
9225
- // Figure out the pattern type.
9226
- Type patternType = solution.simplifyType (solution.getType (info.pattern ));
9227
- patternType = patternType->reconstituteSugar (/* recursive=*/ false );
9228
-
9229
- // Check whether this enum element is resolved via ~= application.
9230
- if (auto *enumElement = dyn_cast<EnumElementPattern>(info.pattern )) {
9231
- if (auto target = cs.getTargetFor (enumElement)) {
9232
- auto *EP = target->getExprPattern ();
9233
- auto enumType = solution.getResolvedType (EP);
9234
-
9235
- auto *matchCall = target->getAsExpr ();
9236
-
9237
- auto *result = matchCall->walk (*this );
9238
- if (!result)
9239
- return None;
9240
-
9241
- {
9242
- auto *matchVar = EP->getMatchVar ();
9243
- matchVar->setInterfaceType (enumType->mapTypeOutOfContext ());
9244
- }
9245
-
9246
- EP->setMatchExpr (result);
9247
- EP->setType (enumType);
9248
-
9249
- (*caseLabelItem)->setPattern (EP, /* resolved=*/ true );
9250
- return target;
9251
- }
9252
- }
9253
-
9254
- // Coerce the pattern to its appropriate type.
9255
- TypeResolutionOptions patternOptions (TypeResolverContext::InExpression);
9256
- patternOptions |= TypeResolutionFlags::OverrideType;
9257
- auto contextualPattern =
9258
- ContextualPattern::forRawPattern (info.pattern ,
9259
- target.getDeclContext ());
9260
- if (auto coercedPattern = TypeChecker::coercePatternToType (
9261
- contextualPattern, patternType, patternOptions)) {
9262
- (*caseLabelItem)->setPattern (coercedPattern, /* resolved=*/ true );
9263
- } else {
9296
+ auto pattern = rewritePattern (info.pattern , target.getDeclContext ());
9297
+ if (!pattern)
9264
9298
return None;
9265
- }
9299
+
9300
+ (*caseLabelItem)->setPattern (pattern.get (), /* resolved=*/ true );
9266
9301
9267
9302
// If there is a guard expression, coerce that.
9268
9303
if (auto *guardExpr = info.guardExpr ) {
@@ -9330,8 +9365,13 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
9330
9365
options |= TypeResolutionFlags::OverrideType;
9331
9366
}
9332
9367
9368
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9369
+ return ::tryRewriteExprPattern (
9370
+ EP, solution, ty, [&](auto target) { return rewriteTarget (target); });
9371
+ };
9372
+
9333
9373
if (auto coercedPattern = TypeChecker::coercePatternToType (
9334
- contextualPattern, patternType, options)) {
9374
+ contextualPattern, patternType, options, tryRewritePattern )) {
9335
9375
auto resultTarget = target;
9336
9376
resultTarget.setPattern (coercedPattern);
9337
9377
return resultTarget;
0 commit comments