@@ -8646,6 +8646,9 @@ namespace {
8646
8646
return Action::SkipChildren ();
8647
8647
}
8648
8648
8649
+ NullablePtr<Pattern>
8650
+ rewritePattern (Pattern *pattern, DeclContext *DC);
8651
+
8649
8652
// / Rewrite the target, producing a new target.
8650
8653
Optional<SyntacticElementTarget>
8651
8654
rewriteTarget (SyntacticElementTarget target);
@@ -8892,12 +8895,68 @@ static Expr *wrapAsyncLetInitializer(
8892
8895
return resultInit;
8893
8896
}
8894
8897
8898
+ static Pattern *rewriteExprPattern (const SyntacticElementTarget &matchTarget,
8899
+ Type patternTy,
8900
+ RewriteTargetFn rewriteTarget) {
8901
+ auto *EP = matchTarget.getExprPattern ();
8902
+
8903
+ // See if we can simplify to another kind of pattern.
8904
+ if (auto simplified = TypeChecker::trySimplifyExprPattern (EP, patternTy))
8905
+ return simplified.get ();
8906
+
8907
+ auto resultTarget = rewriteTarget (matchTarget);
8908
+ if (!resultTarget)
8909
+ return nullptr ;
8910
+
8911
+ EP->setMatchExpr (resultTarget->getAsExpr ());
8912
+ EP->getMatchVar ()->setInterfaceType (patternTy->mapTypeOutOfContext ());
8913
+ EP->setType (patternTy);
8914
+ return EP;
8915
+ }
8916
+
8917
+ // / Attempt to rewrite either an ExprPattern, or a pattern that was solved as
8918
+ // / an ExprPattern, e.g an EnumElementPattern that could not refer to an enum
8919
+ // / case.
8920
+ static Optional<Pattern *>
8921
+ tryRewriteExprPattern (Pattern *P, Solution &solution, Type patternTy,
8922
+ RewriteTargetFn rewriteTarget) {
8923
+ // See if we have a match expression target.
8924
+ auto matchTarget = solution.getTargetFor (P);
8925
+ if (!matchTarget)
8926
+ return None;
8927
+
8928
+ return rewriteExprPattern (*matchTarget, patternTy, rewriteTarget);
8929
+ }
8930
+
8931
+ NullablePtr<Pattern> ExprWalker::rewritePattern (Pattern *pattern,
8932
+ DeclContext *DC) {
8933
+ auto &solution = Rewriter.solution ;
8934
+
8935
+ // Figure out the pattern type.
8936
+ auto patternTy = solution.getResolvedType (pattern);
8937
+ patternTy = patternTy->reconstituteSugar (/* recursive=*/ false );
8938
+
8939
+ // Coerce the pattern to its appropriate type.
8940
+ TypeResolutionOptions patternOptions (TypeResolverContext::InExpression);
8941
+ patternOptions |= TypeResolutionFlags::OverrideType;
8942
+
8943
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
8944
+ return ::tryRewriteExprPattern (
8945
+ EP, solution, ty, [&](auto target) { return rewriteTarget (target); });
8946
+ };
8947
+
8948
+ auto contextualPattern = ContextualPattern::forRawPattern (pattern, DC);
8949
+ return TypeChecker::coercePatternToType (contextualPattern, patternTy,
8950
+ patternOptions, tryRewritePattern);
8951
+ }
8952
+
8895
8953
// / Apply the given solution to the initialization target.
8896
8954
// /
8897
8955
// / \returns the resulting initialization expression.
8898
8956
static Optional<SyntacticElementTarget>
8899
8957
applySolutionToInitialization (Solution &solution, SyntacticElementTarget target,
8900
- Expr *initializer) {
8958
+ Expr *initializer,
8959
+ RewriteTargetFn rewriteTarget) {
8901
8960
auto wrappedVar = target.getInitializationWrappedVar ();
8902
8961
Type initType;
8903
8962
if (wrappedVar) {
@@ -8962,10 +9021,14 @@ applySolutionToInitialization(Solution &solution, SyntacticElementTarget target,
8962
9021
8963
9022
finalPatternType = finalPatternType->reconstituteSugar (/* recursive =*/ false );
8964
9023
9024
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9025
+ return ::tryRewriteExprPattern (EP, solution, ty, rewriteTarget);
9026
+ };
9027
+
8965
9028
// Apply the solution to the pattern as well.
8966
9029
auto contextualPattern = target.getContextualPattern ();
8967
9030
if (auto coercedPattern = TypeChecker::coercePatternToType (
8968
- contextualPattern, finalPatternType, options)) {
9031
+ contextualPattern, finalPatternType, options, tryRewritePattern )) {
8969
9032
resultTarget.setPattern (coercedPattern);
8970
9033
} else {
8971
9034
return None;
@@ -9112,10 +9175,15 @@ static Optional<SyntacticElementTarget> applySolutionToForEachStmt(
9112
9175
TypeResolutionOptions options (TypeResolverContext::ForEachStmt);
9113
9176
options |= TypeResolutionFlags::OverrideType;
9114
9177
9178
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9179
+ return ::tryRewriteExprPattern (EP, solution, ty, rewriteTarget);
9180
+ };
9181
+
9115
9182
// Apply the solution to the pattern as well.
9116
9183
auto contextualPattern = target.getContextualPattern ();
9117
9184
auto coercedPattern = TypeChecker::coercePatternToType (
9118
- contextualPattern, forEachStmtInfo.initType , options);
9185
+ contextualPattern, forEachStmtInfo.initType , options,
9186
+ tryRewritePattern);
9119
9187
if (!coercedPattern)
9120
9188
return None;
9121
9189
@@ -9203,7 +9271,8 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
9203
9271
switch (target.getExprContextualTypePurpose ()) {
9204
9272
case CTP_Initialization: {
9205
9273
auto initResultTarget = applySolutionToInitialization (
9206
- solution, target, rewrittenExpr);
9274
+ solution, target, rewrittenExpr,
9275
+ [&](auto target) { return rewriteTarget (target); });
9207
9276
if (!initResultTarget)
9208
9277
return None;
9209
9278
@@ -9294,47 +9363,11 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
9294
9363
ConstraintSystem &cs = solution.getConstraintSystem ();
9295
9364
auto info = *cs.getCaseLabelItemInfo (*caseLabelItem);
9296
9365
9297
- // Figure out the pattern type.
9298
- Type patternType = solution.simplifyType (solution.getType (info.pattern ));
9299
- patternType = patternType->reconstituteSugar (/* recursive=*/ false );
9300
-
9301
- // Check whether this enum element is resolved via ~= application.
9302
- if (auto *enumElement = dyn_cast<EnumElementPattern>(info.pattern )) {
9303
- if (auto target = cs.getTargetFor (enumElement)) {
9304
- auto *EP = target->getExprPattern ();
9305
- auto enumType = solution.getResolvedType (EP);
9306
-
9307
- auto *matchCall = target->getAsExpr ();
9308
-
9309
- auto *result = matchCall->walk (*this );
9310
- if (!result)
9311
- return None;
9312
-
9313
- {
9314
- auto *matchVar = EP->getMatchVar ();
9315
- matchVar->setInterfaceType (enumType->mapTypeOutOfContext ());
9316
- }
9317
-
9318
- EP->setMatchExpr (result);
9319
- EP->setType (enumType);
9320
-
9321
- (*caseLabelItem)->setPattern (EP, /* resolved=*/ true );
9322
- return target;
9323
- }
9324
- }
9325
-
9326
- // Coerce the pattern to its appropriate type.
9327
- TypeResolutionOptions patternOptions (TypeResolverContext::InExpression);
9328
- patternOptions |= TypeResolutionFlags::OverrideType;
9329
- auto contextualPattern =
9330
- ContextualPattern::forRawPattern (info.pattern ,
9331
- target.getDeclContext ());
9332
- if (auto coercedPattern = TypeChecker::coercePatternToType (
9333
- contextualPattern, patternType, patternOptions)) {
9334
- (*caseLabelItem)->setPattern (coercedPattern, /* resolved=*/ true );
9335
- } else {
9366
+ auto pattern = rewritePattern (info.pattern , target.getDeclContext ());
9367
+ if (!pattern)
9336
9368
return None;
9337
- }
9369
+
9370
+ (*caseLabelItem)->setPattern (pattern.get (), /* resolved=*/ true );
9338
9371
9339
9372
// If there is a guard expression, coerce that.
9340
9373
if (auto *guardExpr = info.guardExpr ) {
@@ -9402,8 +9435,13 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
9402
9435
options |= TypeResolutionFlags::OverrideType;
9403
9436
}
9404
9437
9438
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9439
+ return ::tryRewriteExprPattern (
9440
+ EP, solution, ty, [&](auto target) { return rewriteTarget (target); });
9441
+ };
9442
+
9405
9443
if (auto coercedPattern = TypeChecker::coercePatternToType (
9406
- contextualPattern, patternType, options)) {
9444
+ contextualPattern, patternType, options, tryRewritePattern )) {
9407
9445
auto resultTarget = target;
9408
9446
resultTarget.setPattern (coercedPattern);
9409
9447
return resultTarget;
0 commit comments