@@ -8582,6 +8582,9 @@ namespace {
8582
8582
return Action::SkipChildren ();
8583
8583
}
8584
8584
8585
+ NullablePtr<Pattern>
8586
+ rewritePattern (Pattern *pattern, DeclContext *DC);
8587
+
8585
8588
// / Rewrite the target, producing a new target.
8586
8589
Optional<SyntacticElementTarget>
8587
8590
rewriteTarget (SyntacticElementTarget target);
@@ -8828,12 +8831,68 @@ static Expr *wrapAsyncLetInitializer(
8828
8831
return resultInit;
8829
8832
}
8830
8833
8834
+ static Pattern *rewriteExprPattern (const SyntacticElementTarget &matchTarget,
8835
+ Type patternTy,
8836
+ RewriteTargetFn rewriteTarget) {
8837
+ auto *EP = matchTarget.getExprPattern ();
8838
+
8839
+ // See if we can simplify to another kind of pattern.
8840
+ if (auto simplified = TypeChecker::trySimplifyExprPattern (EP, patternTy))
8841
+ return simplified.get ();
8842
+
8843
+ auto resultTarget = rewriteTarget (matchTarget);
8844
+ if (!resultTarget)
8845
+ return nullptr ;
8846
+
8847
+ EP->setMatchExpr (resultTarget->getAsExpr ());
8848
+ EP->getMatchVar ()->setInterfaceType (patternTy->mapTypeOutOfContext ());
8849
+ EP->setType (patternTy);
8850
+ return EP;
8851
+ }
8852
+
8853
+ // / Attempt to rewrite either an ExprPattern, or a pattern that was solved as
8854
+ // / an ExprPattern, e.g an EnumElementPattern that could not refer to an enum
8855
+ // / case.
8856
+ static Optional<Pattern *>
8857
+ tryRewriteExprPattern (Pattern *P, Solution &solution, Type patternTy,
8858
+ RewriteTargetFn rewriteTarget) {
8859
+ // See if we have a match expression target.
8860
+ auto matchTarget = solution.getTargetFor (P);
8861
+ if (!matchTarget)
8862
+ return None;
8863
+
8864
+ return rewriteExprPattern (*matchTarget, patternTy, rewriteTarget);
8865
+ }
8866
+
8867
+ NullablePtr<Pattern> ExprWalker::rewritePattern (Pattern *pattern,
8868
+ DeclContext *DC) {
8869
+ auto &solution = Rewriter.solution ;
8870
+
8871
+ // Figure out the pattern type.
8872
+ auto patternTy = solution.getResolvedType (pattern);
8873
+ patternTy = patternTy->reconstituteSugar (/* recursive=*/ false );
8874
+
8875
+ // Coerce the pattern to its appropriate type.
8876
+ TypeResolutionOptions patternOptions (TypeResolverContext::InExpression);
8877
+ patternOptions |= TypeResolutionFlags::OverrideType;
8878
+
8879
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
8880
+ return ::tryRewriteExprPattern (
8881
+ EP, solution, ty, [&](auto target) { return rewriteTarget (target); });
8882
+ };
8883
+
8884
+ auto contextualPattern = ContextualPattern::forRawPattern (pattern, DC);
8885
+ return TypeChecker::coercePatternToType (contextualPattern, patternTy,
8886
+ patternOptions, tryRewritePattern);
8887
+ }
8888
+
8831
8889
// / Apply the given solution to the initialization target.
8832
8890
// /
8833
8891
// / \returns the resulting initialization expression.
8834
8892
static Optional<SyntacticElementTarget>
8835
8893
applySolutionToInitialization (Solution &solution, SyntacticElementTarget target,
8836
- Expr *initializer) {
8894
+ Expr *initializer,
8895
+ RewriteTargetFn rewriteTarget) {
8837
8896
auto wrappedVar = target.getInitializationWrappedVar ();
8838
8897
Type initType;
8839
8898
if (wrappedVar) {
@@ -8898,10 +8957,14 @@ applySolutionToInitialization(Solution &solution, SyntacticElementTarget target,
8898
8957
8899
8958
finalPatternType = finalPatternType->reconstituteSugar (/* recursive =*/ false );
8900
8959
8960
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
8961
+ return ::tryRewriteExprPattern (EP, solution, ty, rewriteTarget);
8962
+ };
8963
+
8901
8964
// Apply the solution to the pattern as well.
8902
8965
auto contextualPattern = target.getContextualPattern ();
8903
8966
if (auto coercedPattern = TypeChecker::coercePatternToType (
8904
- contextualPattern, finalPatternType, options)) {
8967
+ contextualPattern, finalPatternType, options, tryRewritePattern )) {
8905
8968
resultTarget.setPattern (coercedPattern);
8906
8969
} else {
8907
8970
return None;
@@ -9048,10 +9111,15 @@ static Optional<SyntacticElementTarget> applySolutionToForEachStmt(
9048
9111
TypeResolutionOptions options (TypeResolverContext::ForEachStmt);
9049
9112
options |= TypeResolutionFlags::OverrideType;
9050
9113
9114
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9115
+ return ::tryRewriteExprPattern (EP, solution, ty, rewriteTarget);
9116
+ };
9117
+
9051
9118
// Apply the solution to the pattern as well.
9052
9119
auto contextualPattern = target.getContextualPattern ();
9053
9120
auto coercedPattern = TypeChecker::coercePatternToType (
9054
- contextualPattern, forEachStmtInfo.initType , options);
9121
+ contextualPattern, forEachStmtInfo.initType , options,
9122
+ tryRewritePattern);
9055
9123
if (!coercedPattern)
9056
9124
return None;
9057
9125
@@ -9139,7 +9207,8 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
9139
9207
switch (target.getExprContextualTypePurpose ()) {
9140
9208
case CTP_Initialization: {
9141
9209
auto initResultTarget = applySolutionToInitialization (
9142
- solution, target, rewrittenExpr);
9210
+ solution, target, rewrittenExpr,
9211
+ [&](auto target) { return rewriteTarget (target); });
9143
9212
if (!initResultTarget)
9144
9213
return None;
9145
9214
@@ -9230,47 +9299,11 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
9230
9299
ConstraintSystem &cs = solution.getConstraintSystem ();
9231
9300
auto info = *cs.getCaseLabelItemInfo (*caseLabelItem);
9232
9301
9233
- // Figure out the pattern type.
9234
- Type patternType = solution.simplifyType (solution.getType (info.pattern ));
9235
- patternType = patternType->reconstituteSugar (/* recursive=*/ false );
9236
-
9237
- // Check whether this enum element is resolved via ~= application.
9238
- if (auto *enumElement = dyn_cast<EnumElementPattern>(info.pattern )) {
9239
- if (auto target = cs.getTargetFor (enumElement)) {
9240
- auto *EP = target->getExprPattern ();
9241
- auto enumType = solution.getResolvedType (EP);
9242
-
9243
- auto *matchCall = target->getAsExpr ();
9244
-
9245
- auto *result = matchCall->walk (*this );
9246
- if (!result)
9247
- return None;
9248
-
9249
- {
9250
- auto *matchVar = EP->getMatchVar ();
9251
- matchVar->setInterfaceType (enumType->mapTypeOutOfContext ());
9252
- }
9253
-
9254
- EP->setMatchExpr (result);
9255
- EP->setType (enumType);
9256
-
9257
- (*caseLabelItem)->setPattern (EP, /* resolved=*/ true );
9258
- return target;
9259
- }
9260
- }
9261
-
9262
- // Coerce the pattern to its appropriate type.
9263
- TypeResolutionOptions patternOptions (TypeResolverContext::InExpression);
9264
- patternOptions |= TypeResolutionFlags::OverrideType;
9265
- auto contextualPattern =
9266
- ContextualPattern::forRawPattern (info.pattern ,
9267
- target.getDeclContext ());
9268
- if (auto coercedPattern = TypeChecker::coercePatternToType (
9269
- contextualPattern, patternType, patternOptions)) {
9270
- (*caseLabelItem)->setPattern (coercedPattern, /* resolved=*/ true );
9271
- } else {
9302
+ auto pattern = rewritePattern (info.pattern , target.getDeclContext ());
9303
+ if (!pattern)
9272
9304
return None;
9273
- }
9305
+
9306
+ (*caseLabelItem)->setPattern (pattern.get (), /* resolved=*/ true );
9274
9307
9275
9308
// If there is a guard expression, coerce that.
9276
9309
if (auto *guardExpr = info.guardExpr ) {
@@ -9338,8 +9371,13 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
9338
9371
options |= TypeResolutionFlags::OverrideType;
9339
9372
}
9340
9373
9374
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9375
+ return ::tryRewriteExprPattern (
9376
+ EP, solution, ty, [&](auto target) { return rewriteTarget (target); });
9377
+ };
9378
+
9341
9379
if (auto coercedPattern = TypeChecker::coercePatternToType (
9342
- contextualPattern, patternType, options)) {
9380
+ contextualPattern, patternType, options, tryRewritePattern )) {
9343
9381
auto resultTarget = target;
9344
9382
resultTarget.setPattern (coercedPattern);
9345
9383
return resultTarget;
0 commit comments