Skip to content

Commit 16f6a2e

Browse files
committed
[TypeChecker] Extract ~= application synthesis into a function
1 parent 5ec5ffc commit 16f6a2e

File tree

2 files changed

+49
-23
lines changed

2 files changed

+49
-23
lines changed

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -849,14 +849,48 @@ bool TypeChecker::typeCheckExprPattern(ExprPattern *EP, DeclContext *DC,
849849
"typecheck-expr-pattern", EP);
850850
PrettyStackTracePattern stackTrace(Context, "type-checking", EP);
851851

852+
auto tildeEqualsApplication =
853+
synthesizeTildeEqualsOperatorApplication(EP, DC, rhsType);
854+
855+
if (!tildeEqualsApplication)
856+
return true;
857+
858+
VarDecl *matchVar;
859+
Expr *matchCall;
860+
861+
std::tie(matchVar, matchCall) = *tildeEqualsApplication;
862+
863+
// Result of `~=` should always be a boolean.
864+
auto contextualTy = Context.getBoolDecl()->getDeclaredInterfaceType();
865+
auto target = SolutionApplicationTarget::forExprPattern(matchCall, DC, EP,
866+
contextualTy);
867+
868+
// Check the expression as a condition.
869+
auto result = typeCheckExpression(target);
870+
if (!result)
871+
return true;
872+
873+
// Save the synthesized $match variable in the pattern.
874+
EP->setMatchVar(matchVar);
875+
// Save the type-checked expression in the pattern.
876+
EP->setMatchExpr(result->getAsExpr());
877+
// Set the type on the pattern.
878+
EP->setType(rhsType);
879+
return false;
880+
}
881+
882+
Optional<std::pair<VarDecl *, BinaryExpr *>>
883+
TypeChecker::synthesizeTildeEqualsOperatorApplication(ExprPattern *EP,
884+
DeclContext *DC,
885+
Type enumType) {
886+
auto &Context = DC->getASTContext();
852887
// Create a 'let' binding to stand in for the RHS value.
853888
auto *matchVar =
854889
new (Context) VarDecl(/*IsStatic*/ false, VarDecl::Introducer::Let,
855890
EP->getLoc(), Context.Id_PatternMatchVar, DC);
856-
matchVar->setInterfaceType(rhsType->mapTypeOutOfContext());
891+
matchVar->setInterfaceType(enumType->mapTypeOutOfContext());
857892

858893
matchVar->setImplicit();
859-
EP->setMatchVar(matchVar);
860894

861895
// Find '~=' operators for the match.
862896
auto matchLookup =
@@ -866,19 +900,19 @@ bool TypeChecker::typeCheckExprPattern(ExprPattern *EP, DeclContext *DC,
866900
auto &diags = DC->getASTContext().Diags;
867901
if (!matchLookup) {
868902
diags.diagnose(EP->getLoc(), diag::no_match_operator);
869-
return true;
903+
return None;
870904
}
871-
905+
872906
SmallVector<ValueDecl*, 4> choices;
873907
for (auto &result : matchLookup) {
874908
choices.push_back(result.getValueDecl());
875909
}
876-
910+
877911
if (choices.empty()) {
878912
diags.diagnose(EP->getLoc(), diag::no_match_operator);
879-
return true;
913+
return None;
880914
}
881-
915+
882916
// Build the 'expr ~= var' expression.
883917
// FIXME: Compound name locations.
884918
auto *matchOp =
@@ -890,24 +924,10 @@ bool TypeChecker::typeCheckExprPattern(ExprPattern *EP, DeclContext *DC,
890924
auto *matchVarRef = new (Context) DeclRefExpr(matchVar,
891925
DeclNameLoc(EP->getEndLoc()),
892926
/*Implicit=*/true);
893-
Expr *matchCall = BinaryExpr::create(Context, EP->getSubExpr(), matchOp,
927+
auto *matchCall = BinaryExpr::create(Context, EP->getSubExpr(), matchOp,
894928
matchVarRef, /*implicit*/ true);
895929

896-
// Result of `~=` should always be a boolean.
897-
auto contextualTy = Context.getBoolDecl()->getDeclaredInterfaceType();
898-
auto target = SolutionApplicationTarget::forExprPattern(matchCall, DC, EP,
899-
contextualTy);
900-
901-
// Check the expression as a condition.
902-
auto result = typeCheckExpression(target);
903-
if (!result)
904-
return true;
905-
906-
// Save the type-checked expression in the pattern.
907-
EP->setMatchExpr(result->getAsExpr());
908-
// Set the type on the pattern.
909-
EP->setType(rhsType);
910-
return false;
930+
return std::make_pair(matchVar, matchCall);
911931
}
912932

913933
static Type replaceArchetypesWithTypeVariables(ConstraintSystem &cs,

lib/Sema/TypeChecker.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,12 @@ Pattern *coercePatternToType(ContextualPattern pattern, Type type,
677677
TypeResolutionOptions options);
678678
bool typeCheckExprPattern(ExprPattern *EP, DeclContext *DC, Type type);
679679

680+
/// Synthesize ~= operator application used to infer enum members
681+
/// in `case` patterns.
682+
Optional<std::pair<VarDecl *, BinaryExpr *>>
683+
synthesizeTildeEqualsOperatorApplication(ExprPattern *EP, DeclContext *DC,
684+
Type enumType);
685+
680686
/// Coerce the specified parameter list of a ClosureExpr to the specified
681687
/// contextual type.
682688
void coerceParameterListToType(ParameterList *P, AnyFunctionType *FN);

0 commit comments

Comments
 (0)