Skip to content

Commit f15a0b1

Browse files
committed
[CSFix] Detect conflicting pattern variables
The fix indentifies the conflicting variables and the expected "join" type e.g. `case .a(let x), .b(let x)` where `a(Int)` and `b(String)`.
1 parent 1099cca commit f15a0b1

File tree

3 files changed

+66
-1
lines changed

3 files changed

+66
-1
lines changed

include/swift/Sema/CSFix.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,10 @@ enum class FixKind : uint8_t {
398398
/// Coerce a result type of a call to a particular existential type
399399
/// by adding `as any <#Type#>`.
400400
AddExplicitExistentialCoercion,
401+
402+
/// For example `.a(let x), .b(let x)` where `x` gets bound to different
403+
/// types.
404+
RenameConflictingPatternVariables,
401405
};
402406

403407
class ConstraintFix {
@@ -3016,6 +3020,50 @@ class AddExplicitExistentialCoercion final : public ConstraintFix {
30163020
ConstraintLocator *locator);
30173021
};
30183022

3023+
class RenameConflictingPatternVariables final
3024+
: public ConstraintFix,
3025+
private llvm::TrailingObjects<RenameConflictingPatternVariables,
3026+
VarDecl *> {
3027+
friend TrailingObjects;
3028+
3029+
Type ExpectedType;
3030+
unsigned NumConflicts;
3031+
3032+
RenameConflictingPatternVariables(ConstraintSystem &cs, Type expectedTy,
3033+
ArrayRef<VarDecl *> conflicts,
3034+
ConstraintLocator *locator)
3035+
: ConstraintFix(cs, FixKind::RenameConflictingPatternVariables, locator),
3036+
ExpectedType(expectedTy), NumConflicts(conflicts.size()) {
3037+
std::uninitialized_copy(conflicts.begin(), conflicts.end(),
3038+
getConflictingBuffer().begin());
3039+
}
3040+
3041+
MutableArrayRef<VarDecl *> getConflictingBuffer() {
3042+
return {getTrailingObjects<VarDecl *>(), NumConflicts};
3043+
}
3044+
3045+
public:
3046+
std::string getName() const override { return "rename pattern variables"; }
3047+
3048+
ArrayRef<VarDecl *> getConflictingVars() const {
3049+
return {getTrailingObjects<VarDecl *>(), NumConflicts};
3050+
}
3051+
3052+
bool diagnose(const Solution &solution, bool asNote = false) const override;
3053+
3054+
bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override {
3055+
return diagnose(*commonFixes.front().first);
3056+
}
3057+
3058+
static RenameConflictingPatternVariables *
3059+
create(ConstraintSystem &cs, Type expectedTy, ArrayRef<VarDecl *> conflicts,
3060+
ConstraintLocator *locator);
3061+
3062+
static bool classof(ConstraintFix *fix) {
3063+
return fix->getKind() == FixKind::RenameConflictingPatternVariables;
3064+
}
3065+
};
3066+
30193067
} // end namespace constraints
30203068
} // end namespace swift
30213069

lib/Sema/CSFix.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2424,3 +2424,19 @@ AddExplicitExistentialCoercion::create(ConstraintSystem &cs, Type resultTy,
24242424
return new (cs.getAllocator())
24252425
AddExplicitExistentialCoercion(cs, resultTy, locator);
24262426
}
2427+
2428+
bool RenameConflictingPatternVariables::diagnose(const Solution &solution,
2429+
bool asNote) const {
2430+
return false;
2431+
}
2432+
2433+
RenameConflictingPatternVariables *
2434+
RenameConflictingPatternVariables::create(ConstraintSystem &cs, Type expectedTy,
2435+
ArrayRef<VarDecl *> conflicts,
2436+
ConstraintLocator *locator) {
2437+
unsigned size = totalSizeToAlloc<VarDecl *>(conflicts.size());
2438+
void *mem = cs.getAllocator().Allocate(
2439+
size, alignof(RenameConflictingPatternVariables));
2440+
return new (mem)
2441+
RenameConflictingPatternVariables(cs, expectedTy, conflicts, locator);
2442+
}

lib/Sema/CSSimplify.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12908,7 +12908,8 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
1290812908
case FixKind::SpecifyTypeForPlaceholder:
1290912909
case FixKind::AllowAutoClosurePointerConversion:
1291012910
case FixKind::IgnoreKeyPathContextualMismatch:
12911-
case FixKind::NotCompileTimeConst: {
12911+
case FixKind::NotCompileTimeConst:
12912+
case FixKind::RenameConflictingPatternVariables: {
1291212913
return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved;
1291312914
}
1291412915

0 commit comments

Comments
 (0)