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