Skip to content

Commit 8729801

Browse files
committed
Sema: Store an 'invalid' bit in PoundHasSymbolInfo to avoid repeated if #_hasSymbol diagnostics.
1 parent 034e53a commit 8729801

File tree

5 files changed

+27
-6
lines changed

5 files changed

+27
-6
lines changed

include/swift/AST/Stmt.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,14 +398,15 @@ class alignas(8) PoundAvailableInfo final :
398398
class PoundHasSymbolInfo final : public ASTAllocated<PoundHasSymbolInfo> {
399399
Expr *SymbolExpr;
400400
ConcreteDeclRef ReferencedDecl;
401+
bool Invalid;
401402

402403
SourceLoc PoundLoc;
403404
SourceLoc LParenLoc;
404405
SourceLoc RParenLoc;
405406

406407
PoundHasSymbolInfo(SourceLoc PoundLoc, SourceLoc LParenLoc, Expr *SymbolExpr,
407408
SourceLoc RParenLoc)
408-
: SymbolExpr(SymbolExpr), ReferencedDecl(), PoundLoc(PoundLoc),
409+
: SymbolExpr(SymbolExpr), ReferencedDecl(), Invalid(), PoundLoc(PoundLoc),
409410
LParenLoc(LParenLoc), RParenLoc(RParenLoc){};
410411

411412
public:
@@ -419,6 +420,10 @@ class PoundHasSymbolInfo final : public ASTAllocated<PoundHasSymbolInfo> {
419420
ConcreteDeclRef getReferencedDecl() { return ReferencedDecl; }
420421
void setReferencedDecl(ConcreteDeclRef CDR) { ReferencedDecl = CDR; }
421422

423+
/// Returns true if the referenced decl has been diagnosed as invalid.
424+
bool isInvalid() const { return Invalid; }
425+
void setInvalid() { Invalid = true; }
426+
422427
SourceLoc getLParenLoc() const { return LParenLoc; }
423428
SourceLoc getRParenLoc() const { return RParenLoc; }
424429
SourceLoc getStartLoc() const { return PoundLoc; }

lib/Sema/CSApply.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8927,12 +8927,14 @@ ExprWalker::rewriteTarget(SolutionApplicationTarget target) {
89278927

89288928
case StmtConditionElement::CK_HasSymbol: {
89298929
ConstraintSystem &cs = solution.getConstraintSystem();
8930+
auto info = condElement.getHasSymbolInfo();
89308931
auto target = *cs.getSolutionApplicationTarget(&condElement);
89318932
auto resolvedTarget = rewriteTarget(target);
8932-
if (!resolvedTarget)
8933+
if (!resolvedTarget) {
8934+
info->setInvalid();
89338935
return None;
8936+
}
89348937

8935-
auto info = condElement.getHasSymbolInfo();
89368938
auto rewrittenExpr = resolvedTarget->getAsExpr();
89378939
info->setSymbolExpr(rewrittenExpr);
89388940
info->setReferencedDecl(

lib/Sema/MiscDiagnostics.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4319,6 +4319,9 @@ static void checkLabeledStmtConditions(ASTContext &ctx,
43194319

43204320
case StmtConditionElement::CK_HasSymbol: {
43214321
auto info = elt.getHasSymbolInfo();
4322+
if (info->isInvalid())
4323+
break;
4324+
43224325
auto symbolExpr = info->getSymbolExpr();
43234326
if (!symbolExpr)
43244327
break;
@@ -4334,11 +4337,13 @@ static void checkLabeledStmtConditions(ASTContext &ctx,
43344337
ctx.Diags.diagnose(symbolExpr->getLoc(),
43354338
diag::has_symbol_decl_must_be_weak,
43364339
decl->getDescriptiveKind(), decl->getName());
4340+
info->setInvalid();
43374341
}
43384342
} else {
43394343
// Diagnose because we weren't able to interpret the expression as one
43404344
// that uniquely identifies a single declaration.
43414345
ctx.Diags.diagnose(symbolExpr->getLoc(), diag::has_symbol_invalid_expr);
4346+
info->setInvalid();
43424347
}
43434348
break;
43444349
}

lib/Sema/TypeCheckStmt.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -504,10 +504,13 @@ bool TypeChecker::typeCheckStmtConditionElement(StmtConditionElement &elt,
504504
auto exprTy = TypeChecker::typeCheckExpression(E, dc);
505505
Info->setSymbolExpr(E);
506506

507-
if (exprTy)
508-
Info->setReferencedDecl(getReferencedDeclForHasSymbolCondition(E));
507+
if (!exprTy) {
508+
Info->setInvalid();
509+
return true;
510+
}
509511

510-
return !exprTy;
512+
Info->setReferencedDecl(getReferencedDeclForHasSymbolCondition(E));
513+
return false;
511514
}
512515

513516
if (auto E = elt.getBooleanOrNull()) {

test/Sema/has_symbol.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/has_symbol_helper.swiftmodule -parse-as-library %S/Inputs/has_symbol_helper.swift -enable-library-evolution
33
// RUN: %target-typecheck-verify-swift -disable-availability-checking -I %t
4+
// RUN: %target-typecheck-verify-swift -disable-availability-checking -I %t -enable-experimental-feature ResultBuilderASTTransform
45

56
// UNSUPPORTED: OS=windows-msvc
67

@@ -161,4 +162,9 @@ struct MyView {
161162
if #_hasSymbol(localFunc) { image } // expected-warning {{global function 'localFunc()' is not a weakly linked declaration}}
162163
else { image }
163164
}
165+
166+
@ViewBuilder var noArgFuncView: some View {
167+
if #_hasSymbol(noArgFunc()) { image } // expected-error {{#_hasSymbol condition must refer to a declaration}}
168+
else { image }
169+
}
164170
}

0 commit comments

Comments
 (0)