@@ -8570,6 +8570,9 @@ namespace {
8570
8570
return Action::SkipChildren ();
8571
8571
}
8572
8572
8573
+ NullablePtr<Pattern>
8574
+ rewritePattern (Pattern *pattern, DeclContext *DC);
8575
+
8573
8576
// / Rewrite the target, producing a new target.
8574
8577
Optional<SyntacticElementTarget>
8575
8578
rewriteTarget (SyntacticElementTarget target);
@@ -8816,12 +8819,68 @@ static Expr *wrapAsyncLetInitializer(
8816
8819
return resultInit;
8817
8820
}
8818
8821
8822
+ static Pattern *rewriteExprPattern (SyntacticElementTarget matchTarget,
8823
+ Type patternTy,
8824
+ RewriteTargetFn rewriteTarget) {
8825
+ auto *EP = matchTarget.getExprPattern ();
8826
+
8827
+ // See if we can simplify to another kind of pattern.
8828
+ if (auto simplified = TypeChecker::trySimplifyExprPattern (EP, patternTy))
8829
+ return simplified.get ();
8830
+
8831
+ auto resultTarget = rewriteTarget (matchTarget);
8832
+ if (!resultTarget)
8833
+ return nullptr ;
8834
+
8835
+ matchTarget = *resultTarget;
8836
+
8837
+ EP->setMatchExpr (matchTarget.getAsExpr ());
8838
+ EP->getMatchVar ()->setInterfaceType (patternTy->mapTypeOutOfContext ());
8839
+ EP->setType (patternTy);
8840
+ return EP;
8841
+ }
8842
+
8843
+ static Optional<Pattern *>
8844
+ tryRewriteExprPattern (Pattern *P, Solution &solution, Type patternTy,
8845
+ RewriteTargetFn rewriteTarget) {
8846
+ // We may either have an ExprPattern, or a pattern that was mapped to an
8847
+ // ExprPattern, such as an EnumElementPattern.
8848
+ auto matchTarget = solution.getTargetFor (P);
8849
+ if (!matchTarget)
8850
+ return None;
8851
+
8852
+ return rewriteExprPattern (*matchTarget, patternTy, rewriteTarget);
8853
+ }
8854
+
8855
+ NullablePtr<Pattern> ExprWalker::rewritePattern (Pattern *pattern,
8856
+ DeclContext *DC) {
8857
+ auto &solution = Rewriter.solution ;
8858
+
8859
+ // Figure out the pattern type.
8860
+ auto patternTy = solution.getResolvedType (pattern);
8861
+ patternTy = patternTy->reconstituteSugar (/* recursive=*/ false );
8862
+
8863
+ // Coerce the pattern to its appropriate type.
8864
+ TypeResolutionOptions patternOptions (TypeResolverContext::InExpression);
8865
+ patternOptions |= TypeResolutionFlags::OverrideType;
8866
+
8867
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
8868
+ return ::tryRewriteExprPattern (
8869
+ EP, solution, ty, [&](auto target) { return rewriteTarget (target); });
8870
+ };
8871
+
8872
+ auto contextualPattern = ContextualPattern::forRawPattern (pattern, DC);
8873
+ return TypeChecker::coercePatternToType (contextualPattern, patternTy,
8874
+ patternOptions, tryRewritePattern);
8875
+ }
8876
+
8819
8877
// / Apply the given solution to the initialization target.
8820
8878
// /
8821
8879
// / \returns the resulting initialization expression.
8822
8880
static Optional<SyntacticElementTarget>
8823
8881
applySolutionToInitialization (Solution &solution, SyntacticElementTarget target,
8824
- Expr *initializer) {
8882
+ Expr *initializer,
8883
+ RewriteTargetFn rewriteTarget) {
8825
8884
auto wrappedVar = target.getInitializationWrappedVar ();
8826
8885
Type initType;
8827
8886
if (wrappedVar) {
@@ -8886,10 +8945,15 @@ applySolutionToInitialization(Solution &solution, SyntacticElementTarget target,
8886
8945
8887
8946
finalPatternType = finalPatternType->reconstituteSugar (/* recursive =*/ false );
8888
8947
8948
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
8949
+ return ::tryRewriteExprPattern (
8950
+ EP, solution, ty, [&](auto target) { return rewriteTarget (target); });
8951
+ };
8952
+
8889
8953
// Apply the solution to the pattern as well.
8890
8954
auto contextualPattern = target.getContextualPattern ();
8891
8955
if (auto coercedPattern = TypeChecker::coercePatternToType (
8892
- contextualPattern, finalPatternType, options)) {
8956
+ contextualPattern, finalPatternType, options, tryRewritePattern )) {
8893
8957
resultTarget.setPattern (coercedPattern);
8894
8958
} else {
8895
8959
return None;
@@ -9036,10 +9100,16 @@ static Optional<SyntacticElementTarget> applySolutionToForEachStmt(
9036
9100
TypeResolutionOptions options (TypeResolverContext::ForEachStmt);
9037
9101
options |= TypeResolutionFlags::OverrideType;
9038
9102
9103
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9104
+ return ::tryRewriteExprPattern (
9105
+ EP, solution, ty, [&](auto target) { return rewriteTarget (target); });
9106
+ };
9107
+
9039
9108
// Apply the solution to the pattern as well.
9040
9109
auto contextualPattern = target.getContextualPattern ();
9041
9110
auto coercedPattern = TypeChecker::coercePatternToType (
9042
- contextualPattern, forEachStmtInfo.initType , options);
9111
+ contextualPattern, forEachStmtInfo.initType , options,
9112
+ tryRewritePattern);
9043
9113
if (!coercedPattern)
9044
9114
return None;
9045
9115
@@ -9127,7 +9197,8 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
9127
9197
switch (target.getExprContextualTypePurpose ()) {
9128
9198
case CTP_Initialization: {
9129
9199
auto initResultTarget = applySolutionToInitialization (
9130
- solution, target, rewrittenExpr);
9200
+ solution, target, rewrittenExpr,
9201
+ [&](auto target) { return rewriteTarget (target); });
9131
9202
if (!initResultTarget)
9132
9203
return None;
9133
9204
@@ -9218,47 +9289,11 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
9218
9289
ConstraintSystem &cs = solution.getConstraintSystem ();
9219
9290
auto info = *cs.getCaseLabelItemInfo (*caseLabelItem);
9220
9291
9221
- // Figure out the pattern type.
9222
- Type patternType = solution.simplifyType (solution.getType (info.pattern ));
9223
- patternType = patternType->reconstituteSugar (/* recursive=*/ false );
9224
-
9225
- // Check whether this enum element is resolved via ~= application.
9226
- if (auto *enumElement = dyn_cast<EnumElementPattern>(info.pattern )) {
9227
- if (auto target = cs.getTargetFor (enumElement)) {
9228
- auto *EP = target->getExprPattern ();
9229
- auto enumType = solution.getResolvedType (EP);
9230
-
9231
- auto *matchCall = target->getAsExpr ();
9232
-
9233
- auto *result = matchCall->walk (*this );
9234
- if (!result)
9235
- return None;
9236
-
9237
- {
9238
- auto *matchVar = EP->getMatchVar ();
9239
- matchVar->setInterfaceType (enumType->mapTypeOutOfContext ());
9240
- }
9241
-
9242
- EP->setMatchExpr (result);
9243
- EP->setType (enumType);
9244
-
9245
- (*caseLabelItem)->setPattern (EP, /* resolved=*/ true );
9246
- return target;
9247
- }
9248
- }
9249
-
9250
- // Coerce the pattern to its appropriate type.
9251
- TypeResolutionOptions patternOptions (TypeResolverContext::InExpression);
9252
- patternOptions |= TypeResolutionFlags::OverrideType;
9253
- auto contextualPattern =
9254
- ContextualPattern::forRawPattern (info.pattern ,
9255
- target.getDeclContext ());
9256
- if (auto coercedPattern = TypeChecker::coercePatternToType (
9257
- contextualPattern, patternType, patternOptions)) {
9258
- (*caseLabelItem)->setPattern (coercedPattern, /* resolved=*/ true );
9259
- } else {
9292
+ auto pattern = rewritePattern (info.pattern , target.getDeclContext ());
9293
+ if (!pattern)
9260
9294
return None;
9261
- }
9295
+
9296
+ (*caseLabelItem)->setPattern (pattern.get (), /* resolved=*/ true );
9262
9297
9263
9298
// If there is a guard expression, coerce that.
9264
9299
if (auto *guardExpr = info.guardExpr ) {
@@ -9326,8 +9361,13 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
9326
9361
options |= TypeResolutionFlags::OverrideType;
9327
9362
}
9328
9363
9364
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9365
+ return ::tryRewriteExprPattern (
9366
+ EP, solution, ty, [&](auto target) { return rewriteTarget (target); });
9367
+ };
9368
+
9329
9369
if (auto coercedPattern = TypeChecker::coercePatternToType (
9330
- contextualPattern, patternType, options)) {
9370
+ contextualPattern, patternType, options, tryRewritePattern )) {
9331
9371
auto resultTarget = target;
9332
9372
resultTarget.setPattern (coercedPattern);
9333
9373
return resultTarget;
0 commit comments