@@ -8554,6 +8554,9 @@ namespace {
8554
8554
return Action::SkipChildren ();
8555
8555
}
8556
8556
8557
+ NullablePtr<Pattern>
8558
+ rewritePattern (Pattern *pattern, DeclContext *DC);
8559
+
8557
8560
// / Rewrite the target, producing a new target.
8558
8561
Optional<SolutionApplicationTarget>
8559
8562
rewriteTarget (SolutionApplicationTarget target);
@@ -8800,12 +8803,68 @@ static Expr *wrapAsyncLetInitializer(
8800
8803
return resultInit;
8801
8804
}
8802
8805
8806
+ static Pattern *rewriteExprPattern (SolutionApplicationTarget matchTarget,
8807
+ Type patternTy,
8808
+ RewriteTargetFn rewriteTarget) {
8809
+ auto *EP = matchTarget.getExprPattern ();
8810
+
8811
+ // See if we can simplify to another kind of pattern.
8812
+ if (auto simplified = TypeChecker::trySimplifyExprPattern (EP, patternTy))
8813
+ return simplified.get ();
8814
+
8815
+ auto resultTarget = rewriteTarget (matchTarget);
8816
+ if (!resultTarget)
8817
+ return nullptr ;
8818
+
8819
+ matchTarget = *resultTarget;
8820
+
8821
+ EP->setMatchExpr (matchTarget.getAsExpr ());
8822
+ EP->getMatchVar ()->setInterfaceType (patternTy->mapTypeOutOfContext ());
8823
+ EP->setType (patternTy);
8824
+ return EP;
8825
+ }
8826
+
8827
+ static Optional<Pattern *>
8828
+ tryRewriteExprPattern (Pattern *P, Solution &solution, Type patternTy,
8829
+ RewriteTargetFn rewriteTarget) {
8830
+ // We may either have an ExprPattern, or a pattern that was mapped to an
8831
+ // ExprPattern, such as an EnumElementPattern.
8832
+ auto &cs = solution.getConstraintSystem ();
8833
+ auto matchTarget = cs.getSolutionApplicationTarget (P);
8834
+ if (!matchTarget)
8835
+ return None;
8836
+
8837
+ return rewriteExprPattern (*matchTarget, patternTy, rewriteTarget);
8838
+ }
8839
+
8840
+ NullablePtr<Pattern> ExprWalker::rewritePattern (Pattern *pattern,
8841
+ DeclContext *DC) {
8842
+ auto &solution = Rewriter.solution ;
8843
+
8844
+ // Figure out the pattern type.
8845
+ auto patternTy = solution.getResolvedType (pattern);
8846
+ patternTy = patternTy->reconstituteSugar (/* recursive=*/ false );
8847
+
8848
+ // Coerce the pattern to its appropriate type.
8849
+ TypeResolutionOptions patternOptions (TypeResolverContext::InExpression);
8850
+ patternOptions |= TypeResolutionFlags::OverrideType;
8851
+
8852
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
8853
+ return ::tryRewriteExprPattern (
8854
+ EP, solution, ty, [&](auto target) { return rewriteTarget (target); });
8855
+ };
8856
+
8857
+ auto contextualPattern = ContextualPattern::forRawPattern (pattern, DC);
8858
+ return TypeChecker::coercePatternToType (contextualPattern, patternTy,
8859
+ patternOptions, tryRewritePattern);
8860
+ }
8861
+
8803
8862
// / Apply the given solution to the initialization target.
8804
8863
// /
8805
8864
// / \returns the resulting initialization expression.
8806
8865
static Optional<SolutionApplicationTarget> applySolutionToInitialization (
8807
- Solution &solution, SolutionApplicationTarget target,
8808
- Expr *initializer ) {
8866
+ Solution &solution, SolutionApplicationTarget target, Expr *initializer,
8867
+ RewriteTargetFn rewriteTarget ) {
8809
8868
auto wrappedVar = target.getInitializationWrappedVar ();
8810
8869
Type initType;
8811
8870
if (wrappedVar) {
@@ -8870,10 +8929,15 @@ static Optional<SolutionApplicationTarget> applySolutionToInitialization(
8870
8929
8871
8930
finalPatternType = finalPatternType->reconstituteSugar (/* recursive =*/ false );
8872
8931
8932
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
8933
+ return ::tryRewriteExprPattern (
8934
+ EP, solution, ty, [&](auto target) { return rewriteTarget (target); });
8935
+ };
8936
+
8873
8937
// Apply the solution to the pattern as well.
8874
8938
auto contextualPattern = target.getContextualPattern ();
8875
8939
if (auto coercedPattern = TypeChecker::coercePatternToType (
8876
- contextualPattern, finalPatternType, options)) {
8940
+ contextualPattern, finalPatternType, options, tryRewritePattern )) {
8877
8941
resultTarget.setPattern (coercedPattern);
8878
8942
} else {
8879
8943
return None;
@@ -9023,10 +9087,16 @@ static Optional<SolutionApplicationTarget> applySolutionToForEachStmt(
9023
9087
TypeResolutionOptions options (TypeResolverContext::ForEachStmt);
9024
9088
options |= TypeResolutionFlags::OverrideType;
9025
9089
9090
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9091
+ return ::tryRewriteExprPattern (
9092
+ EP, solution, ty, [&](auto target) { return rewriteTarget (target); });
9093
+ };
9094
+
9026
9095
// Apply the solution to the pattern as well.
9027
9096
auto contextualPattern = target.getContextualPattern ();
9028
9097
auto coercedPattern = TypeChecker::coercePatternToType (
9029
- contextualPattern, forEachStmtInfo.initType , options);
9098
+ contextualPattern, forEachStmtInfo.initType , options,
9099
+ tryRewritePattern);
9030
9100
if (!coercedPattern)
9031
9101
return None;
9032
9102
@@ -9114,7 +9184,8 @@ ExprWalker::rewriteTarget(SolutionApplicationTarget target) {
9114
9184
switch (target.getExprContextualTypePurpose ()) {
9115
9185
case CTP_Initialization: {
9116
9186
auto initResultTarget = applySolutionToInitialization (
9117
- solution, target, rewrittenExpr);
9187
+ solution, target, rewrittenExpr,
9188
+ [&](auto target) { return rewriteTarget (target); });
9118
9189
if (!initResultTarget)
9119
9190
return None;
9120
9191
@@ -9205,47 +9276,11 @@ ExprWalker::rewriteTarget(SolutionApplicationTarget target) {
9205
9276
ConstraintSystem &cs = solution.getConstraintSystem ();
9206
9277
auto info = *cs.getCaseLabelItemInfo (*caseLabelItem);
9207
9278
9208
- // Figure out the pattern type.
9209
- Type patternType = solution.simplifyType (solution.getType (info.pattern ));
9210
- patternType = patternType->reconstituteSugar (/* recursive=*/ false );
9211
-
9212
- // Check whether this enum element is resolved via ~= application.
9213
- if (auto *enumElement = dyn_cast<EnumElementPattern>(info.pattern )) {
9214
- if (auto target = cs.getSolutionApplicationTarget (enumElement)) {
9215
- auto *EP = target->getExprPattern ();
9216
- auto enumType = solution.getResolvedType (EP);
9217
-
9218
- auto *matchCall = target->getAsExpr ();
9219
-
9220
- auto *result = matchCall->walk (*this );
9221
- if (!result)
9222
- return None;
9223
-
9224
- {
9225
- auto *matchVar = EP->getMatchVar ();
9226
- matchVar->setInterfaceType (enumType->mapTypeOutOfContext ());
9227
- }
9228
-
9229
- EP->setMatchExpr (result);
9230
- EP->setType (enumType);
9231
-
9232
- (*caseLabelItem)->setPattern (EP, /* resolved=*/ true );
9233
- return target;
9234
- }
9235
- }
9236
-
9237
- // Coerce the pattern to its appropriate type.
9238
- TypeResolutionOptions patternOptions (TypeResolverContext::InExpression);
9239
- patternOptions |= TypeResolutionFlags::OverrideType;
9240
- auto contextualPattern =
9241
- ContextualPattern::forRawPattern (info.pattern ,
9242
- target.getDeclContext ());
9243
- if (auto coercedPattern = TypeChecker::coercePatternToType (
9244
- contextualPattern, patternType, patternOptions)) {
9245
- (*caseLabelItem)->setPattern (coercedPattern, /* resolved=*/ true );
9246
- } else {
9279
+ auto pattern = rewritePattern (info.pattern , target.getDeclContext ());
9280
+ if (!pattern)
9247
9281
return None;
9248
- }
9282
+
9283
+ (*caseLabelItem)->setPattern (pattern.get (), /* resolved=*/ true );
9249
9284
9250
9285
// If there is a guard expression, coerce that.
9251
9286
if (auto *guardExpr = info.guardExpr ) {
@@ -9314,8 +9349,13 @@ ExprWalker::rewriteTarget(SolutionApplicationTarget target) {
9314
9349
options |= TypeResolutionFlags::OverrideType;
9315
9350
}
9316
9351
9352
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9353
+ return ::tryRewriteExprPattern (
9354
+ EP, solution, ty, [&](auto target) { return rewriteTarget (target); });
9355
+ };
9356
+
9317
9357
if (auto coercedPattern = TypeChecker::coercePatternToType (
9318
- contextualPattern, patternType, options)) {
9358
+ contextualPattern, patternType, options, tryRewritePattern )) {
9319
9359
auto resultTarget = target;
9320
9360
resultTarget.setPattern (coercedPattern);
9321
9361
return resultTarget;
0 commit comments