Skip to content

Commit 5b8dfc7

Browse files
committed
[CS] Emit fallback diagnostic if needed for IgnoreInvalidASTNode
If no other error has been emitted, make sure we emit a fallback diagnostic rather than crashing in the ASTVerifier or SILGen.
1 parent 79e8a6c commit 5b8dfc7

File tree

7 files changed

+27
-8
lines changed

7 files changed

+27
-8
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5736,7 +5736,7 @@ class ConstraintSystem {
57365736

57375737
/// If we aren't certain that we've emitted a diagnostic, emit a fallback
57385738
/// diagnostic.
5739-
void maybeProduceFallbackDiagnostic(SyntacticElementTarget target) const;
5739+
void maybeProduceFallbackDiagnostic(SourceLoc loc) const;
57405740

57415741
/// Check whether given AST node represents an argument of an application
57425742
/// of some sort (call, operator invocation, subscript etc.)

lib/Sema/CSApply.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10021,7 +10021,7 @@ ConstraintSystem::applySolution(Solution &solution,
1002110021
{
1002210022
const auto &score = solution.getFixedScore();
1002310023
if (score.Data[SK_Fix] > numResolvableFixes || score.Data[SK_Hole] > 0) {
10024-
maybeProduceFallbackDiagnostic(target);
10024+
maybeProduceFallbackDiagnostic(target.getLoc());
1002510025
return std::nullopt;
1002610026
}
1002710027
}

lib/Sema/CSDiagnostics.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,11 @@ bool FailureDiagnostic::conformsToKnownProtocol(
236236
return TypeChecker::conformsToKnownProtocol(type, protocol);
237237
}
238238

239+
bool FallbackDiagnostic::diagnoseAsError() {
240+
getConstraintSystem().maybeProduceFallbackDiagnostic(getLoc());
241+
return true;
242+
}
243+
239244
Type RequirementFailure::getOwnerType() const {
240245
auto anchor = getAnchor();
241246
// If diagnostic is anchored at assignment expression

lib/Sema/CSDiagnostics.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,15 @@ class FailureDiagnostic {
210210
llvm::SmallVectorImpl<char> &scratch) const;
211211
};
212212

213+
/// Emits a fallback diagnostic message if no other error has been emitted.
214+
class FallbackDiagnostic final : public FailureDiagnostic {
215+
public:
216+
FallbackDiagnostic(const Solution &solution, ConstraintLocator *locator)
217+
: FailureDiagnostic(solution, locator) {}
218+
219+
bool diagnoseAsError() override;
220+
};
221+
213222
/// Base class for all of the diagnostics related to generic requirement
214223
/// failures, provides common information like failed requirement,
215224
/// declaration where such requirement comes from, etc.

lib/Sema/CSFix.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2187,7 +2187,10 @@ AllowKeyPathWithoutComponents::create(ConstraintSystem &cs,
21872187

21882188
bool IgnoreInvalidResultBuilderBody::diagnose(const Solution &solution,
21892189
bool asNote) const {
2190-
return true; // Already diagnosed by `matchResultBuilder`.
2190+
// This should already be diagnosed by `matchResultBuilder`, emit a fallback
2191+
// diagnostic if not.
2192+
FallbackDiagnostic diag(solution, getLocator());
2193+
return diag.diagnose(asNote);
21912194
}
21922195

21932196
IgnoreInvalidResultBuilderBody *
@@ -2198,7 +2201,10 @@ IgnoreInvalidResultBuilderBody::create(ConstraintSystem &cs,
21982201

21992202
bool IgnoreInvalidASTNode::diagnose(const Solution &solution,
22002203
bool asNote) const {
2201-
return true; // Already diagnosed by the producer of ErrorExpr or ErrorType.
2204+
// This should already be diagnosed by the producer of ErrorExpr or ErrorType,
2205+
// emit a fallback diagnostic if not.
2206+
FallbackDiagnostic diag(solution, getLocator());
2207+
return diag.diagnose(asNote);
22022208
}
22032209

22042210
IgnoreInvalidASTNode *IgnoreInvalidASTNode::create(ConstraintSystem &cs,

lib/Sema/CSSolver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1457,7 +1457,7 @@ ConstraintSystem::solve(SyntacticElementTarget &target,
14571457
}
14581458

14591459
case SolutionResult::Error:
1460-
maybeProduceFallbackDiagnostic(target);
1460+
maybeProduceFallbackDiagnostic(target.getLoc());
14611461
return std::nullopt;
14621462

14631463
case SolutionResult::TooComplex: {

lib/Sema/ConstraintSystem.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4875,8 +4875,7 @@ bool ConstraintSystem::isConformanceUnavailable(ProtocolConformanceRef conforman
48754875

48764876
/// If we aren't certain that we've emitted a diagnostic, emit a fallback
48774877
/// diagnostic.
4878-
void ConstraintSystem::maybeProduceFallbackDiagnostic(
4879-
SyntacticElementTarget target) const {
4878+
void ConstraintSystem::maybeProduceFallbackDiagnostic(SourceLoc loc) const {
48804879
if (Options.contains(ConstraintSystemFlags::SuppressDiagnostics))
48814880
return;
48824881

@@ -4888,7 +4887,7 @@ void ConstraintSystem::maybeProduceFallbackDiagnostic(
48884887
(diagnosticTransaction && diagnosticTransaction->hasErrors()))
48894888
return;
48904889

4891-
ctx.Diags.diagnose(target.getLoc(), diag::failed_to_produce_diagnostic);
4890+
ctx.Diags.diagnose(loc, diag::failed_to_produce_diagnostic);
48924891
}
48934892

48944893
SourceLoc constraints::getLoc(ASTNode anchor) {

0 commit comments

Comments
 (0)