Skip to content

Commit 62ba749

Browse files
committed
[Diagnostics] Diagnose conflicting pattern variables
Diagnose situations where pattern variables with the same name have conflicting types: ```swift enum E { case a(Int) case b(String) } func test(e: E) { switch e { case .a(let x), .b(let x): ... } } ``` In this example `x` is bound to `Int` and `String` at the same time which is incorrect.
1 parent f15a0b1 commit 62ba749

File tree

3 files changed

+47
-1
lines changed

3 files changed

+47
-1
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8212,3 +8212,12 @@ void MissingExplicitExistentialCoercion::fixIt(
82128212
"as " + ErasedResultType->getString(printOpts) +
82138213
(requiresParens ? ")" : ""));
82148214
}
8215+
8216+
bool ConflictingPatternVariables::diagnoseAsError() {
8217+
for (auto *var : Vars) {
8218+
emitDiagnosticAt(var->getStartLoc(),
8219+
diag::type_mismatch_multiple_pattern_list, getType(var),
8220+
ExpectedType);
8221+
}
8222+
return true;
8223+
}

lib/Sema/CSDiagnostics.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2764,6 +2764,41 @@ class MissingExplicitExistentialCoercion final : public FailureDiagnostic {
27642764
bool fixItRequiresParens() const;
27652765
};
27662766

2767+
/// Diagnose situations where pattern variables with the same name
2768+
/// have conflicting types:
2769+
///
2770+
/// \code
2771+
/// enum E {
2772+
/// case a(Int)
2773+
/// case b(String)
2774+
/// }
2775+
///
2776+
/// func test(e: E) {
2777+
/// switch e {
2778+
/// case .a(let x), .b(let x): ...
2779+
/// }
2780+
/// }
2781+
/// \endcode
2782+
///
2783+
/// In this example `x` is bound to `Int` and `String` at the same
2784+
/// time which is incorrect.
2785+
class ConflictingPatternVariables final : public FailureDiagnostic {
2786+
Type ExpectedType;
2787+
SmallVector<VarDecl *, 4> Vars;
2788+
2789+
public:
2790+
ConflictingPatternVariables(const Solution &solution, Type expectedTy,
2791+
ArrayRef<VarDecl *> conflicts,
2792+
ConstraintLocator *locator)
2793+
: FailureDiagnostic(solution, locator),
2794+
ExpectedType(resolveType(expectedTy)),
2795+
Vars(conflicts.begin(), conflicts.end()) {
2796+
assert(!Vars.empty());
2797+
}
2798+
2799+
bool diagnoseAsError() override;
2800+
};
2801+
27672802
} // end namespace constraints
27682803
} // end namespace swift
27692804

lib/Sema/CSFix.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2427,7 +2427,9 @@ AddExplicitExistentialCoercion::create(ConstraintSystem &cs, Type resultTy,
24272427

24282428
bool RenameConflictingPatternVariables::diagnose(const Solution &solution,
24292429
bool asNote) const {
2430-
return false;
2430+
ConflictingPatternVariables failure(solution, ExpectedType,
2431+
getConflictingVars(), getLocator());
2432+
return failure.diagnose(asNote);
24312433
}
24322434

24332435
RenameConflictingPatternVariables *

0 commit comments

Comments
 (0)