@@ -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,68 @@ static Expr *wrapAsyncLetInitializer(
8820
8823
return resultInit;
8821
8824
}
8822
8825
8826
+ static Pattern *rewriteExprPattern (const 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
+ EP->setMatchExpr (resultTarget->getAsExpr ());
8840
+ EP->getMatchVar ()->setInterfaceType (patternTy->mapTypeOutOfContext ());
8841
+ EP->setType (patternTy);
8842
+ return EP;
8843
+ }
8844
+
8845
+ // / Attempt to rewrite either an ExprPattern, or a pattern that was solved as
8846
+ // / an ExprPattern, e.g an EnumElementPattern that could not refer to an enum
8847
+ // / case.
8848
+ static Optional<Pattern *>
8849
+ tryRewriteExprPattern (Pattern *P, Solution &solution, Type patternTy,
8850
+ RewriteTargetFn rewriteTarget) {
8851
+ // See if we have a match expression target.
8852
+ auto matchTarget = solution.getTargetFor (P);
8853
+ if (!matchTarget)
8854
+ return None;
8855
+
8856
+ return rewriteExprPattern (*matchTarget, patternTy, rewriteTarget);
8857
+ }
8858
+
8859
+ NullablePtr<Pattern> ExprWalker::rewritePattern (Pattern *pattern,
8860
+ DeclContext *DC) {
8861
+ auto &solution = Rewriter.solution ;
8862
+
8863
+ // Figure out the pattern type.
8864
+ auto patternTy = solution.getResolvedType (pattern);
8865
+ patternTy = patternTy->reconstituteSugar (/* recursive=*/ false );
8866
+
8867
+ // Coerce the pattern to its appropriate type.
8868
+ TypeResolutionOptions patternOptions (TypeResolverContext::InExpression);
8869
+ patternOptions |= TypeResolutionFlags::OverrideType;
8870
+
8871
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
8872
+ return ::tryRewriteExprPattern (
8873
+ EP, solution, ty, [&](auto target) { return rewriteTarget (target); });
8874
+ };
8875
+
8876
+ auto contextualPattern = ContextualPattern::forRawPattern (pattern, DC);
8877
+ return TypeChecker::coercePatternToType (contextualPattern, patternTy,
8878
+ patternOptions, tryRewritePattern);
8879
+ }
8880
+
8823
8881
// / Apply the given solution to the initialization target.
8824
8882
// /
8825
8883
// / \returns the resulting initialization expression.
8826
8884
static Optional<SyntacticElementTarget>
8827
8885
applySolutionToInitialization (Solution &solution, SyntacticElementTarget target,
8828
- Expr *initializer) {
8886
+ Expr *initializer,
8887
+ RewriteTargetFn rewriteTarget) {
8829
8888
auto wrappedVar = target.getInitializationWrappedVar ();
8830
8889
Type initType;
8831
8890
if (wrappedVar) {
@@ -8890,10 +8949,14 @@ applySolutionToInitialization(Solution &solution, SyntacticElementTarget target,
8890
8949
8891
8950
finalPatternType = finalPatternType->reconstituteSugar (/* recursive =*/ false );
8892
8951
8952
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
8953
+ return ::tryRewriteExprPattern (EP, solution, ty, rewriteTarget);
8954
+ };
8955
+
8893
8956
// Apply the solution to the pattern as well.
8894
8957
auto contextualPattern = target.getContextualPattern ();
8895
8958
if (auto coercedPattern = TypeChecker::coercePatternToType (
8896
- contextualPattern, finalPatternType, options)) {
8959
+ contextualPattern, finalPatternType, options, tryRewritePattern )) {
8897
8960
resultTarget.setPattern (coercedPattern);
8898
8961
} else {
8899
8962
return None;
@@ -9040,10 +9103,15 @@ static Optional<SyntacticElementTarget> applySolutionToForEachStmt(
9040
9103
TypeResolutionOptions options (TypeResolverContext::ForEachStmt);
9041
9104
options |= TypeResolutionFlags::OverrideType;
9042
9105
9106
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9107
+ return ::tryRewriteExprPattern (EP, solution, ty, rewriteTarget);
9108
+ };
9109
+
9043
9110
// Apply the solution to the pattern as well.
9044
9111
auto contextualPattern = target.getContextualPattern ();
9045
9112
auto coercedPattern = TypeChecker::coercePatternToType (
9046
- contextualPattern, forEachStmtInfo.initType , options);
9113
+ contextualPattern, forEachStmtInfo.initType , options,
9114
+ tryRewritePattern);
9047
9115
if (!coercedPattern)
9048
9116
return None;
9049
9117
@@ -9131,7 +9199,8 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
9131
9199
switch (target.getExprContextualTypePurpose ()) {
9132
9200
case CTP_Initialization: {
9133
9201
auto initResultTarget = applySolutionToInitialization (
9134
- solution, target, rewrittenExpr);
9202
+ solution, target, rewrittenExpr,
9203
+ [&](auto target) { return rewriteTarget (target); });
9135
9204
if (!initResultTarget)
9136
9205
return None;
9137
9206
@@ -9222,47 +9291,11 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
9222
9291
ConstraintSystem &cs = solution.getConstraintSystem ();
9223
9292
auto info = *cs.getCaseLabelItemInfo (*caseLabelItem);
9224
9293
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 {
9294
+ auto pattern = rewritePattern (info.pattern , target.getDeclContext ());
9295
+ if (!pattern)
9264
9296
return None;
9265
- }
9297
+
9298
+ (*caseLabelItem)->setPattern (pattern.get (), /* resolved=*/ true );
9266
9299
9267
9300
// If there is a guard expression, coerce that.
9268
9301
if (auto *guardExpr = info.guardExpr ) {
@@ -9330,8 +9363,13 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
9330
9363
options |= TypeResolutionFlags::OverrideType;
9331
9364
}
9332
9365
9366
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9367
+ return ::tryRewriteExprPattern (
9368
+ EP, solution, ty, [&](auto target) { return rewriteTarget (target); });
9369
+ };
9370
+
9333
9371
if (auto coercedPattern = TypeChecker::coercePatternToType (
9334
- contextualPattern, patternType, options)) {
9372
+ contextualPattern, patternType, options, tryRewritePattern )) {
9335
9373
auto resultTarget = target;
9336
9374
resultTarget.setPattern (coercedPattern);
9337
9375
return resultTarget;
0 commit comments