From ae756d023566ea4ee3b4fc90fc748a829a922f91 Mon Sep 17 00:00:00 2001 From: Hamish Knight Date: Tue, 14 Mar 2023 11:56:01 +0000 Subject: [PATCH 1/3] [CS] NFC: Add a couple of parameters to `createConjunction` Allow callers to customize the isolation and referenced vars. --- lib/Sema/CSSyntacticElement.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/Sema/CSSyntacticElement.cpp b/lib/Sema/CSSyntacticElement.cpp index d0d30de7901e3..1d47876959cc6 100644 --- a/lib/Sema/CSSyntacticElement.cpp +++ b/lib/Sema/CSSyntacticElement.cpp @@ -306,11 +306,12 @@ using ElementInfo = std::tuple elements, - ConstraintLocator *locator) { - bool isIsolated = false; - + ConstraintLocator *locator, + bool isIsolated = false, + ArrayRef extraTypeVars = {}) { SmallVector constraints; SmallVector referencedVars; + referencedVars.append(extraTypeVars.begin(), extraTypeVars.end()); if (locator->directlyAt()) { auto *closure = castToExpr(locator->getAnchor()); From c77caf2c72db6a3ff2fe9bc0f2276d3f33cafec4 Mon Sep 17 00:00:00 2001 From: Hamish Knight Date: Tue, 14 Mar 2023 11:56:01 +0000 Subject: [PATCH 2/3] [CS] NFC: Simplify SyntacticElementTarget construction for ExprPattern --- include/swift/Sema/SyntacticElementTarget.h | 14 ++------------ lib/Sema/CSSimplify.cpp | 6 +----- lib/Sema/SyntacticElementTarget.cpp | 12 ++++++++++++ lib/Sema/TypeCheckConstraints.cpp | 9 ++------- 4 files changed, 17 insertions(+), 24 deletions(-) diff --git a/include/swift/Sema/SyntacticElementTarget.h b/include/swift/Sema/SyntacticElementTarget.h index 39ec72455dcd9..b742bcc825533 100644 --- a/include/swift/Sema/SyntacticElementTarget.h +++ b/include/swift/Sema/SyntacticElementTarget.h @@ -190,13 +190,6 @@ class SyntacticElementTarget { ConstraintLocator *convertTypeLocator, bool isDiscarded); - SyntacticElementTarget(Expr *expr, DeclContext *dc, ExprPattern *pattern, - Type patternType) - : SyntacticElementTarget(expr, dc, CTP_ExprPattern, patternType, - /*isDiscarded=*/false) { - setPattern(pattern); - } - SyntacticElementTarget(ClosureExpr *closure, Type convertType) { kind = Kind::closure; this->closure.closure = closure; @@ -296,11 +289,8 @@ class SyntacticElementTarget { forPropertyWrapperInitializer(VarDecl *wrappedVar, DeclContext *dc, Expr *initializer); - static SyntacticElementTarget forExprPattern(Expr *expr, DeclContext *dc, - ExprPattern *pattern, - Type patternTy) { - return {expr, dc, pattern, patternTy}; - } + /// Form a target for the match expression of an ExprPattern. + static SyntacticElementTarget forExprPattern(ExprPattern *pattern); /// This is useful for code completion. ASTNode getAsASTNode() const { diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 7babeb38f8de1..705632a9fc4de 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -9957,17 +9957,13 @@ static bool inferEnumMemberThroughTildeEqualsOperator( if (!pattern->hasUnresolvedOriginalExpr()) return true; - auto *DC = pattern->getDeclContext(); auto &ctx = cs.getASTContext(); // Retrieve a corresponding ExprPattern which we can solve with ~=. auto *EP = llvm::cantFail(ctx.evaluator(EnumElementExprPatternRequest{pattern})); - // result of ~= operator is always a `Bool`. - auto *matchCall = EP->getMatchExpr(); - auto target = SyntacticElementTarget::forExprPattern( - matchCall, DC, EP, ctx.getBoolDecl()->getDeclaredInterfaceType()); + auto target = SyntacticElementTarget::forExprPattern(EP); DiagnosticTransaction diagnostics(ctx.Diags); { diff --git a/lib/Sema/SyntacticElementTarget.cpp b/lib/Sema/SyntacticElementTarget.cpp index a35dbc0a63d9c..a4ddbba2e0e2e 100644 --- a/lib/Sema/SyntacticElementTarget.cpp +++ b/lib/Sema/SyntacticElementTarget.cpp @@ -202,6 +202,18 @@ SyntacticElementTarget SyntacticElementTarget::forPropertyWrapperInitializer( return target; } +SyntacticElementTarget +SyntacticElementTarget::forExprPattern(ExprPattern *pattern) { + auto *DC = pattern->getDeclContext(); + auto &ctx = DC->getASTContext(); + + // Result of ~= operator is always a `Bool`. + SyntacticElementTarget target(pattern->getMatchExpr(), DC, CTP_ExprPattern, + ctx.getBoolType(), /*isDiscarded*/ false); + target.setPattern(pattern); + return target; +} + ContextualPattern SyntacticElementTarget::getContextualPattern() const { if (kind == Kind::uninitializedVar) { assert(patternBinding); diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp index 552d76b59269b..680e55f17764b 100644 --- a/lib/Sema/TypeCheckConstraints.cpp +++ b/lib/Sema/TypeCheckConstraints.cpp @@ -919,7 +919,7 @@ bool TypeChecker::typeCheckCondition(Expr *&expr, DeclContext *dc) { return !resultTy; } -/// Find the '~=` operator that can compare an expression inside a pattern to a +/// Find the `~=` operator that can compare an expression inside a pattern to a /// value of a given type. bool TypeChecker::typeCheckExprPattern(ExprPattern *EP, DeclContext *DC, Type rhsType) { @@ -930,13 +930,8 @@ bool TypeChecker::typeCheckExprPattern(ExprPattern *EP, DeclContext *DC, EP->getMatchVar()->setInterfaceType(rhsType->mapTypeOutOfContext()); - // Result of `~=` should always be a boolean. - auto *matchCall = EP->getMatchExpr(); - auto contextualTy = Context.getBoolDecl()->getDeclaredInterfaceType(); - auto target = - SyntacticElementTarget::forExprPattern(matchCall, DC, EP, contextualTy); - // Check the expression as a condition. + auto target = SyntacticElementTarget::forExprPattern(EP); auto result = typeCheckExpression(target); if (!result) return true; From c44675ca462f8ea1daf10f4a6ea2bc9a25557cc1 Mon Sep 17 00:00:00 2001 From: Hamish Knight Date: Tue, 14 Mar 2023 11:56:01 +0000 Subject: [PATCH 3/3] [CS] Add null check for the pattern in SyntacticElementTarget::getSourceRange For an external property wrapper, there may not be a pattern here. I believe this should only be hit during `-debug-constraints` or if there's a too complex error (which I'm not sure is possible to produce in this case), so no test. --- include/swift/Sema/SyntacticElementTarget.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/include/swift/Sema/SyntacticElementTarget.h b/include/swift/Sema/SyntacticElementTarget.h index b742bcc825533..eab8edefe9ae0 100644 --- a/include/swift/Sema/SyntacticElementTarget.h +++ b/include/swift/Sema/SyntacticElementTarget.h @@ -771,11 +771,13 @@ class SyntacticElementTarget { // For an initialization, include the pattern in the range too. if (isForInitialization()) { - if (auto patternRange = getInitializationPattern()->getSourceRange()) { - if (range.isInvalid()) { - range = patternRange; - } else { - range.widen(patternRange); + if (auto *pattern = getInitializationPattern()) { + if (auto patternRange = pattern->getSourceRange()) { + if (range.isInvalid()) { + range = patternRange; + } else { + range.widen(patternRange); + } } } }