@@ -8705,6 +8705,9 @@ namespace {
87058705 return Action::SkipChildren ();
87068706 }
87078707
8708+ NullablePtr<Pattern>
8709+ rewritePattern (Pattern *pattern, DeclContext *DC);
8710+
87088711 // / Rewrite the target, producing a new target.
87098712 Optional<SyntacticElementTarget>
87108713 rewriteTarget (SyntacticElementTarget target);
@@ -8951,12 +8954,68 @@ static Expr *wrapAsyncLetInitializer(
89518954 return resultInit;
89528955}
89538956
8957+ static Pattern *rewriteExprPattern (const SyntacticElementTarget &matchTarget,
8958+ Type patternTy,
8959+ RewriteTargetFn rewriteTarget) {
8960+ auto *EP = matchTarget.getExprPattern ();
8961+
8962+ // See if we can simplify to another kind of pattern.
8963+ if (auto simplified = TypeChecker::trySimplifyExprPattern (EP, patternTy))
8964+ return simplified.get ();
8965+
8966+ auto resultTarget = rewriteTarget (matchTarget);
8967+ if (!resultTarget)
8968+ return nullptr ;
8969+
8970+ EP->setMatchExpr (resultTarget->getAsExpr ());
8971+ EP->getMatchVar ()->setInterfaceType (patternTy->mapTypeOutOfContext ());
8972+ EP->setType (patternTy);
8973+ return EP;
8974+ }
8975+
8976+ // / Attempt to rewrite either an ExprPattern, or a pattern that was solved as
8977+ // / an ExprPattern, e.g an EnumElementPattern that could not refer to an enum
8978+ // / case.
8979+ static Optional<Pattern *>
8980+ tryRewriteExprPattern (Pattern *P, Solution &solution, Type patternTy,
8981+ RewriteTargetFn rewriteTarget) {
8982+ // See if we have a match expression target.
8983+ auto matchTarget = solution.getTargetFor (P);
8984+ if (!matchTarget)
8985+ return None;
8986+
8987+ return rewriteExprPattern (*matchTarget, patternTy, rewriteTarget);
8988+ }
8989+
8990+ NullablePtr<Pattern> ExprWalker::rewritePattern (Pattern *pattern,
8991+ DeclContext *DC) {
8992+ auto &solution = Rewriter.solution ;
8993+
8994+ // Figure out the pattern type.
8995+ auto patternTy = solution.getResolvedType (pattern);
8996+ patternTy = patternTy->reconstituteSugar (/* recursive=*/ false );
8997+
8998+ // Coerce the pattern to its appropriate type.
8999+ TypeResolutionOptions patternOptions (TypeResolverContext::InExpression);
9000+ patternOptions |= TypeResolutionFlags::OverrideType;
9001+
9002+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9003+ return ::tryRewriteExprPattern (
9004+ EP, solution, ty, [&](auto target) { return rewriteTarget (target); });
9005+ };
9006+
9007+ auto contextualPattern = ContextualPattern::forRawPattern (pattern, DC);
9008+ return TypeChecker::coercePatternToType (contextualPattern, patternTy,
9009+ patternOptions, tryRewritePattern);
9010+ }
9011+
89549012// / Apply the given solution to the initialization target.
89559013// /
89569014// / \returns the resulting initialization expression.
89579015static Optional<SyntacticElementTarget>
89589016applySolutionToInitialization (Solution &solution, SyntacticElementTarget target,
8959- Expr *initializer) {
9017+ Expr *initializer,
9018+ RewriteTargetFn rewriteTarget) {
89609019 auto wrappedVar = target.getInitializationWrappedVar ();
89619020 Type initType;
89629021 if (wrappedVar) {
@@ -9021,10 +9080,14 @@ applySolutionToInitialization(Solution &solution, SyntacticElementTarget target,
90219080
90229081 finalPatternType = finalPatternType->reconstituteSugar (/* recursive =*/ false );
90239082
9083+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9084+ return ::tryRewriteExprPattern (EP, solution, ty, rewriteTarget);
9085+ };
9086+
90249087 // Apply the solution to the pattern as well.
90259088 auto contextualPattern = target.getContextualPattern ();
90269089 if (auto coercedPattern = TypeChecker::coercePatternToType (
9027- contextualPattern, finalPatternType, options)) {
9090+ contextualPattern, finalPatternType, options, tryRewritePattern )) {
90289091 resultTarget.setPattern (coercedPattern);
90299092 } else {
90309093 return None;
@@ -9171,10 +9234,15 @@ static Optional<SyntacticElementTarget> applySolutionToForEachStmt(
91719234 TypeResolutionOptions options (TypeResolverContext::ForEachStmt);
91729235 options |= TypeResolutionFlags::OverrideType;
91739236
9237+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9238+ return ::tryRewriteExprPattern (EP, solution, ty, rewriteTarget);
9239+ };
9240+
91749241 // Apply the solution to the pattern as well.
91759242 auto contextualPattern = target.getContextualPattern ();
91769243 auto coercedPattern = TypeChecker::coercePatternToType (
9177- contextualPattern, forEachStmtInfo.initType , options);
9244+ contextualPattern, forEachStmtInfo.initType , options,
9245+ tryRewritePattern);
91789246 if (!coercedPattern)
91799247 return None;
91809248
@@ -9262,7 +9330,8 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
92629330 switch (target.getExprContextualTypePurpose ()) {
92639331 case CTP_Initialization: {
92649332 auto initResultTarget = applySolutionToInitialization (
9265- solution, target, rewrittenExpr);
9333+ solution, target, rewrittenExpr,
9334+ [&](auto target) { return rewriteTarget (target); });
92669335 if (!initResultTarget)
92679336 return None;
92689337
@@ -9353,47 +9422,11 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
93539422 ConstraintSystem &cs = solution.getConstraintSystem ();
93549423 auto info = *cs.getCaseLabelItemInfo (*caseLabelItem);
93559424
9356- // Figure out the pattern type.
9357- Type patternType = solution.simplifyType (solution.getType (info.pattern ));
9358- patternType = patternType->reconstituteSugar (/* recursive=*/ false );
9359-
9360- // Check whether this enum element is resolved via ~= application.
9361- if (auto *enumElement = dyn_cast<EnumElementPattern>(info.pattern )) {
9362- if (auto target = cs.getTargetFor (enumElement)) {
9363- auto *EP = target->getExprPattern ();
9364- auto enumType = solution.getResolvedType (EP);
9365-
9366- auto *matchCall = target->getAsExpr ();
9367-
9368- auto *result = matchCall->walk (*this );
9369- if (!result)
9370- return None;
9371-
9372- {
9373- auto *matchVar = EP->getMatchVar ();
9374- matchVar->setInterfaceType (enumType->mapTypeOutOfContext ());
9375- }
9376-
9377- EP->setMatchExpr (result);
9378- EP->setType (enumType);
9379-
9380- (*caseLabelItem)->setPattern (EP, /* resolved=*/ true );
9381- return target;
9382- }
9383- }
9384-
9385- // Coerce the pattern to its appropriate type.
9386- TypeResolutionOptions patternOptions (TypeResolverContext::InExpression);
9387- patternOptions |= TypeResolutionFlags::OverrideType;
9388- auto contextualPattern =
9389- ContextualPattern::forRawPattern (info.pattern ,
9390- target.getDeclContext ());
9391- if (auto coercedPattern = TypeChecker::coercePatternToType (
9392- contextualPattern, patternType, patternOptions)) {
9393- (*caseLabelItem)->setPattern (coercedPattern, /* resolved=*/ true );
9394- } else {
9425+ auto pattern = rewritePattern (info.pattern , target.getDeclContext ());
9426+ if (!pattern)
93959427 return None;
9396- }
9428+
9429+ (*caseLabelItem)->setPattern (pattern.get (), /* resolved=*/ true );
93979430
93989431 // If there is a guard expression, coerce that.
93999432 if (auto *guardExpr = info.guardExpr ) {
@@ -9461,8 +9494,13 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
94619494 options |= TypeResolutionFlags::OverrideType;
94629495 }
94639496
9497+ auto tryRewritePattern = [&](Pattern *EP, Type ty) {
9498+ return ::tryRewriteExprPattern (
9499+ EP, solution, ty, [&](auto target) { return rewriteTarget (target); });
9500+ };
9501+
94649502 if (auto coercedPattern = TypeChecker::coercePatternToType (
9465- contextualPattern, patternType, options)) {
9503+ contextualPattern, patternType, options, tryRewritePattern )) {
94669504 auto resultTarget = target;
94679505 resultTarget.setPattern (coercedPattern);
94689506 return resultTarget;
0 commit comments