@@ -8703,6 +8703,9 @@ namespace {
8703
8703
return Action::SkipChildren ();
8704
8704
}
8705
8705
8706
+ NullablePtr<Pattern>
8707
+ rewritePattern (Pattern *pattern, DeclContext *DC);
8708
+
8706
8709
// / Rewrite the target, producing a new target.
8707
8710
Optional<SyntacticElementTarget>
8708
8711
rewriteTarget (SyntacticElementTarget target);
@@ -8949,12 +8952,68 @@ static Expr *wrapAsyncLetInitializer(
8949
8952
return resultInit;
8950
8953
}
8951
8954
8955
+ static Pattern *rewriteExprPattern (const SyntacticElementTarget &matchTarget,
8956
+ Type patternTy,
8957
+ RewriteTargetFn rewriteTarget) {
8958
+ auto *EP = matchTarget.getExprPattern ();
8959
+
8960
+ // See if we can simplify to another kind of pattern.
8961
+ if (auto simplified = TypeChecker::trySimplifyExprPattern (EP, patternTy))
8962
+ return simplified.get ();
8963
+
8964
+ auto resultTarget = rewriteTarget (matchTarget);
8965
+ if (!resultTarget)
8966
+ return nullptr ;
8967
+
8968
+ EP->setMatchExpr (resultTarget->getAsExpr ());
8969
+ EP->getMatchVar ()->setInterfaceType (patternTy->mapTypeOutOfContext ());
8970
+ EP->setType (patternTy);
8971
+ return EP;
8972
+ }
8973
+
8974
+ // / Attempt to rewrite either an ExprPattern, or a pattern that was solved as
8975
+ // / an ExprPattern, e.g an EnumElementPattern that could not refer to an enum
8976
+ // / case.
8977
+ static Optional<Pattern *>
8978
+ tryRewriteExprPattern (Pattern *P, Solution &solution, Type patternTy,
8979
+ RewriteTargetFn rewriteTarget) {
8980
+ // See if we have a match expression target.
8981
+ auto matchTarget = solution.getTargetFor (P);
8982
+ if (!matchTarget)
8983
+ return None;
8984
+
8985
+ return rewriteExprPattern (*matchTarget, patternTy, rewriteTarget);
8986
+ }
8987
+
8988
+ NullablePtr<Pattern> ExprWalker::rewritePattern (Pattern *pattern,
8989
+ DeclContext *DC) {
8990
+ auto &solution = Rewriter.solution ;
8991
+
8992
+ // Figure out the pattern type.
8993
+ auto patternTy = solution.getResolvedType (pattern);
8994
+ patternTy = patternTy->reconstituteSugar (/* recursive=*/ false );
8995
+
8996
+ // Coerce the pattern to its appropriate type.
8997
+ TypeResolutionOptions patternOptions (TypeResolverContext::InExpression);
8998
+ patternOptions |= TypeResolutionFlags::OverrideType;
8999
+
9000
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9001
+ return ::tryRewriteExprPattern (
9002
+ EP, solution, ty, [&](auto target) { return rewriteTarget (target); });
9003
+ };
9004
+
9005
+ auto contextualPattern = ContextualPattern::forRawPattern (pattern, DC);
9006
+ return TypeChecker::coercePatternToType (contextualPattern, patternTy,
9007
+ patternOptions, tryRewritePattern);
9008
+ }
9009
+
8952
9010
// / Apply the given solution to the initialization target.
8953
9011
// /
8954
9012
// / \returns the resulting initialization expression.
8955
9013
static Optional<SyntacticElementTarget>
8956
9014
applySolutionToInitialization (Solution &solution, SyntacticElementTarget target,
8957
- Expr *initializer) {
9015
+ Expr *initializer,
9016
+ RewriteTargetFn rewriteTarget) {
8958
9017
auto wrappedVar = target.getInitializationWrappedVar ();
8959
9018
Type initType;
8960
9019
if (wrappedVar) {
@@ -9019,10 +9078,14 @@ applySolutionToInitialization(Solution &solution, SyntacticElementTarget target,
9019
9078
9020
9079
finalPatternType = finalPatternType->reconstituteSugar (/* recursive =*/ false );
9021
9080
9081
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9082
+ return ::tryRewriteExprPattern (EP, solution, ty, rewriteTarget);
9083
+ };
9084
+
9022
9085
// Apply the solution to the pattern as well.
9023
9086
auto contextualPattern = target.getContextualPattern ();
9024
9087
if (auto coercedPattern = TypeChecker::coercePatternToType (
9025
- contextualPattern, finalPatternType, options)) {
9088
+ contextualPattern, finalPatternType, options, tryRewritePattern )) {
9026
9089
resultTarget.setPattern (coercedPattern);
9027
9090
} else {
9028
9091
return None;
@@ -9169,10 +9232,15 @@ static Optional<SyntacticElementTarget> applySolutionToForEachStmt(
9169
9232
TypeResolutionOptions options (TypeResolverContext::ForEachStmt);
9170
9233
options |= TypeResolutionFlags::OverrideType;
9171
9234
9235
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9236
+ return ::tryRewriteExprPattern (EP, solution, ty, rewriteTarget);
9237
+ };
9238
+
9172
9239
// Apply the solution to the pattern as well.
9173
9240
auto contextualPattern = target.getContextualPattern ();
9174
9241
auto coercedPattern = TypeChecker::coercePatternToType (
9175
- contextualPattern, forEachStmtInfo.initType , options);
9242
+ contextualPattern, forEachStmtInfo.initType , options,
9243
+ tryRewritePattern);
9176
9244
if (!coercedPattern)
9177
9245
return None;
9178
9246
@@ -9260,7 +9328,8 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
9260
9328
switch (target.getExprContextualTypePurpose ()) {
9261
9329
case CTP_Initialization: {
9262
9330
auto initResultTarget = applySolutionToInitialization (
9263
- solution, target, rewrittenExpr);
9331
+ solution, target, rewrittenExpr,
9332
+ [&](auto target) { return rewriteTarget (target); });
9264
9333
if (!initResultTarget)
9265
9334
return None;
9266
9335
@@ -9351,47 +9420,11 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
9351
9420
ConstraintSystem &cs = solution.getConstraintSystem ();
9352
9421
auto info = *cs.getCaseLabelItemInfo (*caseLabelItem);
9353
9422
9354
- // Figure out the pattern type.
9355
- Type patternType = solution.simplifyType (solution.getType (info.pattern ));
9356
- patternType = patternType->reconstituteSugar (/* recursive=*/ false );
9357
-
9358
- // Check whether this enum element is resolved via ~= application.
9359
- if (auto *enumElement = dyn_cast<EnumElementPattern>(info.pattern )) {
9360
- if (auto target = cs.getTargetFor (enumElement)) {
9361
- auto *EP = target->getExprPattern ();
9362
- auto enumType = solution.getResolvedType (EP);
9363
-
9364
- auto *matchCall = target->getAsExpr ();
9365
-
9366
- auto *result = matchCall->walk (*this );
9367
- if (!result)
9368
- return None;
9369
-
9370
- {
9371
- auto *matchVar = EP->getMatchVar ();
9372
- matchVar->setInterfaceType (enumType->mapTypeOutOfContext ());
9373
- }
9374
-
9375
- EP->setMatchExpr (result);
9376
- EP->setType (enumType);
9377
-
9378
- (*caseLabelItem)->setPattern (EP, /* resolved=*/ true );
9379
- return target;
9380
- }
9381
- }
9382
-
9383
- // Coerce the pattern to its appropriate type.
9384
- TypeResolutionOptions patternOptions (TypeResolverContext::InExpression);
9385
- patternOptions |= TypeResolutionFlags::OverrideType;
9386
- auto contextualPattern =
9387
- ContextualPattern::forRawPattern (info.pattern ,
9388
- target.getDeclContext ());
9389
- if (auto coercedPattern = TypeChecker::coercePatternToType (
9390
- contextualPattern, patternType, patternOptions)) {
9391
- (*caseLabelItem)->setPattern (coercedPattern, /* resolved=*/ true );
9392
- } else {
9423
+ auto pattern = rewritePattern (info.pattern , target.getDeclContext ());
9424
+ if (!pattern)
9393
9425
return None;
9394
- }
9426
+
9427
+ (*caseLabelItem)->setPattern (pattern.get (), /* resolved=*/ true );
9395
9428
9396
9429
// If there is a guard expression, coerce that.
9397
9430
if (auto *guardExpr = info.guardExpr ) {
@@ -9459,8 +9492,13 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
9459
9492
options |= TypeResolutionFlags::OverrideType;
9460
9493
}
9461
9494
9495
+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9496
+ return ::tryRewriteExprPattern (
9497
+ EP, solution, ty, [&](auto target) { return rewriteTarget (target); });
9498
+ };
9499
+
9462
9500
if (auto coercedPattern = TypeChecker::coercePatternToType (
9463
- contextualPattern, patternType, options)) {
9501
+ contextualPattern, patternType, options, tryRewritePattern )) {
9464
9502
auto resultTarget = target;
9465
9503
resultTarget.setPattern (coercedPattern);
9466
9504
return resultTarget;
0 commit comments