Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/swift/Sema/ConstraintSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -5736,7 +5736,7 @@ class ConstraintSystem {

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

/// Check whether given AST node represents an argument of an application
/// of some sort (call, operator invocation, subscript etc.)
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/CSApply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10021,7 +10021,7 @@ ConstraintSystem::applySolution(Solution &solution,
{
const auto &score = solution.getFixedScore();
if (score.Data[SK_Fix] > numResolvableFixes || score.Data[SK_Hole] > 0) {
maybeProduceFallbackDiagnostic(target);
maybeProduceFallbackDiagnostic(target.getLoc());
return std::nullopt;
}
}
Expand Down
5 changes: 5 additions & 0 deletions lib/Sema/CSDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,11 @@ bool FailureDiagnostic::conformsToKnownProtocol(
return TypeChecker::conformsToKnownProtocol(type, protocol);
}

bool FallbackDiagnostic::diagnoseAsError() {
getConstraintSystem().maybeProduceFallbackDiagnostic(getLoc());
return true;
}

Type RequirementFailure::getOwnerType() const {
auto anchor = getAnchor();
// If diagnostic is anchored at assignment expression
Expand Down
9 changes: 9 additions & 0 deletions lib/Sema/CSDiagnostics.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,15 @@ class FailureDiagnostic {
llvm::SmallVectorImpl<char> &scratch) const;
};

/// Emits a fallback diagnostic message if no other error has been emitted.
class FallbackDiagnostic final : public FailureDiagnostic {
public:
FallbackDiagnostic(const Solution &solution, ConstraintLocator *locator)
: FailureDiagnostic(solution, locator) {}

bool diagnoseAsError() override;
};

/// Base class for all of the diagnostics related to generic requirement
/// failures, provides common information like failed requirement,
/// declaration where such requirement comes from, etc.
Expand Down
10 changes: 8 additions & 2 deletions lib/Sema/CSFix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2187,7 +2187,10 @@ AllowKeyPathWithoutComponents::create(ConstraintSystem &cs,

bool IgnoreInvalidResultBuilderBody::diagnose(const Solution &solution,
bool asNote) const {
return true; // Already diagnosed by `matchResultBuilder`.
// This should already be diagnosed by `matchResultBuilder`, emit a fallback
// diagnostic if not.
FallbackDiagnostic diag(solution, getLocator());
return diag.diagnose(asNote);
}

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

bool IgnoreInvalidASTNode::diagnose(const Solution &solution,
bool asNote) const {
return true; // Already diagnosed by the producer of ErrorExpr or ErrorType.
// This should already be diagnosed by the producer of ErrorExpr or ErrorType,
// emit a fallback diagnostic if not.
FallbackDiagnostic diag(solution, getLocator());
return diag.diagnose(asNote);
}

IgnoreInvalidASTNode *IgnoreInvalidASTNode::create(ConstraintSystem &cs,
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/CSSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1457,7 +1457,7 @@ ConstraintSystem::solve(SyntacticElementTarget &target,
}

case SolutionResult::Error:
maybeProduceFallbackDiagnostic(target);
maybeProduceFallbackDiagnostic(target.getLoc());
return std::nullopt;

case SolutionResult::TooComplex: {
Expand Down
5 changes: 2 additions & 3 deletions lib/Sema/ConstraintSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4875,8 +4875,7 @@ bool ConstraintSystem::isConformanceUnavailable(ProtocolConformanceRef conforman

/// If we aren't certain that we've emitted a diagnostic, emit a fallback
/// diagnostic.
void ConstraintSystem::maybeProduceFallbackDiagnostic(
SyntacticElementTarget target) const {
void ConstraintSystem::maybeProduceFallbackDiagnostic(SourceLoc loc) const {
if (Options.contains(ConstraintSystemFlags::SuppressDiagnostics))
return;

Expand All @@ -4888,7 +4887,7 @@ void ConstraintSystem::maybeProduceFallbackDiagnostic(
(diagnosticTransaction && diagnosticTransaction->hasErrors()))
return;

ctx.Diags.diagnose(target.getLoc(), diag::failed_to_produce_diagnostic);
ctx.Diags.diagnose(loc, diag::failed_to_produce_diagnostic);
}

SourceLoc constraints::getLoc(ASTNode anchor) {
Expand Down
8 changes: 5 additions & 3 deletions lib/Sema/TypeCheckType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2637,10 +2637,12 @@ static Type evaluateTypeResolution(const TypeResolution *resolution,
TypeResolver(*resolution, silContext)
.resolveType(TyR, resolution->getOptions());

// If we resolved down to an error, make sure to mark the typeRepr as invalid
// so we don't produce a redundant diagnostic.
// If we resolved down to an error, and we haven't silenced diagnostics, make
// sure to mark the typeRepr as invalid so we don't produce a redundant
// diagnostic.
if (result->hasError()) {
TyR->setInvalid();
if (!options.contains(TypeResolutionFlags::SilenceErrors))
TyR->setInvalid();
return result;
}

Expand Down
14 changes: 14 additions & 0 deletions test/Constraints/patterns.swift
Original file line number Diff line number Diff line change
Expand Up @@ -820,3 +820,17 @@ do {
}
}
}

// Make sure we diagnose 'Undefined' here.
func testUndefinedTypeInPattern(_ x: Int) {
switch x {
case Optional<Undefined>.alsoUndefined: // expected-error {{cannot find type 'Undefined' in scope}}
break
}
_ = {
switch x {
case Optional<Undefined>.alsoUndefined: // expected-error {{cannot find type 'Undefined' in scope}}
break
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// {"kind":"typecheck","original":"b7a10f72","signature":"(anonymous namespace)::Verifier::walkToExprPre(swift::Expr*)","signatureAssert":"Assertion failed: ((HadError || !isa<SourceFile *>(M) || cast<SourceFile *>(M)->ASTStage < SourceFile::TypeChecked) && \"OverloadedDeclRef\" \"in wrong phase\"), function walkToExprPre"}
// RUN: not --crash %target-swift-frontend -typecheck %s
// RUN: not %target-swift-frontend -typecheck %s
func a(b : Int) {
_ = {
switch b {
Expand Down