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