Skip to content

Commit be607d1

Browse files
committed
[CS] Introduce performSyntacticDiagnosticsForTarget
Add a function that deals with invoking syntactic diagnostics for all the expressions involved in a SolutionApplicationTarget. Resolves SR-13260 Resolves rdar://65903005
1 parent 1907330 commit be607d1

File tree

4 files changed

+55
-1
lines changed

4 files changed

+55
-1
lines changed

lib/Sema/ConstraintSystem.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5596,6 +5596,11 @@ bool isKnownKeyPathDecl(ASTContext &ctx, ValueDecl *decl);
55965596
/// statements that could produce non-void result.
55975597
bool hasExplicitResult(ClosureExpr *closure);
55985598

5599+
/// Emit diagnostics for syntactic restrictions within a given solution
5600+
/// application target.
5601+
void performSyntacticDiagnosticsForTarget(
5602+
const SolutionApplicationTarget &target, bool isExprStmt);
5603+
55995604
} // end namespace constraints
56005605

56015606
template<typename ...Args>

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1995,6 +1995,33 @@ bool GenericRequirementsCheckListener::diagnoseUnsatisfiedRequirement(
19951995
return false;
19961996
}
19971997

1998+
void constraints::performSyntacticDiagnosticsForTarget(
1999+
const SolutionApplicationTarget &target, bool isExprStmt) {
2000+
auto *dc = target.getDeclContext();
2001+
switch (target.kind) {
2002+
case SolutionApplicationTarget::Kind::expression: {
2003+
// First emit diagnostics for the main expression.
2004+
performSyntacticExprDiagnostics(target.getAsExpr(), dc, isExprStmt);
2005+
2006+
// If this is a for-in statement, we also need to check the where clause if
2007+
// present.
2008+
if (target.isForEachStmt()) {
2009+
if (auto *whereExpr = target.getForEachStmtInfo().whereExpr)
2010+
performSyntacticExprDiagnostics(whereExpr, dc, /*isExprStmt*/ false);
2011+
}
2012+
return;
2013+
}
2014+
case SolutionApplicationTarget::Kind::function:
2015+
case SolutionApplicationTarget::Kind::stmtCondition:
2016+
case SolutionApplicationTarget::Kind::caseLabelItem:
2017+
case SolutionApplicationTarget::Kind::patternBinding:
2018+
case SolutionApplicationTarget::Kind::uninitializedWrappedVar:
2019+
// Nothing to do for these.
2020+
return;
2021+
}
2022+
llvm_unreachable("Unhandled case in switch!");
2023+
}
2024+
19982025
#pragma mark High-level entry points
19992026
Type TypeChecker::typeCheckExpression(Expr *&expr, DeclContext *dc,
20002027
Type convertType,
@@ -2096,7 +2123,7 @@ TypeChecker::typeCheckExpression(
20962123
// expression now.
20972124
if (!cs.shouldSuppressDiagnostics()) {
20982125
bool isExprStmt = options.contains(TypeCheckExprFlags::IsExprStmt);
2099-
performSyntacticExprDiagnostics(result, dc, isExprStmt);
2126+
performSyntacticDiagnosticsForTarget(*resultTarget, isExprStmt);
21002127
}
21012128

21022129
resultTarget->setExpr(result);

test/Constraints/availability.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,12 @@ func test_contextual_member_with_availability() {
3434

3535
_ = Test(.foo) // Ok
3636
}
37+
38+
@available(*, unavailable)
39+
func unavailableFunction(_ x: Int) -> Bool { true } // expected-note {{'unavailableFunction' has been explicitly marked unavailable here}}
40+
41+
// SR-13260: Availability checking not working in the where clause of a for
42+
// loop.
43+
func sr13260(_ arr: [Int]) {
44+
for x in arr where unavailableFunction(x) {} // expected-error {{'unavailableFunction' is unavailable}}
45+
}

test/decl/var/function_builders_availability.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,16 @@ tuplify(true) { x in
8484
Option.best // expected-error{{'best' is only available in macOS 10.15.4 or newer}}
8585
// expected-note@-1{{add 'if #available' version check}}
8686
}
87+
88+
@available(*, unavailable)
89+
func unavailableFunc(_ x: Bool) -> Bool {} // expected-note {{'unavailableFunc' has been explicitly marked unavailable here}}
90+
91+
// SR-13260: Availability checking not working in the where clause of a for
92+
// loop.
93+
tuplify(true) { b in
94+
for x in [b] where unavailableFunc(x) { // expected-error {{'unavailableFunc' is unavailable}}
95+
""
96+
Option.best // expected-error{{'best' is only available in macOS 10.15.4 or newer}}
97+
// expected-note@-1{{add 'if #available' version check}}
98+
}
99+
}

0 commit comments

Comments
 (0)